我正在嘗試使用 Golang 制作 https 代理。一開始我知道,瀏覽器會發送帶有結尾的標頭\r\n和套接字塊read(),直到讀取這些字符為止。但是當它被加密(ssl/tls)和 HTTP 1.1(保持連接有效)時
- 瀏覽器如何知道讀取資料結束?
- 他們是否逐位元組讀取并在末尾讀取一些特殊字符(這對大資料來說是一種好方法嗎?)?
- 或者他們首先發送資料大小(如 tcp 套接字主題中所建議)?
- 作為代理,我如何在流式傳輸或加載簡單的 html 頁面時了解資料的結尾?
這只是代碼的一部分,當我在本地網路中運行它時它可以作業,但在服務器(vps)中將阻塞讀取直到連接關閉。完整代碼在這里
func write(client_to_proxy net.Conn, browser_to_client net.Conn) {
defer client_to_proxy.Close()
buffer := make([]byte, 1024)
reader := bufio.NewReader(browser_to_client)
for {
length, err := reader.Read(buffer)
if length > 0 {
fmt.Println(time.Now().Format(time.Stamp) " READ from client to browser: " strconv.Itoa(length))
//fmt.Println(string(buffer[:readLeng]))
writeLength, err := client_to_proxy.Write(buffer[:length])
if writeLength > 0 {
fmt.Println(time.Now().Format(time.Stamp) " WRITE from client to browser: " strconv.Itoa(writeLength))
}
if err != nil {
fmt.Println("ERR6 ", err)
return
}
}
if err != nil {
fmt.Println("ERR5 ", err)
return
}
}
}
func read(client_to_proxy net.Conn, browser_to_client net.Conn) {
defer browser_to_client.Close()
buffer := make([]byte, 1024)
reader := bufio.NewReader(client_to_proxy)
length, err := reader.Read(buffer)
fmt.Println(time.Now().Format(time.Stamp) " READ from proxy to client: " strconv.Itoa(length))
fmt.Println(string(buffer))
if length > 0 {
writeLength, err := browser_to_client.Write(buffer[:length])
fmt.Println(time.Now().Format(time.Stamp) " WRITE from client to browser: " strconv.Itoa(writeLength))
if err != nil {
fmt.Println("ERR7 ", err)
return
}
}
if err != nil {
return
}
go write(client_to_proxy, browser_to_client)
for {
length, err := reader.Read(buffer)
fmt.Println(time.Now().Format(time.Stamp) " READ from proxy to client: " strconv.Itoa(length))
//fmt.Println(string(buffer[:length]))
if length > 0 {
writeLength, err := browser_to_client.Write(buffer[:length])
fmt.Println(time.Now().Format(time.Stamp) " WRITE from client to browser: " strconv.Itoa(writeLength))
if err != nil {
fmt.Println("ERR8 ", err)
return
}
}
if err != nil {
return
}
}
}
編輯 1:
我使用這樣的客戶端和服務器 go 應用程式 browser->client->proxy->so.com 然后 so.com->prxoy->client->browser 我不想加密資料!我的問題出在“客戶端”應用程式上,我不知道應該讀取多少位元組才能解鎖read()!
uj5u.com熱心網友回復:
瀏覽器如何知道讀取資料結束?
通過執行標準。
對于 HTTP/1.1,請參閱RFC 7230 第 3.3 節訊息正文長度以了解如何確定正文長度的詳細資訊。提示:基于 HTTP 標頭的資訊,如 Content-length 和 Transfer-Encoding。
作為代理,我如何在流式傳輸或加載簡單的 html 頁面時了解資料的結尾?
對于純 HTTP 訊息,代理的行為相同。
HTTPS 流量使用隧道通過代理在客戶端和服務器之間通過端到端加密傳遞。該隧道是通過 CONNECT 請求創建的,該請求僅在 TCP 連接關閉時結束。代理無法洞察連接,因此也無法確定加密流量中各種請求和回應的 HTTP 訊息標頭和正文的位置。
uj5u.com熱心網友回復:
感謝 Steffen Ullrich,瀏覽器服務器,首先發送標頭,每個標頭都用\r\n. 這樣他們就可以逐行閱讀標題。一個標題鍵,值可以告訴其余資料(正文)的大小。這些標頭在兩者之間加密。所以他們知道應該讀取多少資料。但作為代理,我們應該將彼此(套接字)通過管道連接在一起,并在 Golang 中使用io.copy(src, dst). 所以不需要知道之間傳輸的資料大小和其他 tcp 問題。也使它作業得更快,因為它發生在較低級別的網路中。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/536296.html
