Description
Description
The following code:
<?php
echo file_get_contents('http://127.0.0.1:8080/test', false, stream_context_create(['http' => ['method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query(['hello' => 'world'])]]));
echo file_get_contents('http://127.0.0.1:8080/test', false, stream_context_create(['http' => ['method' => 'PATCH', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query(['hello' => 'world'])]]));
echo file_get_contents('http://127.0.0.1:8080/test/', false, stream_context_create(['http' => ['method' => 'POST', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query(['hello' => 'world'])]]));
echo file_get_contents('http://127.0.0.1:8080/test/', false, stream_context_create(['http' => ['method' => 'PATCH', 'header' => 'Content-type: application/x-www-form-urlencoded', 'content' => http_build_query(['hello' => 'world'])]]));
Resulted in this output:
{"method":"GET"}
{"method":"GET"}
{"hello":"world","method":"POST"}
{"hello":"world","method":"PATCH"}
But I expected this output instead:
{"hello":"world","method":"POST"}
{"hello":"world","method":"PATCH"}
{"hello":"world","method":"POST"}
{"hello":"world","method":"PATCH"}
The server on 127.0.0.1:8080 is this small Flask app (I'm not really a PHP person anymore so I couldn't be bothered to use PHP for this after not having written any PHP code in the last 15 or so years ;)):
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test/', methods=['GET', 'POST', 'PATCH'])
def test():
return jsonify(method=request.method, **request.form)
app.run(port=8080)
When sending a request to the URL without the trailing slash, it uses a HTTP 308 redirect to redirect to the URL with that slash.
Clients are required to keep the method and payload when encountering such a redirect:
See MDN:
The request method and the body will not be altered, whereas 301 may incorrectly sometimes be changed to a GET method.
And even RFC7538 specifying this status code is pretty clear about the expected behavior from clients:
Note: This status code is similar to 301 (Moved Permanently) ([RFC7231], Section 6.4.2), except that it does not allow changing the request method from POST to GET.
PHP Version
8.2.6
Operating System
No response