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

Popular posts from this blog

html - How to style widget with post count different than without post count -

How to remove text and logo OR add Overflow on Android ActionBar using AppCompat on API 8? -

javascript - storing input from prompt in array and displaying the array -