最近买了本书《HTTP权威指南》,看了第一章,看到书上说通过telnet模拟HTTP请求,我这个学渣就发现自己没学过计算机网络。
今天翻了一下考研指定教材《计算机网络》,里面也以访问清华大学主页为例详细讲了通信过程:
- 浏览器分析链接指向页面的URL。
- 浏览器向DNS请求解析www.tsinghua.edu.cn的IP地址。
- 域名系统DNS解析出清华大学服务器的IP地址为166.111.4.100。
- 浏览器与服务器建立TCP连接(在服务器端IP地址是166.111.4.100,端口是80)。
- 浏览器发出取文件命令:GET /chn/yxsz/index.htma
- 服务器www.tsinghua.edu.cn给出响应,把文件index.htm发送给浏览器。
- 释放TCP连接。
- 浏览器显示“清华大学院系设置”文件index.htm中的所有文本。
HTTP协议就是:与指定IP和端口建立TCP连接,然后通过连接发送请求命令、头和数据。服务器响应的数据也会通过这个请求得到。
考过研的连这个都不懂的伤不起啊。
在这里我主要想自己基于TCP连接来模拟一次HTTP请求。测试是否能发送HTTP的头信息,通过User-Agent字段来模拟。还要发送Body信息测试Body的发送。
1. telnet模拟请求
$ telnet blog.cyeam.com 80
GET / HTTP/1.0
此命令可以建立连接,建立之后,输入请求命令,方法为GET,路径是根路径\
,端口是80。然后再输入两个回车,就可以发送请求了。这里会返回响应状态码、响应头和Body。响应返回后,这次的telnet请求也会随之关闭。POST的发送可以参考HTTP POST via telnet - Burak’s logs
2. POSTMAN模拟请求
POSTMAN是一个Chrome插件,很强大,能够模拟HTTP请求,查看请求和响应的全部内容。我一般还会用它的Preview功能,这样能看到所有的请求数据。
3. beego模拟服务器
也可以用公网上的服务器进行测试,但是没有办法查看服务器端收到的请求详细内容,用beego搭了服务器来测试(服务器还是beego最熟。。。)。
beego当中获取User-Agent通过this.Ctx.Request.UserAgent()
实现。获取Body内容通过string(this.Ctx.Input.RequestBody)
实现,还需要在配置文件加入copyrequestbody = true
,默认取到的Body是空的。beego服务器功能的验证可以通过POSTMAN模拟。
4. 基于TCP套接字实现HTTP的POST请求
通过POSTMAN的Preview查看完整请求和telnet使用,发现HTTP请求的命令、头和Body是通过换行符\n
来区分的。POSTMAN抓到的如下:
POST HTTP/1.1
Host: localhost:8080
Cache-Control: no-cache
Postman-Token: 649dbec6-4f13-7064-67f0-11461281ceb2
This is body
可以得到结论:HTTP命令、头和Body通过换行符来区分。第一行是请求命令,跟着是HTTP头,他们之间通过一个换行符区分,头直接也是通过一个换行符区分。两个换行符之后,是Body信息。
通过大Golang发送请求:
conn.Write([]byte("POST / HTTP/1.0\nUser-Agent: Cyeam\nContent-Length: 4\n\nBody\r\n\r\n"))
需要注意一点,如果要传入Body内容,必须在头当中加入长度信息Content-Length: 4
,否则服务器依然无法获取,反正beego是这样,可能是获取Body前会先判断一下长度,如果是0就不读取Body信息了。完整代码借鉴了《Go 语言编程》第五章的内容。
参考文献
- 【1】《HTTP权威指南》
- 【2】《计算机网络 - 谢希仁》
- 【3】HTTP POST via telnet - Burak’s logs
原文链接:基于TCP套接字,通过Golang模拟HTTP请求,转载请注明来源!
有疑问加站长微信联系(非本文作者)