首先先来了解一下HTTP的基本知识:HTTP下午茶
本节我们来解析一下浏览器的请求,重点分为以下几步:
解析http request
- 观察收到的http数据
- 解析 request 请求行 的 method url version
- 解析 header
- 解析 body
观察收到的http请求
上一节我们完成了一个简单的基于TCP/IP的socket server 程序。那么接下来底层的东西我们就先不用考虑了,直接用socket就行。我们只要考虑应用层的HTTP协议,一旦我们的服务器程序能读懂HTTP请求,并做出符合HTTP协议的响应,那么也就完成了HTTP的通信。
上一节最后测试的时候我们用telnet成功连接了我们的服务器,但只是向它传送了一些没有意义的字符。如果是浏览器,会传送什么呢?
我们继续打开我们的服务器,然后试着在浏览器地址栏输入我们的服务器地址: 127.0.0.1:10000 后访问,发现浏览器:
那是说我们返回给浏览器的数据浏览器读不懂,因为现代的浏览器默认用http协议请求访问我们的服务器,而我们的返回的数据只是"helloworld"字符串,并不符合http协议的返回格式。虽然如此,但浏览器却是很有诚意的给我们的服务器发标准的http请求,不信我们看下我们的服务器收到的信息:
先观察一会儿,看起来第一行是http请求的类型,第二行开始是一些":"号分割的键值对。的确如此,第一行告诉我们是用的GET请求,请求的url是"/",用的是1.1的HTTP版本。第二行开始是HTTP的请求头部。 除了GET请求外,另一种常用的请求是POST。用浏览器发POST请求稍麻烦,我们就借用curl工具来发送个HTTP POST请求给服务器看下数据又会是怎们样的:
curl -d "message=nice to meet you" 127.0.0.1:9734/hello
, 服务器收到的信息:
POST /hello HTTP/1.1
Host: 127.0.0.1:10000
User-Agent: curl/7.54.0
Accept: */*
Content-Length: 24
Content-Type: application/x-www-form-urlencoded
message=nice to meet you
可以看到头部信息之后多了一空行和之后的POST的body数据信息。还要注意的是Content-Length头,代表POST的body数据的大小。
解析 request 的 method url version
先来解析最简单的第一行: "POST /hello HTTP/1.1", 只需要用空格split出三个字符串就好了。
//request.h
#ifndef __REQUEST__
#define __REQUEST__
#include <string>
#inc