茱莉亚·伊万斯

Ruby HTTP库中的惊喜

嗨,朋友们!我在工作中帮助决定一些Ruby HTTP客户端库,我学到了一些让我吃惊的事情(以及一些我不同意的决定)。

最后我做了一些开源考古,结果很有趣!让我们学习一些东西吧!!

Ruby HTTP库:一个分类法

HTTP库在概念上非常简单——所有的HTTP都是,在大多数情况下,是否向服务器发送一些文本(GET/awesomepage.html)他们会给你发回一些其他的文本OMG猫)但是事实证明,HTTP有很多特性,因此,我们有一些库来帮助我们组合这些请求并为我们解析响应。

这个精彩的幻灯片比较HTTP库。它有一个很棒的幻灯片:

这个幻灯片告诉我们,Ruby中基本上只有4个HTTP库:

  • Net::HTTP(内置在Ruby中)
  • 埃克森
  • HTTP客户端
  • libcurl(一个C HTTP库)绑定的变体,那个卷曲用途)

就是这样。所有其他的图书馆都建立在这些图书馆之上。我们可以对这些进行更进一步的分类!NET::Excon和httpclient都使用Ruby的内置插座用于建立TCP连接的库。所以真正的分类法是

*Socket接口(操作系统)*Ruby套接字库*Excon*Net::HTTP*httpclient*libcurl*Ruby绑定

我发现当试图理解可能性的景观时,像这样的分类法非常有用。不要考虑15或20个图书馆,现在只有4个!!

我只想说两个库:Excon和Net::HTTP

Net::HTTP中的一个惊喜

今天HN的头版有个帖子,是关于nginx代理将重试HTTP请求.这是不受欢迎的和可怕的,因为——当你提出请求时,你经常希望只发生一次!如果您的GET请求意味着什么执行此交易?那么它不应该只是随机重试——您想要控制它!!

同样地,Net::HTTP将重试GET,头,放,删除,选项,以及TRACE请求。据我所知,你不能把这关掉。下面是这样做的代码.

代码片段:

如果count==0&IDEMPOTENT_MethHODS_include?(req.method)count+=1@socket.close如果@socket而不是@socket.close呢?“由于错误#{异常}而关闭,重试“重试

我真的很惊讶,有点吃惊地得知这一点。我想弄清楚为什么这么说,所以我发现Ruby bug跟踪器中引入这种行为的问题!!.事实证明,这个重试特性是在2012年添加到Ruby的!之所以添加它,是因为HTTP/1.1的RFC建议HTTP客户端以这种方式操作.

只要请求序列是等幂的,客户端软件就应该重新打开传输连接并在没有用户交互的情况下重新传输中止的请求序列(参见9.1.2节)。

呵呵。这是(就像你看到的,如果我链接到nginx blogpost上的评论线程)一个有争议的选择——对于网络浏览器侵权行为来说意义重大,对于从代码中调用的库进行自动重试,可能意义不大,没有能力配置它。

惊喜在激昂

不久前,我写为什么您应该(稍微)了解TCP,在那里,我有神秘的慢HTTP请求,它们毫无理由地缓慢。这是因为艾克森!当使用Excon使用主体(如POST请求)进行HTTP请求时,它相当于

socket.write(headers)socket.write(body)

这是密码。

这样就为请求创建了两个TCP数据包,并且可能导致数据包被延迟(正如我在那篇TCP文章中所讨论的)。这不好!!

我在Excon调查了这件事的历史。有一个Github问题涉及到Nagle的算法以及从2013年开始的这个精确的性能问题,而且似乎已经修好了,然后在这个问题,因为他们在进行字符串连接时遇到问题。所以看起来图书馆的作者明白了他们所做的选择,但是就是没有时间解决这个问题。

更新:现在在Excon修好了,截至3月7日发布的v0.48.0,2016。(拉动请求)哎呀!!

我们如何发现惊喜?(或:查阅图书馆)

把依赖关系介绍给我最可怕的事情是——我怎么知道一年后它会不会让我不愉快,在生产中??

我没有做过这么多,而且我想做得更好。我有几个想法要开始。

第一,Net::HTTP可能是2000行代码,不包括评论。它有1000行评论。代码就在这里。.很多都是包装方法!在工作中,我认为,要审查一个2000行的拉动请求有点困难,但也许不完全超出合理性的范围!我能读2000行代码,主要是!!

所以我试过了。我发现HTTP总是设置TCP_NODELAY检查超时时时要小心使用单调时钟.第一个让我惊讶!我希望这也是可配置的。我没有太努力地阅读Excon的代码,因为此时已经过了午夜。

我理解一些代码的第二个想法是——试着想想我可能想要运行代码的所有情况,把那些情况都处理掉!然后我可以看看它是否运行了我期望的系统调用。

我仍然非常缺乏审查这种依赖关系的经验。有些东西不像2000行代码,要检查起来会困难得多!但我想到,安全人员定期审计代码,因此,阅读图书馆以了解它们做什么,以及它们是否安全使用,可能并非完全异常。

开源!!

事实证明,开源项目就像所有的软件项目一样——它们做意想不到的事情,然后,当我去找出为什么一个人决定这么做时,我通常会哦,我明白你为什么做出那个决定了!“即使我不同意。

当我遇到执行某些事情的代码时,我不同意,我想起了这个伟大的段落论高级工程师-

批评代码而不是人——善待编码器,不符合规定。尽可能,使您的所有评论都积极,并致力于改进代码。将评论与当地标准相关联,程序规格,提高了性能,等。

什么是“烟囱?? 女性专用空间是黑客