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