@@ -1613,73 +1613,10 @@ def connect
16131613 s . setsockopt ( Socket ::IPPROTO_TCP , Socket ::TCP_NODELAY , 1 )
16141614 debug "opened"
16151615 if use_ssl?
1616- if proxy?
1617- plain_sock = BufferedIO . new ( s , read_timeout : @read_timeout ,
1618- write_timeout : @write_timeout ,
1619- continue_timeout : @continue_timeout ,
1620- debug_output : @debug_output )
1621- buf = +"CONNECT #{ conn_address } :#{ @port } HTTP/#{ HTTPVersion } \r \n " \
1622- "Host: #{ @address } :#{ @port } \r \n "
1623- if proxy_user
1624- credential = [ "#{ proxy_user } :#{ proxy_pass } " ] . pack ( 'm0' )
1625- buf << "Proxy-Authorization: Basic #{ credential } \r \n "
1626- end
1627- buf << "\r \n "
1628- plain_sock . write ( buf )
1629- HTTPResponse . read_new ( plain_sock ) . value
1630- # assuming nothing left in buffers after successful CONNECT response
1631- end
1632-
1633- ssl_parameters = Hash . new
1634- iv_list = instance_variables
1635- SSL_IVNAMES . each_with_index do |ivname , i |
1636- if iv_list . include? ( ivname )
1637- value = instance_variable_get ( ivname )
1638- unless value . nil?
1639- ssl_parameters [ SSL_ATTRIBUTES [ i ] ] = value
1640- end
1641- end
1642- end
1643- @ssl_context . set_params ( ssl_parameters )
1644- unless @ssl_context . session_cache_mode . nil? # a dummy method on JRuby
1645- @ssl_context . session_cache_mode =
1646- OpenSSL ::SSL ::SSLContext ::SESSION_CACHE_CLIENT |
1647- OpenSSL ::SSL ::SSLContext ::SESSION_CACHE_NO_INTERNAL_STORE
1648- end
1649- if @ssl_context . respond_to? ( :session_new_cb ) # not implemented under JRuby
1650- @ssl_context . session_new_cb = proc { |sock , sess | @ssl_session = sess }
1651- end
1652-
1653- # Still do the post_connection_check below even if connecting
1654- # to IP address
1655- verify_hostname = @ssl_context . verify_hostname
1656-
1657- # Server Name Indication (SNI) RFC 3546/6066
1658- case @address
1659- when Resolv ::IPv4 ::Regex , Resolv ::IPv6 ::Regex
1660- # don't set SNI, as IP addresses in SNI is not valid
1661- # per RFC 6066, section 3.
1662-
1663- # Avoid openssl warning
1664- @ssl_context . verify_hostname = false
1665- else
1666- ssl_host_address = @address
1667- end
1668-
1669- debug "starting SSL for #{ conn_addr } :#{ conn_port } ..."
1670- s = OpenSSL ::SSL ::SSLSocket . new ( s , @ssl_context )
1671- s . sync_close = true
1672- s . hostname = ssl_host_address if s . respond_to? ( :hostname= ) && ssl_host_address
1673-
1674- if @ssl_session and
1675- Process . clock_gettime ( Process ::CLOCK_REALTIME ) < @ssl_session . time . to_f + @ssl_session . timeout
1676- s . session = @ssl_session
1677- end
1678- ssl_socket_connect ( s , @open_timeout )
1679- if ( @ssl_context . verify_mode != OpenSSL ::SSL ::VERIFY_NONE ) && verify_hostname
1680- s . post_connection_check ( @address )
1681- end
1682- debug "SSL established, protocol: #{ s . ssl_version } , cipher: #{ s . cipher [ 0 ] } "
1616+ proxy_connect ( s , conn_address ) if proxy?
1617+ setup_ssl_context
1618+ s = setup_ssl_socket ( s , conn_addr , conn_port )
1619+ ssl_connect ( s )
16831620 end
16841621 @socket = BufferedIO . new ( s , read_timeout : @read_timeout ,
16851622 write_timeout : @write_timeout ,
@@ -1696,6 +1633,85 @@ def connect
16961633 end
16971634 private :connect
16981635
1636+ def proxy_connect ( s , conn_address )
1637+ plain_sock = BufferedIO . new ( s , read_timeout : @read_timeout ,
1638+ write_timeout : @write_timeout ,
1639+ continue_timeout : @continue_timeout ,
1640+ debug_output : @debug_output )
1641+ buf = "CONNECT #{ conn_address } :#{ @port } HTTP/#{ HTTPVersion } \r \n "
1642+ buf << "Host: #{ @address } :#{ @port } \r \n "
1643+ if proxy_user
1644+ credential = [ "#{ proxy_user } :#{ proxy_pass } " ] . pack ( 'm0' )
1645+ buf << "Proxy-Authorization: Basic #{ credential } \r \n "
1646+ end
1647+ buf << "\r \n "
1648+ plain_sock . write ( buf )
1649+ HTTPResponse . read_new ( plain_sock ) . value
1650+ # assuming nothing left in buffers after successful CONNECT response
1651+ end
1652+ private :proxy_connect
1653+
1654+ def setup_ssl_context
1655+ ssl_parameters = Hash . new
1656+ iv_list = instance_variables
1657+ SSL_IVNAMES . each_with_index do |ivname , i |
1658+ if iv_list . include? ( ivname )
1659+ value = instance_variable_get ( ivname )
1660+ unless value . nil?
1661+ ssl_parameters [ SSL_ATTRIBUTES [ i ] ] = value
1662+ end
1663+ end
1664+ end
1665+ @ssl_context . set_params ( ssl_parameters )
1666+ unless @ssl_context . session_cache_mode . nil? # a dummy method on JRuby
1667+ @ssl_context . session_cache_mode =
1668+ OpenSSL ::SSL ::SSLContext ::SESSION_CACHE_CLIENT |
1669+ OpenSSL ::SSL ::SSLContext ::SESSION_CACHE_NO_INTERNAL_STORE
1670+ end
1671+ if @ssl_context . respond_to? ( :session_new_cb ) # not implemented under JRuby
1672+ @ssl_context . session_new_cb = proc { |sock , sess | @ssl_session = sess }
1673+ end
1674+ end
1675+ private :setup_ssl_context
1676+
1677+ def setup_ssl_socket ( s , conn_addr , conn_port )
1678+ # Still do the post_connection_check below even if connecting
1679+ # to IP address
1680+ verify_hostname = @ssl_context . verify_hostname
1681+
1682+ # Server Name Indication (SNI) RFC 3546/6066
1683+ case @address
1684+ when Resolv ::IPv4 ::Regex , Resolv ::IPv6 ::Regex
1685+ # don't set SNI, as IP addresses in SNI is not valid
1686+ # per RFC 6066, section 3.
1687+
1688+ # Avoid openssl warning
1689+ @ssl_context . verify_hostname = false
1690+ else
1691+ ssl_host_address = @address
1692+ end
1693+
1694+ debug "starting SSL for #{ conn_addr } :#{ conn_port } ..."
1695+ s = OpenSSL ::SSL ::SSLSocket . new ( s , @ssl_context )
1696+ s . sync_close = true
1697+ s . hostname = ssl_host_address if s . respond_to? ( :hostname= ) && ssl_host_address
1698+ s
1699+ end
1700+ private :setup_ssl_socket
1701+
1702+ def ssl_connect ( s )
1703+ if @ssl_session and
1704+ Process . clock_gettime ( Process ::CLOCK_REALTIME ) < @ssl_session . time . to_f + @ssl_session . timeout
1705+ s . session = @ssl_session
1706+ end
1707+ ssl_socket_connect ( s , @open_timeout )
1708+ if ( @ssl_context . verify_mode != OpenSSL ::SSL ::VERIFY_NONE ) && verify_hostname
1709+ s . post_connection_check ( @address )
1710+ end
1711+ debug "SSL established, protocol: #{ s . ssl_version } , cipher: #{ s . cipher [ 0 ] } "
1712+ end
1713+ private :ssl_connect
1714+
16991715 def on_connect
17001716 end
17011717 private :on_connect
0 commit comments