學寫 HTTP Tunnel

来源:互联网 发布:极限脱出 知乎 编辑:程序博客网 时间:2024/05/16 06:54

我有位朋友, 佢做嘅公司 block 咗所有 IM 同 Web IM. 唯一可以用嘅就係 Gmail 入面嘅 Google Talk. 但係近幾日, Gmail 去倒, 但係 Google Talk 就 block 咗. 要同佢傾計, 唯有狂 send Gmail 啦...

我想學一下點寫 HTTP push, 所以好快手咁寫咗個 HTTP Tunnel 出黎, 仲可以係 IIS 同 UltiDev Cassini 上面行, 亦都學咗好多嘢, 我想係呢度 conclude 一下學咗啲咩. 係 conclude 之前想提返大家少少關於 tunneling 嘅嘢.

  1. HTTP 係 half-duplex, 要 tunnel 一條 full-duplex TCP, 就要用兩條 HTTP connection
  2. Client 個程式 listen 住 localhost:12345, 咁所有 traffic 開去呢個 port, 就會 encapsulate 落 HTTP packet 入面, 再 send 去 tunnel server
  3. Server 接到 packet, 就會用 blocking 嗰條 HTTP push channel, 去 send 返俾 client
  4. 理論上, 雖然係開 local resources 嘅嘢, 但係 IIS 唔應該會有問題

咁以下就係學倒嘅嘢

  1. 有兩條 HTTP, 一條係 Client -> Server, 另一條係 Server -> Client
    1. Client -> Server, 呢條只不過係普普通通嘅 Web Services 都得, 因為係 client 去 server, 就好似 HTTP model 咁, 亦都唔會 blocking
    2. Server -> Client, 呢條就會 block 住, 直到有 data 或者 timeout
    3. 如果用 Web Services 寫第二條, 佢會 block 住之後所有嘅 request, 即係第一條係唔俾人 block connect, 唔知點解, 我亦唔可以開兩個 Worker Process (因為 socket 只會 bind 住其中一個)
    4. 要咁寫, 一定要用 .ASHX (Generic Handler), 唔一定要 IHttpAsyncHandler, 普通嘅 IHttpHandler 都得
    5. 如果 send 唔用 .ASHX, 就會有機會 block 住 receive, 所以兩個都應該寫 .ASHX
  2. HttpWebRequest.Proxy 唔 set 嘅話, 係唔會行倒 ISA server 嘅 NTLM authentication
  3. WinInet 開嘅 HTTP connection 係有限制, 去 HTTP 1.1 最多兩條, HTTP 1.0 最多四條
    1. Local server 係無呢個 limit
    2. Registry 有得 set, 不過唔係好 work
    3. FireFox 有可能會開 8 條, 最少 2 條, 可以人手較, 但係唔方便, 亦都唔係 workaround, 因為我想用 MSN Messenger
    4. 寫個程式時要 limit 只係會開 2 條, 張 N 條嘅 connection encapsulate 入呢兩條入面
  4. 用 observer pattern 去管理 connection 嘅 closure
    1. 因為 WinSock 有兩種 closure: graceful 同 reset
    2. 又因為你有兩個 socket 可以收 closure
    3. 所以, 你有 4 種 closure 方法
    4. 用 observer pattern 最簡單, 不過你最好寫個 manager 去做管理, 唔可以只係一個 List<> 就攪掂

最終, 訓咗兩晚覺就攪掂咗個程式, 仲可以行 HTTPS. 用咗大概 42 小時, 但係實際落手做只係做咗 11 個鐘左右.

p.s. 有 PortReverser + HttpTunnel, 就可以夾埋做一個 traverse NAT/HTTP firewall 嘅 package 

原创粉丝点击