Tuesday, February 21, 2006

HTTPS open-uri : basic authentication over SSL

Today I was looking for a way to open HTTPS urls with basic authentication. While looking, I came across this post wheich shows you how to patch open-uri to work with HTTPS.

I ended up using 'net/https' with 'net/http' to implement the basic authentication over SSL. So try it at your own risk and if it works, let me know ;)
Re: Patch that enables https in open-uri.rb

Here is the patch by Tanaka Akira

Index: lib/open-uri.rb
===================================================================
RCS file: /src/ruby/lib/open-uri.rb,v
retrieving revision 1.28
diff -u -p -r1.28 open-uri.rb
--- lib/open-uri.rb 5 Feb 2005 14:13:27 -0000 1.28
+++ lib/open-uri.rb 5 Feb 2005 14:14:25 -0000
@@ -539,9 +539,8 @@ module URI
header['host'] += ":#{uri.port}" if uri.port
end

- require 'net/http'
resp = nil
- Net::HTTP.start(self.host, self.port) {|http|
+ http_start(self.host, self.port) {|http|
http.request_get(uri.to_s, header) {|response|
resp = response
if options[:content_length_proc] && Net::HTTPSuccess === resp
@@ -576,11 +575,32 @@ module URI
end

include OpenURI::OpenRead
+
+ private
+ def http_start(host, port, &block)
+ require 'net/http'
+ Net::HTTP.start(host, port, &block)
+ end
end

class HTTPS
- def proxy_open(buf, uri, options) # :nodoc:
- raise ArgumentError, "open-uri doesn't support https."
+ private
+ def http_start(host, port, &block)
+ require 'net/https'
+ http = Net::HTTP.new(host, port)
+ http.verify_mode = OpenSSL::SSL::VERIFY_PEER
+ setup_ca_certificates(http)
+ http.use_ssl = true
+ http.start(&block)
+ end
+
+ def setup_ca_certificates(http)
+ if File.file? '/etc/ssl/certs/ca-certificates.crt'
+ # Debian ca-certificates package
+ http.ca_file = '/etc/ssl/certs/ca-certificates.crt'
+ else
+ raise SecurityError, 'CA certificates not found'
+ end
end
end


For those interested in how exactly I did Basic Authentication over SSL:

require 'net/http'
require "net/https"
@http=Net::HTTP.new('www.site.com', 443)
@http.use_ssl = true
@http.start() {|http|
req = Net::HTTP::Get.new('/file')
req.basic_auth 'user', 'pass'
response = http.request(req)
print response.body
}


If you want to test the above out, try
Blogger API

5 Comments:

At 11:57 AM, Blogger chriss72 said...

I am so grateful for this post...thanks!

 
At 11:25 AM, Blogger Unknown said...

Very grateful too - this worked on the first try, after hours of combing through bad/incomplete documentation... Thanks!

 
At 4:50 AM, Blogger Wieczo said...

Thank you very much!
I can finally use Hpricot with HTTPS.

 
At 12:00 AM, Blogger CaDs said...

Thanks pal, that really worked for me :)

 
At 12:18 AM, Blogger massi said...

How to get the user password ?

 

Post a Comment

<< Home

eXTReMe Tracker