When Nginx encounters an HTTP delete request +iis deployment

Source: Internet
Author: User
Tags lowercase

A team retreat to develop an independent CS framework project, painstakingly came out the first version, the test passed, the online single server gray test through, very happy,
So go process official release, according to the general project deployment of distributed multiple servers, the result of the problem, many visits almost all reported 400 errors ...
The whole team, the weekend, the final positioning to the following features:
-Get/post/put request is normal, only delete request must now 400 error;
-individual host to back-end server is normal, only the reverse proxy of the access front Nginx error
-the same request, with Postman or fiddler composer sent to Nginx, but return to normal ...

Find OP assistance troubleshooting, OP troubleshooting results:
-There is no delete request log at all in the access_log of Nginx, and no Nginx forwarded delete requests are received on IIS
-Other requests like Get/post, Nginx and IIS have normal records.
-Nginx has been working properly, and has served dozens of items that also have a delete, and there have been no problems.

So, the team thought it was a C-terminal code problem, resulting in the delete request did not send out, or time out, on the repeated packaging version of the test, uncertain ...

The final question returned to my hand, because it is a C # project, and the online problem is a must, the first step is certainly to log, Webrequest.header and WebException.Response.Header print out, the project client code roughly abbreviated as follows:

public string getpage (string url, string param, Enummethod method, dictionary<string,string> header) {var request
  = (HttpWebRequest) webrequest.create (URL); Request. Method = method.
  ToString (); foreach (var pair in headers) {request. Headers.add (pair. Key, pair.
  Value); } if (!string. IsNullOrEmpty (param)) {byte[] L_data = encoding.
    GetBytes (param); Request. ContentLength = L_data.
    Length; using (Stream newstream = Request. GetRequestStream ()) {newstream.write (l_data, 0, L_data.)
        Length);
    Newstream.close (); } else request.
      contentlength = 0;
  HttpWebResponse response; try {response = (HttpWebResponse) request.
  GetResponse (); The catch (WebException webexp) {using (var Responseerr = (HttpWebResponse) webexp.response) using (var sr = new StreamReader (responseerr.stream, encoding)) {//Return of the header of the error request and response to print returns "Request header information : \ r \ n "+ request." Headers + "\r\n\r\n Response header information: \ r\ n "+ responseerr.headers +" \r\n\r\n Response content: \ r \ n "+ html;
        return HTML; }
  }

The error-response content that was printed is indeed returned by Nginx:

 

Strange, why not in the Nginx access log.
Then put the printed header exactly the same as the Fiddler composer Test, you can actually receive a normal 200 response,
In order to avoid environmental problems, but also put on my own machine testing, but also normal ...

In order to clarify the idea and use their familiar environment verification, I returned to my computer, a new project, pure handwritten a piece of code, a debugging, the results of the test passed, returned 200 ...

var request = (HttpWebRequest) webrequest.create ("http://xxx");
Request. method = "DELETE";
Request. Headers.add ("", ""); Add just those header
var response = (HttpWebResponse) request. GetResponse ();

Send the above code to the team, replace the old code, verify through ...
So a line of the recovery of the old code to verify, the final positioning, the problem is:equest. Method = method. ToString ();
Here is the "Delete", you have to pass the full capitalization, and I handwritten code, the habit of writing in uppercase, at first did not notice that the item is lowercase ...
Let the other party change to delete, solve the problem

Wait a minute, what's not right ...
Look at the Enummethod enumeration definition in the other project:

Public enum Enummethod
{get
  ,
  Post, put
  ,
  Delete
}

The other 3 get/post/put is also lowercase ah.
Decompile looked at the source code of WebRequest, in the execution: WebRequest. method = "POST"; , the code is invoked:

return knownhttpverb.namedheaders[(object) name] as Knownhttpverb?? 
    New Knownhttpverb (name, False, False, false, false);

And Knownhttpverb's definition is as follows, it automatically converts get/post/put to uppercase, there is no delete ... What the heck

And looked at the Nginx code: HTTPS://GITHUB.COM/NGINX/NGINX/BLOB/MASTER/SRC/HTTP/NGX_HTTP_PARSE.C
The inside is explicitly limited, only the method is supported, and the error is returned directly:

if (Ch < ' A ' | | ch > ' Z ') && ch!= ' _ ' && ch!= '-') {return
    Ngx_http_parse_invalid_method;
  }

To summarize the cause of the problem:
-team members are unfamiliar with the HTTP protocol, and the code uses lowercase method to send HTTP requests
- . NET bottom will automatically convert Get/post/put to uppercase and then send the request, but omitted the delete
-Nginx strictly follows the HTTP protocol, receiving only uppercase method;
-Nginx found lowercase method, returned the error directly, and skipped subsequent log steps

The detour of the investigation process:
-IIS is not case-sensitive, causing the test and single station to fail to authenticate to the problem;
-Nginx did not record the specific error log, unable to troubleshoot;
-Team members do not view webexception.response content and nginx The daily log, wasting a lot of time thinking that the code did not find the request;
-The Postman and fiddler composer Method is a Drop-down box that cannot be manually entered and therefore cannot be reproduced;
-In C # code, request. Headers does not include the requested method and URL, so it is not possible to verify the first time

At the end of the question, publicize the RFC2616 HTTP protocol standard, section 5.1.1: https://tools.ietf.org/html/rfc2616#section-5.1.1
It is clearly stated here that the method of HTTP request is case-sensitive.
You can search here: case-sensitive, know what content to be case-sensitive;
Search again: case-insensitive, know what is not case-sensitive.
Of course, for a qualified web Developer, learning and understanding the HTTP protocol is an essential knowledge.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.