Пример #1
0
// Round trips the request to the selected proxy and writes back the response
func (p *Handler) proxyRequest(w http.ResponseWriter, r *http.Request) error {
	// Lookup the Proxy registered for the given pair: method, path.
	proxy, params, _ := p.GetRouter().Lookup(r.Method, r.URL.Path)
	if len(params) > 0 {
		// fmt.Printf("params: %+v \n", params)
		r.URL.RawQuery = url.Values(params).Encode() + "&" + r.URL.RawQuery
	}
	if proxy == nil {
		p.logger.Warn("Handler failed to route: %s ", r.URL.Path)
		return errors.FromStatus(http.StatusBadGateway)
	}

	// Create a unique request with sequential ids that will be passed to all interfaces.
	fctx := context.NewFlowContext(r, w, atomic.AddInt64(&p.lastRequestId, 1), nil)

	// The roundtrip thru the whole pipeline of modules
	response, err := proxy.ProcessChain(fctx)

	// Preparing the response back to the client if applicable
	if response != nil {
		httputils.CopyHeaders(w.Header(), response.Header)
		w.WriteHeader(response.StatusCode)
		if response.Body == nil {
			logutils.FileLogger.Warn("Empty body contained on the response")
		} else {
			io.Copy(w, response.Body)
			defer response.Body.Close()
		}
		return nil
	} else {
		return err
	}
}
Пример #2
0
// Adds all the headers and change the  url to point to the endpoint.
func copyRequest(req *http.Request, body httputils.MultiReader, endpointURL *url.URL) *http.Request {
	outReq := new(http.Request)
	*outReq = *req // includes shallow copies of maps, but we handle this below

	// Set the body to the enhanced body that can be re-read multiple times and buffered to disk
	outReq.Body = body

	outReq.URL.Scheme = endpointURL.Scheme
	outReq.URL.Host = endpointURL.Host
	outReq.URL.Opaque = req.RequestURI
	// raw query is already included in RequestURI, so ignore it to avoid dupes
	outReq.URL.RawQuery = ""

	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)
	httputils.CopyHeaders(outReq.Header, req.Header)
	return outReq
}