28 September 2014
使用Golang语言,了解HTTP协议通信过程。

最近买了本书《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 语言编程》第五章的内容。

本文所涉及到的完整源码请测试客户端测试服务器


参考文献

原文链接:基于TCP套接字,通过Golang模拟HTTP请求,转载请注明来源!

EOF