Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
364 views
in Technique[技术] by (71.8m points)

php - Is $_SERVER['REQUEST_METHOD'] guaranteed to be uppercase?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Short answer: no, it's not guaranteed, but normally receiving a non-uppercase HTTP method means that the client was in violation of spec.

Long answer:

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 "
"
The method used by your request was GET
$ curl http://localhost/echo_method.php -X gEt -w "
"
The method used by your request was gEt
$ curl http://localhost/echo_method.php -X fWoRbLeWoRbLe -w "
"
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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...