Skip to content
Browse files

Merge pull request #22 from cramerdev/mess-with-removing-the-http-res…

…ponse

Mess with removing the http response
  • Loading branch information...
2 parents e7a92aa + e2ed0d9 commit 60a9fd0ed96f546557606a5ea48046f3c8f39efc Travis Palmer committed
View
25 lib/whois/server/adapters/base.rb
@@ -9,6 +9,7 @@
require 'whois/record/part'
require 'whois/record'
+require 'whois/tcp_proxy_socket'
require 'socket'
@@ -190,13 +191,33 @@ def query_the_socket(query, host, port = nil)
#
# @api private
def ask_the_socket(query, *args)
- client = TCPSocket.new(*args)
+ client = socket_factory(*args)
client.write("#{query}\r\n") # I could use put(foo) and forget the \n
- client.read # but write/read is more symmetric than puts/read
+ # but write/read is more symmetric than puts/read
+ strip_proxy_response(client.read) # remove the http part from the proxy response
ensure # and I really want to use read instead of gets.
client.close if client # If != client something went wrong.
end
+ # Choose the correct socket to use based on the options
+ #
+ # @api private
+ def socket_factory(*args)
+ options[:proxy] ? Whois::TCPProxySocket.new(*args, options[:proxy]).tcp_socket :
+ TCPSocket.new(*args)
+ end
+
+ # Strip the response from a proxy if we're using one
+ #
+ # @api private
+ def strip_proxy_response(response)
+ if options[:proxy]
+ lines = response.split("\r\n").drop(1)
+ lines.drop_while {|i| i.empty? }.join("\r\n")
+ else
+ response
+ end
+ end
end
end
View
37 lib/whois/tcp_proxy_socket.rb
@@ -0,0 +1,37 @@
+require 'base64'
+require 'socket'
+
+module Whois
+ class TCPProxySocket
+ attr_accessor :host, :port, :proxy_options, :tcp_socket
+
+ def initialize(*args)
+ self.host = args.shift
+ self.port = args.shift
+ self.proxy_options = args.pop
+ self.tcp_socket = TCPSocket.new(proxy_options[:host], proxy_options[:port], *args)
+
+ http_connect.each do |line|
+ tcp_socket.puts line
+ end
+ end
+
+ private
+
+ def basic_auth_header
+ "Proxy-Authorization: Basic #{encoded_credentials}"
+ end
+
+ def encoded_credentials
+ Base64.strict_encode64 "#{proxy_options[:user]}:#{proxy_options[:pass]}"
+ end
+
+ def http_connect
+ [
+ "CONNECT #{host}:#{port} HTTP/1.1",
+ basic_auth_header,
+ ""
+ ]
+ end
+ end
+end
View
57 spec/whois/server/adapters/base_spec.rb
@@ -157,4 +157,61 @@
end
end
+ describe '#socket_factory' do
+ let(:options) { {} }
+
+ before(:each) do
+ TCPSocket.stubs(:new)
+ @base = klass.new(:tld, ".test", "whois.test", options)
+ end
+
+ context 'without a proxy' do
+ before(:each) do
+ TCPSocket.stubs(:new)
+ end
+
+ it 'should create a TCPSocket' do
+ TCPSocket.expects(:new)
+ @base.send(:socket_factory, 'localhost', 43)
+ end
+ end
+
+ context 'with a proxy' do
+ let(:options) { { :proxy => {} } }
+
+ before(:each) do
+ TCPSocket.any_instance.stubs(:initialize).returns(stub(:puts => nil))
+ Whois::TCPProxySocket.any_instance.stubs(:initialize).returns(stub(:tcp_socket => nil))
+ end
+
+ it 'should initialize a TCPProxySocket' do
+ Whois::TCPProxySocket.any_instance.expects(:initialize)
+ @base.send(:socket_factory, 'localhost', 43)
+ end
+ end
+
+ describe '#strip_proxy_response' do
+ let(:options) { {} }
+ let(:response) { "HTTP/1.0 200 Connection established\r\nhello" }
+
+ before(:each) do
+ @base = klass.new(:tld, ".test", "whois.test", options)
+ end
+
+ context 'with no proxy set' do
+ it 'should not modify the response' do
+ @base.send(:strip_proxy_response, response).should == response
+ end
+ end
+
+ context 'with a proxy set' do
+ let(:options) { { :proxy => {} } }
+
+ it 'should strip a response' do
+ @base.send(:strip_proxy_response, response).should == 'hello'
+ end
+ end
+ end
+ end
+
end
View
21 spec/whois/tcp_proxy_socket_spec.rb
@@ -0,0 +1,21 @@
+require "spec_helper"
+
+describe Whois::TCPProxySocket do
+ let(:proxy_options) { { :host => '9.9.9.9', :port => 55555, :user => 'user',
+ :pass => 'pass' } }
+
+ before(:each) do
+ TCPSocket.stubs(:new).returns(stub(:puts => nil))
+ end
+
+ describe '#http_connect' do
+ it 'should do an http connect to the proxy server' do
+ @socket = klass.new('127.0.0.1', 43, nil, nil, proxy_options)
+ @socket.send(:http_connect).should == [
+ "CONNECT 127.0.0.1:43 HTTP/1.1",
+ "Proxy-Authorization: Basic dXNlcjpwYXNz",
+ ""
+ ]
+ end
+ end
+end

0 comments on commit 60a9fd0

Please sign in to comment.
Something went wrong with that request. Please try again.