How to use readResponse method of conn Package

Best Gauge code snippet using conn.readResponse

proxy_test.go

Source:proxy_test.go Github

copy

Full Screen

1// Copyright 2015 Google Inc. All rights reserved.2//3// Licensed under the Apache License, Version 2.0 (the "License");4// you may not use this file except in compliance with the License.5// You may obtain a copy of the License at6//7// http://www.apache.org/licenses/LICENSE-2.08//9// Unless required by applicable law or agreed to in writing, software10// distributed under the License is distributed on an "AS IS" BASIS,11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12// See the License for the specific language governing permissions and13// limitations under the License.14package martian15import (16 "bufio"17 "bytes"18 "crypto/tls"19 "crypto/x509"20 "errors"21 "fmt"22 "io"23 "io/ioutil"24 "net"25 "net/http"26 "net/url"27 "os"28 "strings"29 "testing"30 "time"31 "github.com/google/martian/log"32 "github.com/google/martian/martiantest"33 "github.com/google/martian/mitm"34 "github.com/google/martian/proxyutil"35)36type tempError struct{}37func (e *tempError) Error() string { return "temporary" }38func (e *tempError) Timeout() bool { return true }39func (e *tempError) Temporary() bool { return true }40type timeoutListener struct {41 net.Listener42 errCount int43 err error44}45func newTimeoutListener(l net.Listener, errCount int) net.Listener {46 return &timeoutListener{47 Listener: l,48 errCount: errCount,49 err: &tempError{},50 }51}52func (l *timeoutListener) Accept() (net.Conn, error) {53 if l.errCount > 0 {54 l.errCount--55 return nil, l.err56 }57 return l.Listener.Accept()58}59func TestIntegrationTemporaryTimeout(t *testing.T) {60 t.Parallel()61 l, err := net.Listen("tcp", "[::]:0")62 if err != nil {63 t.Fatalf("net.Listen(): got %v, want no error", err)64 }65 p := NewProxy()66 defer p.Close()67 tr := martiantest.NewTransport()68 p.SetRoundTripper(tr)69 p.SetTimeout(200 * time.Millisecond)70 // Start the proxy with a listener that will return a temporary error on71 // Accept() three times.72 go p.Serve(newTimeoutListener(l, 3))73 conn, err := net.Dial("tcp", l.Addr().String())74 if err != nil {75 t.Fatalf("net.Dial(): got %v, want no error", err)76 }77 defer conn.Close()78 req, err := http.NewRequest("GET", "http://example.com", nil)79 if err != nil {80 t.Fatalf("http.NewRequest(): got %v, want no error", err)81 }82 req.Header.Set("Connection", "close")83 // GET http://example.com/ HTTP/1.184 // Host: example.com85 if err := req.WriteProxy(conn); err != nil {86 t.Fatalf("req.WriteProxy(): got %v, want no error", err)87 }88 res, err := http.ReadResponse(bufio.NewReader(conn), req)89 if err != nil {90 t.Fatalf("http.ReadResponse(): got %v, want no error", err)91 }92 defer res.Body.Close()93 if got, want := res.StatusCode, 200; got != want {94 t.Errorf("res.StatusCode: got %d, want %d", got, want)95 }96}97func TestIntegrationHTTP(t *testing.T) {98 t.Parallel()99 l, err := net.Listen("tcp", "[::]:0")100 if err != nil {101 t.Fatalf("net.Listen(): got %v, want no error", err)102 }103 p := NewProxy()104 defer p.Close()105 p.SetRequestModifier(nil)106 p.SetResponseModifier(nil)107 tr := martiantest.NewTransport()108 p.SetRoundTripper(tr)109 p.SetTimeout(200 * time.Millisecond)110 tm := martiantest.NewModifier()111 tm.RequestFunc(func(req *http.Request) {112 ctx := NewContext(req)113 ctx.Set("martian.test", "true")114 })115 tm.ResponseFunc(func(res *http.Response) {116 ctx := NewContext(res.Request)117 v, _ := ctx.Get("martian.test")118 res.Header.Set("Martian-Test", v.(string))119 })120 p.SetRequestModifier(tm)121 p.SetResponseModifier(tm)122 go p.Serve(l)123 conn, err := net.Dial("tcp", l.Addr().String())124 if err != nil {125 t.Fatalf("net.Dial(): got %v, want no error", err)126 }127 defer conn.Close()128 req, err := http.NewRequest("GET", "http://example.com", nil)129 if err != nil {130 t.Fatalf("http.NewRequest(): got %v, want no error", err)131 }132 // GET http://example.com/ HTTP/1.1133 // Host: example.com134 if err := req.WriteProxy(conn); err != nil {135 t.Fatalf("req.WriteProxy(): got %v, want no error", err)136 }137 res, err := http.ReadResponse(bufio.NewReader(conn), req)138 if err != nil {139 t.Fatalf("http.ReadResponse(): got %v, want no error", err)140 }141 if got, want := res.StatusCode, 200; got != want {142 t.Fatalf("res.StatusCode: got %d, want %d", got, want)143 }144 if got, want := res.Header.Get("Martian-Test"), "true"; got != want {145 t.Errorf("res.Header.Get(%q): got %q, want %q", "Martian-Test", got, want)146 }147}148func TestIntegrationHTTP100Continue(t *testing.T) {149 t.Parallel()150 l, err := net.Listen("tcp", "[::]:0")151 if err != nil {152 t.Fatalf("net.Listen(): got %v, want no error", err)153 }154 p := NewProxy()155 defer p.Close()156 p.SetTimeout(2 * time.Second)157 sl, err := net.Listen("tcp", "[::]:0")158 if err != nil {159 t.Fatalf("net.Listen(): got %v, want no error", err)160 }161 go func() {162 conn, err := sl.Accept()163 if err != nil {164 log.Errorf("proxy_test: failed to accept connection: %v", err)165 return166 }167 defer conn.Close()168 log.Infof("proxy_test: accepted connection: %s", conn.RemoteAddr())169 req, err := http.ReadRequest(bufio.NewReader(conn))170 if err != nil {171 log.Errorf("proxy_test: failed to read request: %v", err)172 return173 }174 if req.Header.Get("Expect") == "100-continue" {175 log.Infof("proxy_test: received 100-continue request")176 conn.Write([]byte("HTTP/1.1 100 Continue\r\n\r\n"))177 log.Infof("proxy_test: sent 100-continue response")178 } else {179 log.Infof("proxy_test: received non 100-continue request")180 res := proxyutil.NewResponse(417, nil, req)181 res.Header.Set("Connection", "close")182 res.Write(conn)183 return184 }185 res := proxyutil.NewResponse(200, req.Body, req)186 res.Header.Set("Connection", "close")187 res.Write(conn)188 log.Infof("proxy_test: sent 200 response")189 }()190 tm := martiantest.NewModifier()191 p.SetRequestModifier(tm)192 p.SetResponseModifier(tm)193 go p.Serve(l)194 conn, err := net.Dial("tcp", l.Addr().String())195 if err != nil {196 t.Fatalf("net.Dial(): got %v, want no error", err)197 }198 defer conn.Close()199 host := sl.Addr().String()200 raw := fmt.Sprintf("POST http://%s/ HTTP/1.1\r\n"+201 "Host: %s\r\n"+202 "Content-Length: 12\r\n"+203 "Expect: 100-continue\r\n\r\n", host, host)204 if _, err := conn.Write([]byte(raw)); err != nil {205 t.Fatalf("conn.Write(headers): got %v, want no error", err)206 }207 go func() {208 select {209 case <-time.After(time.Second):210 conn.Write([]byte("body content"))211 }212 }()213 res, err := http.ReadResponse(bufio.NewReader(conn), nil)214 if err != nil {215 t.Fatalf("http.ReadResponse(): got %v, want no error", err)216 }217 defer res.Body.Close()218 if got, want := res.StatusCode, 200; got != want {219 t.Fatalf("res.StatusCode: got %d, want %d", got, want)220 }221 got, err := ioutil.ReadAll(res.Body)222 if err != nil {223 t.Fatalf("ioutil.ReadAll(): got %v, want no error", err)224 }225 if want := []byte("body content"); !bytes.Equal(got, want) {226 t.Errorf("res.Body: got %q, want %q", got, want)227 }228 if !tm.RequestModified() {229 t.Error("tm.RequestModified(): got false, want true")230 }231 if !tm.ResponseModified() {232 t.Error("tm.ResponseModified(): got false, want true")233 }234}235func TestIntegrationHTTPDownstreamProxy(t *testing.T) {236 t.Parallel()237 // Start first proxy to use as downstream.238 dl, err := net.Listen("tcp", "[::]:0")239 if err != nil {240 t.Fatalf("net.Listen(): got %v, want no error", err)241 }242 downstream := NewProxy()243 defer downstream.Close()244 dtr := martiantest.NewTransport()245 dtr.Respond(299)246 downstream.SetRoundTripper(dtr)247 downstream.SetTimeout(600 * time.Millisecond)248 go downstream.Serve(dl)249 // Start second proxy as upstream proxy, will write to downstream proxy.250 ul, err := net.Listen("tcp", "[::]:0")251 if err != nil {252 t.Fatalf("net.Listen(): got %v, want no error", err)253 }254 upstream := NewProxy()255 defer upstream.Close()256 // Set upstream proxy's downstream proxy to the host:port of the first proxy.257 upstream.SetDownstreamProxy(&url.URL{258 Host: dl.Addr().String(),259 })260 upstream.SetTimeout(600 * time.Millisecond)261 go upstream.Serve(ul)262 // Open connection to upstream proxy.263 conn, err := net.Dial("tcp", ul.Addr().String())264 if err != nil {265 t.Fatalf("net.Dial(): got %v, want no error", err)266 }267 defer conn.Close()268 req, err := http.NewRequest("GET", "http://example.com", nil)269 if err != nil {270 t.Fatalf("http.NewRequest(): got %v, want no error", err)271 }272 // GET http://example.com/ HTTP/1.1273 // Host: example.com274 if err := req.WriteProxy(conn); err != nil {275 t.Fatalf("req.WriteProxy(): got %v, want no error", err)276 }277 // Response from downstream proxy.278 res, err := http.ReadResponse(bufio.NewReader(conn), req)279 if err != nil {280 t.Fatalf("http.ReadResponse(): got %v, want no error", err)281 }282 if got, want := res.StatusCode, 299; got != want {283 t.Fatalf("res.StatusCode: got %d, want %d", got, want)284 }285}286func TestIntegrationHTTPDownstreamProxyError(t *testing.T) {287 t.Parallel()288 l, err := net.Listen("tcp", "[::]:0")289 if err != nil {290 t.Fatalf("net.Listen(): got %v, want no error", err)291 }292 p := NewProxy()293 defer p.Close()294 // Set proxy's downstream proxy to invalid host:port to force failure.295 p.SetDownstreamProxy(&url.URL{296 Host: "[::]:0",297 })298 p.SetTimeout(600 * time.Millisecond)299 tm := martiantest.NewModifier()300 reserr := errors.New("response error")301 tm.ResponseError(reserr)302 p.SetResponseModifier(tm)303 go p.Serve(l)304 // Open connection to upstream proxy.305 conn, err := net.Dial("tcp", l.Addr().String())306 if err != nil {307 t.Fatalf("net.Dial(): got %v, want no error", err)308 }309 defer conn.Close()310 req, err := http.NewRequest("CONNECT", "//example.com:443", nil)311 if err != nil {312 t.Fatalf("http.NewRequest(): got %v, want no error", err)313 }314 // CONNECT example.com:443 HTTP/1.1315 // Host: example.com316 if err := req.Write(conn); err != nil {317 t.Fatalf("req.Write(): got %v, want no error", err)318 }319 // Response from upstream proxy, assuming downstream proxy failed to CONNECT.320 res, err := http.ReadResponse(bufio.NewReader(conn), req)321 if err != nil {322 t.Fatalf("http.ReadResponse(): got %v, want no error", err)323 }324 if got, want := res.StatusCode, 502; got != want {325 t.Fatalf("res.StatusCode: got %d, want %d", got, want)326 }327 if got, want := res.Header["Warning"][1], reserr.Error(); !strings.Contains(got, want) {328 t.Errorf("res.Header.get(%q): got %q, want to contain %q", "Warning", got, want)329 }330}331func TestIntegrationTLSHandshakeErrorCallback(t *testing.T) {332 t.Parallel()333 l, err := net.Listen("tcp", "[::]:0")334 if err != nil {335 t.Fatalf("net.Listen(): got %v, want no error", err)336 }337 p := NewProxy()338 defer p.Close()339 // Test TLS server.340 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", time.Hour)341 if err != nil {342 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)343 }344 mc, err := mitm.NewConfig(ca, priv)345 if err != nil {346 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)347 }348 var herr error349 mc.SetHandshakeErrorCallback(func(_ *http.Request, err error) { herr = fmt.Errorf("handshake error") })350 p.SetMITM(mc)351 tl, err := net.Listen("tcp", "[::]:0")352 if err != nil {353 t.Fatalf("tls.Listen(): got %v, want no error", err)354 }355 tl = tls.NewListener(tl, mc.TLS())356 go http.Serve(tl, http.HandlerFunc(357 func(rw http.ResponseWriter, req *http.Request) {358 rw.WriteHeader(200)359 }))360 tm := martiantest.NewModifier()361 // Force the CONNECT request to dial the local TLS server.362 tm.RequestFunc(func(req *http.Request) {363 req.URL.Host = tl.Addr().String()364 })365 go p.Serve(l)366 conn, err := net.Dial("tcp", l.Addr().String())367 if err != nil {368 t.Fatalf("net.Dial(): got %v, want no error", err)369 }370 defer conn.Close()371 req, err := http.NewRequest("CONNECT", "//example.com:443", nil)372 if err != nil {373 t.Fatalf("http.NewRequest(): got %v, want no error", err)374 }375 // CONNECT example.com:443 HTTP/1.1376 // Host: example.com377 //378 // Rewritten to CONNECT to host:port in CONNECT request modifier.379 if err := req.Write(conn); err != nil {380 t.Fatalf("req.Write(): got %v, want no error", err)381 }382 // CONNECT response after establishing tunnel.383 if _, err := http.ReadResponse(bufio.NewReader(conn), req); err != nil {384 t.Fatalf("http.ReadResponse(): got %v, want no error", err)385 }386 tlsconn := tls.Client(conn, &tls.Config{387 ServerName: "example.com",388 // Client has no cert so it will get "x509: certificate signed by unknown authority" from the389 // handshake and send "remote error: bad certificate" to the server.390 RootCAs: x509.NewCertPool(),391 })392 defer tlsconn.Close()393 req, err = http.NewRequest("GET", "https://example.com", nil)394 if err != nil {395 t.Fatalf("http.NewRequest(): got %v, want no error", err)396 }397 req.Header.Set("Connection", "close")398 if got, want := req.Write(tlsconn), "x509: certificate signed by unknown authority"; !strings.Contains(got.Error(), want) {399 t.Fatalf("Got incorrect error from Client Handshake(), got: %v, want: %v", got, want)400 }401 // TODO: herr is not being asserted against. It should be pushed on to a channel402 // of err, and the assertion should pull off of it and assert. That design resulted in the test403 // hanging for unknown reasons.404 t.Skip("skipping assertion of handshake error callback error due to mysterious deadlock")405 if got, want := herr, "remote error: bad certificate"; !strings.Contains(got.Error(), want) {406 t.Fatalf("Got incorrect error from Server Handshake(), got: %v, want: %v", got, want)407 }408}409func TestIntegrationConnect(t *testing.T) {410 t.Parallel()411 l, err := net.Listen("tcp", "[::]:0")412 if err != nil {413 t.Fatalf("net.Listen(): got %v, want no error", err)414 }415 p := NewProxy()416 defer p.Close()417 // Test TLS server.418 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", time.Hour)419 if err != nil {420 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)421 }422 mc, err := mitm.NewConfig(ca, priv)423 if err != nil {424 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)425 }426 tl, err := net.Listen("tcp", "[::]:0")427 if err != nil {428 t.Fatalf("tls.Listen(): got %v, want no error", err)429 }430 tl = tls.NewListener(tl, mc.TLS())431 go http.Serve(tl, http.HandlerFunc(432 func(rw http.ResponseWriter, req *http.Request) {433 rw.WriteHeader(299)434 }))435 tm := martiantest.NewModifier()436 reqerr := errors.New("request error")437 reserr := errors.New("response error")438 // Force the CONNECT request to dial the local TLS server.439 tm.RequestFunc(func(req *http.Request) {440 req.URL.Host = tl.Addr().String()441 })442 tm.RequestError(reqerr)443 tm.ResponseError(reserr)444 p.SetRequestModifier(tm)445 p.SetResponseModifier(tm)446 go p.Serve(l)447 conn, err := net.Dial("tcp", l.Addr().String())448 if err != nil {449 t.Fatalf("net.Dial(): got %v, want no error", err)450 }451 defer conn.Close()452 req, err := http.NewRequest("CONNECT", "//example.com:443", nil)453 if err != nil {454 t.Fatalf("http.NewRequest(): got %v, want no error", err)455 }456 // CONNECT example.com:443 HTTP/1.1457 // Host: example.com458 //459 // Rewritten to CONNECT to host:port in CONNECT request modifier.460 if err := req.Write(conn); err != nil {461 t.Fatalf("req.Write(): got %v, want no error", err)462 }463 // CONNECT response after establishing tunnel.464 res, err := http.ReadResponse(bufio.NewReader(conn), req)465 if err != nil {466 t.Fatalf("http.ReadResponse(): got %v, want no error", err)467 }468 if got, want := res.StatusCode, 200; got != want {469 t.Fatalf("res.StatusCode: got %d, want %d", got, want)470 }471 if !tm.RequestModified() {472 t.Error("tm.RequestModified(): got false, want true")473 }474 if !tm.ResponseModified() {475 t.Error("tm.ResponseModified(): got false, want true")476 }477 if got, want := res.Header.Get("Warning"), reserr.Error(); !strings.Contains(got, want) {478 t.Errorf("res.Header.Get(%q): got %q, want to contain %q", "Warning", got, want)479 }480 roots := x509.NewCertPool()481 roots.AddCert(ca)482 tlsconn := tls.Client(conn, &tls.Config{483 ServerName: "example.com",484 RootCAs: roots,485 })486 defer tlsconn.Close()487 req, err = http.NewRequest("GET", "https://example.com", nil)488 if err != nil {489 t.Fatalf("http.NewRequest(): got %v, want no error", err)490 }491 req.Header.Set("Connection", "close")492 // GET / HTTP/1.1493 // Host: example.com494 // Connection: close495 if err := req.Write(tlsconn); err != nil {496 t.Fatalf("req.Write(): got %v, want no error", err)497 }498 res, err = http.ReadResponse(bufio.NewReader(tlsconn), req)499 if err != nil {500 t.Fatalf("http.ReadResponse(): got %v, want no error", err)501 }502 defer res.Body.Close()503 if got, want := res.StatusCode, 299; got != want {504 t.Fatalf("res.StatusCode: got %d, want %d", got, want)505 }506 if got, want := res.Header.Get("Warning"), reserr.Error(); strings.Contains(got, want) {507 t.Errorf("res.Header.Get(%q): got %s, want to not contain %s", "Warning", got, want)508 }509}510func TestIntegrationConnectDownstreamProxy(t *testing.T) {511 t.Parallel()512 // Start first proxy to use as downstream.513 dl, err := net.Listen("tcp", "[::]:0")514 if err != nil {515 t.Fatalf("net.Listen(): got %v, want no error", err)516 }517 downstream := NewProxy()518 defer downstream.Close()519 dtr := martiantest.NewTransport()520 dtr.Respond(299)521 downstream.SetRoundTripper(dtr)522 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", 2*time.Hour)523 if err != nil {524 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)525 }526 mc, err := mitm.NewConfig(ca, priv)527 if err != nil {528 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)529 }530 downstream.SetMITM(mc)531 go downstream.Serve(dl)532 // Start second proxy as upstream proxy, will CONNECT to downstream proxy.533 ul, err := net.Listen("tcp", "[::]:0")534 if err != nil {535 t.Fatalf("net.Listen(): got %v, want no error", err)536 }537 upstream := NewProxy()538 defer upstream.Close()539 // Set upstream proxy's downstream proxy to the host:port of the first proxy.540 upstream.SetDownstreamProxy(&url.URL{541 Host: dl.Addr().String(),542 })543 go upstream.Serve(ul)544 // Open connection to upstream proxy.545 conn, err := net.Dial("tcp", ul.Addr().String())546 if err != nil {547 t.Fatalf("net.Dial(): got %v, want no error", err)548 }549 defer conn.Close()550 req, err := http.NewRequest("CONNECT", "//example.com:443", nil)551 if err != nil {552 t.Fatalf("http.NewRequest(): got %v, want no error", err)553 }554 // CONNECT example.com:443 HTTP/1.1555 // Host: example.com556 if err := req.Write(conn); err != nil {557 t.Fatalf("req.Write(): got %v, want no error", err)558 }559 // Response from downstream proxy starting MITM.560 res, err := http.ReadResponse(bufio.NewReader(conn), req)561 if err != nil {562 t.Fatalf("http.ReadResponse(): got %v, want no error", err)563 }564 if got, want := res.StatusCode, 200; got != want {565 t.Fatalf("res.StatusCode: got %d, want %d", got, want)566 }567 roots := x509.NewCertPool()568 roots.AddCert(ca)569 tlsconn := tls.Client(conn, &tls.Config{570 // Validate the hostname.571 ServerName: "example.com",572 // The certificate will have been MITM'd, verify using the MITM CA573 // certificate.574 RootCAs: roots,575 })576 defer tlsconn.Close()577 req, err = http.NewRequest("GET", "https://example.com", nil)578 if err != nil {579 t.Fatalf("http.NewRequest(): got %v, want no error", err)580 }581 // GET / HTTP/1.1582 // Host: example.com583 if err := req.Write(tlsconn); err != nil {584 t.Fatalf("req.Write(): got %v, want no error", err)585 }586 // Response from MITM in downstream proxy.587 res, err = http.ReadResponse(bufio.NewReader(tlsconn), req)588 if err != nil {589 t.Fatalf("http.ReadResponse(): got %v, want no error", err)590 }591 defer res.Body.Close()592 if got, want := res.StatusCode, 299; got != want {593 t.Fatalf("res.StatusCode: got %d, want %d", got, want)594 }595}596func TestIntegrationMITM(t *testing.T) {597 t.Parallel()598 l, err := net.Listen("tcp", "[::]:0")599 if err != nil {600 t.Fatalf("net.Listen(): got %v, want no error", err)601 }602 p := NewProxy()603 defer p.Close()604 tr := martiantest.NewTransport()605 tr.Func(func(req *http.Request) (*http.Response, error) {606 res := proxyutil.NewResponse(200, nil, req)607 res.Header.Set("Request-Scheme", req.URL.Scheme)608 return res, nil609 })610 p.SetRoundTripper(tr)611 p.SetTimeout(600 * time.Millisecond)612 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", 2*time.Hour)613 if err != nil {614 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)615 }616 mc, err := mitm.NewConfig(ca, priv)617 if err != nil {618 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)619 }620 p.SetMITM(mc)621 tm := martiantest.NewModifier()622 reqerr := errors.New("request error")623 reserr := errors.New("response error")624 tm.RequestError(reqerr)625 tm.ResponseError(reserr)626 p.SetRequestModifier(tm)627 p.SetResponseModifier(tm)628 go p.Serve(l)629 conn, err := net.Dial("tcp", l.Addr().String())630 if err != nil {631 t.Fatalf("net.Dial(): got %v, want no error", err)632 }633 defer conn.Close()634 req, err := http.NewRequest("CONNECT", "//example.com:443", nil)635 if err != nil {636 t.Fatalf("http.NewRequest(): got %v, want no error", err)637 }638 // CONNECT example.com:443 HTTP/1.1639 // Host: example.com640 if err := req.Write(conn); err != nil {641 t.Fatalf("req.Write(): got %v, want no error", err)642 }643 // Response MITM'd from proxy.644 res, err := http.ReadResponse(bufio.NewReader(conn), req)645 if err != nil {646 t.Fatalf("http.ReadResponse(): got %v, want no error", err)647 }648 if got, want := res.StatusCode, 200; got != want {649 t.Errorf("res.StatusCode: got %d, want %d", got, want)650 }651 if got, want := res.Header.Get("Warning"), reserr.Error(); !strings.Contains(got, want) {652 t.Errorf("res.Header.Get(%q): got %q, want to contain %q", "Warning", got, want)653 }654 roots := x509.NewCertPool()655 roots.AddCert(ca)656 tlsconn := tls.Client(conn, &tls.Config{657 ServerName: "example.com",658 RootCAs: roots,659 })660 defer tlsconn.Close()661 req, err = http.NewRequest("GET", "https://example.com", nil)662 if err != nil {663 t.Fatalf("http.NewRequest(): got %v, want no error", err)664 }665 // GET / HTTP/1.1666 // Host: example.com667 if err := req.Write(tlsconn); err != nil {668 t.Fatalf("req.Write(): got %v, want no error", err)669 }670 // Response from MITM proxy.671 res, err = http.ReadResponse(bufio.NewReader(tlsconn), req)672 if err != nil {673 t.Fatalf("http.ReadResponse(): got %v, want no error", err)674 }675 defer res.Body.Close()676 if got, want := res.StatusCode, 200; got != want {677 t.Errorf("res.StatusCode: got %d, want %d", got, want)678 }679 if got, want := res.Header.Get("Request-Scheme"), "https"; got != want {680 t.Errorf("res.Header.Get(%q): got %q, want %q", "Request-Scheme", got, want)681 }682 if got, want := res.Header.Get("Warning"), reserr.Error(); !strings.Contains(got, want) {683 t.Errorf("res.Header.Get(%q): got %q, want to contain %q", "Warning", got, want)684 }685}686func TestIntegrationTransparentHTTP(t *testing.T) {687 t.Parallel()688 l, err := net.Listen("tcp", "[::]:0")689 if err != nil {690 t.Fatalf("net.Listen(): got %v, want no error", err)691 }692 p := NewProxy()693 defer p.Close()694 tr := martiantest.NewTransport()695 p.SetRoundTripper(tr)696 p.SetTimeout(200 * time.Millisecond)697 tm := martiantest.NewModifier()698 p.SetRequestModifier(tm)699 p.SetResponseModifier(tm)700 go p.Serve(l)701 conn, err := net.Dial("tcp", l.Addr().String())702 if err != nil {703 t.Fatalf("net.Dial(): got %v, want no error", err)704 }705 defer conn.Close()706 req, err := http.NewRequest("GET", "http://example.com", nil)707 if err != nil {708 t.Fatalf("http.NewRequest(): got %v, want no error", err)709 }710 // GET / HTTP/1.1711 // Host: www.example.com712 if err := req.Write(conn); err != nil {713 t.Fatalf("req.Write(): got %v, want no error", err)714 }715 res, err := http.ReadResponse(bufio.NewReader(conn), req)716 if err != nil {717 t.Fatalf("http.ReadResponse(): got %v, want no error", err)718 }719 if got, want := res.StatusCode, 200; got != want {720 t.Fatalf("res.StatusCode: got %d, want %d", got, want)721 }722 if !tm.RequestModified() {723 t.Error("tm.RequestModified(): got false, want true")724 }725 if !tm.ResponseModified() {726 t.Error("tm.ResponseModified(): got false, want true")727 }728}729func TestIntegrationTransparentMITM(t *testing.T) {730 t.Parallel()731 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", 2*time.Hour)732 if err != nil {733 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)734 }735 mc, err := mitm.NewConfig(ca, priv)736 if err != nil {737 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)738 }739 // Start TLS listener with config that will generate certificates based on740 // SNI from connection.741 //742 // BUG: tls.Listen will not accept a tls.Config where Certificates is empty,743 // even though it is supported by tls.Server when GetCertificate is not nil.744 l, err := net.Listen("tcp", "[::]:0")745 if err != nil {746 t.Fatalf("net.Listen(): got %v, want no error", err)747 }748 l = tls.NewListener(l, mc.TLS())749 p := NewProxy()750 defer p.Close()751 tr := martiantest.NewTransport()752 tr.Func(func(req *http.Request) (*http.Response, error) {753 res := proxyutil.NewResponse(200, nil, req)754 res.Header.Set("Request-Scheme", req.URL.Scheme)755 return res, nil756 })757 p.SetRoundTripper(tr)758 tm := martiantest.NewModifier()759 p.SetRequestModifier(tm)760 p.SetResponseModifier(tm)761 go p.Serve(l)762 roots := x509.NewCertPool()763 roots.AddCert(ca)764 tlsconn, err := tls.Dial("tcp", l.Addr().String(), &tls.Config{765 // Verify the hostname is example.com.766 ServerName: "example.com",767 // The certificate will have been generated during MITM, so we need to768 // verify it with the generated CA certificate.769 RootCAs: roots,770 })771 if err != nil {772 t.Fatalf("tls.Dial(): got %v, want no error", err)773 }774 defer tlsconn.Close()775 req, err := http.NewRequest("GET", "https://example.com", nil)776 if err != nil {777 t.Fatalf("http.NewRequest(): got %v, want no error", err)778 }779 // Write Encrypted request directly, no CONNECT.780 // GET / HTTP/1.1781 // Host: example.com782 if err := req.Write(tlsconn); err != nil {783 t.Fatalf("req.Write(): got %v, want no error", err)784 }785 res, err := http.ReadResponse(bufio.NewReader(tlsconn), req)786 if err != nil {787 t.Fatalf("http.ReadResponse(): got %v, want no error", err)788 }789 defer res.Body.Close()790 if got, want := res.StatusCode, 200; got != want {791 t.Fatalf("res.StatusCode: got %d, want %d", got, want)792 }793 if got, want := res.Header.Get("Request-Scheme"), "https"; got != want {794 t.Errorf("res.Header.Get(%q): got %q, want %q", "Request-Scheme", got, want)795 }796 if !tm.RequestModified() {797 t.Errorf("tm.RequestModified(): got false, want true")798 }799 if !tm.ResponseModified() {800 t.Errorf("tm.ResponseModified(): got false, want true")801 }802}803func TestIntegrationFailedRoundTrip(t *testing.T) {804 t.Parallel()805 l, err := net.Listen("tcp", "[::]:0")806 if err != nil {807 t.Fatalf("net.Listen(): got %v, want no error", err)808 }809 p := NewProxy()810 defer p.Close()811 tr := martiantest.NewTransport()812 trerr := errors.New("round trip error")813 tr.RespondError(trerr)814 p.SetRoundTripper(tr)815 p.SetTimeout(200 * time.Millisecond)816 go p.Serve(l)817 conn, err := net.Dial("tcp", l.Addr().String())818 if err != nil {819 t.Fatalf("net.Dial(): got %v, want no error", err)820 }821 defer conn.Close()822 req, err := http.NewRequest("GET", "http://example.com", nil)823 if err != nil {824 t.Fatalf("http.NewRequest(): got %v, want no error", err)825 }826 // GET http://example.com/ HTTP/1.1827 // Host: example.com828 if err := req.WriteProxy(conn); err != nil {829 t.Fatalf("req.WriteProxy(): got %v, want no error", err)830 }831 // Response from failed round trip.832 res, err := http.ReadResponse(bufio.NewReader(conn), req)833 if err != nil {834 t.Fatalf("http.ReadResponse(): got %v, want no error", err)835 }836 defer res.Body.Close()837 if got, want := res.StatusCode, 502; got != want {838 t.Errorf("res.StatusCode: got %d, want %d", got, want)839 }840 if got, want := res.Header.Get("Warning"), trerr.Error(); !strings.Contains(got, want) {841 t.Errorf("res.Header.Get(%q): got %q, want to contain %q", "Warning", got, want)842 }843}844func TestIntegrationSkipRoundTrip(t *testing.T) {845 t.Parallel()846 l, err := net.Listen("tcp", "[::]:0")847 if err != nil {848 t.Fatalf("net.Listen(): got %v, want no error", err)849 }850 p := NewProxy()851 defer p.Close()852 // Transport will be skipped, no 500.853 tr := martiantest.NewTransport()854 tr.Respond(500)855 p.SetRoundTripper(tr)856 p.SetTimeout(200 * time.Millisecond)857 tm := martiantest.NewModifier()858 tm.RequestFunc(func(req *http.Request) {859 ctx := NewContext(req)860 ctx.SkipRoundTrip()861 })862 p.SetRequestModifier(tm)863 go p.Serve(l)864 conn, err := net.Dial("tcp", l.Addr().String())865 if err != nil {866 t.Fatalf("net.Dial(): got %v, want no error", err)867 }868 defer conn.Close()869 req, err := http.NewRequest("GET", "http://example.com", nil)870 if err != nil {871 t.Fatalf("http.NewRequest(): got %v, want no error", err)872 }873 // GET http://example.com/ HTTP/1.1874 // Host: example.com875 if err := req.WriteProxy(conn); err != nil {876 t.Fatalf("req.WriteProxy(): got %v, want no error", err)877 }878 // Response from skipped round trip.879 res, err := http.ReadResponse(bufio.NewReader(conn), req)880 if err != nil {881 t.Fatalf("http.ReadResponse(): got %v, want no error", err)882 }883 defer res.Body.Close()884 if got, want := res.StatusCode, 200; got != want {885 t.Errorf("res.StatusCode: got %d, want %d", got, want)886 }887}888func TestHTTPThroughConnectWithMITM(t *testing.T) {889 t.Parallel()890 l, err := net.Listen("tcp", "[::]:0")891 if err != nil {892 t.Fatalf("net.Listen(): got %v, want no error", err)893 }894 p := NewProxy()895 defer p.Close()896 tm := martiantest.NewModifier()897 tm.RequestFunc(func(req *http.Request) {898 ctx := NewContext(req)899 ctx.SkipRoundTrip()900 if req.Method != "GET" && req.Method != "CONNECT" {901 t.Errorf("unexpected method on request handler: %v", req.Method)902 }903 })904 p.SetRequestModifier(tm)905 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", 2*time.Hour)906 if err != nil {907 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)908 }909 mc, err := mitm.NewConfig(ca, priv)910 if err != nil {911 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)912 }913 p.SetMITM(mc)914 go p.Serve(l)915 conn, err := net.Dial("tcp", l.Addr().String())916 if err != nil {917 t.Fatalf("net.Dial(): got %v, want no error", err)918 }919 defer conn.Close()920 req, err := http.NewRequest("CONNECT", "//example.com:80", nil)921 if err != nil {922 t.Fatalf("http.NewRequest(): got %v, want no error", err)923 }924 // CONNECT example.com:80 HTTP/1.1925 // Host: example.com926 if err := req.Write(conn); err != nil {927 t.Fatalf("req.Write(): got %v, want no error", err)928 }929 // Response skipped round trip.930 res, err := http.ReadResponse(bufio.NewReader(conn), req)931 if err != nil {932 t.Fatalf("http.ReadResponse(): got %v, want no error", err)933 }934 res.Body.Close()935 if got, want := res.StatusCode, 200; got != want {936 t.Errorf("res.StatusCode: got %d, want %d", got, want)937 }938 req, err = http.NewRequest("GET", "http://example.com", nil)939 if err != nil {940 t.Fatalf("http.NewRequest(): got %v, want no error", err)941 }942 // GET http://example.com/ HTTP/1.1943 // Host: example.com944 if err := req.WriteProxy(conn); err != nil {945 t.Fatalf("req.WriteProxy(): got %v, want no error", err)946 }947 // Response from skipped round trip.948 res, err = http.ReadResponse(bufio.NewReader(conn), req)949 if err != nil {950 t.Fatalf("http.ReadResponse(): got %v, want no error", err)951 }952 res.Body.Close()953 if got, want := res.StatusCode, 200; got != want {954 t.Errorf("res.StatusCode: got %d, want %d", got, want)955 }956 req, err = http.NewRequest("GET", "http://example.com", nil)957 if err != nil {958 t.Fatalf("http.NewRequest(): got %v, want no error", err)959 }960 // GET http://example.com/ HTTP/1.1961 // Host: example.com962 if err := req.WriteProxy(conn); err != nil {963 t.Fatalf("req.WriteProxy(): got %v, want no error", err)964 }965 // Response from skipped round trip.966 res, err = http.ReadResponse(bufio.NewReader(conn), req)967 if err != nil {968 t.Fatalf("http.ReadResponse(): got %v, want no error", err)969 }970 res.Body.Close()971 if got, want := res.StatusCode, 200; got != want {972 t.Errorf("res.StatusCode: got %d, want %d", got, want)973 }974}975func TestServerClosesConnection(t *testing.T) {976 t.Parallel()977 dstl, err := net.Listen("tcp", "[::]:0")978 if err != nil {979 t.Fatalf("Failed to create http listener: %v", err)980 }981 defer dstl.Close()982 go func() {983 t.Logf("Waiting for server side connection")984 conn, err := dstl.Accept()985 if err != nil {986 t.Fatalf("Got error while accepting connection on destination listener: %v", err)987 }988 t.Logf("Accepted server side connection")989 buf := make([]byte, 16384)990 if _, err := conn.Read(buf); err != nil {991 t.Fatalf("Error reading: %v", err)992 }993 _, err = conn.Write([]byte("HTTP/1.1 301 MOVED PERMANENTLY\r\n" +994 "Server: \r\n" +995 "Date: \r\n" +996 "Referer: \r\n" +997 "Location: http://www.foo.com/\r\n" +998 "Content-type: text/html\r\n" +999 "Connection: close\r\n\r\n"))1000 if err != nil {1001 t.Fatalf("Got error while writting to connection on destination listener: %v", err)1002 }1003 conn.Close()1004 }()1005 l, err := net.Listen("tcp", "[::]:0")1006 if err != nil {1007 t.Fatalf("net.Listen(): got %v, want no error", err)1008 }1009 ca, priv, err := mitm.NewAuthority("martian.proxy", "Martian Authority", 2*time.Hour)1010 if err != nil {1011 t.Fatalf("mitm.NewAuthority(): got %v, want no error", err)1012 }1013 mc, err := mitm.NewConfig(ca, priv)1014 if err != nil {1015 t.Fatalf("mitm.NewConfig(): got %v, want no error", err)1016 }1017 p := NewProxy()1018 p.SetMITM(mc)1019 defer p.Close()1020 // Start the proxy with a listener that will return a temporary error on1021 // Accept() three times.1022 go p.Serve(newTimeoutListener(l, 3))1023 conn, err := net.Dial("tcp", l.Addr().String())1024 if err != nil {1025 t.Fatalf("net.Dial(): got %v, want no error", err)1026 }1027 defer conn.Close()1028 req, err := http.NewRequest("CONNECT", fmt.Sprintf("//%s", dstl.Addr().String()), nil)1029 if err != nil {1030 t.Fatalf("http.NewRequest(): got %v, want no error", err)1031 }1032 // CONNECT example.com:443 HTTP/1.11033 // Host: example.com1034 if err := req.Write(conn); err != nil {1035 t.Fatalf("req.Write(): got %v, want no error", err)1036 }1037 res, err := http.ReadResponse(bufio.NewReader(conn), req)1038 if err != nil {1039 t.Fatalf("http.ReadResponse(): got %v, want no error", err)1040 }1041 res.Body.Close()1042 _, err = conn.Write([]byte("GET / HTTP/1.1\r\n" +1043 "User-Agent: curl/7.35.0\r\n" +1044 fmt.Sprintf("Host: %s\r\n", dstl.Addr()) +1045 "Accept: */*\r\n\r\n"))1046 if err != nil {1047 t.Fatalf("Error while writing GET request: %v", err)1048 }1049 res, err = http.ReadResponse(bufio.NewReader(io.TeeReader(conn, os.Stderr)), req)1050 if err != nil {1051 t.Fatalf("http.ReadResponse(): got %v, want no error", err)1052 }1053 _, err = ioutil.ReadAll(res.Body)1054 if err != nil {1055 t.Fatalf("error while ReadAll: %v", err)1056 }1057 defer res.Body.Close()1058}...

Full Screen

Full Screen

listener_test.go

Source:listener_test.go Github

copy

Full Screen

...166 connectionTestWrapper(t, conn, expected)167}168func TestProxyListener_goReadProxyRoutine_ErrorReading(t *testing.T) {169 conn := &ConnMock{170 ReadReplies: []readResponse{171 readResponse{172 Error: fmt.Errorf("EXPECTED"),173 },174 },175 }176 expected := "Error reading first byte: EXPECTED"177 connectionTestWrapper(t, conn, expected)178}179func TestProxyListener_goReadProxyRoutine_InvalidReadBytes(t *testing.T) {180 conn := &ConnMock{181 ReadReplies: []readResponse{182 readResponse{183 Data: []byte("XX"),184 },185 },186 }187 expected := "Invalid number of bytes read: 2"188 connectionTestWrapper(t, conn, expected)189}190func TestProxyListener_goReadProxyRoutine_InvalidFirstByte(t *testing.T) {191 conn := &ConnMock{192 ReadReplies: []readResponse{193 readResponse{194 Data: []byte("X"),195 },196 },197 }198 expected := "Invalid first byte: 88"199 connectionTestWrapper(t, conn, expected)200}201func TestProxyListener_readVersion1_ClosedEarly(t *testing.T) {202 conn := &ConnMock{203 ReadReplies: []readResponse{204 readResponse{205 Data: []byte("P"),206 },207 },208 }209 expected := "TCP session closed prior to PROXY line."210 connectionTestWrapper(t, conn, expected)211}212func TestProxyListener_readVersion1_TCPError(t *testing.T) {213 conn := &ConnMock{214 ReadReplies: []readResponse{215 readResponse{216 Data: []byte("P"),217 },218 readResponse{219 Error: fmt.Errorf("EXPECTED"),220 },221 },222 }223 expected := "TCP error reading PROXY line: EXPECTED"224 connectionTestWrapper(t, conn, expected)225}226func TestProxyListener_readVersion1_NonProxyStart(t *testing.T) {227 conn := &ConnMock{228 ReadReplies: []readResponse{229 readResponse{230 Data: []byte("P"),231 },232 readResponse{233 Data: []byte("WTFWTFWTF"),234 },235 },236 }237 expected := "First line did not start with 'PROXY '"238 connectionTestWrapper(t, conn, expected)239}240func TestProxyListener_readVersion1_LineTooLong(t *testing.T) {241 conn := &ConnMock{242 ReadReplies: makeReplies([]byte(strings.Repeat("X", 200))),243 }244 expected := "PROXY line malformed (too long)"245 connectionTestWrapper(t, conn, expected)246}247func TestProxyListener_readVersion1_ErrorReading(t *testing.T) {248 conn := &ConnMock{249 ReadReplies: []readResponse{250 readResponse{251 Data: []byte("P"),252 },253 readResponse{254 Data: []byte("ROXY "),255 },256 readResponse{257 Error: fmt.Errorf("EXPECTED"),258 },259 },260 }261 expected := "Error reading PROXY line: EXPECTED"262 connectionTestWrapper(t, conn, expected)263}264func TestProxyListener_readVersion1_InvalidByteResponse(t *testing.T) {265 conn := &ConnMock{266 ReadReplies: []readResponse{267 readResponse{268 Data: []byte("P"),269 },270 readResponse{271 Data: []byte("ROXY "),272 },273 readResponse{274 Data: []byte("XX"),275 },276 },277 }278 expected := "Invalid number of bytes read from socket: 2"279 connectionTestWrapper(t, conn, expected)280}281func TestProxyListener_readVersion1_WrongNumberOfElements(t *testing.T) {282 conn := &ConnMock{283 ReadReplies: makeReplies([]byte("1 2 3 4 5 6 7 8 9\n\r")),284 }285 expected := "PROXY line is malformed, incorrect number of elements: 10"286 connectionTestWrapper(t, conn, expected)287}288func TestProxyListener_readVersion1_InvalidProtocol(t *testing.T) {289 conn := &ConnMock{290 ReadReplies: makeReplies([]byte("XXX 1 2 3 4\n\r")),291 }292 expected := "Protocol element of the PROXY line is invalid: XXX"293 connectionTestWrapper(t, conn, expected)294}295func TestProxyListener_readVersion1_BadSourcePort(t *testing.T) {296 conn := &ConnMock{297 ReadReplies: makeReplies(298 []byte("TCP4 1.1.1.1 2.2.2.2 X 1\n\r")),299 }300 expected := `destination port element of the PROXY line is not an int: ` +301 `strconv.ParseInt: parsing "X": invalid syntax`302 connectionTestWrapper(t, conn, expected)303}304func TestProxyListener_readVersion1_SecondDeadlineError(t *testing.T) {305 conn := &ConnMock{306 DeadlineErrors: []error{nil, fmt.Errorf("EXPECTED")},307 ReadReplies: makeReplies(308 []byte("TCP4 1.1.1.1 2.2.2.2 1 2\n\r")),309 }310 expected := "Error unsetting deadline on the socket: EXPECTED"311 connectionTestWrapper(t, conn, expected)312}313func TestProxyListener_readVersion1_Success(t *testing.T) {314 errors := make([]error, 0, 2)315 pl := &ProxyListener{316 listener: &ListenerMock{317 AcceptReplies: []acceptResponse{318 acceptResponse{Conn: &ConnMock{319 ReadReplies: makeReplies(320 []byte("TCP4 1.1.1.1 2.2.2.2 1 2\n\r"),321 []byte("OK")),322 }},323 },324 },325 errorChan: make(chan error),326 acceptChan: make(chan net.Conn),327 ProtocolError: func(err error) {328 errors = append(errors, err)329 },330 ProtocolDeadline: time.Second,331 }332 pl.waitGroup.Add(1)333 go pl.goAcceptRoutine()334 // Check the results.335 if len(errors) != 0 {336 t.Logf("%#v", errors)337 t.Fatalf("No error expected, at least one returned.")338 }339 select {340 case conn := <-pl.acceptChan:341 data := make([]byte, 2)342 if conn.RemoteAddr().String() != "1.1.1.1:1" {343 t.Fatalf(344 "The Addr was not parsed properly (expected 1.1.1.1:1): %s",345 conn.RemoteAddr())346 } else if n, err := conn.Read(data); err != nil {347 t.Fatalf("Error reading post-proxy data: %s", err)348 } else if n != 2 {349 t.Fatalf("Unknown read size: %d", n)350 } else if !bytes.Equal(data, []byte("OK")) {351 t.Fatalf("Unexpected response (expected OK): %#v", data)352 }353 case <-time.NewTimer(time.Millisecond * 10).C:354 t.Fatalf("No connection was passed to the channel.")355 }356 // Stop the processor.357 <-pl.errorChan358 pl.Stop()359}360func TestProxyListener_readBinary_EarlyHeaderEOF(t *testing.T) {361 conn := &ConnMock{362 ReadReplies: []readResponse{363 readResponse{364 Data: []byte{0x0D},365 },366 },367 }368 expected := "Error reading binary header data: EOF"369 connectionTestWrapper(t, conn, expected)370}371func TestProxyListener_readBinary_TCPError(t *testing.T) {372 conn := &ConnMock{373 ReadReplies: []readResponse{374 readResponse{375 Data: []byte{0x0D},376 },377 readResponse{378 Error: fmt.Errorf("EXPECTED"),379 },380 },381 }382 expected := "Error reading binary header data: EXPECTED"383 connectionTestWrapper(t, conn, expected)384}385func TestProxyListener_readBinary_InvalidHeader(t *testing.T) {386 conn := &ConnMock{387 ReadReplies: []readResponse{388 readResponse{389 Data: []byte{0x0D},390 },391 readResponse{392 Data: bytes.Repeat([]byte{0}, 15),393 },394 },395 }396 expected := "Static header bytes did not match expected value."397 connectionTestWrapper(t, conn, expected)398}399func TestProxyListener_readBinary_InvalidVersion(t *testing.T) {400 conn := &ConnMock{401 ReadReplies: []readResponse{402 readResponse{403 Data: []byte{0x0D},404 },405 readResponse{406 Data: []byte{407 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,408 0x51, 0x55, 0x49, 0x54, 0x10,409 },410 },411 readResponse{412 Data: []byte{0xF0, 0x00, 0x00, 0x00},413 },414 },415 }416 expected := "Version in the header was not 2: 15"417 connectionTestWrapper(t, conn, expected)418}419func TestProxyListener_readBinary_InvalidCommandBits(t *testing.T) {420 conn := &ConnMock{421 ReadReplies: []readResponse{422 readResponse{423 Data: []byte{0x0D},424 },425 readResponse{426 Data: []byte{427 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,428 0x51, 0x55, 0x49, 0x54, 0x10,429 },430 },431 readResponse{432 Data: []byte{0x2F, 0x00, 0x00, 0x00},433 },434 },435 }436 expected := "Command bits contained an invalid value: 15"437 connectionTestWrapper(t, conn, expected)438}439func TestProxyListener_readBinary_InvalidFamilyBits(t *testing.T) {440 conn := &ConnMock{441 ReadReplies: []readResponse{442 readResponse{443 Data: []byte{0x0D},444 },445 readResponse{446 Data: []byte{447 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,448 0x51, 0x55, 0x49, 0x54, 0x10,449 },450 },451 readResponse{452 Data: []byte{0x20, 0xF0, 0x00, 0x00},453 },454 },455 }456 expected := "Family bits contained an invalid value: 15"457 connectionTestWrapper(t, conn, expected)458}459func TestProxyListener_readBinary_InvalidProtocolBits(t *testing.T) {460 conn := &ConnMock{461 ReadReplies: []readResponse{462 readResponse{463 Data: []byte{0x0D},464 },465 readResponse{466 Data: []byte{467 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,468 0x51, 0x55, 0x49, 0x54, 0x10,469 },470 },471 readResponse{472 Data: []byte{0x20, 0x0F, 0x00, 0x00},473 },474 },475 }476 expected := "Protocol bits contained an invalid value: 15"477 connectionTestWrapper(t, conn, expected)478}479func TestProxyListener_readBinary_LengthTooLarge(t *testing.T) {480 conn := &ConnMock{481 ReadReplies: []readResponse{482 readResponse{483 Data: []byte{0x0D},484 },485 readResponse{486 Data: []byte{487 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,488 0x51, 0x55, 0x49, 0x54, 0x10,489 },490 },491 readResponse{492 Data: []byte{0x20, 0x00, 0xEE, 0xFF},493 },494 },495 }496 expected := "Length integer is too large to be valid: 61183"497 connectionTestWrapper(t, conn, expected)498}499func TestProxyListener_readBinary_ErrReadingAddressData(t *testing.T) {500 conn := &ConnMock{501 ReadReplies: []readResponse{502 readResponse{503 Data: []byte{0x0D},504 },505 readResponse{506 Data: []byte{507 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,508 0x51, 0x55, 0x49, 0x54, 0x10,509 },510 },511 readResponse{512 Data: []byte{0x20, 0x00, 0x00, 0x01},513 },514 readResponse{515 Error: fmt.Errorf("EXPECTED"),516 },517 },518 }519 expected := "Error reading binary address data: EXPECTED"520 connectionTestWrapper(t, conn, expected)521}522func TestProxyListener_readBinary_SecondDeadlineError(t *testing.T) {523 conn := &ConnMock{524 DeadlineErrors: []error{nil, fmt.Errorf("EXPECTED")},525 ReadReplies: []readResponse{526 readResponse{527 Data: []byte{0x0D},528 },529 readResponse{530 Data: []byte{531 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,532 0x51, 0x55, 0x49, 0x54, 0x10,533 },534 },535 readResponse{536 Data: []byte{0x20, 0x00, 0x00, 0x00},537 },538 },539 }540 expected := "Error unsetting deadline on the socket: EXPECTED"541 connectionTestWrapper(t, conn, expected)542}543func TestProxyListener_readBinary_LocalSuccess(t *testing.T) {544 errors := make([]error, 0, 2)545 pl := &ProxyListener{546 listener: &ListenerMock{547 AcceptReplies: []acceptResponse{548 acceptResponse{Conn: &ConnMock{549 RawRemoteAddr: &AddrMock{550 network: "net",551 str: "1.1.1.1:1",552 },553 ReadReplies: []readResponse{554 readResponse{555 Data: []byte{0x0D},556 },557 readResponse{558 Data: []byte{559 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,560 0x51, 0x55, 0x49, 0x54, 0x10,561 },562 },563 readResponse{564 Data: []byte{0x20, 0x00, 0x00, 0x00},565 },566 readResponse{567 Data: []byte("OK"),568 },569 },570 }},571 },572 },573 errorChan: make(chan error),574 acceptChan: make(chan net.Conn),575 ProtocolError: func(err error) {576 errors = append(errors, err)577 },578 ProtocolDeadline: time.Second,579 }580 pl.waitGroup.Add(1)581 go pl.goAcceptRoutine()582 // Check the results.583 if len(errors) != 0 {584 t.Logf("%#v", errors)585 t.Fatalf("No error expected, at least one returned.")586 }587 select {588 case conn := <-pl.acceptChan:589 data := make([]byte, 2)590 if conn.RemoteAddr().String() != "1.1.1.1:1" {591 t.Fatalf(592 "The Addr was not passed through properly: %s",593 conn.RemoteAddr())594 } else if n, err := conn.Read(data); err != nil {595 t.Fatalf("Error reading post-proxy data: %s", err)596 } else if n != 2 {597 t.Fatalf("Unknown read size: %d", n)598 } else if !bytes.Equal(data, []byte("OK")) {599 t.Fatalf("Unexpected response (expected OK): %#v", data)600 }601 case <-time.NewTimer(time.Millisecond * 10).C:602 t.Fatalf("No connection was passed to the channel.")603 }604 // Stop the processor.605 <-pl.errorChan606 pl.Stop()607}608func TestProxyListener_readBinary_TCPIPv4AddressTooLong(t *testing.T) {609 conn := &ConnMock{610 ReadReplies: []readResponse{611 readResponse{612 Data: []byte{0x0D},613 },614 readResponse{615 Data: []byte{616 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,617 0x51, 0x55, 0x49, 0x54, 0x10,618 },619 },620 readResponse{621 Data: []byte{0x21, 0x11, 0x00, 0x00},622 },623 },624 }625 expected := "Invalid address length for a INET proxy (should be 12): 0"626 connectionTestWrapper(t, conn, expected)627}628func TestProxyListener_readBinary_TCPOverIPv4(t *testing.T) {629 errors := make([]error, 0, 2)630 pl := &ProxyListener{631 listener: &ListenerMock{632 AcceptReplies: []acceptResponse{633 acceptResponse{Conn: &ConnMock{634 RawRemoteAddr: &AddrMock{635 network: "net",636 str: "0.0.0.0:0",637 },638 ReadReplies: []readResponse{639 readResponse{640 Data: []byte{0x0D},641 },642 readResponse{643 Data: []byte{644 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,645 0x51, 0x55, 0x49, 0x54, 0x10,646 },647 },648 readResponse{649 Data: []byte{0x21, 0x11, 0x00, 0x0C},650 },651 readResponse{652 Data: []byte{0x01, 0x02, 0x03, 0x04},653 },654 readResponse{655 Data: []byte{0x05, 0x06, 0x07, 0x08},656 },657 readResponse{658 Data: []byte{0x09, 0x0A},659 },660 readResponse{661 Data: []byte{0x0B, 0x0C},662 },663 readResponse{664 Data: []byte("OK"),665 },666 },667 }},668 },669 },670 errorChan: make(chan error),671 acceptChan: make(chan net.Conn),672 ProtocolError: func(err error) {673 errors = append(errors, err)674 },675 ProtocolDeadline: time.Second,676 }677 pl.waitGroup.Add(1)678 go pl.goAcceptRoutine()679 // Check the results.680 if len(errors) != 0 {681 t.Logf("%#v", errors)682 t.Fatalf("No error expected, at least one returned.")683 }684 select {685 case conn := <-pl.acceptChan:686 data := make([]byte, 2)687 if conn.RemoteAddr().String() != "1.2.3.4:2314" {688 t.Fatalf(689 "The Addr was not passed through properly: %s",690 conn.RemoteAddr())691 } else if n, err := conn.Read(data); err != nil {692 t.Fatalf("Error reading post-proxy data: %s", err)693 } else if n != 2 {694 t.Fatalf("Unknown read size: %d", n)695 } else if !bytes.Equal(data, []byte("OK")) {696 t.Fatalf("Unexpected response (expected OK): %#v", data)697 }698 case <-time.NewTimer(time.Millisecond * 10).C:699 t.Fatalf("No connection was passed to the channel.")700 }701 // Stop the processor.702 <-pl.errorChan703 pl.Stop()704}705func TestProxyListener_readBinary_UDPIPv4AddressTooLong(t *testing.T) {706 conn := &ConnMock{707 ReadReplies: []readResponse{708 readResponse{709 Data: []byte{0x0D},710 },711 readResponse{712 Data: []byte{713 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,714 0x51, 0x55, 0x49, 0x54, 0x10,715 },716 },717 readResponse{718 Data: []byte{0x21, 0x12, 0x00, 0x00},719 },720 },721 }722 expected := "Invalid address length for a INET proxy (should be 12): 0"723 connectionTestWrapper(t, conn, expected)724}725func TestProxyListener_readBinary_UDPOverIPv4(t *testing.T) {726 errors := make([]error, 0, 2)727 pl := &ProxyListener{728 listener: &ListenerMock{729 AcceptReplies: []acceptResponse{730 acceptResponse{Conn: &ConnMock{731 RawRemoteAddr: &AddrMock{732 network: "net",733 str: "0.0.0.0:0",734 },735 ReadReplies: []readResponse{736 readResponse{737 Data: []byte{0x0D},738 },739 readResponse{740 Data: []byte{741 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,742 0x51, 0x55, 0x49, 0x54, 0x10,743 },744 },745 readResponse{746 Data: []byte{0x21, 0x12, 0x00, 0x0C},747 },748 readResponse{749 Data: []byte{0x01, 0x02, 0x03, 0x04},750 },751 readResponse{752 Data: []byte{0x05, 0x06, 0x07, 0x08},753 },754 readResponse{755 Data: []byte{0x09, 0x0A},756 },757 readResponse{758 Data: []byte{0x0B, 0x0C},759 },760 readResponse{761 Data: []byte("OK"),762 },763 },764 }},765 },766 },767 errorChan: make(chan error),768 acceptChan: make(chan net.Conn),769 ProtocolError: func(err error) {770 errors = append(errors, err)771 },772 ProtocolDeadline: time.Second,773 }774 pl.waitGroup.Add(1)775 go pl.goAcceptRoutine()776 // Check the results.777 if len(errors) != 0 {778 t.Logf("%#v", errors)779 t.Fatalf("No error expected, at least one returned.")780 }781 select {782 case conn := <-pl.acceptChan:783 data := make([]byte, 2)784 if conn.RemoteAddr().String() != "1.2.3.4:2314" {785 t.Fatalf(786 "The Addr was not passed through properly: %s",787 conn.RemoteAddr())788 } else if n, err := conn.Read(data); err != nil {789 t.Fatalf("Error reading post-proxy data: %s", err)790 } else if n != 2 {791 t.Fatalf("Unknown read size: %d", n)792 } else if !bytes.Equal(data, []byte("OK")) {793 t.Fatalf("Unexpected response (expected OK): %#v", data)794 }795 case <-time.NewTimer(time.Millisecond * 10).C:796 t.Fatalf("No connection was passed to the channel.")797 }798 // Stop the processor.799 <-pl.errorChan800 pl.Stop()801}802func TestProxyListener_readBinary_TCPIPv6AddressTooLong(t *testing.T) {803 conn := &ConnMock{804 ReadReplies: []readResponse{805 readResponse{806 Data: []byte{0x0D},807 },808 readResponse{809 Data: []byte{810 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,811 0x51, 0x55, 0x49, 0x54, 0x10,812 },813 },814 readResponse{815 Data: []byte{0x21, 0x21, 0x00, 0x00},816 },817 },818 }819 expected := "Invalid address length for a INET6 proxy (should be 36): 0"820 connectionTestWrapper(t, conn, expected)821}822func TestProxyListener_readBinary_TCPOverIPv6(t *testing.T) {823 errors := make([]error, 0, 2)824 pl := &ProxyListener{825 listener: &ListenerMock{826 AcceptReplies: []acceptResponse{827 acceptResponse{Conn: &ConnMock{828 RawRemoteAddr: &AddrMock{829 network: "net",830 str: "0.0.0.0:0",831 },832 ReadReplies: []readResponse{833 readResponse{834 Data: []byte{0x0D},835 },836 readResponse{837 Data: []byte{838 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,839 0x51, 0x55, 0x49, 0x54, 0x10,840 },841 },842 readResponse{843 Data: []byte{0x21, 0x21, 0x00, 0x24},844 },845 readResponse{846 Data: []byte{847 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,848 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,849 },850 },851 readResponse{852 Data: []byte{853 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,854 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,855 },856 },857 readResponse{858 Data: []byte{0x09, 0x0A},859 },860 readResponse{861 Data: []byte{0x0B, 0x0C},862 },863 readResponse{864 Data: []byte("OK"),865 },866 },867 }},868 },869 },870 errorChan: make(chan error),871 acceptChan: make(chan net.Conn),872 ProtocolError: func(err error) {873 errors = append(errors, err)874 },875 ProtocolDeadline: time.Second,876 }877 pl.waitGroup.Add(1)878 go pl.goAcceptRoutine()879 // Check the results.880 if len(errors) != 0 {881 t.Logf("%#v", errors)882 t.Fatalf("No error expected, at least one returned.")883 }884 select {885 case conn := <-pl.acceptChan:886 addrExpected := "[1:203:405:607:809:a0b:c0d:e0f]:2314"887 data := make([]byte, 2)888 if conn.RemoteAddr().String() != addrExpected {889 t.Fatalf(890 "The Addr was not passed through properly: %s",891 conn.RemoteAddr())892 } else if n, err := conn.Read(data); err != nil {893 t.Fatalf("Error reading post-proxy data: %s", err)894 } else if n != 2 {895 t.Fatalf("Unknown read size: %d", n)896 } else if !bytes.Equal(data, []byte("OK")) {897 t.Fatalf("Unexpected response (expected OK): %#v", data)898 }899 case <-time.NewTimer(time.Millisecond * 10).C:900 t.Fatalf("No connection was passed to the channel.")901 }902 // Stop the processor.903 <-pl.errorChan904 pl.Stop()905}906func TestProxyListener_readBinary_UDPIPv6AddressTooLong(t *testing.T) {907 conn := &ConnMock{908 ReadReplies: []readResponse{909 readResponse{910 Data: []byte{0x0D},911 },912 readResponse{913 Data: []byte{914 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,915 0x51, 0x55, 0x49, 0x54, 0x10,916 },917 },918 readResponse{919 Data: []byte{0x21, 0x22, 0x00, 0x00},920 },921 },922 }923 expected := "Invalid address length for a INET6 proxy (should be 36): 0"924 connectionTestWrapper(t, conn, expected)925}926func TestProxyListener_readBinary_UDPOverIPv6(t *testing.T) {927 errors := make([]error, 0, 2)928 pl := &ProxyListener{929 listener: &ListenerMock{930 AcceptReplies: []acceptResponse{931 acceptResponse{Conn: &ConnMock{932 RawRemoteAddr: &AddrMock{933 network: "net",934 str: "0.0.0.0:0",935 },936 ReadReplies: []readResponse{937 readResponse{938 Data: []byte{0x0D},939 },940 readResponse{941 Data: []byte{942 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,943 0x51, 0x55, 0x49, 0x54, 0x10,944 },945 },946 readResponse{947 Data: []byte{0x21, 0x22, 0x00, 0x24},948 },949 readResponse{950 Data: []byte{951 0x0F, 0x0E, 0x0D, 0x0C, 0x0B, 0x0A, 0x09, 0x08,952 0x07, 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00,953 },954 },955 readResponse{956 Data: []byte{957 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,958 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,959 },960 },961 readResponse{962 Data: []byte{0x09, 0x0A},963 },964 readResponse{965 Data: []byte{0x0B, 0x0C},966 },967 readResponse{968 Data: []byte("OK"),969 },970 },971 }},972 },973 },974 errorChan: make(chan error),975 acceptChan: make(chan net.Conn),976 ProtocolError: func(err error) {977 errors = append(errors, err)978 },979 ProtocolDeadline: time.Second,980 }981 pl.waitGroup.Add(1)982 go pl.goAcceptRoutine()983 // Check the results.984 if len(errors) != 0 {985 t.Logf("%#v", errors)986 t.Fatalf("No error expected, at least one returned.")987 }988 select {989 case conn := <-pl.acceptChan:990 addrExpected := "[f0e:d0c:b0a:908:706:504:302:100]:2314"991 data := make([]byte, 2)992 if conn.RemoteAddr().String() != addrExpected {993 t.Fatalf(994 "The Addr was not passed through properly: %s",995 conn.RemoteAddr())996 } else if n, err := conn.Read(data); err != nil {997 t.Fatalf("Error reading post-proxy data: %s", err)998 } else if n != 2 {999 t.Fatalf("Unknown read size: %d", n)1000 } else if !bytes.Equal(data, []byte("OK")) {1001 t.Fatalf("Unexpected response (expected OK): %#v", data)1002 }1003 case <-time.NewTimer(time.Millisecond * 10).C:1004 t.Fatalf("No connection was passed to the channel.")1005 }1006 // Stop the processor.1007 <-pl.errorChan1008 pl.Stop()1009}1010func TestProxyListener_readBinary_UnspportedCombination(t *testing.T) {1011 conn := &ConnMock{1012 ReadReplies: []readResponse{1013 readResponse{1014 Data: []byte{0x0D},1015 },1016 readResponse{1017 Data: []byte{1018 0x0AD, 0x0D, 0x0A, 0x00, 0x0D, 0x0A,1019 0x51, 0x55, 0x49, 0x54, 0x10,1020 },1021 },1022 readResponse{1023 Data: []byte{0x21, 0x32, 0x00, 0x00},1024 },1025 readResponse{1026 Data: bytes.Repeat([]byte{0}, 36),1027 },1028 },1029 }1030 expected := "Unsupported family/protocol combination."1031 connectionTestWrapper(t, conn, expected)1032}1033func TestProxyListener_Accept_Error(t *testing.T) {1034 p := &ProxyListener{1035 errorChan: make(chan error, 1),1036 acceptChan: make(chan net.Conn, 1),1037 }1038 p.errorChan <- fmt.Errorf("EXPECTED")1039 conn, err := p.Accept()...

Full Screen

Full Screen

readResponse

Using AI Code Generation

copy

Full Screen

1func main() {2 conn := new(conn)3 conn.readResponse()4}5func main() {6 conn := new(conn)7 conn.readResponse()8}9./1.go:7: conn.readResponse undefined (type *conn has no field or method readResponse)10./2.go:7: conn.readResponse undefined (type *conn has no field or method readResponse)11func main() {12 conn := new(conn)13 conn.(*conn).readResponse()14}15func main() {16 conn := new(conn)17 conn.(*conn).readResponse()18}

Full Screen

Full Screen

readResponse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 conn, err := net.Dial("tcp", "localhost:8080")4 if err != nil {5 log.Fatal(err)6 }7 defer conn.Close()8 if err != nil {9 log.Fatal(err)10 }11 err = req.Write(conn)12 if err != nil {13 log.Fatal(err)14 }15 resp, err := http.ReadResponse(bufio.NewReader(conn), req)16 if err != nil {17 log.Fatal(err)18 }19 fmt.Println("Response status:", resp.Status)20 body, err := ioutil.ReadAll(resp.Body)21 if err != nil {22 log.Fatal(err)23 }24 fmt.Println("Response body:", string(body))25}

Full Screen

Full Screen

readResponse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 jar, _ := cookiejar.New(nil)4 client := http.Client{5 }6 resp, _ := client.Do(req)7 fmt.Println(resp.Cookies())8}9[{GOOGAPPUID

Full Screen

Full Screen

readResponse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 if err != nil {4 fmt.Println("Error: ", err)5 }6 fmt.Println("Response Status: ", resp.Status)7 fmt.Println("Response Headers: ", resp.Header)8 fmt.Println("Response Body: ", resp.Body)9}10Response Headers: map[Content-Type:[text/html; charset=UTF-8] Date:[Thu, 11 Feb 2021 13:47:17 GMT] Expires:[-1] P3p:[CP="This is not a P3P policy! See g.co/p3phelp for more info."] Server:[gws] Set-Cookie:[1P_JAR=2021-02-11-13; expires=Sat, 13-Mar-2021 13:47:17 GMT; path=/; domain=.google.com; Secure, NID=204=Z6U5J6Q2m1f5R6jKkH8F7A2gMzRZfJxgKj8d1O3qg3Jy7pZUVdS0eI7ZJ0XZTz1t4v4tj0f0GJfFw4wSfSd8cPjTtX9Tz1i4Q4Dj8LsNtP4e4M; expires=Fri, 11-Aug-2021 13:47:17 GMT; path=/; domain=.google.com; HttpOnly; Secure] Transfer-Encoding:[chunked]]11import (12func main() {13 if err != nil {14 fmt.Println("Error: ", err)15 }16 defer resp.Body.Close()17 body, err := ioutil.ReadAll(resp.Body)18 if err != nil {19 fmt.Println("Error: ", err)20 }21 fmt.Println("Response Body: ", string(body))22}

Full Screen

Full Screen

readResponse

Using AI Code Generation

copy

Full Screen

1import (2func main() {3 fmt.Println("Hello, World!")4}5import (6func main() {7 fmt.Println("Hello, World!")8}9import (10func main() {11 fmt.Println("Hello, World!")12}13import (14func main() {15 fmt.Println("Hello, World!")16}17import (18func main() {19 fmt.Println("Hello, World!")20}21import (22func main() {23 fmt.Println("Hello, World!")24}25import (26func main() {27 fmt.Println("Hello, World!")28}29import (30func main() {31 fmt.Println("Hello, World!")32}33import (34func main() {35 fmt.Println("Hello, World!")36}37import (38func main() {39 fmt.Println("Hello, World!")40}

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful