七叶笔记 » golang编程 » 深入理解Go的http

深入理解Go的http

围棋中的超文本传输协议

Go有一个非常强大的标准库,其中最常用的部分是net/http包,它提供的结构使得HTTPservers和客户端的开发非常简单。在一些边缘情况下,非常欢迎对http和相关包有更深入的理解。

大多数RESTful HTTP应用编程接口请求不必处理许多事情。人们通常需要从GET请求中读取查询变量,或者从POST请求中读取表单变量,在某些情况下,为了保存文件或获取 JSON 有效负载,需要读取POST主体。人们求助于现有的net/http为此目的公开相关字段和函数的结构。

net/http/httputil

不幸的是,没有多少人知道httputil,过了很久我才在野外看到它。该包提供了有用的实用功能,转储请求。毫无疑问,在你过去的某个时候,你可能写了一些代码来转储请求方法,即请求r.网址。路径,或者类似的东西:

为名称,标题:=范围r.标题{为_,h :=范围标题{ fmt。Printf(%v: %v\n,姓名,h) }} 

别担心。我们都去过那里。

如果您想调试您的HTTP请求,您真正需要做的就是导入net/http/httputil打包并调用转储请求带参数*http。请求和一个布尔值来指定是否也要泵送请求体。该函数返回一个[]字节,错误,你可以这样使用它:

转储:=功能(r *http。请求){ output,err := httputil。转储请求(r,真实的)如果呃!=无{ fmt。Println("转储请求时出错:",呃)返回} fmt。Println(线(输出)) 

函数调用 将转储您的请求方法,URI,如果您有查询参数、头和请求体的话。应该是这样的:

开机自检 /API/v3/projects/1234567/notices?key=FIXMEHTTP/1.1主机:10.1.1.2:3000接受 编码 :gzip内容长度:617内容类型:应用程序/json用户代理:Go-http-client/1.1发布_请求_正文_此处
 

请求体是io。ReadCloser

随着错误集线器我们正在处理一些压缩的超文本传输协议有效载荷。这意味着有效载荷需要一些解码。使用函数javascript或PHP,在解码JSON有效负载之前,您需要链接几个函数调用,例如gzip和base64解码。

围棋在这方面要优雅得多。你当然可以遵循其他语言的不良习惯,称之为ioutil。ReadAll在请求体上获取内容,然后依次通过几个函数获取解码结果。

或者,你可以意识到http。请求。正文是一个io。ReadCloser。这意味着你可以把你的有效载荷解码成一个流。例如,哨兵客户端瑞文-go首先压缩JSON有效载荷,然后对其进行base64编码。

有效载荷的解码器如下所示:

base64解码器:= base64。新解码器(base64。StdEncoding,r.Body)gz,err := zlib。新阅读器(base64解码器)如果呃!=无{返回错误}推迟gz。关闭()解码器:= json。新解码器(gz)vart SentryV6Noticeerr =解码器。解码(&t)如果呃!=无{返回右侧车身。关闭()//...
 

界面io。ReadCloser也满足io。读者。有了这个,我们可以首先创建一个base64解码器,然后将它传递给兹利布。NewReader创建zlib解码器/阅读器,并最终将它传递到杰森。新解码器,我们可以用它来解码有效载荷。

处理io。ReadCloser和io。读者很简单。与使用相比,上述实现具有速度/内存使用非常高效的优点[]字节或者线变量。这些不可避免地会使用更多的内存,性能比上面差。

“在Go: request中需要了解的关于HTTP的内容。身体是木卫一。read closer # golang ” via @ TiTpetric

点击发送推文

处理程序和 句柄 unc

有两种类型为HTTP处理程序声明签名。最常见的类型,http。HandlerFunc的isa类型别名func(http。ResponseWriter,*http。请求)。你可以把这个传给http。HandleFunc()。最普通的类型,http。处理者是一个接口,它应该实现一个ServeHTTP(http。ResponseWriter,*http。请求)。

作为第二种形式的一个例子,有一个http。 文件服务器 ()提供的功能。这是文档中使用as-is的示例,它将为您的/ tmp 目录:

http。句柄("/",http。文件服务器(http。目录("/tmp ")) 

因为您可能不想或不需要为以下内容提供签名http。处理但是http。HandleFunc,您可以这样“包装”代码:

功能 文件服务器(路径线) http。HandlerFunc{ server := http。文件服务器(http。目录(路径))返回 功能(w http。ResponseWriter,r *http。请求){服务器。ServeHTTP(w,r) }}http。HandleFunc("/",文件服务器("/tmp ")) 

这个例子本身并不好——提供的展开函数没有增加任何功能。但是让我们考虑下面的用例。虚拟环境应用可以使用浏览器历史应用编程接口来模拟页面加载。这意味着当你点击/关于,javascript负责呈现网页。其他框架,如重新和角度工作,也是如此。为了可靠地支持用户在浏览器中按刷新,服务器上任何不存在的页面都应该返回/index. html

//为index.html服务,以防找不到请求的文件(或其他操作系统)。Stat错误)
功能 serveIndex(资产路径线,提供http。处理程序) http。HandlerFunc{返回 功能(w http。ResponseWriter,r *http。请求){ indexPage :=路径。加入(资产路径," index.html ")requestedPage :=路径。连接(资产路径,网址路径),错误:=操作系统。Stat(请求页面)如果呃!=无{//如果页面不存在,则提供索引http。ServeFile(w,r,indexPage)返回}发球。ServeHTTP(w,r) }} 

该功能使用os。Stat()来判断一个文件是否不存在,在这种情况下index.html。一切都被包裹在一个http。HandlerFunc。这是一个直接来自vue-serve项目。

“Go #protip -您可以包装其他http处理程序来扩展功能#golang”通过@TitPetric

点击发送推文

回应者

这http。响应者是一个io。作者。这意味着您可以将JSON直接编码给理解的作者。还有许多例子先编码JSON,然后在响应编写器上调用Write()。如果你想把gzip压缩链接到这上面,和作者一起去应该是你最好的选择。

类型JSON结构{价值连接{}}功能 (self *JSON) ServeHTTP(w http。ResponseWriter,r *http。请求){编码器:= json。新编码器(w)错误:=编码器。编码(自我价值)如果呃!=无{ http。错误(w,err。错误(),503)}} 

同样,我们可以使用io。复制读出文件。我的意思是,你真的想在把文件写给应答者之前,先读几GB大小的文件吗?我想是的。

额外提示:处理者httputil。反向氧化实施a复制缓冲区更适合代理请求的函数。它的签名类似于io。复制。

“了解httputil。反向氧化?利用响应记录器作为io。作者:)#golang “通过@TitPetric

点击发送推文

测试超文本传输协议处理器

如果你想自动化一些测试,正如你应该做的,人们通常会求助于外部工具和验证器来测试他们的应用编程接口响应。Go拥有编写测试所需的一切,但没有这些。使用net/http/httptest您可以创建一个服务器,它将从您的http。处理者而不用插座。让我们看看如何做到这一点:

包裹主要的进口("编码/json "
" io/ioutil "
“日志”
" net/http "
" net/http/httptest ")类型JSON结构{价值连接{}}功能 (self *JSON) ServeHTTP(w http。ResponseWriter,r *http。请求){编码器:= json。新编码器(w)错误:=编码器。编码(自我价值)如果呃!=无{ http。错误(w,err。错误(),503)}}功能 主要的(){处理程序:= &JSON{“你好,世界”}服务器:= httptest。新闻服务器(处理程序)推迟服务器。关闭()检查:=功能(错误错误){如果呃!=无{日志。致命(错误)} }分别,错误:= http。获取(服务器。检查(错误)正文,错误:= ioutil。ReadAll(分别为。正文)检查(错误)日志。Printf("收到:%d %s\n ",分别为。状态代码,身体)} 

完整的示例已打开去游乐场。通过以下方式创建测试http服务器httptest。新闻服务器这需要http。处理者作为参数。您可以通过引用向服务器请求东西服务器。网址在呼叫中http。得到。不用额外的工具,你几乎可以测试你写的任何东西。

“开始在没有外部工具的情况下测试您的超文本传输协议处理器,使用net/HTTP/HTTP putil包#golang”通过@TitPetric

点击发送推文

结论

尽管对于发布/获取请求来说非常简单,但是它的范围要广得多。了解开发服务器时的一些最佳实践和选项将有助于您实现更好的实现。虽然创建快速的微服务当然是可能的,但是在创建更好的微服务时也应该小心。

如果你想改进你的应用程序,去吧,或者别的什么地方,去看看并订阅错误集线器。我们正在编写一个错误捕获服务,它将让您知道您的应用程序是否有需要处理的错误。如果你想了解更多关于围棋和如何使用围棋的知识,请查看下面的书籍列表。

看go语言,关注VX公众号:studytogo

声明:转载此文是出于网络的。若有来源标注错误或侵犯了您的合法权益,请作者持权属证明与本网联系,我们将及时更正、删除,谢谢。

相关文章