-
-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multipart handling #13
Conversation
Future change will be made and the class will become a body parser as well
- fixed the header overflow - added the body to the Request - parse POST form the body content or as multipart/form-data - handle file uploads - use Content-Length to know when the content arrived
Hi @onigoetz Thank you very much for your hard work and contribution. This is absolutely something we want! My apologies it's taking so long, this PR is coming up on my todo list of things to review. |
$content = ltrim($content, "\r\n"); | ||
|
||
$path = tempnam(sys_get_temp_dir(), "php"); | ||
$err = file_put_contents($path, $content); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Filesystem interactions block. We can't have these in the library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for your input. but then how could we handle file uploads ?
Keeping them in memory is too dangerous because of the size these uploads could be.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Following the Single Responsibility Principle the library should be all things handling and serving HTTP. How to transfer a file is defined in the HTTP specification but not how to save it. I think at this point instead of writing to a file we should provide indirection for the user to handle the file in chunks.
For example if I were implementing this I think I would want a callback to receive a file in chunks and as I received each chunk I would pipe it to a file using react/filesystem or perhaps pipe it to a worker script that writes to disk (but blocks).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for the idea, I'll figure something out and update the pull request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Imho it would be better when you use streams and pass those along. That way the developer can decide what to do with the contents of the stream.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You think one stream per fileupload or the raw stream ?
I'll look how I can do that, I'm not a stream expert
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A stream per fileupload. Ping me on IRC or on twitter if you have questions about that. Happy to help :).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have suggestion about how to do that:
- add one more argument (callable or factory) for handling file uploads to server constructor
- then when it comes to file handling we just call callable or factory (with arguments like file name, mime type) and pass everything to method of object it returned (if there was no callable or factory - just ignore uploaded file, it is too expensive to store it in memory)
- after whole request parsed we'll have access to array with all objects we've created for uploaded files
What you think about such approach?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your ideas, I will try to make it this week.
# By Michael Arenzon # Via Chris Boden (1) and Michael Arenzon (1) * 'master' of github.com:reactphp/http: just for better ide completion
@onigoetz after reading you're message here reactphp/reactphp#3 (comment) want me to look into that for you and make a PR on your PR? |
@WyriHaximus yes I would be very happy if you can help on the matter. |
@onigoetz I'll look into it tonight or tomorrow 👍 |
Any progress on that? |
None one my part, @WyriHaximus were you able to take a look ? |
I did take a look, started writing some code and got stuck at the time.
Will revisit it soon to see if I can work it out this time.
|
* source/master: Removed a blank as pointed out in this comment: 10af1f5#commitcomment-11894795 Added 0.4.1 Use new Guzzle PSR7 parser Test against PHP7 Adding Code Climate badge to readme # Conflicts: # src/RequestHeaderParser.php
Hi guys, I updated my fork to be up to date with all the changes on the master branch. I also changed the logic to not store the file upload in temp files, but keep them in a stream. I think this PR could be merged as-is and another pull-request could finish the work I started. What do you think ? As things are working pretty well on the multipart handling part. |
@onigoetz cheers looks good, will have a go with it again this weekend. My apologies for not getting back to you last time. I've looked into converting it into a stream streaming files and that looked harder then expected at the time. Going to either a special stream/buffer for it and do a follow up PR getting that in. This next bit is a braindump from a previous chat on IRC about it. The idea was to emit events on files found in the stream and also on multipart bits. Since steaming support also has to be done I can include the above bit in that PR as well :). |
I'll follow this up shortly with another PR before tagging it. Thanks for the work 👍 |
Can't believe it was finally merged) Yay! |
👍 awesome ! |
@onigoetz will try to dedicate as mush OSS time as I can on the follow up. Will comment here when the initial WIP PR is up |
Awesome! Cant believe tooo 👍 |
As much as I'd love to see multipart handling in here, I have to admit I'm not a big fan of the current implementation. I think it's important to consider that HTTP request bodies can be of arbitrary sizes. While a common form submission only results in a few (kilo)bytes of data, it's quite common to use HTTP-based APIs to transmit multi-megabytes of data. The same applies to uploading files via HTML forms or using CLI-based tools to trigger similar HTTP requests. Admittedly, a streaming approach where only small chunks are kept in memory is probably slightly more complicated to implement and likely more difficult to consume from a user perspective. FWIW, a streaming approach could probably look somewhat similar to a TAR-file decoder which emits an event for each part and then only streams its contents. I have to admit I hate posting links to my own libraries, but perhaps https://github.com/clue/php-tar-react could be a good start here? Any considerations? |
@clue working on a streaming implementation inspired by clue/php-tar-react 👍 |
@WyriHaximus Awesome, keep me posted! Would love to take a look at this eventually |
@clue will do, gained some good experience with out-of-the-box streams in https://github.com/reactphp/filesystem so it should be a matter get getting into the flow |
I admit my first implementation was very naive and I wanted to make a streaming implementation after a first working version, sadly I did not have time to do so. """ Stéphane Goetz Mobile : +41 79/824.77.68 On 4 sept. 2015 20:19 +0200, Cees-Jan [email protected], wrote:
|
#41 is the follow up PR, feedback is welcome |
This effectively reverts to 8602944, thus reverting reactphp#13, reactphp#37, reactphp#45 and reactphp#47
Hello,
I added basic support for multipart for files and POST requests
I also wrote the unit tests for this part and improved the existing ones.
One thing that could be done better is that now, it waits for the whole body before it parses it, we could implement a system where it feeds the content to the parser and the files are created on the fly and we don't use the whole memory for file uploads.