Closed Schaumbaum closed 8 years ago
I believe _method is only read as a pseudo request if it is sent in a post request.
See the docs here: https://laravel.com/docs/5.2/routing#form-method-spoofing
Thanks for your remark. I have checked this and it is like you said, the "_method" parameter seems only to be resolved for POST requests. I have updated my question regarding to this. But now Laravels behavior looks even more Inconsistent to me than before. One POST request is redirected with POST and the other with GET.
Have you tried it without the post request and just the put request? Does laravel read the post with _method=put and trigger the put route?
All three requests trigger the PUT route (/), but then they are redirected to different routes.
When checking the used method with
$request->method();
all three are resolved as PUT requests (before the redirect).
Hmmm, Mite be better to hear something from @GrahamCampbell or @taylorotwell see if this is intended behaviour or not
The method spoofing with _method
is only enabled for http posts since it's a workaround for browser forms only supporting get and post. A client able to send put/delete requests directly has no need for it.
The docs for curl 7.43.0 states...
-L, --location (HTTP/HTTPS) If the server reports that the requested page has moved to a different location (indicated with a Location: header and a 3XX response code), this option will make curl redo the request on the new place. If used together with -i, --include or -I, --head, headers from all requested pages will be shown. When authentication is used, curl only sends its credentials to the initial host. If a redirect takes curl to a different host, it won't be able to intercept the user+password. See also --location-trusted on how to change this. You can limit the amount of redirects to follow by using the --max-redirs option.
When curl follows a redirect and the request is not a plain GET (for example POST or PUT), it will do the following request with a GET if the HTTP response was 301, 302, or 303. If the response code was any other 3xx code, curl will re-send the following request using the same unmodified method.
[...]
-X, --request
(HTTP) Specifies a custom request method to use when communicating with the HTTP server. The specified request method will be used instead of the method otherwise used (which defaults to GET). Read the HTTP 1.1 specification for details and explanations. Common additional HTTP requests include PUT and DELETE, but related technologies like WebDAV offers PROPFIND, COPY, MOVE and more. Normally you don't need this option. All sorts of GET, HEAD, POST and PUT requests are rather invoked by using dedicated command line options.
This option only changes the actual word used in the HTTP request, it does not alter the way curl behaves. So for example if you want to make a proper HEAD request, using -X HEAD will not suffice. You need to use the -I, --head option.
The method string you set with -X will be used for all requests, which if you for example use -L, --location may cause unintended side-effects when curl doesn't change request method according to the HTTP 30x response codes - and similar.
[...]
- `curl -L --data="_method="PUT"`` Issues a POST (since you've sending data), Laravel sees a PUT, and curl uses a GET for redirection.
curl -L -X POST --data "_method=PUT"
Same as above, but you force the redirection to use POST.curl -L -X PUT
Issues a PUT, and forces a PUT for redirection.
Basically, you're telling curl which http method to use for the redirect with -X, and not just the initial request. This isn't a Laravel issue, but just the way you tell curl to behave.
Thanks for your great answer. This totally makes sense. I haven't found any differences at Laravels redirect responses, because there weren't any. I was absolutely mislead, because the HTTP client (HttpRequester) I used before had the same behavior (maybe it uses curl under the hood). With this new knowledge I have checked more HTTP clients and some (for example Postman) are following the redirect (as expected by me) with a GET method. My conclusion is to be very careful with redirects within an API/Webservice context. Laravel is behaving correct. Therefore this issue can be closed.
When using a "native" HTTP PUT request (eg using CURL) I will be redirected to the main page (/) with a PUT request, while if using a HTTP POST request with a "_method=put" parameter (which is resolved as a PUT request within the Laravel framework) I'm redirected with a GET request, which in my opinion should be the behavior also with a "native" request. I'm using the Laravel Framework Version 5.2.35.
routes.php
requests
Addition: Checking the incoming curl requests with
$request->method();
shows that all are resolved as PUT requests, but the redirect differs for every request.