{"id":611,"date":"2009-11-25T23:09:06","date_gmt":"2009-11-25T15:09:06","guid":{"rendered":"http:\/\/blog.lolyco.com\/sean\/?p=611"},"modified":"2009-11-26T11:17:38","modified_gmt":"2009-11-26T03:17:38","slug":"ab-apache-bench-hanging-with-k-keep-alive-switch","status":"publish","type":"post","link":"https:\/\/blog.lolyco.com\/sean\/2009\/11\/25\/ab-apache-bench-hanging-with-k-keep-alive-switch\/","title":{"rendered":"Ab &#8211; Apache Bench hanging with -k Keep-Alive switch"},"content":{"rendered":"<p>This problem was making me go blind! I&#8217;m testing Spinneret with ab at the moment, trying to make sure there&#8217;s no disastrous behaviour under load. I found that ab just stopped after the first request if I used the -k switch. I&#8217;m not sure the problem is my fault, exactly, but I have &#8216;solved&#8217; it. HTTP 1.0 didn&#8217;t have persistent connections. In HTTP 1.1, the <em>default<\/em> behaviour is persistence, so only a mechanism for explicitly closing a connection is provided.<\/p>\n<p style=\"text-align: center;\">\n<div id=\"attachment_617\" style=\"width: 450px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/spider.my\/\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-617\" class=\"size-full wp-image-617 \" title=\"My Spider\" src=\"http:\/\/blog.lolyco.com\/sean\/wp-content\/uploads\/2009\/11\/myspider.png\" alt=\"My Spider\" width=\"440\" height=\"120\" \/><\/a><p id=\"caption-attachment-617\" class=\"wp-caption-text\">My Spider<\/p><\/div>\n<p>Apache bench offers the &#8216;-k&#8217; switch to allow you to test your webserver with persistent connections, but sends a HTTP\/1.0 request. The -k switch causes ab to send the header &#8220;Connection: Keep-Alive&#8221; to the server. Spinneret&#8217;s debugging log confirmed a response was sent back, and the &#8216;-v&#8217; switch (verbose) in ab would even show that it received the response, but it would just &#8216;hang&#8217; at that point, until it timed out:<\/p>\n<p><code>LOG: Response code = 200<br \/>\napr_poll: The timeout specified has expired (70007)<\/code><\/p>\n<p>I wasted a lot of time imagining what could be wrong with it before I decided to just duplicate the response from an Apache server that worked with the -k switch in ab. I spotted that Apache was returning the &#8216;Connection: Keep-Alive&#8217; header. Adding that header field to a Spinneret response to a HTTP\/1.0 request that contains it solves the problem with ab.<\/p>\n<p>This behaviour isn&#8217;t specified anywhere, but it is suggested in an <a href=\"http:\/\/www.w3.org\/Protocols\/HTTP\/1.1\/draft-ietf-http-v11-spec-01.html#Persistent%20Connections\">Internet Draft for HTTP\/1.1 at w3.org<\/a>:<\/p>\n<blockquote><p>The <code>Connection<\/code> header field with a keep-alive keyword must be sent on all requests and responses that wish to continue the persistence.<\/p><\/blockquote>\n<p>Perhaps the nice people at Apache might consider some less baffling behaviour for when amateur webserver programmers attempt to pick up their tools!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This problem was making me go blind! I&#8217;m testing Spinneret with ab at the moment, trying to make sure there&#8217;s no disastrous behaviour under load. I found that ab just stopped after the first request if I used the -k switch. I&#8217;m not sure the problem is my fault, exactly, but I have &#8216;solved&#8217; it. [&hellip;]<\/p>\n","protected":false},"author":3,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14,20,50,3,45],"tags":[24,107,109,41,19,9,18,105,57],"class_list":["post-611","post","type-post","status-publish","format-standard","hentry","category-broken","category-fixed","category-foss","category-software","category-spinneret","tag-apache","tag-broken","tag-fixed","tag-http","tag-malaysia","tag-open-source","tag-server","tag-software","tag-web"],"_links":{"self":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts\/611","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/users\/3"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/comments?post=611"}],"version-history":[{"count":6,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts\/611\/revisions"}],"predecessor-version":[{"id":615,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/posts\/611\/revisions\/615"}],"wp:attachment":[{"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/media?parent=611"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/categories?post=611"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.lolyco.com\/sean\/wp-json\/wp\/v2\/tags?post=611"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}