On Thu, Nov 6, 2014 at 2:44 AM, Sanford Whiteman <figureone...@gmail.com> wrote:
> > The HTTP specification doesn't restrict how the request body is encoded > > based on the request verb. > > I never said it did... please don't put words in my mouth. > > As Will notes, you're sidestepping the point, which standards-savvy > people have been driving at for years: the semantic differences (== > intent, == meaning) among HTTP methods. HTTP specifications *do* > define -- in your words, "restrict" -- the intended disposition of the > entity-body based on the HTTP method. The methods *do* distinguish > whether the entity-body is intended as a precomposed resource to be > stored at the request-URI (PUT) -- or whether it may contain key-value > strings, multipart MIME data, or arbitrary text and/or binary data > ranges (POST) which must be interpreted by application code at the > request-URI (which must itself exist) as they have no inherent final > disposition. > > It's easy to certify the semantics in your lab. > > Set up a capable web server with no preprocessor at all (no PHP, no > SSI, nothing). Choose a URI that currently returns a 404, like > /test.abc. PUT a well-formed multipart/form-data body to that URI. > What you will get is the entire multipart stored within the filesystem > at the mapped URI. And provided the server's file extension <-> MIME > mappings are consistent, you'll then be able to GET the file as > multipart/form-data. > > Now POST that body to another nonexistent URI. You'll get a 404 or > 405. Full stop. > > This core difference is really not that hard to understand, and > there's no reason for PHP to act, stupidly, like it it isn't there (as > in make-people-dumber stupid, not make-life-easy stupid). > First off, let's make some discrepancies abundantly clear. PUT is not intended to necessarily store the request entity body on the file system. Its intention is to store the entity body at the request URI. That is to say, the URI !== File System. So this unfounded claim that decomposition should not happen within PHP at the request level, isn't a justification for prohibiting PHP from decomposing the body. For example, if the Content-type designated in the request indicates application/binary it is safe to say that PHP should not attempt to disassemble the input stream beyond applying the decoding from the Content-encoding header (which may actually happen at the web server level). However, in this event it would make it a lot more convenient for the client if the entity is stored in $_FILES where its access is still more manageable through the receiving code. Wherein one can take advantage of reliable features such as move_uploaded_file(), which inhibit some security measures that would be beneficial to the user. Again, we haven't changed the intent of the request by making it easier for the user to take advantage of existing PHP features to service said request. We also haven't we changed the typical outcome of this request, because through today's work-flow the input stream remains at the discretion of the user. With the change of storing the input stream in $_FILES, the temporary file gets discarded by PHP if the user doesn't move it. Same thing if they don't do anything with the input stream (today). Additionally, I don't believe that this makes PHP or its users any "dumber". It just makes handling the request in PHP more consistent and intuitive. This has both added convenience as well as added performance and security benefits by taking advantage of already existing functionality in PHP. I completely understand, however, that the existing functionality only targets form data. So while PUT requests aren't form data, they are still very much a part of the overall handling of requests that can be sent to PHP. So why not expand the same functionality to also target those use cases? While you may see this as a fundamental change in the way PHP works, it's not actually too far off from what PHP had always intended (which was dealing with the web in the first place). It just so happens that PHP's primary intention has been outgrown by the evolution of the web, which now entails more RESTful APIs than before. > > > multipart form data is useful for including both form data and binary > data with successive parts > > Of course. Multipart MIME is also key to the modern e-mail ecosystem. > And, similarly, multipart e-mails are kept as opaque as possible in > transit. Antivirus and spam scanners need to peek inside multipart > mail, but they don't decompose them and put the parts back on the wire > separately, because that is not the meaning of "transfer this e-mail." > Neither do end-user apps aim to decompose MIME messages when they're > idling in a message db, because that's not the meaning of "save this > e-mail." On the other hand multiparts *are* intended to be decomposed > by mail apps when a user opens them: in that case, there's a clear > semantic justification for expanding the contents for the user: "read > this e-mail." > > In sum, "multipart is useful" is quite obviously true, but it's a > straw man, as it does not respond to the question about expanding > multipart entities in all contexts. > > Sure, they are in transit up until they reach PHP. At which point they have reached an end point capable of dealing with the request. In this analogy, PHP would be the mail app. It would deal with both the opening and facilitating of the message, because it very well may need to decompose that message before storing it and then reassemble it in the retrieval phase. It also may not have to, but that's up to the user writing the PHP code on how they chose to deal with that part. Because PHP is a pre-processor, after all. It's job is to assemble and disassemble information in order to facilitate the request/response model that it's built on. Also, I think you're the one creating the straw man here as nothing in the spec prohibits the use of a multipart mime based on the request verb. So we aren't expanding it to all contexts since its context remains intact. It's a media type intended to disclose itself to the server for the purpose of identifying the enclosed body. It's still up to the server how to handle that media type. No one says you may not decompose the multipart mime at the server level. > > but many APIs may apply a PUT request using multipart form > > People do dumb things. You haven't answered why they would fixate upon > PUT, since they cannot possibly lack support for POST. What, now for > the umpteenth++ time, is the technical/business/personal justification > for this design, with POST available? Again this whole debate is > upside down. People have to *choose* to use PUT, even in cURL. It > doesn't happen by accident. It's not the XMLHttpRequest default. It > can't happen from an HTML form. Why are they doing it? > I think you're losing sight of the intent here. We're talking about people trying to build RESTful APIs. Meaning that the intent of PUT varies from POST. If you wanted to build a RESTful API similar to that of Google Drive, for example, you wouldn't use POST to create new files on the drive. You would want your API to make intentions very clear to differentiate between POST/PUT/DELETE and so on... So the justification for using PUT is self-serving. The choice of wanting to use a multipart mime is not for us to try and justify. Why would you prohibit the user on the content-type if the very protocol doesn't? We're just trying to make it easier for them to handle that request as many are clearly struggling with it. Finally I'd like to say that... I think a lot of these arguments against allowing PHP to do something are very opinionated and shouldn't be the basis of our decision. I think that the decision to let PHP do something should be based on need, feasibility, and maintainability, as they have usually been in the past. The idea of letting PHP deal with PUT and other request verbs as consistently as it deals with POST and GET is clearly needed. Whether or not some people like it isn't important. What's important is that it's feasible (or seemingly so up until this point) and only the actual implementation can prove its maintainability. So I'd much rather focus on analyzing these points rather than the opinions of whether not someone thinks one way of doing things is considered under the guise of REST or not. Or whether not PHP should be allowed to handle things other than form data. Why wouldn't it? PHP is a web-focused language. This is an HTTP-specific problem and PHP is capable of handling it.