// Worker func worker(t *http.Transport, reqChan chan *http.Request, respChan chan Response) { for req := range reqChan { resp, err := t.RoundTrip(req) r := Response{resp, err} respChan <- r } }
func login(c *cli.Context) { println("echo login,", c.Args().Get(0), c.Args().Get(1)) // client := &http.Client{} reqest, _ := http.NewRequest("GET", "https://passport.baidu.com", nil) reqest.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8") reqest.Header.Set("Accept-Encoding", "gzip, deflate, sdch") reqest.Header.Set("Accept-Language", "en-US,en;q=0.8,zh-CN;q=0.6,zh-TW;q=0.4") reqest.Header.Set("Connection", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36") transport := http.Transport{} response, err := transport.RoundTrip(reqest) if err != nil { // t.Fatal(err) } // // Check if you received the status codes you expect. There may // // status codes other than 200 which are acceptable. // if resp.StatusCode != 200 && resp.StatusCode != 302 { // t.Fatal("Failed with status", resp.Status) // } // response,_ := client.Do(reqest) if response.StatusCode == 302 { // body, _ := ioutil.ReadAll(response.Body) // bodystr := string(body); fmt.Println("cookie: ", response.Cookies()) } else { fmt.Println("error, code=", response.StatusCode) } println("login done") }
func image(command *bot.Cmd, matches []string) (msg string, err error) { client := &http.Client{} request, _ := http.NewRequest("GET", fmt.Sprintf(imageURL, url.QueryEscape(matches[1])), nil) request.Header.Set("Ocp-Apim-Subscription-Key", bot.Config.Bing) response, _ := client.Do(request) defer response.Body.Close() body, _ := ioutil.ReadAll(response.Body) var results ImageResults json.Unmarshal(body, &results) if err != nil { return fmt.Sprintf("No results for %s", matches[1]), nil } if len(results.Value) == 0 { return fmt.Sprintf("No results for %s", matches[1]), nil } pageURL := results.Value[0].ContentURL transport := http.Transport{} request, _ = http.NewRequest("HEAD", pageURL, nil) response, _ = transport.RoundTrip(request) pageURL = response.Header.Get("Location") output := fmt.Sprintf("Bing | %s | %s", matches[1], pageURL) return output, nil }
func (r exampleDomainRewriter) RoundTrip(req *http.Request) (resp *http.Response, err error) { req.URL.Scheme = "http" req.URL.Host = r.RewriteURL.Host t := http.Transport{} return t.RoundTrip(req) }
func (srv *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) error { transport := new(http.Transport) h, ok := w.(http.Hijacker) if !ok { return errors.New("Unable to hijack connection") } r.Host = srv.addr r.URL.Host = r.Host if len(r.URL.Scheme) == 0 { r.URL.Scheme = "http" } response, err := transport.RoundTrip(r) if err != nil { return err } conn, _, err := h.Hijack() if err != nil { return err } defer conn.Close() defer response.Body.Close() return response.Write(conn) }
// Proxy the request to the given endpoint, execute observers and middlewares chains func (l *HttpLocation) proxyToEndpoint(tr *http.Transport, o *Options, endpoint endpoint.Endpoint, req request.Request) (*http.Response, error) { a := &request.BaseAttempt{Endpoint: endpoint} l.observerChain.ObserveRequest(req) defer l.observerChain.ObserveResponse(req, a) defer req.AddAttempt(a) it := l.middlewareChain.GetIter() defer l.unwindIter(it, req, a) for v := it.Next(); v != nil; v = it.Next() { a.Response, a.Error = v.ProcessRequest(req) if a.Response != nil || a.Error != nil { // Move the iterator forward to count it again once we unwind the chain it.Next() log.Errorf("Midleware intercepted request with response=%s, error=%s", a.Response.Status, a.Error) return a.Response, a.Error } } // Forward the request and mirror the response start := o.TimeProvider.UtcNow() a.Response, a.Error = tr.RoundTrip(req.GetHttpRequest()) a.Duration = o.TimeProvider.UtcNow().Sub(start) return a.Response, a.Error }
func (this *RequestHandler) HandleHttpRequest(transport *http.Transport, address string) (*http.Response, error) { this.request.URL.Scheme = "http" this.request.URL.Host = address if host, _, err := net.SplitHostPort(this.request.RemoteAddr); err == nil { xForwardFor := append(this.request.Header["X-Forwarded-For"], host) this.request.Header.Set("X-Forwarded-For", strings.Join(xForwardFor, ", ")) } else { log.Println("set X-Forwarded-For error:", err) } if _, ok := this.request.Header[http.CanonicalHeaderKey("X-Request-Start")]; !ok { this.request.Header.Set("X-Request-Start", strconv.FormatInt(time.Now().UnixNano()/1e6, 10)) } this.request.Close = true this.request.Header.Del("Connection") response, err := transport.RoundTrip(this.request) if err != nil { return response, err } for k, vv := range response.Header { for _, v := range vv { this.response.Header().Add(k, v) } } return response, err }
func TestAuthRequest(t *testing.T) { const backendResponse = "I am the backend" const backendStatus = 200 mux := http.NewServeMux() mux.HandleFunc(serverConfig.ProtectPath, genericRequestHandlerAuthWrapper) mux.HandleFunc(serverConfig.CallbackPath, oauthCallbackHandler) server = httptest.NewServer(mux) backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if len(r.TransferEncoding) > 0 { t.Errorf("backend got unexpected TransferEncoding: %v", r.TransferEncoding) } if r.Header.Get("X-Forwarded-For") == "" { t.Errorf("didn't get X-Forwarded-For header") } w.Header().Set("X-Foo", "bar") http.SetCookie(w, &http.Cookie{Name: "flavor", Value: "chocolateChip"}) w.WriteHeader(backendStatus) w.Write([]byte(backendResponse)) })) defer backend.Close() backendURL, err := url.Parse(backend.URL) if err != nil { t.Fatal(err) } serverConfig.ProxyURL = *backendURL // Test request & response req, _ := http.NewRequest("GET", server.URL, nil) req.Host = "some-name" req.Header.Set("Connection", "close") req.Close = true // Handle the request transport := new(http.Transport) response, err := transport.RoundTrip(req) if err != nil { t.Fatalf("Get: %v", err) } if g, e := response.StatusCode, backendStatus; g != e { t.Errorf("got response.StatusCode %d; expected %d", g, e) } bodyBytes, _ := ioutil.ReadAll(response.Body) if g, e := string(bodyBytes), backendResponse; g != e { t.Errorf("got body %q; expected %q", g, e) } if g, e := response.Header.Get("X-Foo"), "bar"; g != e { t.Errorf("got X-Foo %q; expected %q", g, e) } if cookie := response.Cookies()[0]; cookie.Name != "flavor" { t.Errorf("unexpected cookie %q", cookie.Name) } }
func relayHttpRequest( client *http.Client, transport *http.Transport, request *http.Request, responseWriter http.ResponseWriter) { // Transform received request struct before using as input to relayed request request.Close = false request.RequestURI = "" for _, key := range hopHeaders { request.Header.Del(key) } // Relay the HTTP request and get the response. Use a client when supplied, // otherwise a transport. A client handles cookies and redirects, and a // transport does not. var response *http.Response var err error if client != nil { response, err = client.Do(request) } else { response, err = transport.RoundTrip(request) } if err != nil { NoticeAlert("%s", common.ContextError(FilterUrlError(err))) forceClose(responseWriter) return } defer response.Body.Close() // Relay the remote response headers for _, key := range hopHeaders { response.Header.Del(key) } for key, _ := range responseWriter.Header() { responseWriter.Header().Del(key) } for key, values := range response.Header { for _, value := range values { responseWriter.Header().Add(key, value) } } // Relay the response code and body responseWriter.WriteHeader(response.StatusCode) _, err = io.Copy(responseWriter, response.Body) if err != nil { NoticeAlert("%s", common.ContextError(err)) forceClose(responseWriter) return } }
func Fanout(transport *http.Transport, request *http.Request, endpoints []*Endpoint) (*http.Response, error) { body, err := ioutil.ReadAll(request.Body) if err != nil { return nil, err } responses := make(chan *http.Response, len(endpoints)) errs := make(chan error, len(endpoints)) for _, e := range endpoints { url := *request.URL url.Scheme = "http" url.Host = e.Addr req := *request req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) req.URL = &url req.Close = true request := &req go func() { response, err := transport.RoundTrip(request) if err != nil { errs <- err } else { responses <- response } }() defer transport.CancelRequest(request) } var fanoutErr error var response *http.Response for i := 0; i < len(endpoints); i++ { select { case fanoutErr = <-errs: case response = <-responses: if response.StatusCode < 400 { return response, nil } } } if response != nil { return response, nil } return nil, fanoutErr }
func RoundRobin(transport *http.Transport, request *http.Request, endpoints []*Endpoint) (*http.Response, error) { startingPoint := rand.Intn(len(endpoints)) body, err := ioutil.ReadAll(request.Body) if err != nil { return nil, err } attempts := 0 i := startingPoint for { if i == len(endpoints) { i = 0 } url := *request.URL url.Scheme = "http" url.Host = endpoints[i].Addr req := *request req.Body = ioutil.NopCloser(bytes.NewBuffer(body)) req.URL = &url req.Close = true request := &req response, err := transport.RoundTrip(request) attempts++ i++ if attempts == len(endpoints) { return response, err } if err != nil { continue } if response.StatusCode < 400 { return response, nil } response.Body.Close() } panic("unreachable") }
// BenchmarkExpand may consume all open files in server. When running this // test, you should configure max open files server can open. This can // commonly be done through "ulimit -n 10000" shell command. func BenchmarkExpand(b *testing.B) { b.StopTimer() shortReq, _ := json.Marshal(shortReq{LongURL: "http://www.google.com"}) req, err := http.NewRequest( "POST", "http://127.0.0.1:3030/short", bytes.NewBuffer(shortReq)) req.Header.Set("Content-Type", "application/json") client := &http.Client{} resp, err := client.Do(req) if err != nil { b.Fatal(err) } if resp.StatusCode != http.StatusOK { b.Fatalf("http response status: %v", resp.StatusCode) } body, _ := ioutil.ReadAll(resp.Body) var shortResp shortResp json.Unmarshal(body, &shortResp) shortURL := shortResp.ShortURL b.StartTimer() for i := 0; i < b.N; i++ { req, err := http.NewRequest( "GET", fmt.Sprintf("%v", shortURL), nil, ) if err != nil { b.Fatal(err) } transport := http.Transport{} resp, err := transport.RoundTrip(req) if err != nil { b.Fatal(err) } if resp.StatusCode != http.StatusTemporaryRedirect { b.Log(shortURL) b.Log(resp.Request.URL) b.Fatalf("http response status: %v", resp.StatusCode) } } }
func (h *RequestHandler) HandleHttpRequest(transport *http.Transport, endpoint *route.Endpoint) (*http.Response, error) { h.transport = transport h.setupRequest(endpoint) h.setupConnection() endpointResponse, err := transport.RoundTrip(h.request) if err != nil { return endpointResponse, err } h.forwardResponseHeaders(endpointResponse) h.setupStickySession(endpointResponse, endpoint) return endpointResponse, err }
func TestUnauthRequest(t *testing.T) { mux := http.NewServeMux() mux.HandleFunc(serverConfig.ProtectPath, genericRequestHandler) mux.HandleFunc(serverConfig.CallbackPath, oauthCallbackHandler) server = httptest.NewServer(mux) req, _ := http.NewRequest("GET", server.URL, nil) client := new(http.Transport) response, err := client.RoundTrip(req) if err != nil { t.Fatalf("Get: %v", err) } location := response.Header.Get("Location") if !strings.HasPrefix(location, "https://accounts.google.com/o/oauth2") { t.Errorf("Expected Location header incorrect: %q", location) } }
// Do an HTTP roundtrip using the payload data in buf and the request metadata // in info. func roundTripWithHTTP(buf []byte, info *RequestInfo) (*http.Response, error) { tr := new(http.Transport) if info.ProxyURL != nil { if info.ProxyURL.Scheme != "http" { panic(fmt.Sprintf("don't know how to use proxy %s", info.ProxyURL.String())) } tr.Proxy = http.ProxyURL(info.ProxyURL) } req, err := http.NewRequest("POST", info.URL.String(), bytes.NewReader(buf)) if err != nil { return nil, err } if info.Host != "" { req.Host = info.Host } req.Header.Set("X-Session-Id", info.SessionID) return tr.RoundTrip(req) }
func proxy(target string, w http.ResponseWriter, r *http.Request) { stripped := r.RequestURI[strings.Index(r.RequestURI[1:], "/")+1:] uri := target + stripped body, err := ioutil.ReadAll(r.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("ERROR: %s", err) return } rr, err := http.NewRequest(r.Method, uri, bytes.NewBuffer(body)) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("ERROR: %s", err) return } copyHeader(r.Header, &rr.Header) // Create a client and query the target var transport http.Transport resp, err := transport.RoundTrip(rr) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("ERROR: %s", err) return } defer resp.Body.Close() body, err = ioutil.ReadAll(resp.Body) if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Printf("ERROR: %s", err) return } dH := w.Header() copyHeader(resp.Header, &dH) w.Write(body) }
func CheckRedirect(reqUrl string) (bool, string, int) { client := http.Transport{} req, _ := http.NewRequest("HEAD", reqUrl, nil) r, err := client.RoundTrip(req) if err != nil { return false, "", 502 } lv := &url.URL{} lv, err = r.Location() if err == nil { reqUrl = lv.String() } if r.StatusCode < 300 { return false, reqUrl, 200 } else if r.StatusCode >= 300 && r.StatusCode < 400 { return true, reqUrl, r.StatusCode } else { return false, "", 502 } }
func loginAttack(options *Options) { target := fmt.Sprintf("http://%s:%d", options.Host, options.Port) endpoint := fmt.Sprintf("%s%s", target, options.Uri) fmt.Println("Starting login attack on", endpoint) file, err := os.Open("dictionary.txt") if err != nil { fmt.Println(err) } defer file.Close() var lines []string scanner := bufio.NewScanner(file) for scanner.Scan() { lines = append(lines, scanner.Text()) } for _, password := range lines { data := url.Values{} data.Set("inputEmail", "*****@*****.**") data.Set("inputPassword", password) request, _ := http.NewRequest("POST", endpoint, strings.NewReader(data.Encode())) request.Header.Set("Content-Type", "application/x-www-form-urlencoded") if options.From != "" { request.Header.Add("X-Forwarded-For", options.From) } transport := http.Transport{} response, _ := transport.RoundTrip(request) defer response.Body.Close() if response.StatusCode == 302 { fmt.Println("The password is:", password) os.Exit(0) } } }
func StartClient(url_, heads, requestBody string, meth string, dka bool, responseChan chan *Response, waitGroup *sync.WaitGroup, tc int) { defer waitGroup.Done() var tr *http.Transport u, err := url.Parse(url_) if err == nil && u.Scheme == "https" { var tlsConfig *tls.Config if *insecure { tlsConfig = &tls.Config{ InsecureSkipVerify: true, } } else { // Load client cert cert, err := tls.LoadX509KeyPair(*certFile, *keyFile) if err != nil { log.Fatal(err) } // Load CA cert caCert, err := ioutil.ReadFile(*caFile) if err != nil { log.Fatal(err) } caCertPool := x509.NewCertPool() caCertPool.AppendCertsFromPEM(caCert) // Setup HTTPS client tlsConfig = &tls.Config{ Certificates: []tls.Certificate{cert}, RootCAs: caCertPool, } tlsConfig.BuildNameToCertificate() } tr = &http.Transport{TLSClientConfig: tlsConfig, DisableKeepAlives: dka} } else { tr = &http.Transport{DisableKeepAlives: dka} } requestBodyReader := strings.NewReader(requestBody) req, _ := http.NewRequest(meth, url_, requestBodyReader) sets := strings.Split(heads, "\n") //Split incoming header string by \n and build header pairs for i := range sets { split := strings.SplitN(sets[i], ":", 2) if len(split) == 2 { req.Header.Set(split[0], split[1]) } } timer := NewTimer() for { timer.Reset() resp, err := tr.RoundTrip(req) respObj := &Response{} if err != nil { respObj.Error = true } else { if resp.ContentLength < 0 { // -1 if the length is unknown data, err := ioutil.ReadAll(resp.Body) if err == nil { respObj.Size = int64(len(data)) } } else { respObj.Size = resp.ContentLength } respObj.StatusCode = resp.StatusCode resp.Body.Close() } respObj.Duration = timer.Duration() if len(responseChan) >= tc { break } responseChan <- respObj } }
// ServeHTTP catches a client request and proxies it to the destination server, // then waits for the server's answer and sends it back to the client. // // (this method should not be called directly). func (p *Proxy) ServeHTTP(wri http.ResponseWriter, req *http.Request) { var err error var transport *http.Transport pr := p.newProxiedRequest(wri, req) out := new(http.Request) *out = *req if req.TLS == nil { transport = &http.Transport{} out.URL.Scheme = "http" } else { transport = &http.Transport{ TLSClientConfig: &tls.Config{ InsecureSkipVerify: false, }, } out.URL.Scheme = "https" } // Making sure the Host header is present. out.URL.Host = out.Host out.Header.Add("Host", out.Host) out.Proto = "HTTP/1.1" out.ProtoMajor = 1 out.ProtoMinor = 1 out.Close = false // Walking over directors. for i := range p.directors { if err := p.directors[i].Direct(out); err != nil { log.Printf("Director: %q", err) } } // Intercepting request body. body := bytes.NewBuffer(nil) bodyCopy := bytes.NewBuffer(nil) io.Copy(io.MultiWriter(body, bodyCopy), out.Body) out.Body = ioutil.NopCloser(body) // Proxying client request to destination server. if pr.Response, err = transport.RoundTrip(out); err != nil { log.Printf("RoundTrip: %q", err) wri.WriteHeader(http.StatusInternalServerError) return } // (Response received). // Resetting body (so it can be read later) out.Body = ioutil.NopCloser(bodyCopy) // Walking over interceptos. for i := range p.interceptors { if err := p.interceptors[i].Intercept(pr.Response); err != nil { log.Printf("Interceptor: %q", err) } } // Copying response headers to the writer we are going to send to the client. copyHeader(pr.ResponseWriter.Header(), pr.Response.Header) // Copying response status. pr.ResponseWriter.WriteHeader(pr.Response.StatusCode) // Running writers. ws := make([]io.WriteCloser, 0, len(p.writers)) for i := range p.writers { var w io.WriteCloser var err error if w, err = p.writers[i].NewWriteCloser(pr.Response); err != nil { log.Printf("WriteCloser: %q", err) continue } ws = append(ws, w) } defer pr.Response.Body.Close() // Writing response. writers := make([]io.Writer, 0, len(ws)+1) writers = append(writers, pr.ResponseWriter) for i := range ws { writers = append(writers, ws[i]) } if _, err := io.Copy(io.MultiWriter(writers...), pr.Response.Body); err != nil { log.Printf("io.Copy: %q", err) } // Closing write closers. for i := range ws { if err := ws[i].Close(); err != nil { log.Printf("WriteCloser.Close: %q", err) } } // Walking over loggers. for i := range p.loggers { if err := p.loggers[i].Log(pr); err != nil { log.Printf("Log: %q", err) } } }
func (e *periodicExporter) updateSlaves() { log.Debug("discovering slaves...") // This will redirect us to the elected mesos master redirectURL := fmt.Sprintf("%s/master/redirect", e.opts.masterURL) rReq, err := http.NewRequest("GET", redirectURL, nil) if err != nil { panic(err) } tr := http.Transport{ DisableKeepAlives: true, } rresp, err := tr.RoundTrip(rReq) if err != nil { log.Warn(err) return } defer rresp.Body.Close() // This will/should return http://master.ip:5050 masterLoc := rresp.Header.Get("Location") if masterLoc == "" { log.Warnf("%d response missing Location header", rresp.StatusCode) return } log.Debugf("current elected master at: %s", masterLoc) // Find all active slaves stateURL := fmt.Sprintf("%s/master/state.json", masterLoc) resp, err := http.Get(stateURL) if err != nil { log.Warn(err) return } defer resp.Body.Close() type slave struct { Active bool `json:"active"` Hostname string `json:"hostname"` Pid string `json:"pid"` } var req struct { Slaves []*slave `json:"slaves"` } if err := json.NewDecoder(resp.Body).Decode(&req); err != nil { log.Warnf("failed to deserialize request: %s", err) return } var slaveURLs []string for _, slave := range req.Slaves { if slave.Active { // Extract slave port from pid _, port, err := net.SplitHostPort(slave.Pid) if err != nil { port = "5051" } url := fmt.Sprintf("http://%s:%s", slave.Hostname, port) slaveURLs = append(slaveURLs, url) } } log.Debugf("%d slaves discovered", len(slaveURLs)) e.slaves.Lock() e.slaves.urls = slaveURLs e.slaves.Unlock() }
// send is sending a http.Request without following redirects func (s *FormsAuthSuite) send(r *http.Request) (*http.Response, error) { t := http.Transport{} return t.RoundTrip(r) }
func report(w http.ResponseWriter, r *http.Request) { uri := target + r.RequestURI if useCache && r.Method == "GET" { element, error := cacheGet(uri) if error == nil { dH := w.Header() copyHeader(element.resp.Header, &dH) dH.Add("From-Cache", "true") dH.Set("Content-Length", strconv.Itoa(len(element.body))) w.WriteHeader(element.resp.StatusCode) w.Write(element.body) return } } if showUri { fmt.Println("URI (" + r.Method + "): " + r.Host + r.RequestURI) } if showTargetUri { fmt.Println("Modified URI (" + r.Method + "): " + uri) } requestBody, err := ioutil.ReadAll(r.Body) r.Body.Close() fatal(err) if showRequestHeaders { fmt.Printf("Request Headers: %v\n", r.Header) } if showRequestBody && string(requestBody) != "" { fmt.Printf("Request Body: %s\n", string(requestBody)) } /* We can make changes to the request body (requestBody) here */ r2, err := http.NewRequest(r.Method, uri, bytes.NewBuffer(requestBody)) fatal(err) copyHeader(r.Header, &r2.Header) r2.Header.Set("Content-Length", strconv.Itoa(len(requestBody))) /* We can mess with the request headers here */ // r2.Header.Add("Something", "Some Value") /* */ if showTargetRequestHeaders { fmt.Printf("Modified Request Headers: %v\n", r2.Header) } if showTargetRequestBody && string(requestBody) != "" { fmt.Printf("Modified Request Body: %s\n", string(requestBody)) } var transport http.Transport resp, err := transport.RoundTrip(r2) if err != nil { log.Print(err) return } if showResponseHeaders { fmt.Printf("Response Headers: %v\n", resp.Header) } responseBody, err := getBodyBuffer(resp) if showResponse { fmt.Printf("Response Body: %s\n", responseBody) } /* We can mess with the final response body (responseBody) here */ //responseBody = swap(responseBody, "north", "south") //responseBody = swap(responseBody, "down", "up") //responseBody = replace(responseBody, "nice", "nasty") //responseBody = replace(responseBody, "cool", "hideous") /* */ dH := w.Header() copyHeader(resp.Header, &dH) /* We can mess with the final response headers here */ // fmt.Printf("Resp-Status: %v\n",resp.Status) dH.Add("Requested-Host", r2.Host) /* */ body, _ := compressBody(responseBody, resp) dH.Set("Content-Length", strconv.Itoa(len(body))) if showFinalResponseHeaders { fmt.Printf("Modified Response Headers: %v\n", resp.Header) } if showFinalResponse { fmt.Printf("Modified Response Body: %s\n", responseBody) } w.WriteHeader(resp.StatusCode) w.Write(body) if useCache && r.Method == "GET" { cacheSet(uri, cacheElement{resp: resp, body: body}) } }
func (ctx *ProxyCtx) wrapTransport(tr *http.Transport) RoundTripper { return RoundTripperFunc(func(req *http.Request, ctx *ProxyCtx) (*http.Response, error) { return tr.RoundTrip(req) }) }
server = httptest.NewServer(handler) transport = &http.Transport{} var err error request, err = http.NewRequest("GET", server.URL+"/some-path", nil) Expect(err).ToNot(HaveOccurred()) }) AfterEach(func() { server.Close() }) JustBeforeEach(func() { response, requestErr = transport.RoundTrip(request) }) Context("when the ErrHandler returns nil", func() { BeforeEach(func() { fakeErrHandler.ServeHTTPReturns(nil) }) It("does nothing with the response writer", func() { Expect(response.StatusCode).To(Equal(http.StatusOK)) }) }) Context("when the ErrHandler returns concourse.ErrUnauthorized", func() { BeforeEach(func() { fakeErrHandler.ServeHTTPReturns(concourse.ErrUnauthorized)
}) Context("when forceHTTPS is true", func() { BeforeEach(func() { args = append(args, "-forceHTTPS=true") }) It("redirects HTTP to HTTPS", func() { session = startMainWithArgs(args...) Eventually(session).Should(gbytes.Say("garagepi started")) req, err := http.NewRequest("GET", fmt.Sprintf("http://localhost:%d/", httpPort), nil) Expect(err).NotTo(HaveOccurred()) transport := http.Transport{} resp, err := transport.RoundTrip(req) Expect(resp.StatusCode).To(Equal(http.StatusFound)) expectedLocation := fmt.Sprintf("localhost:%d", httpsPort) location, err := resp.Location() Expect(err).NotTo(HaveOccurred()) Expect(location.Scheme).To(Equal("https")) Expect(location.Host).To(Equal(expectedLocation)) }) }) }) }) }) })
func (e *periodicExporter) updateSlaves() { log.Debug("discovering slaves...") // This will redirect us to the elected mesos master redirectURL := fmt.Sprintf("%s://%s/master/redirect", e.queryURL.Scheme, e.queryURL.Host) rReq, err := http.NewRequest("GET", redirectURL, nil) if err != nil { panic(err) } tr := http.Transport{ DisableKeepAlives: true, } rresp, err := tr.RoundTrip(rReq) if err != nil { log.Warn(err) return } defer rresp.Body.Close() // This will/should return http://master.ip:5050 masterLoc := rresp.Header.Get("Location") if masterLoc == "" { log.Warnf("%d response missing Location header", rresp.StatusCode) return } log.Debugf("current elected master at: %s", masterLoc) // Starting from 0.23.0, a Mesos Master does not set the scheme in the "Location" header. // Use the scheme from the master URL in this case. var stateURL string if strings.HasPrefix(masterLoc, "http") { stateURL = fmt.Sprintf("%s/master/state.json", masterLoc) } else { stateURL = fmt.Sprintf("%s:%s/master/state.json", e.queryURL.Scheme, masterLoc) } var state masterState // Find all active slaves err = getJSON(&state, stateURL) if err != nil { log.Warn(err) return } var slaveURLs []string for _, slave := range state.Slaves { if slave.Active { // Extract slave port from pid _, port, err := net.SplitHostPort(slave.PID) if err != nil { port = "5051" } url := fmt.Sprintf("http://%s:%s", slave.Hostname, port) slaveURLs = append(slaveURLs, url) } } log.Debugf("%d slaves discovered", len(slaveURLs)) e.slaves.Lock() e.slaves.urls = slaveURLs e.slaves.Unlock() }
func (ci *ConnectionInfo) forwardHandler(respWriter http.ResponseWriter, req *http.Request) error { //Get local host/port if not already determined if ci.LocalHost == "" { ci.LocalHost = strings.Split(req.Host, ":")[0] } //Update the request object req.Host = ci.swapHost(req.Host, false) req.URL.Host = req.Host req.URL.Scheme = ci.RemoteProtocol req.RequestURI = "" //go requires that this be empty req.RemoteAddr = "" //go likes filling this one in itself //Save the origin var origOrigin string hasOrigOrigin := false if tempVal, tempOK := req.Header["Origin"]; tempOK && len(tempVal) > 0 { origOrigin = tempVal[0] hasOrigOrigin = true } //---Update the headers--- //Swap hosts in the request headers for k, v := range req.Header { req.Header[k] = ci.swapHostArr(v, false) //TODO: Do cookies need to be treated separately hear? } //Update the allowed encodings if req.Header["Accept-Encoding"] != nil && len(req.Header["Accept-Encoding"]) > 0 { possibleEncodings := strings.Split(req.Header["Accept-Encoding"][0], ",") finalEncodings := make([]string, 0, len(possibleEncodings)) for _, v := range possibleEncodings { v = strings.TrimSpace(v) if strings.EqualFold(v, "gzip") || strings.EqualFold(v, "deflate") { finalEncodings = append(finalEncodings, v) } } req.Header["Accept-Encoding"][0] = strings.Join(finalEncodings, ", ") } ModifyForwarderRequest(ci, req) //Custom callback //TODO: Should the request itself be host-swapped? //Send the request transport := http.Transport{} //Had to use a transport instead of http.Client so that Location header requests would come through instead of being followed resp, err := transport.RoundTrip(req) if err != nil { return err } //Save the access control origin var origAccessControlOrigin string hasOrigAccessControlOrigin := false if tempVal, tempOK := resp.Header["Access-Control-Allow-Origin"]; tempOK && len(tempVal) > 0 { origAccessControlOrigin = tempVal[0] hasOrigAccessControlOrigin = true } //Copy the host-swapped updated return headers //TODO: I am not sure if this is safe right now. Some headers might need to be ignored. headers := respWriter.Header() for k, v := range resp.Header { if k != "Set-Cookie" { //Handle cookies separately, since they are encoded headers[k] = ci.swapHostArr(v, true) } } //Set the access control allow origin newOriginFound := true newAccessControlOrigin := func() string { //Test all the origin types until one succeeds for _, originType := range ci.AccessOrigin { switch originType { case originTypes.Original: if hasOrigAccessControlOrigin { return origAccessControlOrigin } case originTypes.OriginalSwapped: if hasOrigAccessControlOrigin { return headers["Access-Control-Allow-Origin"][0] } case originTypes.LocalHost: return ci.swapHost(ci.RemoteHost, true) case originTypes.RemoteHost: return ci.swapHost(ci.LocalHost, false) case originTypes.RequestOrigin: if hasOrigOrigin { return origOrigin } case originTypes.AcceptAll: return "*" case originTypes.Custom: return ci.CustomAccessOrigin default: panic("Should not get here") } } //If no origin was found newOriginFound = false return "" }() if !newOriginFound && hasOrigAccessControlOrigin { delete(headers, "Access-Control-Allow-Origin") } else if newOriginFound { headers["Access-Control-Allow-Origin"] = []string{newAccessControlOrigin} } //Copy the host-swapped returned cookies for _, c := range resp.Cookies() { unescaped, err := url.QueryUnescape(c.Value) if err == nil { c.Value = url.QueryEscape(ci.swapHost(unescaped, true)) //TODO: More might need to be swapped here, like the Cookie.Domain } http.SetCookie(respWriter, c) } //Get the response content retContent, _ := ioutil.ReadAll(resp.Body) resp.Body.Close() //Host-swap the response (only for text types) recompressType := "" if FirstStringStartsWith(resp.Header["Content-Type"], "text/", true) { //If compressed, decompress var err error if FirstStringStartsWith(resp.Header["Content-Encoding"], "gzip", false) { retContent, recompressType, err = decompress(retContent, "gzip") } else if FirstStringStartsWith(resp.Header["Content-Encoding"], "deflate", false) { retContent, recompressType, err = decompress(retContent, "deflate") } if err != nil { return err } //Do the swap retContent = []byte(ci.swapHost(string(retContent), true)) } retContent = ModifyForwarderReply(ci, respWriter, retContent, req) //Custom callback //Recompress if required if recompressType != "" { var b bytes.Buffer var writer io.WriteCloser if recompressType == "gzip" { writer = gzip.NewWriter(&b) } else { writer = zlib.NewWriter(&b) } writer.Write(retContent) writer.Close() retContent = b.Bytes() } //Update the content length and write the updated headers headers["Content-Length"] = []string{strconv.Itoa(len(retContent))} respWriter.WriteHeader(resp.StatusCode) //Write the status code //Write the content back out respWriter.Write(retContent) return nil }