简体   繁体   中英

Java Socket Programming - 301 Error with HTTP 1.1

I just start learning socket programming with Java and I already encountered an unusual behavior. Here's the code snippet

writer.println("GET " + path + " " + protocol);
//writer.println();
writer.println("Host: " + hostname);
writer.println();
writer.flush();

This will give me "301 Moved Permanently" code with both HTTP 1.1 and 1.0. If I uncomment the empty line between the request and host name

writer.println("GET " + path + " " + protocol);
writer.println();
writer.println("Host: " + hostname);
writer.println();
writer.flush();

It would give me "HTTP/1.1 400 Bad Request" for HTTP 1.1 and "HTTP/1.1 200 OK" for HTTP 1.0.

Why does it have such behavior? Does this happen because we have the request in HTTP 1.0 and the response is in HTTP 1.1?

Thanks.

This will give me "301 Moved Permanently" code with both HTTP 1.1 and 1.0.

HTTP status code 301 is a redirect to a new URL:

The requested resource has been assigned a new permanent URI and any future references to this resource SHOULD use one of the returned URIs. Clients with link editing capabilities ought to automatically re-link references to the Request-URI to one or more of the new references returned by the server, where possible. This response is cacheable unless indicated otherwise.

The new permanent URI SHOULD be given by the Location field in the response. Unless the request method was HEAD, the entity of the response SHOULD contain a short hypertext note with a hyperlink to the new URI(s).

If the 301 status code is received in response to a request other than GET or HEAD, the user agent MUST NOT automatically redirect the request unless it can be confirmed by the user, since this might change the conditions under which the request was issued.

Note: When automatically redirecting a POST request after receiving a 301 status code, some existing HTTP/1.0 user agents will erroneously change it into a GET request.

The server is telling you that the URL you sent your GET request to is no longer valid. You need to extract the value of the Location header from the server's response and then repeat the same request to the specified URL.

It would give me "HTTP/1.1 400 Bad Request" for HTTP 1.1 and "HTTP/1.1 200 OK" for HTTP 1.0.

Why does it have such behavior? Does this happen because we have the request in HTTP 1.0 and the response is in HTTP 1.1?

The Host header is optional in HTTP 1.0 but is required in HTTP 1.1:

A client MUST include a Host header field in all HTTP/1.1 request messages. If the requested URI does not include an Internet host name for the service being requested, then the Host header field MUST be given with an empty value. An HTTP/1.1 proxy MUST ensure that any request message it forwards does contain an appropriate Host header field that identifies the service being requested by the proxy. All Internet-based HTTP/1.1 servers MUST respond with a 400 (Bad Request) status code to any HTTP/1.1 request message which lacks a Host header field.

So, when you do not insert the extra blank line, you end up sending these requests separately:

GET /path HTTP/1.0
Host: hostname

GET /path HTTP/1.1
Host: hostname

Which are both valid.

But, when you insert the extra blank line, you are actually sending two separate requests at one time:

GET /path HTTP/1.x;

Host: hostname

The request headers and request body are separated by a blank line, and a GET request does not have a request body, so the first blank line ends the request.

So, in this case, the first request is valid only for HTTP 1.0 and is invalid for HTTP 1.1 because the Host header is missing. The second request is just plain invalid in either version.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM