示例#1
0
func serveProgressHtml(backend backend, w http.ResponseWriter, req *http.Request) bool {
	// Only do this for modern browsers.
	useragent := req.Header.Get("User-Agent")
	if !strings.Contains(useragent, "Mozilla") || isWebsocket(req) {
		return false
	}

	// TODO: Not for images and those kind of stuff?

	// Only show when we're provisioning
	if backend.IsReady() {
		return false
	}

	info := backend.GetInfo()
	// Okey, we're the ones sending the data.
	w.Header().Add("Cache-Control", "no-cache, no-store, must-revalidate")
	w.Header().Add("Pragma", "no-cache")
	w.Header().Add("Expires", "0")

	// Serve custom progress file?
	if info.ProgressPage != nil && info.ProgressPage.Filename != "" {
		http.ServeFile(w, req, info.ProgressPage.Filename)
	} else if info.ProgressPage != nil && info.ProgressPage.Url != "" {
		director := func(req *http.Request) {
			req.URL, _ = url.Parse(info.ProgressPage.Url)
			req.Host = req.URL.Host
			if info.ProgressPage.Hostname != "" {
				req.Host = info.ProgressPage.Hostname
			}
		}
		proxy := &httputil.ReverseProxy{Director: director}
		proxy.ServeHTTP(w, req)
	} else {
		templateVars := make(map[string]string)
		templateVars["BackgroundColor"] = "#41964B"

		if info.ProgressPage != nil && info.ProgressPage.Style != nil {
			if info.ProgressPage.Style.BackgroundColor != "" {
				templateVars["BackgroundColor"] = info.ProgressPage.Style.BackgroundColor
			}
		}

		tmpl, err := template.New("test").Parse(contents)
		if err != nil {
			log.Panicf("Failed to parse template: %v", err)
		}

		err = tmpl.Execute(w, templateVars)
		if err != nil {
			io.WriteString(w, "Failed to render template")
		}
	}
	return true
}
示例#2
0
文件: utils.go 项目: shtlee/qa
// use specified ip and host
func DoHttpGetEx(host, ip, url string) (b *bytes.Buffer, err error) {
	var (
		req  *http.Request
		resp *http.Response
	)
	lastIdx := strings.LastIndex(ip, ":")
	if lastIdx == strings.Index(ip, ":") {
		lastIdx = len(ip)
	}

	ip2 := string([]byte(ip[7:lastIdx]))
	url2 := replaceHostWithIP(url, host, ip2)
	if req, err = http.NewRequest("GET", url2, nil); err != nil {
		return
	}
	req.Host = host
	if resp, err = http.DefaultClient.Do(req); err != nil {
		return
	}

	defer resp.Body.Close()
	b = new(bytes.Buffer)
	io.Copy(b, resp.Body)
	return
}
示例#3
0
// do an HTTP request to a server and returns the response object and the
// complete response body. There's no need to close the response body as this
// will have been done.
func do(method, req_body, host, ua, uri string, extraHeaders map[string]string) (*http.Response, []byte, error) {
	var err error
	var req *http.Request
	if strings.EqualFold("POST", method) || strings.EqualFold("PUT", method) {
		req, err = http.NewRequest(method, uri, strings.NewReader(req_body))
	} else {
		req, err = http.NewRequest(method, uri, nil)
	}

	if err != nil {
		return nil, nil, err
	}
	if host != "" {
		req.Host = host
	}
	if ua != "" {
		req.Header["User-Agent"] = []string{ua}
	}
	for k, v := range extraHeaders {
		req.Header.Add(k, v)
	}

	resp, err := transport.RoundTrip(req)
	if resp != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		return resp, nil, err
	}

	body, err := ioutil.ReadAll(resp.Body)
	return resp, body, err
}
func forwardRequest(r *http.Request, ip string, destport int, client http.Client, requesturl string, responseChannel chan int, wg *sync.WaitGroup) {
	defer wg.Done()
	r.Host = ip
	r.RequestURI = ""

	newURL, err := url.Parse(fmt.Sprintf("http://%v:%d%v", ip, destport, requesturl))
	if err != nil {
		log.Printf("Error parsing URL: %s\n", err)
		if *debug {
			log.Printf("For URL: %s\n", fmt.Sprintf("http://%v:%d%v", ip, destport, requesturl))
		}
		responseChannel <- 500
		return
	}
	r.URL = newURL
	response, err := client.Do(r)
	if err != nil {
		log.Printf("Error sending request: %s\n", err)
		if *debug {
			log.Printf("For URL: %s\n", r.URL)
		}
		responseChannel <- 500
		return
	}
	io.Copy(ioutil.Discard, response.Body)
	defer response.Body.Close()
	return
}
示例#5
0
文件: fwd.go 项目: narma/oxy
func (f *Forwarder) copyRequest(req *http.Request, u *url.URL) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	outReq.URL = utils.CopyURL(req.URL)
	outReq.URL.Scheme = u.Scheme
	outReq.URL.Host = u.Host
	// workaround for https://github.com/golang/go/issues/10433
	outReq.URL.Opaque = mergeStartingSlashes(req.RequestURI)
	// raw query is already included in RequestURI, so ignore it to avoid dupes
	outReq.URL.RawQuery = ""
	// Do not pass client Host header unless optsetter PassHostHeader is set.
	if f.passHost != true {
		outReq.Host = u.Host
	}
	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1

	// Overwrite close flag so we can keep persistent connection for the backend servers
	outReq.Close = false

	outReq.Header = make(http.Header)
	utils.CopyHeaders(outReq.Header, req.Header)

	if f.rewriter != nil {
		f.rewriter.Rewrite(outReq)
	}
	return outReq
}
示例#6
0
// NewFastHTTPHandler wraps net/http handler to fasthttp request handler,
// so it can be passed to fasthttp server.
//
// While this function may be used for easy switching from net/http to fasthttp,
// it has the following drawbacks comparing to using manually written fasthttp
// request handler:
//
//     * A lot of useful functionality provided by fasthttp is missing
//       from net/http handler.
//     * net/http -> fasthttp handler conversion has some overhead,
//       so the returned handler will be always slower than manually written
//       fasthttp handler.
//
// So it is advisable using this function only for quick net/http -> fasthttp
// switching. Then manually convert net/http handlers to fasthttp handlers
// according to https://github.com/valyala/fasthttp#switching-from-nethttp-to-fasthttp .
func NewFastHTTPHandler(h http.Handler) fasthttp.RequestHandler {
	return func(ctx *fasthttp.RequestCtx) {
		var r http.Request

		body := ctx.PostBody()
		r.Method = string(ctx.Method())
		r.Proto = "HTTP/1.1"
		r.ProtoMajor = 1
		r.ProtoMinor = 1
		r.RequestURI = string(ctx.RequestURI())
		r.ContentLength = int64(len(body))
		r.Host = string(ctx.Host())
		r.RemoteAddr = ctx.RemoteAddr().String()

		hdr := make(http.Header)
		ctx.Request.Header.VisitAll(func(k, v []byte) {
			hdr.Set(string(k), string(v))
		})
		r.Header = hdr
		r.Body = &netHTTPBody{body}

		var w netHTTPResponseWriter
		h.ServeHTTP(&w, &r)

		ctx.SetStatusCode(w.StatusCode())
		for k, vv := range w.Header() {
			for _, v := range vv {
				ctx.Response.Header.Set(k, v)
			}
		}
		ctx.Write(w.body)
	}
}
示例#7
0
文件: server.go 项目: jonaz/devd
// This filthy hack works in conjunction with hostPortStrip to restore the
// original request host after mux match.
func revertOriginalHost(r *http.Request) {
	original := r.Header.Get("_devd_original_host")
	if original != "" {
		r.Host = original
		r.Header.Del("_devd_original_host")
	}
}
示例#8
0
文件: websocket.go 项目: kr/webx
func (p *WebsocketProxy) Proxy(w http.ResponseWriter, r *http.Request) {
	hj, ok := w.(http.Hijacker)
	if !ok {
		log.Println("hijack assertion failed", r.Host, r.URL.Path)
		p.handler.ServeHTTP(w, r) // last-ditch effort as plain http
		return
	}
	conn, rw, err := hj.Hijack()
	if err != nil {
		log.Println("hijack failed", r.Host, r.URL.Path, err)
		p.handler.ServeHTTP(w, r) // last-ditch effort as plain http
		return
	}
	defer conn.Close()
	rw.Flush()

	wrapreq := new(http.Request)
	wrapreq.Proto = "HTTP/1.1"
	wrapreq.ProtoMajor, wrapreq.ProtoMinor = 1, 1
	wrapreq.Method = "WEBSOCKET"
	wrapreq.Host = r.Host
	const dummy = "/"
	wrapreq.URL = &url.URL{Path: dummy}
	var buf bytes.Buffer
	r.Write(&buf)
	wrapreq.Body = ioutil.NopCloser(io.MultiReader(&buf, conn))
	resp, err := p.transport.RoundTrip(wrapreq)
	if err != nil || resp.StatusCode != 200 {
		io.WriteString(conn, "HTTP/1.0 503 Gateway Failed\r\n")
		io.WriteString(conn, "Connection: close\r\n\r\n")
		return
	}
	defer resp.Body.Close()
	io.Copy(conn, resp.Body)
}
示例#9
0
// Sets the Authorization header on the request to use the provided token.
// Will also re-write the host value of the request URL to use the value
// provided in the TokenAuth.
func (a TokenAuth) ApplyAuthentication(r *http.Request) {
	token := fmt.Sprintf("Token %s", a.Token)
	r.Header.Add("Authorization", token)

	r.URL.Host = a.Host
	r.Host = a.Host
}
示例#10
0
文件: lbutils.go 项目: xtracdev/xavi
func (lb *BackendLoadBalancer) DoWithLoadBalancer(req *http.Request, useTLS bool) (*http.Response, error) {
	connectString, err := lb.LoadBalancer.GetConnectAddress()
	if err != nil {
		return nil, err
	}

	log.Debug("connect string is ", connectString)
	req.URL.Host = connectString
	req.Host = connectString

	var transport *http.Transport
	if useTLS == true {
		log.Debug("Configuring TLS transport")
		transport = lb.httpsTransport
		req.URL.Scheme = "https"
	} else {
		log.Debug("Configuring non-TLS transport")
		transport = lb.httpTransport
		req.URL.Scheme = "http"
	}

	client := &http.Client{
		Transport: transport,
	}

	req.RequestURI = "" //Must clear when using http.Client
	return ctxhttp.Do(req.Context(), client, req)
}
示例#11
0
文件: server.go 项目: csarven/gold
// ServeHTTP handles the response
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	if ProxyPath != "" && strings.HasPrefix(req.URL.Path, "/"+ProxyPath) {
		uri, err := url.Parse(req.FormValue("uri"))
		if err != nil {
			s.debug.Println(req.RequestURI, err.Error())
		}
		req.URL = uri
		req.Host = uri.Host
		req.RequestURI = uri.RequestURI()
		proxy.ServeHTTP(w, req)
		return
	}
	if websocketUpgrade(req) {
		websocketServe(w, req)
		return
	}

	defer func() {
		req.Body.Close()
	}()
	r := s.handle(w, &httpRequest{req, s})
	for key := range r.headers {
		w.Header().Set(key, r.headers.Get(key))
	}
	if r.status > 0 {
		w.WriteHeader(r.status)
	}
	if len(r.argv) > 0 {
		fmt.Fprint(w, r.argv...)
	}
}
示例#12
0
文件: fwd.go 项目: pasdoy/oxy
func (f *Forwarder) copyRequest(req *http.Request, u *url.URL) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	outReq.URL = utils.CopyURL(req.URL)
	outReq.URL.Scheme = u.Scheme
	outReq.URL.Host = u.Host
	outReq.URL.Opaque = req.RequestURI
	// raw query is already included in RequestURI, so ignore it to avoid dupes
	outReq.URL.RawQuery = ""
	// Go doesn't implicitly pass the host header unless you set Host on the request
	outReq.Host = u.Host

	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1

	// Overwrite close flag so we can keep persistent connection for the backend servers
	outReq.Close = false

	outReq.Header = make(http.Header)
	utils.CopyHeaders(outReq.Header, req.Header)

	if f.rewriter != nil {
		f.rewriter.Rewrite(outReq)
	}
	return outReq
}
示例#13
0
// Director is required by the proxy; it rewrites the URL
// before the proxy operates
func (p S3ReverseProxy) Director(req *http.Request) {
	// we need to rewrite the URL but also S3 insists on having
	// the host and requesturi correct.
	p.RewriteUrl(req.URL)
	req.RequestURI = req.URL.Path
	req.Host = req.URL.Host
}
示例#14
0
文件: proxy.go 项目: secretsauce/soxy
// proxyHTTP will proxy the http.Request r to the new hos
// This does modify r in the process of proxying the request
func (self *Proxy) proxyHTTP(w http.ResponseWriter, r *http.Request) {

	r.Header.Add("X-Forwarded-Host", r.Host)
	r.Header.Add("X-Forwarded-For", r.RemoteAddr)

	r.Host = self.Target
	r.URL.Host = self.Target

	// Reset Request properteis for Client
	r.URL.Scheme = "http"
	r.RequestURI = ""

	resp, err := self.Client.Do(r)
	if err != nil {
		http.Error(w, BAD_GATEWAY, http.StatusBadGateway)
		return
	}

	// Copy response header
	for key, _ := range resp.Header {
		w.Header().Set(key, resp.Header.Get(key))
	}
	w.WriteHeader(resp.StatusCode)

	io.Copy(w, resp.Body)
}
示例#15
0
文件: server.go 项目: jiakuan/livedev
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)
}
示例#16
0
文件: meek.go 项目: manawenuz/obfs4
func (c *meekConn) roundTrip(sndBuf []byte) (recvBuf []byte, err error) {
	var req *http.Request
	var resp *http.Response

	for retries := 0; retries < maxRetries; retries++ {
		url := *c.args.url
		host := url.Host
		if c.args.front != "" {
			url.Host = c.args.front
		}
		req, err = http.NewRequest("POST", url.String(), bytes.NewReader(sndBuf))
		if err != nil {
			return nil, err
		}
		if c.args.front != "" {
			req.Host = host
		}
		req.Header.Set("X-Session-Id", c.sessionID)
		req.Header.Set("User-Agent", "")

		resp, err = c.transport.RoundTrip(req)
		if err != nil {
			return nil, err
		}
		if resp.StatusCode != http.StatusOK {
			err = fmt.Errorf("status code was %d, not %d", resp.StatusCode, http.StatusOK)
			time.Sleep(retryDelay)
		} else {
			defer resp.Body.Close()
			recvBuf, err = ioutil.ReadAll(io.LimitReader(resp.Body, maxPayloadLength))
			return
		}
	}
	return
}
示例#17
0
func (p *proxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	target := p.targets[rand.Intn(p.count)]
	if p.forwardHost {
		r.Host = target.host
	}
	target.handler.ServeHTTP(w, r)
}
示例#18
0
文件: http.go 项目: github/hub
func (t *verboseTransport) RoundTrip(req *http.Request) (resp *http.Response, err error) {
	if t.Verbose {
		t.dumpRequest(req)
	}

	if t.OverrideURL != nil {
		port := "80"
		if s := strings.Split(req.URL.Host, ":"); len(s) > 1 {
			port = s[1]
		}

		req = cloneRequest(req)
		req.Header.Set("X-Original-Scheme", req.URL.Scheme)
		req.Header.Set("X-Original-Port", port)
		req.Host = req.URL.Host
		req.URL.Scheme = t.OverrideURL.Scheme
		req.URL.Host = t.OverrideURL.Host
	}

	resp, err = t.Transport.RoundTrip(req)

	if err == nil && t.Verbose {
		t.dumpResponse(resp)
	}

	return
}
示例#19
0
func handler(w http.ResponseWriter, r *http.Request) {
	//if (r.URL.Path == "/worker.js") {
	//	noOpServiceWorker(w)
	//	return
	//}

	r.Host = ""
	proxy.ServeHTTP(w, r)
}
示例#20
0
func (rs *RouteServiceConfig) SetupRouteServiceRequest(request *http.Request, args RouteServiceArgs) {
	rs.logger.Debug("proxy.route-service")
	request.Header.Set(RouteServiceSignature, args.Signature)
	request.Header.Set(RouteServiceMetadata, args.Metadata)
	request.Header.Set(RouteServiceForwardedUrl, args.ForwardedUrlRaw)

	request.Host = args.ParsedUrl.Host
	request.URL = args.ParsedUrl
}
示例#21
0
func makeRequest(params map[string]string) (*http.Request, error) {
	r := new(http.Request)
	r.Method = params["METHOD"]
	if r.Method == "" {
		return nil, errors.New("mongrel2: no METHOD")
	}

	r.Proto = params["VERSION"]
	var ok bool
	r.ProtoMajor, r.ProtoMinor, ok = http.ParseHTTPVersion(r.Proto)
	if !ok {
		return nil, errors.New("mongrel2: invalid protocol version")
	}

	r.Trailer = http.Header{}
	r.Header = http.Header{}

	r.Host = params["Host"]
	r.Header.Set("Referer", params["Referer"])
	r.Header.Set("User-Agent", params["User-Agent"])

	if lenstr := params["Content-Length"]; lenstr != "" {
		clen, err := strconv.ParseInt(lenstr, 10, 64)
		if err != nil {
			return nil, errors.New("mongrel2: bad Content-Length")
		}
		r.ContentLength = clen
	}

	for k, v := range params {
		if !skipHeader[k] {
			r.Header.Add(k, v)
		}
	}

	// TODO: cookies

	if r.Host != "" {
		url_, err := url.Parse("http://" + r.Host + params["URI"])
		if err != nil {
			return nil, errors.New("mongrel2: failed to parse host and URI into a URL")
		}
		r.URL = url_
	}
	if r.URL == nil {
		url_, err := url.Parse(params["URI"])
		if err != nil {
			return nil, errors.New("mongrel2: failed to parse URI into a URL")
		}
		r.URL = url_
	}

	// TODO: how do we know if we're using HTTPS?
	// TODO: fill in r.RemoteAddr

	return r, nil
}
示例#22
0
func resolveHeaders(req *http.Request, headers headers) {
	for name, value := range headers {
		req.Header.Set(name, value)
	}

	if host, ok := headers["Host"]; ok {
		req.Host = host
	}
}
示例#23
0
func (h *reverseProxyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	if ip := r.Header.Get("X-Real-Ip"); len(ip) > 0 {
		r.RemoteAddr = ip
	}
	if host := r.Header.Get("X-Forwarded-Host"); len(host) > 0 {
		r.Host = host
	}
	h.inner.ServeHTTP(w, r)
}
示例#24
0
func (p proxy) ServeHTTP(res http.ResponseWriter, r *http.Request) {
	bo := backoff.NewExponentialBackOff()
	bo.MaxElapsedTime = 5 * time.Second
	if err := backoff.Retry(func() error {
		r.URL.Host = base.Host
		r.URL.Scheme = base.Scheme
		r.RequestURI = ""
		r.Host = base.Host

		suppliedToken := r.URL.Query().Get("token")
		if authCookie, err := r.Cookie("grafana-proxy-auth"); err == nil {
			suppliedToken = authCookie.Value
		}

		if cfg.Token != "" && suppliedToken != cfg.Token {
			http.Error(res, "Please add the `?token=xyz` parameter with correct token", http.StatusForbidden)
			return nil
		}

		resp, err := client.Do(r)
		if err != nil {
			return err
		}

		defer resp.Body.Close()

		res.Header().Del("Content-Type")
		for k, v := range resp.Header {
			for _, v1 := range v {
				res.Header().Add(k, v1)
			}
		}

		if r.URL.Query().Get("token") != "" {
			http.SetCookie(res, &http.Cookie{
				Name:   "grafana-proxy-auth",
				Value:  r.URL.Query().Get("token"),
				MaxAge: 31536000, // 1 Year
				Path:   "/",
			})
		}

		if resp.StatusCode == 401 {
			loadLogin()
			return fmt.Errorf("Need to relogin")
		}

		res.WriteHeader(resp.StatusCode)
		written, _ := io.Copy(res, resp.Body)

		log.Printf("%s %s?%s %d %d\n", r.Method, r.URL.Path, r.URL.RawQuery, resp.StatusCode, written)
		return nil
	}, bo); err != nil {
		http.Error(res, fmt.Sprintf("Woot?\n%s", err), http.StatusInternalServerError)
	}
}
示例#25
0
func (h protoHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
	r.Header.Set(xForwardedProto, h.proto)
	// TODO(jmhodges): gross hack in order to get ServeMux to match ports
	// See https://golang.org/issue/10463
	host, _, err := net.SplitHostPort(r.Host)
	if err == nil {
		r.Host = host
	}
	h.inner.ServeHTTP(w, r)
}
示例#26
0
文件: main.go 项目: opennota/nbgate
func reverseProxy(w http.ResponseWriter, req *http.Request) {
	logRequest(req)

	if rSensitivePath.MatchString(req.URL.Path) {
		w.WriteHeader(http.StatusForbidden)
		return
	}

	outReq := new(http.Request)
	outReq.Method = req.Method
	outReq.URL = &url.URL{
		Scheme:   "http",
		Host:     host,
		Path:     req.URL.Path,
		RawQuery: req.URL.RawQuery,
	}
	outReq.Proto = "HTTP/1.1"
	outReq.ProtoMajor = 1
	outReq.ProtoMinor = 1
	outReq.Header = make(http.Header)
	outReq.Body = req.Body
	outReq.ContentLength = req.ContentLength
	outReq.Host = host

	for _, h := range removeHeaders {
		req.Header.Del(h)
	}
	copyHeader(outReq.Header, req.Header)
	outReq.Header.Set("Host", host)
	outReq.Header.Set("Referer", baseURL)
	outReq.Header.Set("Origin", baseURL)

	resp, err := send(outReq)
	if err != nil {
		log.Printf("proxy error: %v", err)
		w.WriteHeader(http.StatusInternalServerError)
		return
	}
	defer resp.Body.Close()

	for _, h := range removeHeaders {
		resp.Header.Del(h)
	}
	if loc := resp.Header.Get("Location"); loc != "" {
		if u, err := url.Parse(loc); err == nil && u.Host == host {
			u.Scheme = "http"
			u.Host = req.Host
			resp.Header.Set("Location", u.String())
		}
	}
	copyHeader(w.Header(), resp.Header)
	w.WriteHeader(resp.StatusCode)

	io.Copy(w, resp.Body)
}
示例#27
0
func (self *HttpServer) request(w http.ResponseWriter, r *http.Request) {
	whitelisthosts := self.vip.GetStringSlice("whitelisthosts")
	if self.MatchHost(whitelisthosts, r.Host) == false {
		w.WriteHeader(http.StatusForbidden)
		w.Write([]byte("sorry '" + r.Host + "' is not in whitelist"))
		return
	}
	upstreams := self.vip.GetStringMapString("httpservers.hs1.upstreams")
	upstream, ok := upstreams[r.Host]
	if ok == false {
		w.WriteHeader(http.StatusForbidden)
		w.Write([]byte("sorry '" + r.Host + "' have not set upstream"))
		return
	}
	r.RequestURI = ""
	dialer := self.dialerpool.Get(upstream)
	if dialer == nil {
		glog.Errorln("get empty from dialer pool ")
		return
	}
	transport := &http.Transport{
		Proxy:               nil,
		Dial:                dialer.Dial,
		TLSHandshakeTimeout: 10 * time.Second,
	}

	client := &http.Client{Transport: transport}
	client.CheckRedirect = func(req *http.Request, via []*http.Request) error {
		return utils.ErrHttpRedirect
	}
	if r.URL.Scheme == "" {
		r.URL.Scheme = "http"
	}
	r.Host = upstream
	r.URL.Host = r.Host
	resp, err := client.Do(r)
	if err != nil && resp == nil {
		http.Error(w, "Error contacting backend server.", 500)
		glog.Errorf("Error connect backend %s: %v", r.RequestURI, err)
		return
	}
	defer resp.Body.Close()

	for k, v := range resp.Header {
		for _, vv := range v {
			w.Header().Add(k, vv)
		}
	}

	w.WriteHeader(resp.StatusCode)
	_, err = io.Copy(w, resp.Body)
	if err != nil {
		glog.V(0).Infoln("io copy error ", err)
	}
}
示例#28
0
func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, reader io.Reader, writer io.Writer) error {
	if len(request.URL.Host) <= 0 {
		response := generateResponse(400, "Bad Request")
		return response.Write(writer)
	}

	request.Host = request.URL.Host
	StripHopByHopHeaders(request)

	ray := s.packetDispatcher.DispatchToOutbound(ctx)
	input := ray.InboundInput()
	output := ray.InboundOutput()

	requestDone := signal.ExecuteAsync(func() error {
		defer input.Close()

		requestWriter := bufio.NewWriter(buf.NewBytesWriter(ray.InboundInput()))
		err := request.Write(requestWriter)
		if err != nil {
			return err
		}
		if err := requestWriter.Flush(); err != nil {
			return err
		}
		return nil
	})

	responseDone := signal.ExecuteAsync(func() error {
		responseReader := bufio.OriginalReader(buf.NewBytesReader(ray.InboundOutput()))
		response, err := http.ReadResponse(responseReader, request)
		if err != nil {
			log.Warning("HTTP: Failed to read response: ", err)
			response = generateResponse(503, "Service Unavailable")
		}
		responseWriter := bufio.NewWriter(writer)
		if err := response.Write(responseWriter); err != nil {
			return err
		}

		if err := responseWriter.Flush(); err != nil {
			return err
		}
		return nil
	})

	if err := signal.ErrorOrFinish2(requestDone, responseDone); err != nil {
		log.Info("HTTP|Server: Connecton ending with ", err)
		input.CloseError()
		output.CloseError()
		return err
	}

	return nil
}
示例#29
0
// ModifyRequest sets the header at name with value on the request.
func (m *modifier) ModifyRequest(_ *martian.Context, req *http.Request) error {
	// Host is treated differently by the http package and the header is
	// explicitly ignored.
	if m.name == "Host" {
		req.Host = m.value
	} else {
		req.Header.Set(m.name, m.value)
	}

	return nil
}
示例#30
0
// RequestHeader returns a new set of headers from a request.
func RequestHeader(req *http.Request) *Header {
	return &Header{
		h:       req.Header,
		host:    func() string { return req.Host },
		cl:      func() int64 { return req.ContentLength },
		te:      func() []string { return req.TransferEncoding },
		setHost: func(host string) { req.Host = host },
		setCL:   func(cl int64) { req.ContentLength = cl },
		setTE:   func(te []string) { req.TransferEncoding = te },
	}
}