Java套接字编程 - HTTP 1.1的301错误

时间:2016-05-17 01:47:30

标签: java sockets http-headers http-1.1 http-1.0

我刚开始用Java学习套接字编程,我已经遇到了一个不寻常的行为。这是代码段

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

这将给我" 301永久移动" HTTP 1.1和1.0的代码。如果我取消注释请求和主机名之间的空行

[HttpPost]

它会为HTTP 1.1提供" HTTP / 1.1 400错误请求" " HTTP / 1.1 200 OK" 对于HTTP 1.0。

为什么会出现这种行为?这是否会发生,因为我们在HTTP 1.0中有请求而响应在HTTP 1.1中?

感谢。

1 个答案:

答案 0 :(得分:3)

  

这将给我" 301永久移动" HTTP 1.1和1.0的代码。

HTTP status code 301是重定向到新网址:

  

已为所请求的资源分配了一个新的永久URI,以及对此资源的任何后续引用应该使用其中一个返回的URI。具有链接编辑功能的客户端应该自动重新链接对Request的引用-URI到服务器返回的一个或多个新引用,如果可能的话。除非另有说明,否则此响应是可缓存的。

     

新的永久URI应该由响应中的Location字段给出。除非请求方法是HEAD,否则响应的实体应该包含一个带有指向新URI的超链接的短超文本注释。 (一个或多个)。

     

如果收到301状态代码以响应GET或HEAD以外的请求,则用户代理不得自动重定向请求,除非用户可以确认,因为这可能会改变请求的条件。发出的。

     

注意:在收到301状态代码后自动重定向POST请求时,某些现有的HTTP / 1.0用户代理会错误地将其更改为GET请求。

服务器告诉您,您发送GET请求的网址已不再有效。您需要从服务器的响应中提取Location标头的值,然后对指定的URL重复相同的请求。

  

它会给我" HTTP / 1.1 400 Bad Request"对于HTTP 1.1和" HTTP / 1.1 200 OK"对于HTTP 1.0。

     

为什么会出现这种行为?这是否会发生,因为我们在HTTP 1.0中有请求而响应在HTTP 1.1中?

HTTP 1.0中的Host标头是可选,但HTTP 1.1中的必需

  

客户端必须在所有HTTP / 1.1请求消息中包含Host头字段。如果请求的URI不包含所请求服务的Internet主机名,则Host头字段必须是给出一个空值。 HTTP / 1.1代理必须确保它转发的任何请求消息都包含一个适当的主机头字段,用于标识代理请求的服务。 所有基于Internet的HTTP / 1.1服务器必须以400(错误请求)状态代码响应任何缺少主机头字段的HTTP / 1.1请求消息。

因此,当您不插入额外的空行时,您最终会单独发送这些请求:

GET /path HTTP/1.0
Host: hostname

GET /path HTTP/1.1
Host: hostname

哪些都有效。

但是,当您插入额外的空白行时,您实际上是一次发送两个单独的请求:

GET /path HTTP/1.x;

Host: hostname

请求标头和请求正文由空行分隔,GET请求没有请求正文,因此第一个空白行结束请求。

因此,在这种情况下,第一个请求仅对HTTP 1.0有效,对HTTP 1.1无效,因为缺少Host标头。第二个请求在两个版本中都是无效的。