I've currently got strtoupper($_SERVER['REQUEST_METHOD'])
in my code.
But is the strtoupper
call necessary? Is $_SERVER['REQUEST_METHOD']
guaranteed to be uppercase already?
Short answer: no, it's not guaranteed, but normally receiving a non-uppercase HTTP method means that the client was in violation of spec.
If you're dealing with methods defined by W3 specs, like GET and POST, then you're guaranteed that a spec-compliant client will send you them in uppercase. This is because HTTP methods are defined as case-sensitive...
The Method token indicates the method to be performed on the resource identified by the Request-URI. The method is case-sensitive.
and the W3-defined methods like OPTIONS, GET, POST etc. are defined in uppercase.
However, if you're dealing with a non-spec-compliant client, neither your webserver nor PHP will magically coerce the value of $_SERVER['REQUEST_METHOD']
to uppercase for you. This can be demonstrated easily with a simple script like this...
<?php
echo "The method used by your request was $_SERVER[REQUEST_METHOD]";
?>
If we hit that script with a HTTP request whose method is not uppercase, it will echo back the method in non-uppercase. Plenty of common tools will let us do this. For example, let's hit it from the UNIX shell:
$ curl http://localhost/echo_method.php -X GET -w "\n"
The method used by your request was GET
$ curl http://localhost/echo_method.php -X gEt -w "\n"
The method used by your request was gEt
$ curl http://localhost/echo_method.php -X fWoRbLeWoRbLe -w "\n"
The method used by your request was fWoRbLeWoRbLe
... or using Python:
>>> import httplib
>>> connection = httplib.HTTPConnection('localhost')
>>> connection.request('pOsT', '/echo_method.php')
>>> connection.getresponse().read()
'The method used by your request was pOsT'
"Okay", you might well say, "so there are potential problems if my API is being used by badly-written scripts or native applications. But my API is only used by AJAX calls triggered by JavaScript running in a web browser. Does this issue affect me?"
Unfortunately, yes. It seems that modern browsers coerce most of the standard HTTP methods to uppercase when sending AJAX, but do not currently do so for either custom HTTP methods or, notably, the PATCH method.
Hitting that same PHP script from before, this time at the Chrome JavaScript console...
var request;
request = new XMLHttpRequest();
request.open("GeT", "http://localhost/echo_method.php", true);
request.send();
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log(request.responseText);
}
}
yields the result
The method used by your request was GET
but changing the HTTP method to pATcH
gives us
var request;
request = new XMLHttpRequest();
request.open("pATcH", "http://localhost/echo_method.php", true);
request.send();
request.onreadystatechange = function() {
if (request.readyState == 4) {
console.log(request.responseText);
}
}
gives us
The method used by your request was pATcH
Worse, web browsers are not the only clients that will coerce all methods except the PATCH method to uppercase.
In conclusion: while the HTTP spec requires that requests include the HTTP method in uppercase (unless it's a custom method specifically defined in a different case), common web tools make it reasonably easy for front-end developers to get this wrong, and PHP's $_SERVER['REQUEST_METHOD']
variable will not magically coerce the method to uppercase for you if they do.
It's up to you, of course, whether you want to rely on your clients complying with spec, validate that the method is uppercase and respond with an appropriate status code (perhaps 400 or 405) and error message if it is not, or accept incorrectly-cased HTTP methods by coercing the method to uppercase yourself via strtoupper($_SERVER['REQUEST_METHOD'])
like the question asker here originally was.
RFC 3875 defines the REQUEST_METHOD
variable as upper case, so it's okay to rely on it.
The REQUEST_METHOD meta-variable MUST be set to the method which should be used by the script to process the request ...
REQUEST_METHOD = method method = "GET" | "POST" | "HEAD" | extension-method extension-method = "PUT" | "DELETE" | token
The method is case sensitive.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With