Hacktoberfest 2026:维护者为十月标记出来的 issue,仍然开放、适合新手。 浏览 Hacktoberfest issue

Is the HTTPS proxy support known-working under real-world conditions?

未关闭
#212 2 条评论 2 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
42/100
Issue 类型
缺陷
描述清晰度
基本清楚
活跃度
停滞
技术栈
ruby
领域
networking

调研方向

首先阅读 lib/net/http.rb 和 Net::Protocol#ssl_socket_connect 中引用的连接流程,然后针对 HTTPS 代理运行 ProxySock 示例。完成的标准是确认 HTTPS 代理是否按描述失败,并记录可复现的结果或经过验证的修正路径。

由索引模型根据 Issue 内容生成。

描述

I've been debugging HTTPS proxy support all day and I'm coming to the conclusion the released implementation may be be broken.

Stepping through an example invocation:

n = Net::HTTP.new('google.com', 443, '127.0.0.1', 4433, nil, nil, nil, true)
n.use_ssl = true
n.get('/')

I don't believe the last step works.

To test I banged out a little helper class that does the initial proxy connection setup:

require 'net/http'

class ProxySock
  attr_accessor :proxy_sock, :s

  def initialize
    @s = TCPSocket.open('127.0.0.1', 4433, nil, nil)
    @proxy_sock = OpenSSL::SSL::SSLSocket.new(@s)
    Net::Protocol.new.send(:ssl_socket_connect, @proxy_sock, 1.0)
  end

  def close
    @proxy_sock.close
  ensure
    @s.close
  end
end

Then, as a baseline, I checked that basic HTTP proxying was working:

ps = ProxySock.new
begin
  ps.proxy_sock.write("GET http://google.com/ HTTP/1.1\r\n\r\n")
  puts ps.proxy_sock.gets("\r\n\r\n")
ensure
  ps.close
end

This returns the expected HTTP/1.1 301 Moved Permanently Location: http://www.google.com/ response.

Then, I tried the flow Net::HTTP currently does:

ps = ProxySock.new
begin
  ps.proxy_sock.write("CONNECT google.com:443 HTTP/1.1\r\n\r\n")
  puts ps.proxy_sock.gets("\r\n\r\n")
  
  endpoint_sock = OpenSSL::SSL::SSLSocket.new(ps.s)
  Net::Protocol.new.send(:ssl_socket_connect, endpoint_sock, 1.0)
  endpoint_sock.write("GET http://google.com/ HTTP/1.1\r\n\r\n")
  puts endpoint_sock.gets("\r\n\r\n")
ensure
  ps.close
end

This throws the following error, which is the same error I get from Net::HTTP:

home/tom/.rbenv/versions/3.4.1/lib/ruby/3.4.0/net/protocol.rb:46:in 'OpenSSL::SSL::SSLSocket#connect_nonblock': SSL_connect returned=1 errno=0 peeraddr=127.0.0.1:4433 state=error: invalid alert (OpenSSL::SSL::SSLError)
        from /home/tom/.rbenv/versions/3.4.1/lib/ruby/3.4.0/net/protocol.rb:46:in 'Net::Protocol#ssl_socket_connect'
        from tmp/logic_test.rb:59:in '<main>'

As a second test I tried performing another HTTP proxy test, this time using CONNECT:

ps = ProxySock.new
begin
  ps.proxy_sock.write("CONNECT google.com:80 HTTP/1.1\r\n\r\n")
  puts ps.proxy_sock.gets("\r\n\r\n")

  ps.proxy_sock.write("GET http://google.com/ HTTP/1.1\r\n\r\n")
  puts ps.proxy_sock.gets("\r\n\r\n")

  ps.s.write("GET http://google.com/ HTTP/1.1\r\n\r\n")
  puts ps.s.gets("\r\n\r\n")
ensure
  ps.close
end

This outputs two blocks. The first block uses the SSL socket and returns HTTP/1.1 301 Moved Permanently, as expected. The second block attempts to use the underlying TCP socket, same as we're trying to do for the endpoint SSL socket, and that returns �*o�Ń7�t��4��w4Q���k�9o� which appears to be encrypted data.

When using a HTTPS proxy the socket s IO will be encrypted, I don't believe this is the correct handle to use for the endpoint encryption.. I believe we need to initialize the endpoint ssl over the proxy_sock to nest the encryption.

To this end, I tried endpoint_sock = OpenSSL::SSL::SSLSocket.new(ps.proxy_sock) but that simply throws wrong argument type OpenSSL::SSL::SSLSocket (expected File) (TypeError). So I don't have a working HTTPS over HTTPS proxy example on hand.

I'm currently of the opinion the implementation here is broken. Am I mistaken? Is there a flaw in my analysis and test cases?

主要语言
Ruby
星标
148
派生
95
平均合并
10 小时 54 分钟
30 天内合并 PR
4

贡献指南

这个仓库没有索引到贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

ruby/net-http 的其他 Issue

查看 ruby/net-http 的全部 Issue

相似的 Issue

更多 Ruby Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。