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