HTTP 100 状态码

  • HTTP 100

The purpose of the 100 (Continue) status (see section 10.1.1) is to allow a client that is sending a request message with a request body to determine if the origin server is willing to accept the request (based on the request headers) before the client sends the request body. In some cases, it might either be inappropriate or highly inefficient for the client to send the body if the server will reject the message without looking at the body.------w3

这段话的大概意思是,服务器根据客户端的请求头判断是否接受客户端的请求。如果接受请求则响应100状态码,服务端根据是否存在 Expect: 100-continue 请求头判断是否是Expect请求(有部分web服务器不能正确的处理Expect请求)

  • curl 验证(curl 请求如果请求体大于1024自己会自动带上 Expect: 100-continue请求头)
curl -v    -d   '大于1024字节' 'http://127.0.0.1:12345/'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 12345 (#0)
> POST / HTTP/1.1
> Host: 127.0.0.1:12345
> User-Agent: curl/7.55.1
> Accept: */*
> Content-Length: 1047(字节数)
> Content-Type: application/x-www-form-urlencoded
> Expect: 100-continue
>
< HTTP/1.1 100 Continue(100 状态码)
*  We are completely uploaded and fine (响应吗是100,发送请求体)
< HTTP/1.1 200 OK
< Date: Sun, 03 Dec 2017 10:51:15 GMT
< Connection: keep-alive
< Content-Length: 7
curl -v    -d   '等于1024字节' 'http://127.0.0.1:12345/'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 12345 (#0)
> POST / HTTP/1.1
> Host: 127.0.0.1:12345
> User-Agent: curl/7.55.1
> Accept: */*
> Content-Length: 1024(等于102字节无响应吗)
> Content-Type: application/x-www-form-urlencoded
>
* upload completely sent off: 1024 out of 1024 bytes
< HTTP/1.1 200 OK
< Date: Sun, 03 Dec 2017 10:53:15 GMT
< Connection: keep-alive
< Content-Length: 7
  • 也可以伪造直接在请求头上带上 Expect: 100-continue
curl -v -H 'Expect:100-continue' 'http://127.0.0.1:12345/'
*   Trying 127.0.0.1...
* TCP_NODELAY set
* Connected to 127.0.0.1 (127.0.0.1) port 12345 (#0)
> GET / HTTP/1.1
> Host: 127.0.0.1:12345
> User-Agent: curl/7.55.1
> Accept: */*
> Expect:100-continue
>
< HTTP/1.1 100 Continue (100状态码)
< HTTP/1.1 200 OK
< Date: Sun, 03 Dec 2017 11:04:49 GMT
< Connection: keep-alive
< Content-Length: 7
  • Node http 中100 状态码的使用
    Node http.server中存在一个checkContinue事件,在请求头中带有Expect: 100-continue时会触发事件(触发checkContinue事件之后不会再触发request事件),如果Excpet的值为空,则不会触发checkContinue事件,直接触发request事件,如果Excpet的值为其它值触发checkExpectation事件
const http = require("http");
const server = http.createServer()
.on('request', (request, response) => {
  console.log(request.headers);
  response.end('Hello Node');
})
.on('checkContinue', (request, response) => {
   // 如果接受请求响应100状态码,触发request
   response.writeContinue();
   server.emit('request', request, response);
   // 不接受请求响应417,请求结束
   //response.statusCode = 417;
   //response.end();
})
.on('checkExpectation', (request, response) => {
 // 如果请求头Expect的只不为空且不是100-continue 触发
  response.statusCode = 500;
  response.end();
})
.listen(12345,'127.0.0.1');

Node http.ClientRequest 中有一个continue事件,当http响应码是100时会触发

const http = require('http');
let data  = '1'.repeat(1200);
let options = {
  'protocol':'http:',
  'hostname':'127.0.0.1',
  'port':'12345',
  'method':'POST',
  'path':'',
  'headers':{
    // 带上Expect请求头,和curl有区别,在请求体超过1024的时候不会自动带上Expect请求头
    'Expect': '100-continue',
    // 带上Connection:Close 否则连接不会断开,只能在,response事件中调用 response.req.destroy()
    //'Connection': 'Close',
    'Content-Length':data.length
  }
};
let client = http.request(options);
client.on('response', function(response){
  console.log(response.headers);
  console.log(response.statusCode);
/*   console.log(response.statusMessage);
  console.log(Object.keys(response));
  console.log(response.connection === response.socket); */
  //response.req.destroy();
}).on('continue', function(){
  // 第一个响应码是 100 触发 发送请求体,这样做的好处是防止了无效的网络数据传输,
  // 如果请求头和请求体一起发送,服务器如果拒绝处理,那请求体就白白发送了。在传输大文件时很有用
  // 服务器响应数据之后触发 response 事件
  // 如果第一个响应码不是100触发 respnse 事件
  client.write(data);
  client.end();
}).on('error', function(error){
  console.log(error)
});
  • 结束
    如果服务能够正确处理Expect: 100-continue 请求头,合理的响应100状态码能够防止无效的网络数据传输。

你可能感兴趣的:(HTTP 100 状态码)