ruby - Am I doing it wrong or is it a bug in net/http? -
i'm using ruby net::http under nginx/phusion passenger server, attempting post json string server. appears post, when sending 'application/json', prematurely closes session server. i.e.:
on server side:
127.0.0.1 - - [03/sep/2013 07:47:14] "post /path/to/submit " 200 45 0.0013 pid=12893 thr=47197563169088 file=ext/nginx/helperagent.cpp:933 time=2013-09-03 07:47:14.830 ]: uncaught exception in passengerserver client thread: exception: cannot read response backend process: connection reset peer (104) backtrace: in 'void client::forwardresponse(passenger::sessionptr&, passenger::filedescriptor&, const passenger::analyticslogptr&)' (helperagent.cpp:698) in 'void client::handlerequest(passenger::filedescriptor&)' (helperagent.cpp:859) in 'void client::threadmain()' (helperagent.cpp:952)
a client side debug session is:
opening connection hostname.com... opened <- "post /path/to/submit http/1.1\r\ncontent-type: application/json\r\naccept: application/json\r\nuser-agent: agent+test\r\nconnection: close\r\nhost: hostname.com\r\ncontent-length: 660\r\n\r\n" <- "[{json string}]" -> "http/1.1 301 moved permanently\r\n" -> "server: nginx/1.2.6\r\n" -> "date: tue, 03 sep 2013 14:47:15 gmt\r\n" -> "content-type: text/html\r\n" -> "content-length: 184\r\n" -> "connection: close\r\n" -> "location: https://hostname.com/path/to/submit\r\n" -> "\r\n" reading 184 bytes... -> "<html>\r\n<head><title>301 moved permanently</title></head>\r\n<body bgcolor=\"white\">\r\n<center><h1>301 moved permanently</h1></center>\r\n<hr><center>nginx/1.2.6</center>\r\n</body>\r\n</html>\r\n" read 184 bytes conn close opening connection hostname.com... opened <- "post /path/to/submit http/1.1\r\ncontent-type: application/json\r\naccept: application/json\r\nuser-agent: agent+test\r\nconnection: close\r\nhost: hostname.com\r\ncontent-length: 660\r\n\r\n" <- "[{json string}]" -> "http/1.1 200 ok\r\n" -> "content-type: text/html;charset=utf-8\r\n" -> "content-length: 45\r\n" -> "connection: close\r\n" -> "status: 200\r\n" -> "x-powered-by: phusion passenger (mod_rails/mod_rack) 3.0.17\r\n" -> "x-frame-options: sameorigin\r\n" -> "x-xss-protection: 1; mode=block\r\n" -> "x-content-type-options: nosniff\r\n" -> "server: nginx/1.2.6 + phusion passenger 3.0.17 (mod_rails/mod_rack)\r\n" -> "strict-transport-security: max-age=31536000\r\n" -> "x-frame-options: deny\r\n" -> "\r\n" reading 45 bytes... -> "some url string" <-- suspicous me. read 45 bytes conn close
the code i'm using submit data is:
private def _http_client(method = 'get', location = nil, limit = 10) raise argumenterror, 'fatal: many http redirects attempted...' if limit == 0 response = nil if location.nil? if @uri.nil? raise argumenterror 'fatal: no location specified. quitting.' end else @uri = uri.parse(location) end client = net::http.new(@uri.host,@uri.port) client.open_timeout = 15 # in seconds client.read_timeout = 15 # in seconds initheader = {'content-type' => 'application/json', 'accept' => 'application/json', 'user-agent' => ua ,} client.set_debug_output $stderr # xxx temporary if @uri.scheme == 'https' client.use_ssl = true client.verify_mode = 0 end if method == 'post' serialized = json.generate(@payload) response = client.send_request('post',@uri.path,serialized,initheader = initheader) puts serialized end # intended pings. in order # full gets (including query_params) # need refactored little. if method == 'get' response = client.get(@uri.path) end case response when net::httpsuccess @status = true when net::httpmovedpermanently @status = false limit = limit - 1 _http_client(method,response['location'],limit) when net::httpclienterror $stderr.puts 'client error.' @status = false when net::httpservererror $stderr.puts 'server error.' @status = false else $stderr.puts 'no idea server returned.' @status = false end unless response.nil? @response = {:code => response.code, :body => (response.body || 'ok')} @code = @response[:code].to_s @http_body = @response[:body].to_s else $stderr.puts 'response server empty. :(' end _send_status end
i'm using:
- ruby version: 1.9.3p448
- nginx 1.2.6
- passenger 3.0.17
i'm pretty sure might doing wrong, i'm new ruby , semi-new kind of web programming.
the code snippet above uses send_request
method i've tried post
, , post2
, resulting in same outcome.
it's suspicious me use 'application/json' in initheader
breaks. when remove it, works alright.
try upgrading phusion passenger 4. handles i/o asynchrony better , in many cases avoids premature connection close problems.
Comments
Post a Comment