func TestServeHTTPReadRequestError(t *testing.T) { p := NewProxy(mitm) // Shorten the timeout to force a ReadRequest error. p.Timeout = time.Second rc, wc := pipeWithTimeout() defer rc.Close() defer wc.Close() rw := newHijackRecorder(wc) req, err := http.NewRequest("CONNECT", "//www.example.com:443", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } go p.ServeHTTP(rw, req) res, err := http.ReadResponse(bufio.NewReader(rc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } res.Body.Close() tlsConn := tlsClient(rc, p.mitm.Authority, "www.example.com") tlsConn.Write([]byte("INVALID /invalid NOTHTTP/1.1\r\n")) if _, err = http.ReadResponse(bufio.NewReader(tlsConn), nil); err != io.ErrUnexpectedEOF { t.Fatalf("http.ReadResponse(): got %v, want io.ErrUnexpectedEOF", err) } }
func TestServeHTTPKeepAlive(t *testing.T) { p := NewProxy(mitm) rc, wc := pipeWithTimeout() defer rc.Close() defer wc.Close() rw := newHijackRecorder(wc) req, err := http.NewRequest("CONNECT", "//www.example.com:443", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } go p.ServeHTTP(rw, req) res, err := http.ReadResponse(bufio.NewReader(rc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } res.Body.Close() tlsConn := tlsClient(rc, p.mitm.Authority, "www.example.com") tt := []struct { closing bool }{ {false}, {false}, {true}, } for _, tc := range tt { req, err = http.NewRequest("GET", "https://www.example.com/", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } // Close the connection on the last request. if tc.closing { req.Header.Set("Connection", "close") } if err := req.Write(tlsConn); err != nil { t.Fatalf("req.Write(): got %v, want no error", err) } res, err = http.ReadResponse(bufio.NewReader(tlsConn), nil) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } res.Body.Close() if got, want := res.StatusCode, 200; got != want { t.Errorf("res.StatusCode: got %d, want %d", got, want) } if tc.closing && !res.Close { t.Error("res.Close: got false, want true") } } }
func TestServeHTTPConnectRequestWithoutMITM(t *testing.T) { p := NewProxy(nil) f := func(w http.ResponseWriter, r *http.Request) { w.Write([]byte("secret!")) } server := httptest.NewTLSServer(http.HandlerFunc(f)) defer server.Close() rc, wc := pipeWithTimeout() defer rc.Close() defer wc.Close() rw := newHijackRecorder(wc) req, err := http.NewRequest("CONNECT", server.URL, nil) if err != nil { t.Fatalf("http.NewRequest(%q, %q, nil): got %v, want no error", "CONNECT", server.URL, err) } go p.ServeHTTP(rw, req) res, err := http.ReadResponse(bufio.NewReader(rc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } if got, want := res.StatusCode, 200; got != want { t.Errorf("res.StatusCode: got %d, want %d", got, want) } req, err = http.NewRequest("GET", server.URL, nil) if err != nil { t.Fatalf("http.NewRequest(%q, %q, nil): got %v, want no error", "GET", server.URL, err) } req.Header.Set("Connection", "close") tlsrc := tls.Client(rc, &tls.Config{ InsecureSkipVerify: true, }) go req.Write(tlsrc) res, err = http.ReadResponse(bufio.NewReader(tlsrc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } got, err := ioutil.ReadAll(res.Body) if err != nil { t.Fatalf("ioutil.ReadAll(res.Body): got %v, want no error", err) } res.Body.Close() if want := []byte("secret!"); !bytes.Equal(got, want) { t.Errorf("res.Body: got %q, want %q", got, want) } }
// StaticResponder returns an HTTP response generator that parses res // for an entire HTTP response, including headers and body. func StaticResponder(res string) func() *http.Response { _, err := http.ReadResponse(bufio.NewReader(strings.NewReader(res)), nil) if err != nil { panic("Invalid response given to StaticResponder: " + err.Error()) } return func() *http.Response { res, _ := http.ReadResponse(bufio.NewReader(strings.NewReader(res)), nil) return res } }
func TestServeHTTPBuildsValidRequest(t *testing.T) { p := NewProxy(mitm) p.RoundTripper = RoundTripFunc(func(req *http.Request) (*http.Response, error) { if got, want := req.URL.Scheme, "https"; got != want { t.Errorf("req.URL.Scheme: got %q, want %q", got, want) } if got, want := req.URL.Host, "www.example.com"; got != want { t.Errorf("req.URL.Host: got %q, want %q", got, want) } if req.RemoteAddr == "" { t.Error("req.RemoteAddr: got empty, want addr") } return proxyutil.NewResponse(201, nil, req), nil }) rc, wc := pipeWithTimeout() defer rc.Close() defer wc.Close() rw := newHijackRecorder(wc) req, err := http.NewRequest("CONNECT", "//www.example.com:443", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } go p.ServeHTTP(rw, req) res, err := http.ReadResponse(bufio.NewReader(rc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } res.Body.Close() tlsConn := tlsClient(rc, p.mitm.Authority, "www.example.com") req, err = http.NewRequest("GET", "https://www.example.com", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no erro", err) } req.Header.Set("Connection", "close") if err := req.Write(tlsConn); err != nil { t.Fatalf("req.Write(): got %v, want no error", err) } res, err = http.ReadResponse(bufio.NewReader(tlsConn), nil) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } defer res.Body.Close() if got, want := res.StatusCode, 201; got != want { t.Errorf("res.StatusCode: got %d, want %d", got, want) } }
// load an external image or fetch it from the cache // and write it to the ResponseWriter func (ipw *ImgProxy) ProxyImage(w http.ResponseWriter, req *http.Request, url string) (err error) { cacheKey := ipw.cacheKey(url) xCacheHeader := "HIT" var resp *http.Response // attempt to read from cache cachedData, ok := ipw.cache.Get(cacheKey) if ok { b := bytes.NewBuffer(cachedData) resp, err = http.ReadResponse(bufio.NewReader(b), req) if err != nil { log.Printf("Unable to read cached entry for %s: %v (cacheKey: %s)", url, err, cacheKey) // remove any invalid data from the cache and // fetch it fresh from upstream ipw.cache.Delete(cacheKey) resp = nil } } // fetch from upstream if resp == nil { xCacheHeader = "MISS" downloadedData := <-ipw.fetchFromUpstream(url) if downloadedData.err != nil { return downloadedData.err } resp, err = http.ReadResponse(bufio.NewReader(bytes.NewBuffer(downloadedData.httpResponseData)), req) if err != nil { return err } } // write to responsewriter copyHeader(w, resp, "Last-Modified") copyHeader(w, resp, "Expires") copyHeader(w, resp, "Etag") w.Header()[http.CanonicalHeaderKey("X-Cache")] = []string{xCacheHeader} if is304 := check304(req, resp); is304 { w.WriteHeader(http.StatusNotModified) return } copyHeader(w, resp, "Content-Length") copyHeader(w, resp, "Content-Type") w.WriteHeader(resp.StatusCode) io.Copy(w, resp.Body) return nil }
func TestServeHTTPModifyResponseError(t *testing.T) { p := NewProxy(mitm) f := func(*Context, *http.Response) error { return fmt.Errorf("modifier error") } p.SetResponseModifier(ResponseModifierFunc(f)) rc, wc := pipeWithTimeout() defer rc.Close() defer wc.Close() rw := newHijackRecorder(wc) req, err := http.NewRequest("CONNECT", "//www.example.com:443", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } go p.ServeHTTP(rw, req) res, err := http.ReadResponse(bufio.NewReader(rc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } res.Body.Close() tlsConn := tlsClient(rc, p.mitm.Authority, "www.example.com") req, err = http.NewRequest("GET", "https://www.example.com/", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no erro", err) } if err := req.Write(tlsConn); err != nil { t.Fatalf("req.Write(): got %v, want no error", err) } res, err = http.ReadResponse(bufio.NewReader(tlsConn), nil) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } defer res.Body.Close() if got, want := res.StatusCode, 400; got != want { t.Errorf("res.StatusCode: got %d, want %d", got, want) } got, err := ioutil.ReadAll(res.Body) if err != nil { t.Fatalf("ioutil.ReadAll(): got %v, want no error", err) } if want := []byte("modifier error"); !bytes.Equal(got, want) { t.Errorf("res.Body: got %q, want %q", got, want) } }
func TestServeHTTPSkipRoundTrip(t *testing.T) { p := NewProxy(mitm) f := func(ctx *Context, _ *http.Request) error { ctx.SkipRoundTrip = true return nil } p.SetRequestModifier(RequestModifierFunc(f)) p.RoundTripper = RoundTripFunc(func(*http.Request) (*http.Response, error) { t.Fatal("RoundTrip(): got called, want skipped") return nil, nil }) rc, wc := pipeWithTimeout() defer rc.Close() defer wc.Close() rw := newHijackRecorder(wc) req, err := http.NewRequest("CONNECT", "//www.example.com:443", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } go p.ServeHTTP(rw, req) res, err := http.ReadResponse(bufio.NewReader(rc), req) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } res.Body.Close() tlsConn := tlsClient(rc, p.mitm.Authority, "www.example.com") req, err = http.NewRequest("GET", "https://www.example.com/", nil) if err != nil { t.Fatalf("http.NewRequest(): got %v, want no error", err) } req.Header.Set("Connection", "close") if err := req.Write(tlsConn); err != nil { t.Fatalf("req.Write(): got %v, want no error", err) } res, err = http.ReadResponse(bufio.NewReader(tlsConn), nil) if err != nil { t.Fatalf("http.ReadResponse(): got %v, want no error", err) } defer res.Body.Close() if got, want := res.StatusCode, 200; got != want { t.Errorf("res.StatusCode: got %d, want %d", got, want) } }
func (st *supervisorTransport) RoundTrip(req *http.Request) (*http.Response, error) { if req.URL == nil { return nil, errors.New("unix: nil Request.URL") } if req.Header == nil { return nil, errors.New("unix: nil Request.Header") } if req.URL.Scheme != "unix" { panic("unix: unsupported protocol scheme") } sock, err := net.Dial("unix", req.URL.Path) if err != nil { return nil, err } defer sock.Close() //create shallow copy of request object newReq := new(http.Request) *newReq = *req newReq.URL = supervisorURL newReq.Write(sock) return http.ReadResponse(bufio.NewReader(sock), req) }
func parseSearchResponse(httpResponse io.Reader, responseAddr *net.UDPAddr) (*SearchResponse, error) { reader := bufio.NewReader(httpResponse) request := &http.Request{} // Needed for ReadResponse but doesn't have to be real response, err := http.ReadResponse(reader, request) if err != nil { return nil, err } headers := response.Header res := &SearchResponse{} res.Control = headers.Get("cache-control") res.Server = headers.Get("server") res.ST = headers.Get("st") res.Ext = headers.Get("ext") res.USN = headers.Get("usn") res.ResponseAddr = responseAddr if headers.Get("location") != "" { res.Location, err = response.Location() if err != nil { return nil, err } } date := headers.Get("date") if date != "" { res.Date, err = http.ParseTime(date) if err != nil { return nil, err } } return res, nil }
func (c *Client) do(method, path string, doOptions doOptions) ([]byte, int, error) { var params io.Reader if doOptions.data != nil || doOptions.forceJSON { buf, err := json.Marshal(doOptions.data) if err != nil { return nil, -1, err } params = bytes.NewBuffer(buf) } if path != "/version" && !c.SkipServerVersionCheck && c.expectedAPIVersion == nil { err := c.checkAPIVersion() if err != nil { return nil, -1, err } } req, err := http.NewRequest(method, c.getURL(path), params) if err != nil { return nil, -1, err } req.Header.Set("User-Agent", userAgent) if doOptions.data != nil { req.Header.Set("Content-Type", "application/json") } else if method == "POST" { req.Header.Set("Content-Type", "plain/text") } var resp *http.Response protocol := c.endpointURL.Scheme address := c.endpointURL.Path if protocol == "unix" { var dial net.Conn dial, err = net.Dial(protocol, address) if err != nil { return nil, -1, err } defer dial.Close() breader := bufio.NewReader(dial) err = req.Write(dial) if err != nil { return nil, -1, err } resp, err = http.ReadResponse(breader, req) } else { resp, err = c.HTTPClient.Do(req) } if err != nil { if strings.Contains(err.Error(), "connection refused") { return nil, -1, ErrConnectionRefused } return nil, -1, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return nil, -1, err } if resp.StatusCode < 200 || resp.StatusCode >= 400 { return nil, resp.StatusCode, newError(resp.StatusCode, body) } return body, resp.StatusCode, nil }
// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1 // request (both keep-alive), when a Handler never writes any // response, the net/http package adds a "Content-Length: 0" response // header. func TestContentLengthZero(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {})) defer ts.Close() for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} { conn, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatalf("error dialing: %v", err) } _, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version) if err != nil { t.Fatalf("error writing: %v", err) } req, _ := http.NewRequest("GET", "/", nil) res, err := http.ReadResponse(bufio.NewReader(conn), req) if err != nil { t.Fatalf("error reading response: %v", err) } if te := res.TransferEncoding; len(te) > 0 { t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te) } if cl := res.ContentLength; cl != 0 { t.Errorf("For version %q, Content-Length = %v; want 0", version, cl) } conn.Close() } }
// TestCopyError tests that we kill the process if there's an error copying // its output. (for example, from the client having gone away) func TestCopyError(t *testing.T) { check(t) if runtime.GOOS == "windows" { t.Skipf("skipping test on %q", runtime.GOOS) } h := &Handler{ Path: "testdata/test.cgi", Root: "/test.cgi", } ts := httptest.NewServer(h) defer ts.Close() conn, err := net.Dial("tcp", ts.Listener.Addr().String()) if err != nil { t.Fatal(err) } req, _ := http.NewRequest("GET", "http://example.com/test.cgi?bigresponse=1", nil) err = req.Write(conn) if err != nil { t.Fatalf("Write: %v", err) } res, err := http.ReadResponse(bufio.NewReader(conn), req) if err != nil { t.Fatalf("ReadResponse: %v", err) } pidstr := res.Header.Get("X-CGI-Pid") if pidstr == "" { t.Fatalf("expected an X-CGI-Pid header in response") } pid, err := strconv.Atoi(pidstr) if err != nil { t.Fatalf("invalid X-CGI-Pid value") } var buf [5000]byte n, err := io.ReadFull(res.Body, buf[:]) if err != nil { t.Fatalf("ReadFull: %d bytes, %v", n, err) } childRunning := func() bool { return isProcessRunning(t, pid) } if !childRunning() { t.Fatalf("pre-conn.Close, expected child to be running") } conn.Close() tries := 0 for tries < 25 && childRunning() { time.Sleep(50 * time.Millisecond * time.Duration(tries)) tries++ } if childRunning() { t.Fatalf("post-conn.Close, expected child to be gone") } }
func parseResponse(msg, hostPort string) *ResponseMessage { resp, err := http.ReadResponse(bufio.NewReader(strings.NewReader(msg)), nil) if err != nil { return nil } defer resp.Body.Close() maxAge := -1 if cc := resp.Header.Get("CACHE-CONTROL"); cc != "" { subMatch := cacheControlAge.FindStringSubmatch(cc) if len(subMatch) == 2 { maxAgeInt64, err := strconv.ParseInt(subMatch[1], 10, 0) if err == nil { maxAge = int(maxAgeInt64) } } } usn := resp.Header.Get("USN") deviceId, urn := extractUrnDeviceIdFromUsn(usn) respMessage := ResponseMessage{ MaxAge: maxAge, SearchType: resp.Header.Get("ST"), Usn: usn, Urn: urn, DeviceId: deviceId, Location: resp.Header.Get("LOCATION"), Server: resp.Header.Get("SERVER"), RawResponse: resp, } return &respMessage }
func (this Tunnel) ServeHTTP(response http.ResponseWriter, request *http.Request) { conn, err := this.session.Open() if err != nil { log.Println(err.Error()) response.Write([]byte("<html><body>" + err.Error() + "</body></html>")) return } defer conn.Close() if err := request.Write(conn); err != nil { log.Println(err.Error()) return } tunnelResponse, err := http.ReadResponse(bufio.NewReader(conn), request) if err != nil { response.Write([]byte("<html><body>" + err.Error() + "</body></html>")) return } for header, values := range tunnelResponse.Header { for _, value := range values { response.Header().Add(header, value) } } response.WriteHeader(tunnelResponse.StatusCode) if tunnelResponse.Body != nil { io.Copy(response, tunnelResponse.Body) } }
func (teller *GoTeller) sendRequest(fileIndex uint32, filename string, to ipaddr.IPAddr, onResponse func(error, uint32, string, *http.Response)) { endpoint := to.String() path := fmt.Sprintf("/get/%d/%s", fileIndex, filename) req, err := http.NewRequest("GET", "http://"+endpoint+path, nil) if err != nil { onResponse(err, fileIndex, filename, nil) return } conn, err := net.Dial("tcp", endpoint) if err != nil { onResponse(err, fileIndex, filename, nil) return } err = req.Write(conn) if err != nil { onResponse(err, fileIndex, filename, nil) return } connReader := bufio.NewReader(conn) res, err := http.ReadResponse(connReader, req) if err != nil { onResponse(err, fileIndex, filename, nil) return } onResponse(nil, fileIndex, filename, res) }
// handleConnection is spawned once per connection from a client, and exits when the client is // done sending requests. func handleConnection(conn net.Conn) { defer conn.Close() reader := bufio.NewReader(conn) for { req, err := http.ReadRequest(reader) if err != nil { if err != io.EOF { log.Printf("Failed to read request: %s", err) } return } // Connect to a backend and send the request along. if be, err := net.Dial("tcp", "127.0.0.1:8081"); err == nil { be_reader := bufio.NewReader(be) if err := req.Write(be); err == nil { if resp, err := http.ReadResponse(be_reader, req); err == nil { FixHttp10Response(resp, req) if err := resp.Write(conn); err == nil { log.Printf("proxied %s: got %d", req.URL.Path, resp.StatusCode) } if resp.Close { return } } } } } }
// issue #177 func (s *S) TestRequestURIEscaping(c *C) { l := s.newHTTPListener(c) defer l.Close() var prefix string uri := "/O08YqxVCf6KRJM6I8p594tzJizQ=/200x300/filters:no_upscale()/http://i.imgur.com/Wru0cNM.jpg?foo=bar" srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { c.Assert(req.RequestURI, Equals, prefix+uri) })) defer srv.Close() addHTTPRoute(c, l) discoverdRegisterHTTP(c, l, srv.Listener.Addr().String()) for _, prefix = range []string{"", "http://example.com"} { conn, err := net.Dial("tcp", l.Addr) c.Assert(err, IsNil) defer conn.Close() fmt.Fprintf(conn, "GET %s HTTP/1.1\r\nHost: example.com\r\n\r\n", prefix+uri) res, err := http.ReadResponse(bufio.NewReader(conn), nil) c.Assert(err, IsNil) c.Assert(res.StatusCode, Equals, 200) } }
func (p *Proxy) connect(req *http.Request) (*http.Response, net.Conn, error) { if p.proxyURL != nil { log.Debugf("martian: CONNECT with downstream proxy: %s", p.proxyURL.Host) conn, err := net.Dial("tcp", p.proxyURL.Host) if err != nil { return nil, nil, err } pbw := bufio.NewWriter(conn) pbr := bufio.NewReader(conn) req.Write(pbw) pbw.Flush() res, err := http.ReadResponse(pbr, req) if err != nil { return nil, nil, err } return res, conn, nil } log.Debugf("martian: CONNECT to host directly: %s", req.URL.Host) conn, err := net.Dial("tcp", req.URL.Host) if err != nil { return nil, nil, err } return proxyutil.NewResponse(200, nil, req), conn, nil }
func (f *FetchServer) decodeResponse(resp *http.Response) (resp1 *http.Response, err error) { if resp.StatusCode != 200 { return resp, nil } var hdrLen uint16 if err = binary.Read(resp.Body, binary.BigEndian, &hdrLen); err != nil { return } hdrBuf := make([]byte, hdrLen) if _, err = io.ReadFull(resp.Body, hdrBuf); err != nil { return } resp1, err = http.ReadResponse(bufio.NewReader(flate.NewReader(bytes.NewReader(hdrBuf))), resp.Request) if err != nil { return } data, _ := ioutil.ReadAll(resp.Body) resp1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(data), resp.Body) return }
func dialHTTP(network, address, codecName string, cFactory ClientCodecFactory, auth bool, connectTimeout time.Duration, config *tls.Config) (*rpc.Client, error) { var err error var conn net.Conn if connectTimeout != 0 { conn, err = net.DialTimeout(network, address, connectTimeout) } else { conn, err = net.Dial(network, address) } if err != nil { return nil, err } if config != nil { conn = tls.Client(conn, config) } _, err = io.WriteString(conn, "CONNECT "+GetRpcPath(codecName, auth)+" HTTP/1.0\n\n") if err != nil { return nil, err } // Require successful HTTP response // before switching to RPC protocol. buffered := NewBufferedConnection(conn) resp, err := http.ReadResponse(buffered.Reader, &http.Request{Method: "CONNECT"}) if err == nil && resp.Status == connected { return rpc.NewClientWithCodec(cFactory(buffered)), nil } if err == nil { err = errors.New("unexpected HTTP response: " + resp.Status) } conn.Close() return nil, &net.OpError{Op: "dial-http", Net: network + " " + address, Addr: nil, Err: err} }
func (t *transport) UpgradeHTTP(req *http.Request, l log15.Logger) (*http.Response, net.Conn, error) { stickyBackend := t.getStickyBackend(req) backends := t.getOrderedBackends(stickyBackend, req) upconn, addr, err := dialTCP(context.Background(), l, backends) if err != nil { status := http.StatusServiceUnavailable if err == errTimeout { status = http.StatusGatewayTimeout } l.Error("dial failed", "status", status, "num_backends", len(backends)) return nil, nil, err } conn := &streamConn{bufio.NewReader(upconn), upconn} req.URL.Host = addr if err := req.Write(conn); err != nil { conn.Close() l.Error("error writing request", "err", err, "backend", addr) return nil, nil, err } res, err := http.ReadResponse(conn.Reader, req) if err != nil { conn.Close() l.Error("error reading response", "err", err, "backend", addr) return nil, nil, err } t.setStickyBackend(res, stickyBackend) return res, conn, nil }
// DialHTTPPath connects to an HTTP RPC server // at the specified network address and path. func DialHTTPPath(network, address, path string) (*Client, error) { var err error conn, err := net.Dial(network, address) if err != nil { return nil, err } io.WriteString(conn, "CONNECT "+path+" HTTP/1.0\n\n") // Require successful HTTP response // before switching to RPC protocol. resp, err := http.ReadResponse(bufio.NewReader(conn), &http.Request{Method: "CONNECT"}) if err == nil && resp.Status == connected { return NewClient(conn), nil } if err == nil { err = errors.New("unexpected HTTP response: " + resp.Status) } conn.Close() return nil, &net.OpError{ Op: "dial-http", Net: network + " " + address, Addr: nil, Err: err, } }
func (f *FetchServer) decodeResponse(resp *http.Response) (resp1 *http.Response, err error) { if resp.StatusCode != 200 { return resp, nil } var hdrLen uint16 if err = binary.Read(resp.Body, binary.BigEndian, &hdrLen); err != nil { return } hdrBuf := make([]byte, hdrLen) if _, err = io.ReadFull(resp.Body, hdrBuf); err != nil { return } resp1, err = http.ReadResponse(bufio.NewReader(flate.NewReader(bytes.NewReader(hdrBuf))), resp.Request) if err != nil { return } const cookieKey string = "Set-Cookie" if cookie := resp1.Header.Get(cookieKey); cookie != "" { parts := strings.Split(cookie, ", ") parts1 := make([]string, 0) for i := 0; i < len(parts); i++ { c := parts[i] if i == 0 || strings.Contains(strings.Split(c, ";")[0], "=") { parts1 = append(parts1, c) } else { parts1[len(parts1)-1] = parts1[len(parts1)-1] + ", " + c } } resp1.Header.Del(cookieKey) for i := 0; i < len(parts1); i++ { resp1.Header.Add(cookieKey, parts1[i]) } } if resp1.StatusCode >= 400 { switch { case resp.Body == nil: break case resp1.Body == nil: resp1.Body = resp.Body default: b, _ := ioutil.ReadAll(resp1.Body) if b != nil && len(b) > 0 { resp1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(b), resp.Body) } else { resp1.Body = resp.Body } } } else { resp1.Body = resp.Body } return }
func doHTTP(s *shim, conf *tls.Config) error { // TODO: support http proxies c := tls.Client(s, conf) s.Start() err := c.Handshake() s.Stop() if err != nil { return fmt.Errorf("http handshake failed: %s", err) } req, _ := http.NewRequest("GET", "/", nil) req.Host = conf.ServerName req.Header = httpHeaders if err := req.Write(c); err != nil { return fmt.Errorf("http request write failed: %s", err) } b := bufio.NewReader(c) resp, err := http.ReadResponse(b, req) if err != nil { return fmt.Errorf("http response read failed: %s", err) } resp.Body.Close() if err := c.Close(); err != nil { return fmt.Errorf("http close failed: %s", err) } return nil }
// fetch html from a WARC file // returns: html, url, err func fromWARC(filename string) ([]byte, string, error) { in, err := os.Open(filename) if err != nil { return nil, "", err } defer in.Close() warcReader := warc.NewReader(in) for { // fmt.Printf("WARC\n") rec, err := warcReader.ReadRecord() if err != nil { return nil, "", fmt.Errorf("Error reading %s: %s", filename, err) } if rec.Header.Get("Warc-Type") != "response" { continue } reqURL := rec.Header.Get("Warc-Target-Uri") // parse response, grab raw html rdr := bufio.NewReader(bytes.NewReader(rec.Block)) response, err := http.ReadResponse(rdr, nil) if err != nil { return nil, "", fmt.Errorf("Error parsing response: %s", err) } defer response.Body.Close() if response.StatusCode != 200 { return nil, "", fmt.Errorf("HTTP error: %d", response.StatusCode) } rawHTML, err := ioutil.ReadAll(response.Body) if err != nil { return nil, "", err } return rawHTML, reqURL, err } }
func TestResponseError(t *testing.T) { message := "Something went seriously wrong." raw := "HTTP/1.1 500 Internal Server Error\r\n" + "\r\n" + `{"status":500,"error":"` + message + `"}` + "\r\n" r := bufio.NewReader(strings.NewReader(raw)) resp, err := http.ReadResponse(r, nil) if err != nil { t.Fatal(err) } err = checkResponse(resp) if err == nil { t.Fatalf("expected error; got: %v", err) } // Check for correct error message expected := fmt.Sprintf("elastic: Error %d (%s): %s", resp.StatusCode, http.StatusText(resp.StatusCode), message) got := err.Error() if got != expected { t.Fatalf("expected %q; got: %q", expected, got) } // Check that error is of type *elastic.Error, which contains additional information e, ok := err.(*Error) if !ok { t.Fatal("expected error to be of type *elastic.Error") } if e.Status != resp.StatusCode { t.Fatalf("expected status code %d; got: %d", resp.StatusCode, e.Status) } if e.Message != message { t.Fatalf("expected error message %q; got: %q", message, e.Message) } }
func (t testTransport) RoundTrip(req *http.Request) (*http.Response, error) { var raw string switch req.URL.Path { case "/ok": raw = "HTTP/1.1 200 OK\n\n" case "/error": return nil, errors.New("http protocol error") case "/nocontent": raw = "HTTP/1.1 204 No Content\n\n" case "/etag": raw = "HTTP/1.1 200 OK\nEtag: \"tag\"\n\n" case "/png": m := image.NewNRGBA(image.Rect(0, 0, 1, 1)) img := new(bytes.Buffer) png.Encode(img, m) raw = fmt.Sprintf("HTTP/1.1 200 OK\nContent-Length: %d\n\n%s", len(img.Bytes()), img.Bytes()) default: raw = "HTTP/1.1 404 Not Found\n\n" } buf := bufio.NewReader(bytes.NewBufferString(raw)) return http.ReadResponse(buf, req) }
// RoundTrip executes the Request and upgrades it. After a successful upgrade, // clients may call SpdyRoundTripper.Connection() to retrieve the upgraded // connection. func (s *SpdyRoundTripper) RoundTrip(req *http.Request) (*http.Response, error) { // TODO what's the best way to clone the request? r := *req req = &r req.Header.Add(httpstream.HeaderConnection, httpstream.HeaderUpgrade) req.Header.Add(httpstream.HeaderUpgrade, HeaderSpdy31) conn, err := s.dial(req) if err != nil { return nil, err } err = req.Write(conn) if err != nil { return nil, err } resp, err := http.ReadResponse(bufio.NewReader(conn), req) if err != nil { return nil, err } s.conn = conn return resp, nil }
// handleConnection is spawned once per connection from a client, // and exits when the client is done sending requests func handleConnection(conn net.Conn) { // always close the conn no matter how this function exits: defer conn.Close() reader := bufio.NewReader(conn) // loop to handle multiple requests from user conn, // since we are now running concurrently: for { req, err := http.ReadRequest(reader) if err != nil { if err != io.EOF { log.Printf("Failed to read request: %s", err) } return } // connect to a backend and send the request along if be, err := net.Dial("tcp", "127.0.0.1:8081"); err == nil { be_reader := bufio.NewReader(be) if err := req.Write(be); err == nil { if resp, err := http.ReadResponse(be_reader, req); err == nil { FixHttp10Response(resp, req) if err := resp.Write(conn); err == nil { log.Printf("proxied %s: got %d", req.URL.Path, resp.StatusCode) } if resp.Close { return } } } } } }