About capturing and saving http

I use

resp, err := http.Get("http://example.com/")

get http.Response, and I want to write exactly to the HTTP handler, but only http.ResponseWriter, so I grabbed it.

...
webConn, webBuf, err := hj.Hijack()
if err != nil {
    // handle error
}
defer webConn.Close()

// Write resp
resp.Write(webBuf)
...

Record raw request

But when I get addicted, the http connection cannot reuse (save-revive), so it slows down.

How to solve?

Thanks! Sorry for my English pool.

12/9 keepalivekeepalive2 keep-alive update , it supports two tcp connections and can be reused.

nokeepalivenokeepalive2 but when I hijack and conn.Close (), it cannot reuse the old connection, so it creates a new tcp connection when I each update.

+4
source share
2 answers

, - , HTTP- , .

, , (http://golang.org/src/pkg/net/http/httputil/reverseproxy.go), .

:

func copyHeader(dst, src http.Header) {
    for k, w := range src {
        for _, v := range w {
            dst.Add(k, v)
        }
    }
}

func copyResponse(r *http.Response, w http.ResponseWriter) {
    copyHeader(w.Header(), r.Header)
    w.WriteHeader(r.StatusCode)
    io.Copy(w, r.Body)
}

func handler(w http.ResponseWriter, r *http.Response) {
    resp, err := http.Get("http://www.example.com")
    if err != nil {
        // handle error
    }
    copyResponse(resp, w)
}
+5

, , keep-alive . , , , .

, net.TCPConn, , .SetKeepAlive(true).

netstat -antc | grep 9090.

:

localhost:9090/ok - ( )
localhost:9090 - , 10 .

package main

import (
    "fmt"
    "net/http"
    "sync"
    "time"
)

func checkError(e error) {
    if e != nil {
        panic(e)
    }
}

var ka_seconds = 10
var conn_id = 0
func main() {
    http.HandleFunc("/ok", func(w http.ResponseWriter, r *http.Request) {
        fmt.Fprintln(w, "ok")
    })
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        conn_id++
        fmt.Printf("Connection %v: Keep-alive is enabled %v seconds\n", conn_id, ka_seconds)
        hj, ok := w.(http.Hijacker)
        if !ok {
            http.Error(w, "webserver doesn't support hijacking", http.StatusInternalServerError)
            return
        }
        conn, bufrw, err := hj.Hijack()
        if err != nil {
            http.Error(w, err.Error(), http.StatusInternalServerError)
            return
        }
        // Don't forget to close the connection:
        time.AfterFunc(time.Second* time.Duration(ka_seconds), func() {
            conn.Close()
            fmt.Printf("Connection %v: Keep-alive is disabled.\n", conn_id)
        })
        resp, err := http.Get("http://www.example.com")
        checkError(err)
        resp.Write(bufrw)
        bufrw.Flush()
    })
    fmt.Println("Listing to localhost:9090")
    http.ListenAndServe(":9090", nil)
}

: http://code.google.com/p/go/issues/detail?id=5645

0

All Articles