Пример #1
1
// DumpResponse is like DumpRequest but dumps a response.
func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) {
	var b bytes.Buffer
	save := resp.Body
	savecl := resp.ContentLength

	if !body {
		// For content length of zero. Make sure the body is an empty
		// reader, instead of returning error through failureToReadBody{}.
		if resp.ContentLength == 0 {
			resp.Body = emptyBody
		} else {
			resp.Body = failureToReadBody{}
		}
	} else if resp.Body == nil {
		resp.Body = emptyBody
	} else {
		save, resp.Body, err = drainBody(resp.Body)
		if err != nil {
			return nil, err
		}
	}
	err = resp.Write(&b)
	if err == errNoBody {
		err = nil
	}
	resp.Body = save
	resp.ContentLength = savecl
	if err != nil {
		return nil, err
	}
	return b.Bytes(), nil
}
Пример #2
0
func (srv *Server) handlerExecutePipeline(request *Request, keepAlive bool) *http.Response {

	var res *http.Response
	// execute the pipeline
	if res = srv.Pipeline.execute(request); res == nil {
		res = StringResponse(request.HttpRequest, 404, nil, "Not Found")
	}

	// The res.Write omits Content-length on 0 length bodies, and by spec,
	// it SHOULD. While this is not MUST, it's kinda broken.  See sec 4.4
	// of rfc2616 and a 200 with a zero length does not satisfy any of the
	// 5 conditions if Connection: keep-alive is set :(
	// I'm forcing chunked which seems to work because I couldn't get the
	// content length to write if it was 0.
	// Specifically, the android http client waits forever if there's no
	// content-length instead of assuming zero at the end of headers. der.
	if res.Body == nil {
		if request.HttpRequest.Method != "HEAD" {
			res.ContentLength = 0
		}
		res.TransferEncoding = []string{"identity"}
		res.Body = ioutil.NopCloser(bytes.NewBuffer([]byte{}))
	} else if res.ContentLength == 0 && len(res.TransferEncoding) == 0 && !((res.StatusCode-100 < 100) || res.StatusCode == 204 || res.StatusCode == 304) {
		// the following is copied from net/http/transfer.go
		// in the std lib, this is only applied to a request.  we need it on a response

		// Test to see if it's actually zero or just unset.
		var buf [1]byte
		n, _ := io.ReadFull(res.Body, buf[:])
		if n == 1 {
			// Oh, guess there is data in this Body Reader after all.
			// The ContentLength field just wasn't set.
			// Stich the Body back together again, re-attaching our
			// consumed byte.
			res.ContentLength = -1
			res.Body = &lengthFixReadCloser{io.MultiReader(bytes.NewBuffer(buf[:]), res.Body), res.Body}
		} else {
			res.TransferEncoding = []string{"identity"}
		}
	}
	if res.ContentLength < 0 && request.HttpRequest.Method != "HEAD" {
		res.TransferEncoding = []string{"chunked"}
	}

	// For HTTP/1.0 and Keep-Alive, sending the Connection: Keep-Alive response header is required
	// because close is default (opposite of 1.1)
	if keepAlive && !request.HttpRequest.ProtoAtLeast(1, 1) {
		res.Header.Set("Connection", "Keep-Alive")
	}

	// cleanup
	request.HttpRequest.Body.Close()
	return res
}
Пример #3
0
func (c *imageTransformer) transformResponse(r *http.Response) {

	var images []APIImages

	if err := json.NewDecoder(r.Body).Decode(&images); err != nil {
		return
	}

	for _, im := range images {

		if im.Labels == nil {
			im.Labels = make(map[string]string)
		}

		im.Labels["hola"] = "world"
	}

	var b bytes.Buffer
	w := bufio.NewWriter(&b)

	// Now take the struct and encode it
	if err := json.NewEncoder(w).Encode(&images); err != nil {
		return
	}

	// Restore the io.ReadCloser to its original state
	r.Body = ioutil.NopCloser(bytes.NewBuffer(b.Bytes()))

	// Set size of modified body
	r.ContentLength = int64(binary.Size(b))
}
Пример #4
0
// DumpResponse is like DumpRequest but dumps a response.
func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) { // dump出响应内容
	var b bytes.Buffer
	save := resp.Body
	savecl := resp.ContentLength

	if !body {
		resp.Body = failureToReadBody{}
	} else if resp.Body == nil {
		resp.Body = emptyBody
	} else {
		save, resp.Body, err = drainBody(resp.Body)
		if err != nil {
			return
		}
	}
	err = resp.Write(&b)
	if err == errNoBody {
		err = nil
	}
	resp.Body = save
	resp.ContentLength = savecl
	if err != nil {
		return nil, err
	}
	return b.Bytes(), nil
}
Пример #5
0
func (c *Client) logResponse(resp *http.Response) error {
	if c.logHTTP {
		var err error
		save := resp.Body
		savecl := resp.ContentLength
		body := true
		if !body {
			resp.Body = failureToReadBody{}
		} else if resp.Body == nil {
			resp.Body = emptyBody
		} else {
			save, resp.Body, err = drainBody(resp.Body)
			if err != nil {
				return err
			}
		}
		fmt.Println("----------- response start -----------")
		err = resp.Write(os.Stderr)
		if err == errNoBody {
			err = nil
		}
		resp.Body = save
		resp.ContentLength = savecl
		if err != nil {
			return err
		}
		fmt.Println("----------- response end -----------")
	}
	return nil
}
Пример #6
0
func maybeUngzipResponse(resp *http.Response) {
	if resp.Header.Get("Content-Encoding") == "gzip" {
		resp.Header.Del("Content-Encoding")
		resp.Header.Del("Content-Length")
		resp.ContentLength = -1
		resp.Body = &gzipReader{body: resp.Body}
	}
}
Пример #7
0
func TestHandleHttpResponseReturnsErrOnZeroContentLength(t *testing.T) {
	var response http.Response

	response.StatusCode = 200
	response.ContentLength = 0

	_, err := handleHTTPResponse(&response, nil)

	assertEqual(t, "No content was returned", err.Error(), "The returned error was not the expected error")
}
Пример #8
0
func (c *URLCache) Restore(res *http.Response) {
	res.Status = c.CachedResponse.Status
	res.StatusCode = c.CachedResponse.StatusCode
	res.Header = c.CachedResponse.Header
	res.ContentLength = c.CachedResponse.ContentLength
	res.TransferEncoding = c.CachedResponse.TransferEncoding
	res.Body = &ClosableBuffer{bytes.NewReader(c.CachedBody)}
	res.Header.Set(CachedHeader, CachedHeaderVal)
	res.Header.Set(CachedMD5Header, c.MD5)
}
Пример #9
0
func TestGobResponseSniff1(t *testing.T) {
	var e request
	e.embedMime = new(embedMime)
	ctx := context.Background()

	response := new(http.Response)
	response.StatusCode = 200

	b := []byte{0x37, 0xff, 0x81, 0x03, 0x01, 0x01, 0x07, 0x72, 0x65,
		0x71, 0x75, 0x65, 0x73, 0x74, 0x01, 0xff, 0x82, 0x00,
		0x01, 0x04, 0x01, 0x03, 0x53, 0x74, 0x72, 0x01, 0x0c,
		0x00, 0x01, 0x03, 0x4e, 0x75, 0x6d, 0x01, 0x08, 0x00,
		0x01, 0x04, 0x42, 0x6f, 0x6f, 0x6c, 0x01, 0x02, 0x00,
		0x01, 0x04, 0x4e, 0x75, 0x6c, 0x6c, 0x01, 0x10, 0x00,
		0x00, 0x00, 0x0e, 0xff, 0x82, 0x01, 0x03, 0x62, 0x61,
		0x72, 0x01, 0xfe, 0x24, 0x40, 0x01, 0x01, 0x00}

	buf := bytes.NewBuffer(b)

	response.Body = ioutil.NopCloser(buf)
	response.ContentLength = int64(buf.Len())

	def := encoding.Default()

	e1, err := def.DecodeResponse(&e)(ctx, response)
	if err != nil {
		t.Logf("Decode Request Failed: %s\n", err)
		t.Fail()
	}

	if e1 != &e {
		t.Logf("Returned Result is NOT the same value: %#v\n", e1)
		t.Fail()
	}

	if e.Str != "bar" {
		t.Logf("e.Str != \"bar\": \"%s\"\n", e.Str)
		t.Fail()
	}

	if e.Num != 10.0 {
		t.Logf("e.Num != 10.0: %f\n", e.Num)
		t.Fail()
	}

	if !e.Bool {
		t.Logf("!e.Bool: %f\n", e.Bool)
		t.Fail()
	}

	if e.Null != nil {
		t.Logf("e.Null != nil: %f\n", e.Null)
		t.Fail()
	}
}
Пример #10
0
func (t *minionTransport) ProcessResponse(req *http.Request, resp *http.Response) (*http.Response, error) {
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		// copying the response body did not work
		return nil, err
	}

	bodyNode := &html.Node{
		Type:     html.ElementNode,
		Data:     "body",
		DataAtom: atom.Body,
	}
	nodes, err := html.ParseFragment(bytes.NewBuffer(body), bodyNode)
	if err != nil {
		glog.Errorf("Failed to found <body> node: %v", err)
		return resp, err
	}

	// Define the method to traverse the doc tree and update href node to
	// point to correct minion
	var updateHRef func(*html.Node)
	updateHRef = func(n *html.Node) {
		if n.Type == html.ElementNode && n.Data == "a" {
			for i, attr := range n.Attr {
				if attr.Key == "href" {
					Url := &url.URL{
						Path: "/proxy/minion/" + req.URL.Host + req.URL.Path + attr.Val,
					}
					n.Attr[i].Val = Url.String()
					break
				}
			}
		}
		for c := n.FirstChild; c != nil; c = c.NextSibling {
			updateHRef(c)
		}
	}

	newContent := &bytes.Buffer{}
	for _, n := range nodes {
		updateHRef(n)
		err = html.Render(newContent, n)
		if err != nil {
			glog.Errorf("Failed to render: %v", err)
		}
	}

	resp.Body = ioutil.NopCloser(newContent)
	// Update header node with new content-length
	// TODO: Remove any hash/signature headers here?
	resp.Header.Del("Content-Length")
	resp.ContentLength = int64(newContent.Len())

	return resp, err
}
Пример #11
0
func RedirectResponse(req *http.Request, url string) *http.Response {
	res := new(http.Response)
	res.StatusCode = 302
	res.ProtoMajor = 1
	res.ProtoMinor = 1
	res.ContentLength = 0
	res.Request = req
	res.Header = make(map[string][]string)
	res.Header.Set("Location", url)
	return res
}
Пример #12
0
func marshalResponseBody(r *http.Response, body interface{}) error {
	newBody, err := json.Marshal(body)
	if err != nil {
		return err
	}
	r.Body = ioutil.NopCloser(bytes.NewReader(newBody))
	r.ContentLength = int64(len(newBody))
	// Stop it being chunked, because that hangs
	r.TransferEncoding = nil
	return nil
}
Пример #13
0
// ResponseHeader returns a new set of headers from a request.
func ResponseHeader(res *http.Response) *Header {
	return &Header{
		h:       res.Header,
		host:    func() string { return "" },
		cl:      func() int64 { return res.ContentLength },
		te:      func() []string { return res.TransferEncoding },
		setHost: func(string) {},
		setCL:   func(cl int64) { res.ContentLength = cl },
		setTE:   func(te []string) { res.TransferEncoding = te },
	}
}
Пример #14
0
func (f *EtagFilter) FilterResponse(request *falcore.Request, res *http.Response) {
	request.CurrentStage.Status = 1 // Skipped (default)
	if if_none_match := request.HttpRequest.Header.Get("If-None-Match"); if_none_match != "" {
		if res.StatusCode == 200 && res.Header.Get("Etag") == if_none_match {
			res.StatusCode = 304
			res.Status = "304 Not Modified"
			res.Body.Close()
			res.Body = nil
			res.ContentLength = 0
			request.CurrentStage.Status = 0 // Success
		}
	}
}
Пример #15
0
func TestHandleHttpResponseReturnsErrOnContentLengthTooLarge(t *testing.T) {
	var response http.Response

	response.StatusCode = 200
	response.ContentLength = MaxFeedSize + 1

	_, err := handleHTTPResponse(&response, nil)

	assertStartsWith(t,
		err.Error(),
		"Feed exceeds maximum size of",
		"The returned error was not the expected error")
}
Пример #16
0
// DumpResponse is like DumpRequest but dumps a response.
func DumpResponse(resp *http.Response, body bool) (dump []byte, err error) {
	var b bytes.Buffer
	save := resp.Body
	savecl := resp.ContentLength
	if !body || resp.Body == nil {
		resp.Body = nil
		resp.ContentLength = 0
	} else {
		save, resp.Body, err = drainBody(resp.Body)
		if err != nil {
			return
		}
	}
	err = resp.Write(&b)
	resp.Body = save
	resp.ContentLength = savecl
	if err != nil {
		return
	}
	dump = b.Bytes()
	return
}
Пример #17
0
// ModifyResponse sets the Content-Type header and overrides the response body.
func (m *Modifier) ModifyResponse(res *http.Response) error {
	// Replace the existing body, close it first.
	res.Body.Close()

	res.Header.Set("Content-Type", m.contentType)

	// Reset the Content-Encoding since we know that the new body isn't encoded.
	res.Header.Del("Content-Encoding")

	res.ContentLength = int64(len(m.body))
	res.Body = ioutil.NopCloser(bytes.NewReader(m.body))

	return nil
}
Пример #18
0
func (rt ResponseTransformMiddleware) HandleResponse(rw http.ResponseWriter, res *http.Response, req *http.Request, ses *SessionState) error {
	_, versionPaths, _, _ := rt.Spec.GetVersionData(req)
	found, meta := rt.Spec.CheckSpecMatchesStatus(req.URL.Path, req.Method, versionPaths, TransformedResponse)
	if found {
		thisMeta := meta.(*TransformSpec)

		// Read the body:
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)

		// Put into an interface:
		var bodyData interface{}
		switch thisMeta.TemplateMeta.TemplateData.Input {
		case tykcommon.RequestXML:
			mxj.XmlCharsetReader = WrappedCharsetReader
			bodyData, err = mxj.NewMapXml(body) // unmarshal
			if err != nil {
				log.WithFields(logrus.Fields{
					"prefix":      "outbound-transform",
					"server_name": rt.Spec.APIDefinition.Proxy.TargetURL,
					"api_id":      rt.Spec.APIDefinition.APIID,
					"path":        req.URL.Path,
				}).Error("Error unmarshalling XML: ", err)
			}
		case tykcommon.RequestJSON:
			json.Unmarshal(body, &bodyData)
		default:
			json.Unmarshal(body, &bodyData)
		}

		// Apply to template
		var bodyBuffer bytes.Buffer
		err = thisMeta.Template.Execute(&bodyBuffer, bodyData)

		if err != nil {
			log.WithFields(logrus.Fields{
				"prefix":      "outbound-transform",
				"server_name": rt.Spec.APIDefinition.Proxy.TargetURL,
				"api_id":      rt.Spec.APIDefinition.APIID,
				"path":        req.URL.Path,
			}).Error("Failed to apply template to request: ", err)
		}

		res.ContentLength = int64(bodyBuffer.Len())
		res.Header.Set("Content-Length", strconv.Itoa(bodyBuffer.Len()))
		res.Body = ioutil.NopCloser(&bodyBuffer)
	}

	return nil
}
Пример #19
0
func TestXMLResponseSniff1(t *testing.T) {
	var e request
	e.embedMime = new(embedMime)
	ctx := context.Background()

	response := new(http.Response)
	response.StatusCode = 200

	str := "<request><str>bar</str><num>10.0</num><bool>true</bool><null>null</null></request>"
	t.Logf("Data: %s\n", str)

	buf := bytes.NewBuffer([]byte(str))

	response.Body = ioutil.NopCloser(buf)
	response.ContentLength = int64(buf.Len())

	def := encoding.Default()

	e1, err := def.DecodeResponse(&e)(ctx, response)
	if err != nil {
		t.Logf("Decode Request Failed: %s\n", err)
		t.Fail()
	}

	if e1 != &e {
		t.Logf("Returned Result is NOT the same value: %#v\n", e1)
		t.Fail()
	}

	if e.Str != "bar" {
		t.Logf("e.Str != \"bar\": \"%s\"\n", e.Str)
		t.Fail()
	}

	if e.Num != 10.0 {
		t.Logf("e.Num != 10.0: %f\n", e.Num)
		t.Fail()
	}

	if !e.Bool {
		t.Logf("!e.Bool: %f\n", e.Bool)
		t.Fail()
	}

	if e.Null != nil {
		t.Logf("e.Null != nil: %f\n", e.Null)
		t.Fail()
	}
}
Пример #20
0
func SimpleResponse(req *http.Request, status int, headers http.Header, body string) *http.Response {
	res := new(http.Response)
	body_rdr := (*fixedResBody)(strings.NewReader(body))
	res.StatusCode = status
	res.ProtoMajor = 1
	res.ProtoMinor = 1
	res.ContentLength = int64((*strings.Reader)(body_rdr).Len())
	res.Request = req
	res.Header = make(map[string][]string)
	res.Body = body_rdr
	if headers != nil {
		res.Header = headers
	}
	return res
}
Пример #21
0
func (res *HTTPResponseEvent) ToResponse() *http.Response {
	raw := new(http.Response)
	raw.Proto = "HTTP"
	raw.ProtoMajor = 1
	raw.ProtoMinor = 1
	//raw.Close = true
	raw.ContentLength = int64(res.Content.Len())
	raw.Header = make(http.Header)
	raw.StatusCode = int(res.Status)
	res.SetHeader("Content-Length", strconv.Itoa(res.Content.Len()))
	for i := 0; i < len(res.Headers); i++ {
		header := res.Headers[i]
		if strings.EqualFold(header.Name, "Set-Cookie") || strings.EqualFold(header.Name, "Set-Cookie2") {
			tmp := strings.Split(header.Value, ",")
			if len(tmp) > 1 {
				var vlist list.List
				for _, v := range tmp {
					if (!strings.Contains(v, "=") || strings.Index(v, "=") > strings.Index(v, ";")) && vlist.Len() > 0 {
						v = vlist.Back().Value.(string) + "," + v
						vlist.Remove(vlist.Back())
						vlist.PushBack(v)
						//headerValues.add(headerValues.removeLast() + "," + v);
					} else {
						vlist.PushBack(v)
					}
				}
				e := vlist.Front()
				for {
					if e == nil {
						break
					}
					raw.Header.Add(header.Name, e.Value.(string))
					e = e.Next()
				}
			} else {
				raw.Header.Add(header.Name, header.Value)
			}
		} else {
			raw.Header.Add(header.Name, header.Value)
		}
	}
	if raw.ContentLength > 0 {
		raw.Body = ioutil.NopCloser(&res.Content)
	}
	return raw
}
Пример #22
0
// fixLinks modifies links in an HTML file such that they will be redirected through the proxy if needed.
func (t *proxyTransport) fixLinks(req *http.Request, resp *http.Response) (*http.Response, error) {
	origBody := resp.Body
	defer origBody.Close()

	newContent := &bytes.Buffer{}
	var reader io.Reader = origBody
	var writer io.Writer = newContent
	encoding := resp.Header.Get("Content-Encoding")
	switch encoding {
	case "gzip":
		var err error
		reader, err = gzip.NewReader(reader)
		if err != nil {
			return nil, fmt.Errorf("errorf making gzip reader: %v", err)
		}
		gzw := gzip.NewWriter(writer)
		defer gzw.Close()
		writer = gzw
	// TODO: support flate, other encodings.
	case "":
		// This is fine
	default:
		// Some encoding we don't understand-- don't try to parse this
		glog.Errorf("Proxy encountered encoding %v for text/html; can't understand this so not fixing links.", encoding)
		return resp, nil
	}

	doc, err := html.Parse(reader)
	if err != nil {
		glog.Errorf("Parse failed: %v", err)
		return resp, err
	}

	t.scan(doc, func(n *html.Node) { t.updateURLs(n, req.URL) })
	if err := html.Render(writer, doc); err != nil {
		glog.Errorf("Failed to render: %v", err)
	}

	resp.Body = ioutil.NopCloser(newContent)
	// Update header node with new content-length
	// TODO: Remove any hash/signature headers here?
	resp.Header.Del("Content-Length")
	resp.ContentLength = int64(newContent.Len())

	return resp, err
}
Пример #23
0
func (rt ResponseTransformMiddleware) HandleResponse(rw http.ResponseWriter, res *http.Response, req *http.Request, ses *SessionState) error {
	// New request checker, more targetted, less likely to fail
	var stat RequestStatus
	var meta interface{}
	var found bool

	_, versionPaths, _, _ := rt.Spec.GetVersionData(req)
	found, meta = rt.Spec.CheckSpecMatchesStatus(req.URL.Path, req.Method, versionPaths, TransformedResponse)
	if found {
		stat = StatusTransformResponse
	}

	if stat == StatusTransformResponse {
		thisMeta := meta.(*TransformSpec)

		// Read the body:
		defer res.Body.Close()
		body, err := ioutil.ReadAll(res.Body)

		// Put into an interface:
		var bodyData interface{}
		switch thisMeta.TemplateMeta.TemplateData.Input {
		case tykcommon.RequestXML:
			log.Warning("XML Input is not supprted")
		case tykcommon.RequestJSON:
			json.Unmarshal(body, &bodyData)
		default:
			json.Unmarshal(body, &bodyData)
		}

		// Apply to template
		var bodyBuffer bytes.Buffer
		log.Warning("RUNNING TRANSFORM")
		err = thisMeta.Template.Execute(&bodyBuffer, bodyData)

		if err != nil {
			log.Error("Failed to apply template to request: ", err)
		}

		res.ContentLength = int64(bodyBuffer.Len())
		res.Header.Set("Content-Length", strconv.Itoa(bodyBuffer.Len()))
		res.Body = ioutil.NopCloser(&bodyBuffer)
	}

	return nil
}
Пример #24
0
// NewNotification returns a notification response with a specific body content.
func NewNotification(body *bytes.Buffer) *http.Response {
	resp := new(http.Response)
	resp.Status = "200 OK"
	resp.StatusCode = http.StatusOK
	resp.ProtoMajor = 1
	resp.ProtoMinor = 0
	resp.Body = ioutil.NopCloser(body)
	resp.ContentLength = int64(body.Len())
	resp.Header = map[string][]string{}
	resp.Header.Set("Content-Type", HTTPContentTypeHAPJson)

	// Will be ignored unfortunately and won't be fixed https://github.com/golang/go/issues/9304
	// Make sure to call FixProtocolSpecifier() instead
	resp.Proto = "EVENT/1.0"

	return resp
}
Пример #25
0
// Create an http Response from scratch, there must be a better way that this but I
// don't know what it is
func concoctResponse(req *http.Request, message string, code int) *http.Response {
	r := http.Response{
		Status:     "Bad Gateway", //strconv.Itoa(code),
		StatusCode: code,
		Proto:      req.Proto,
		ProtoMajor: req.ProtoMajor,
		ProtoMinor: req.ProtoMinor,
		Header:     make(map[string][]string),
		Request:    req,
	}
	body := bytes.NewReader([]byte(message))
	r.Body = ioutil.NopCloser(body)
	r.ContentLength = int64(body.Len())
	r.Header.Add("content-type", "text/plain")
	r.Header.Add("date", time.Now().Format(time.RFC1123))
	r.Header.Add("server", "wstunnel")
	return &r
}
Пример #26
0
// Generate an http.Response using the basic fields
func SimpleResponse(req *http.Request, status int, headers http.Header, contentLength int64, body io.Reader) *http.Response {
	res := new(http.Response)
	res.StatusCode = status
	res.ProtoMajor = 1
	res.ProtoMinor = 1
	res.ContentLength = contentLength
	res.Request = req
	res.Header = make(map[string][]string)
	if body_rdr, ok := body.(io.ReadCloser); ok {
		res.Body = body_rdr
	} else if body != nil {
		res.Body = ioutil.NopCloser(body)
	}
	if headers != nil {
		res.Header = headers
	}
	return res
}
Пример #27
0
func extractBody(resp *http.Response) (extract []byte, err error) {
	save := resp.Body
	savecl := resp.ContentLength

	save, resp.Body, err = copyBody(resp.Body)

	if err != nil {
		return
	}
	defer resp.Body.Close()
	extract, err = ioutil.ReadAll(resp.Body)

	resp.Body = save
	resp.ContentLength = savecl
	if err != nil {
		return nil, err
	}
	return extract, nil
}
Пример #28
0
func (r *response) Response() *http.Response {
	if r.Data == nil {
		r.Data = new(bytes.Buffer)
	}
	out := new(http.Response)
	out.Status = fmt.Sprintf("%d %s", r.StatusCode, http.StatusText(r.StatusCode))
	out.StatusCode = r.StatusCode
	out.Proto = "HTTP/1.1"
	out.ProtoMajor = 1
	out.ProtoMinor = 1
	out.Header = r.Header
	out.Body = &readCloser{r.Data}
	out.ContentLength = int64(r.Data.Len())
	out.TransferEncoding = nil
	out.Close = true
	out.Trailer = make(http.Header)
	out.Request = r.Request
	return out
}
Пример #29
0
func proxyHandler(r *http.Response, ctx *goproxy.ProxyCtx) *http.Response {
	if reAdminUrl.FindString(r.Request.URL.Path) == "" {
		return r
	}

	buf := NewBuffer()
	_, err := buf.B.ReadFrom(r.Body)
	if err != nil {
		log.Print(err)
		return r
	}

	b := reWlsStatus.ReplaceAll(buf.B.Bytes(), activeWls)
	buf.B.Reset()
	buf.B.Write(b)

	r.Body = buf
	r.ContentLength = int64(buf.B.Len())
	return r
}
Пример #30
-1
func (r *Response) Response() *http.Response {
	out := new(http.Response)

	r.headerM.Lock()
	out.Status = fmt.Sprintf("%d %s", r.StatusCode, http.StatusText(r.StatusCode))
	out.StatusCode = r.StatusCode
	out.Header = r.Header
	r.headerM.Unlock()

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

	r.dataM.Lock()
	if r.data == nil {
		out.Body = &ReadCloser{new(bytes.Buffer)}
	} else if unrequestedGzip(r) {
		// User-agents MUST support gzip compression.
		// Regardless of the Accept-Encoding sent by the user-agent, the server may
		// always send content encoded with gzip or deflate encoding.
		r.data.Prep()
		out.Header.Del("Content-Encoding")
		out.Header.Del("Content-Length")
		out.ContentLength = -1
		out.Body = &gzipReader{body: r.data}
	} else {
		r.data.Prep()
		out.Body = r.data
		out.ContentLength = r.data.written
	}
	r.dataM.Unlock()

	out.TransferEncoding = nil
	out.Close = true
	out.Trailer = make(http.Header)
	out.Request = r.Request
	return out
}