Tuesday, April 28, 2009

Net::HTTP and SSL

Just ran into an interesting problem today that I thought I'd post the solution for. Everybody knows about the net/http library, it's a core bundle that lets you do web requests. Well I was using it for posting to an experimental web service a friend had set up, and I ran into a problem. Here was my code:


url = URI.parse("https://someaddress:443/web/service/path")
xml = generate_some_xml
request = Net::HTTP::Post.new(url.path,{"Content-Type"=>"text/xml"})
http = Net::HTTP.new(url.host, url.port)
response = http.start {|http| http.request(request) }


Seems like it should have worked, but I kept running into this message:

wrong status line: "\025\003\001\000\002\002"

after googling around a bit, I figured out that this error message comes up whenever you are trying to connect to an SSL enabled site with plain text. I figured that, like curl, if you used "https" in your url, then you were telling the library that you wanted to use SSL. Well, that's not exactly the way it works. Although I put my "https" into the original url, when it gets passed into the HTTP library on line 4 of my code up above, I'm just handing it the host and the port, not the protocol. This requires the use of an aditional line of code:


url = URI.parse("https://someaddress:443/web/service/path")
xml = generate_some_xml
request = Net::HTTP::Post.new(url.path,{"Content-Type"=>"text/xml"})
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
response = http.start {|http| http.request(request) }


there you have it. Hopefully by finding this post, you figured this out a lot quicker than I did.

5 comments:

Ben Atkin said...

Sort of goes against the Principle of Least Surprise, doesn't it?

Jason McDonald said...

Thanks!

Travis said...

Thanks, you saved me some bafflement here.

House 9 said...

Thank you!

# in case you want to handle both
http.use_ssl = (url.port == 443) ? true : false

Anonymous said...

I think it might be better to write:

http.use_ssl = true if url.is_a?(URI::HTTPS)