Beispiel #1
0
func TestThreadList(t *testing.T) {
	ctl := gomock.NewController(t)
	defer ctl.Finish()

	threadServiceMock := service.NewMockThread(ctl)
	threadServiceMock.
		EXPECT().
		FindThreads(dao.Paging{Limit: 5, Offset: 0, OrderBy: "updated_at desc"}).
		Return(model.ThreadSlice{}, nil).
		Times(1)
	threadHandler := NewThread(threadServiceMock)

	ctx := context.Background()
	{
		r := http.Request{}
		url, err := url.Parse("http://localhost?limit=a&offset=0")
		if err != nil {
			t.Fatal(err)
		}
		r.URL = url
		res := threadHandler.List(ctx, &r)
		assert.Equal(t, response.BadRequest, res, "")
	}

	{
		r := http.Request{}
		url, err := url.Parse("http://localhost?limit=5&offset=0")
		if err != nil {
			t.Fatal(err)
		}
		r.URL = url
		threadHandler.List(ctx, &r)
	}
}
Beispiel #2
0
func (c *Config) MapRequest(r *http.Request) {
	if mapped, err := c.MapURL(r.URL); err != nil {
		r.URL = &url.URL{Host: r.Host, Path: "/404", Scheme: "http"}
	} else {
		r.URL = &mapped
	}
}
Beispiel #3
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
}
Beispiel #4
0
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)
}
Beispiel #5
0
func TestGetFormatForRequest(t *testing.T) {

	var request *http.Request

	request = new(http.Request)
	request.URL, _ = url.Parse(testDomain + "/people/123/groups/456.json")
	if getFormatForRequest(request) != JSON_FORMAT {
		t.Errorf("getFormatForRequest should be 'JSON' not '%s'", getFormatForRequest(request))
	}

	request.URL, _ = url.Parse(testDomain + "/people/123/groups/456.xml")
	if getFormatForRequest(request) != XML_FORMAT {
		t.Errorf("getFormatForRequest should be 'XML' not '%s'", getFormatForRequest(request))
	}

	request.URL, _ = url.Parse(testDomain + "/people/123/groups/456")
	if getFormatForRequest(request) != DEFAULT_FORMAT {
		t.Errorf("getFormatForRequest should be '%s' not '%s'", DEFAULT_FORMAT, getFormatForRequest(request))
	}

	request.URL, _ = url.Parse(testDomain + "/people/123/groups/456.html")
	if getFormatForRequest(request) != HTML_FORMAT {
		t.Errorf("getFormatForRequest should be '%s' not '%s'", HTML_FORMAT, getFormatForRequest(request))
	}
	request.URL, _ = url.Parse(testDomain + "/people/123/groups/456.htm")
	if getFormatForRequest(request) != HTML_FORMAT {
		t.Errorf("getFormatForRequest should be '%s' not '%s'", HTML_FORMAT, getFormatForRequest(request))
	}

	request.URL = nil
	if getFormatForRequest(request) != DEFAULT_FORMAT {
		t.Errorf("getFormatForRequest should be 'JSON' not '%s'", getFormatForRequest(request))
	}

}
Beispiel #6
0
func (r Client) Do(l Logger, req *http.Request) (resp *http.Response, err error) {
	//check bind remote ip
	if r.BindRemoteIp != "" {
		oldReqUrl := req.URL.String()
		oldReqUri, _ := url.Parse(oldReqUrl)

		newUrlStr := fmt.Sprintf("%s://%s%s", oldReqUri.Scheme, r.BindRemoteIp, oldReqUri.RequestURI())
		newUrl, _ := url.Parse(newUrlStr)

		req.URL = newUrl
		req.Header.Set("Host", oldReqUri.Host)
	}

	if l != nil {
		req.Header.Set("X-Reqid", l.ReqId())
	}

	req.Header.Set("User-Agent", UserAgent)
	resp, err = r.Client.Do(req)
	if err != nil {
		return
	}

	if l != nil {
		details := resp.Header["X-Log"]
		if len(details) > 0 {
			l.Xput(details)
		}
	}
	return
}
// ProcessRequest will run any checks on the request on the way through the system, return an error to have the chain fail
func (m *URLRewriteMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Request, configuration interface{}) (error, int) {
	_, versionPaths, _, _ := m.TykMiddleware.Spec.GetVersionData(r)
	found, meta := m.TykMiddleware.Spec.CheckSpecMatchesStatus(r.URL.Path, r.Method, versionPaths, URLRewrite)
	if found {
		log.Debug("Rewriter active")
		thisMeta := meta.(*tykcommon.URLRewriteMeta)
		log.Debug(r.URL)
		oldPath := r.URL.String()
		p, pErr := m.Rewriter.Rewrite(thisMeta, r.URL.String(), true, r)
		if pErr != nil {
			return pErr, 500
		}

		m.CheckHostRewrite(oldPath, p, r)

		newURL, uErr := url.Parse(p)
		if uErr != nil {
			log.Error("URL Rewrite failed, could not parse: ", p)
		} else {
			r.URL = newURL
		}

	}
	return nil, 200
}
Beispiel #8
0
func send(url *url.URL, addr string) result {
	var req http.Request
	req.URL = url

	now := time.Now()
	conn, err := net.Dial("tcp", addr)
	if err != nil {
		return result{0, err}
	}
	defer conn.Close()

	err = req.Write(conn)
	if err != nil {
		return result{0, err}
	}

	ch := make(chan respErr, 1)
	go func() {
		reader := bufio.NewReader(conn)
		response, err := http.ReadResponse(reader, &req)
		ch <- respErr{response, err}
	}()

	var res result

	select {
	case <-time.After(time.Duration(*timeout * 1e6)):
		res = result{time.Now().Sub(now), errors.New("Timeout!")}
	case rerr := <-ch:
		res = result{time.Now().Sub(now), rerr.err}
		rerr.resp.Body.Close()
	}

	return res
}
Beispiel #9
0
func (e Post) Target(r *http.Request) {
	r.Body = ioutil.NopCloser(bytes.NewBuffer(e.Body))
	r.ContentLength = int64(len(e.Body))
	r.Header.Set("Content-Type", e.ContentType)
	r.Method = "POST"
	r.URL = e.URL
}
Beispiel #10
0
func (rrlb *RoundRobinLoadBalancer) ServeHTTP(response http.ResponseWriter, request *http.Request) {
	_, endpoint, _ := rrlb.NextEndpoint()

	fmt.Println("Next Endpoint => " + net.JoinHostPort(endpoint.host.String(), endpoint.port))

	request.Header.Add("X-FORWARDED-FOR", request.RemoteAddr)
	request.Header.Add("Server", "Go Load Balancer")
	fmt.Println(request.Proto)
	client := &http.Client{}

	newRequest := new(http.Request)
	*newRequest = *request

	fmt.Println("Request URI => " + request.RequestURI)

	uri, _ := url.ParseRequestURI(request.RequestURI)

	if len(uri.Scheme) == 0 {
		uri.Scheme = "http"
	}

	newRequest.URL = uri

	newRequest.URL.Host = net.JoinHostPort(endpoint.host.String(), endpoint.port)
	newRequest.URL.User = request.URL.User

	newRequest.RequestURI = ""

	clientResponse, _ := client.Do(newRequest)

	clientResponse.Write(response)
}
Beispiel #11
0
func (st *supervisorTransport) RoundTrip(req *http.Request) (*http.Response, error) {
	if req.URL == nil {
		return nil, errors.New("unix: nil Request.URL")
	}

	if req.Header == nil {
		return nil, errors.New("unix: nil Request.Header")
	}

	if req.URL.Scheme != "unix" {
		panic("unix: unsupported protocol scheme")
	}

	sock, err := net.Dial("unix", req.URL.Path)
	if err != nil {
		return nil, err
	}
	defer sock.Close()

	//create shallow copy of request object
	newReq := new(http.Request)
	*newReq = *req

	newReq.URL = supervisorURL
	newReq.Write(sock)

	return http.ReadResponse(bufio.NewReader(sock), req)
}
Beispiel #12
0
// 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...)
	}
}
Beispiel #13
0
// ApplyTo sets the requests Method to PUT, URL and Body
func (p Put) ApplyTo(req *http.Request) {
	req.Method = "PUT"
	req.URL = p.URL
	req.Body = ioutil.NopCloser(bytes.NewBuffer(p.Body))
	req.ContentLength = int64(len(p.Body))
	req.Header.Set("Content-Type", p.ContentType)
}
Beispiel #14
0
func createRequest() *http.Request {
	r := new(http.Request)
	url := new(url.URL)
	url.Path = "/station/9530"
	r.URL = url
	return r
}
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
}
Beispiel #16
0
Datei: fwd.go Projekt: 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
}
Beispiel #17
0
// Do sends the given request and unmarshals its JSON
// result into resp, which should be a pointer to the response value.
// If an error status is returned, the error will be unmarshaled
// as in Client.Call. The req.Body field must be nil - any request
// body should be provided in the body parameter.
//
// If resp is nil, the response will be ignored if the response was
// successful.
//
// Any error that c.UnmarshalError or c.Doer returns will not
// have its cause masked.
//
// The request URL field is changed to the actual URL used.
func (c *Client) Do(req *http.Request, body io.ReadSeeker, resp interface{}) error {
	reqURL, err := appendURL(c.BaseURL, req.URL.String())
	if err != nil {
		return errgo.Mask(err)
	}
	req.URL = reqURL
	if req.Body != nil {
		return errgo.Newf("%s %s: request body supplied unexpectedly", req.Method, req.URL)
	}
	inferContentLength(req, body)
	doer := c.Doer
	if doer == nil {
		doer = http.DefaultClient
	}
	var httpResp *http.Response
	// Use DoWithBody when it's available and body is not nil.
	doer1, ok := doer.(DoerWithBody)
	if ok && body != nil {
		httpResp, err = doer1.DoWithBody(req, body)
	} else {
		if body != nil {
			req.Body = ioutil.NopCloser(body)
		}
		httpResp, err = doer.Do(req)
	}
	if err != nil {
		return errgo.NoteMask(err, fmt.Sprintf("%s %s", req.Method, req.URL), errgo.Any)
	}
	return c.unmarshalResponse(httpResp, resp)
}
Beispiel #18
0
Datei: fwd.go Projekt: 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
}
Beispiel #19
0
func getResponse(rawUrl string, req *http.Request) (*httputil.ClientConn, *http.Response, error) {
	url, err := url.Parse(rawUrl)
	if url.Scheme == "" {
		rawUrl = "http://" + rawUrl
		url, err = url.Parse(rawUrl)
	}

	if err != nil {
		return nil, nil, err
	}
	req.URL = url
	if debugprint {
		dump, err := httputil.DumpRequest(req, true)
		if err != nil {
			println(err.Error())
		}
		print(string(dump))
	}

	conn, err := newConn(url)
	if err != nil {
		println(err.Error())
		return nil, nil, err
	}

	resp, err := conn.Do(req)
	if err != nil {
		if err != httputil.ErrPersistEOF {
			return nil, nil, err
		}
	}
	return conn, resp, nil
}
Beispiel #20
0
/**
* @brief 重设Request,
*
* @param http.Request
* @param
* @param error
*
* @return
 */
func ResetRequest(request *http.Request, hostAddress string) (*http.Request, error) {
	newUrl, err := url.Parse(hostAddress + request.RequestURI)
	// 清除RequestURI
	request.RequestURI = ""
	// 重新设置地址
	request.URL = newUrl
	return request, err
}
Beispiel #21
0
func nsansDotEu(r *http.Request) {
	server, err := url.Parse("http://localhost:9000" + r.RequestURI)
	if err != nil {
		log.Printf("%#v\n", r)
		log.Println("couldn't create nsans.eu url", err)
	}
	r.URL = server
}
Beispiel #22
0
func manveruDotName(r *http.Request) {
	server, err := url.Parse("http://localhost:8000" + r.RequestURI)
	if err != nil {
		log.Printf("%#v\n", r)
		log.Println("couldn't create manveru.name url", err)
	}
	r.URL = server
}
Beispiel #23
0
// MergeRequest merge the request field in scan with the existing one.
func (s *Scan) MergeRequest(req *http.Request) {

	// set cookie from response (if it is not done..)
	if s.Response != nil {
		s.Cookies = append(s.Cookies, s.Response.Cookies()...)
		// s.CookieJar.SetCookies(s.Request.URL, s.Response.Cookies())
	}

	// read the request body, and then reset the reader
	var post []byte
	if req.Body != nil {
		if post, err := ioutil.ReadAll(req.Body); err == nil {
			req.Body = ioutil.NopCloser(bytes.NewReader(post))
		} else {
			// only possible error is bytes.ErrTooLarge from ioutil package.
			s.Error("MergeRequest", err)
		}
	}

	// resolve relative url.
	if !req.URL.IsAbs() {
		req.URL = s.Request.URL.ResolveReference(req.URL)
	}

	// TODO - drop if Method, URL, Body are same..
	if req == s.Request {
		// s.Logf("Result after merge generate same request.", nil)
	}

	// swap
	prevReq := s.Request
	s.Request = req
	s.RequestBody = string(post)

	// TODO - handle relative URL .

	// Create a cookie jar, add cookie list (so cookie jar reject invalid cookie.)
	jar, _ := cookiejar.New(nil)
	jar.SetCookies(req.URL, s.Cookies)

	// reset cookies
	s.Cookies = make([]*http.Cookie, 0)
	for _, c := range jar.Cookies(req.URL) {
		req.AddCookie(c)
		s.Cookies = append(s.Cookies, c)
	}

	// Add user agent
	req.Header.Set("User-Agent", prevReq.UserAgent())

	// Add referrer - TODO, perhaps we don't need this!

	// remove Response.
	s.Response = nil
	s.ResponseBody = ""

}
Beispiel #24
0
func (requester *Requester) Do(request *http.Request) *Response {
	fullUrl, err := url.Parse(requester.httpUrl(request.URL.String()))
	if err != nil {
		panic(err)
	}

	request.URL = fullUrl
	return requester.sendRequest(request)
}
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
}
Beispiel #26
0
func (rw *rewriteHandler) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	oldURL := rawURL(req)

	// only continue if the Regexp param matches the URL
	if !rw.regexp.MatchString(oldURL) {
		rw.next.ServeHTTP(w, req)
		return
	}

	// apply a rewrite regexp to the URL
	newURL := rw.regexp.ReplaceAllString(oldURL, rw.replacement)

	// replace any variables that may be in there
	rewrittenURL := &bytes.Buffer{}
	if err := ApplyString(newURL, rewrittenURL, req); err != nil {
		rw.errHandler.ServeHTTP(w, req, err)
		return
	}

	// parse the rewritten URL and replace request URL with it
	parsedURL, err := url.Parse(rewrittenURL.String())
	if err != nil {
		rw.errHandler.ServeHTTP(w, req, err)
		return
	}

	if rw.redirect && newURL != oldURL {
		(&redirectHandler{u: parsedURL}).ServeHTTP(w, req)
		return
	}

	req.URL = parsedURL

	// make sure the request URI corresponds the rewritten URL
	req.RequestURI = req.URL.RequestURI()

	if !rw.rewriteBody {
		rw.next.ServeHTTP(w, req)
		return
	}

	bw := &bufferWriter{header: make(http.Header), buffer: &bytes.Buffer{}}
	newBody := &bytes.Buffer{}

	rw.next.ServeHTTP(bw, req)

	if err := Apply(bw.buffer, newBody, req); err != nil {
		log.Errorf("Failed to rewrite response body: %v", err)
		return
	}

	utils.CopyHeaders(w.Header(), bw.Header())
	w.Header().Set("Content-Length", strconv.Itoa(newBody.Len()))
	w.WriteHeader(bw.code)
	io.Copy(w, newBody)
}
Beispiel #27
0
func copyRequest(req *http.Request) *http.Request {
	reqCopy := new(http.Request)
	*reqCopy = *req
	reqCopy.URL = copyURL(req.URL)
	reqCopy.Header = make(http.Header, len(req.Header))
	for k, s := range req.Header {
		reqCopy.Header[k] = append([]string(nil), s...)
	}
	return reqCopy
}
Beispiel #28
0
func (p *Proxy) internalHandler(w http.ResponseWriter, r *http.Request) {
	r.RequestURI = r.RequestURI[len(internalPrefix):]
	url, err := url.Parse(r.RequestURI)
	if err != nil {
		http.Error(w, fmt.Sprintf("Invalid URI %s", err), http.StatusBadRequest)
		return
	}
	r.URL = url
	p.machineHandler(w, r)
}
Beispiel #29
0
// hit executes the passed http.Request and puts the result into results.
// Both transport errors and unsucessfull requests (non {2xx,3xx}) are
// considered errors.
func (a Attacker) hit(req *http.Request, res chan Result) {
	began := time.Now()
	urlBackup := req.URL
	restoreBackup := false

	// inject uniqueness
	if strings.Contains(req.URL.String(), "%d;%d") {
		parsedUrl, err := url.Parse(fmt.Sprintf(req.URL.String(), time.Now().UnixNano(), rand.Int63n(time.Now().Unix())))
		if err == nil {
			req.URL = parsedUrl
			restoreBackup = true
		}
	}

	r, err := a.client.Do(req)
	result := Result{
		Timestamp: began,
		Latency:   time.Since(began),
		BytesOut:  uint64(req.ContentLength),
	}

	if err != nil {
		result.Error = err.Error()
	} else {
		result.URL = r.Request.URL.String()
		result.Code = uint16(r.StatusCode)
		result.Header = r.Header
		if body, err := ioutil.ReadAll(r.Body); err != nil {
			if result.Code < 200 || result.Code >= 300 {
				result.Error = string(body)
			}
		} else {
			result.BytesIn = uint64(len(body))
		}
	}

	if restoreBackup {
		req.URL = urlBackup
	}

	runtime.GC()
	res <- result
}
Beispiel #30
0
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)
}