func (f *FetchServer) encodeRequest(req *http.Request) (*http.Request, error) { var err error var b bytes.Buffer w, err := flate.NewWriter(&b, flate.BestCompression) if err != nil { return nil, err } fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", req.Method, req.URL.String()) req.Header.WriteSubset(w, reqWriteExcludeHeader) fmt.Fprintf(w, "X-Urlfetch-Password: %s\r\n", f.Password) if f.URL.Scheme == "https" { io.WriteString(w, "X-Urlfetch-Https: 1\r\n") } if f.SSLVerify { io.WriteString(w, "X-Urlfetch-SSLVerify: 1\r\n") } io.WriteString(w, "\r\n") if err != nil { return nil, err } w.Close() b0 := make([]byte, 2) binary.BigEndian.PutUint16(b0, uint16(b.Len())) req1 := &http.Request{ Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Method: "POST", URL: f.URL, Host: f.URL.Host, Header: http.Header{}, } if f.URL.Scheme == "http" { for _, key := range []string{"User-Agent", "Accept", "Accept-Encoding", "Accept-Language"} { if value := req.Header.Get(key); value != "" { req1.Header.Set(key, value) } } } if req.ContentLength > 0 { req1.ContentLength = int64(len(b0)+b.Len()) + req.ContentLength req1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(b0), &b, req.Body) } else { req1.ContentLength = int64(len(b0) + b.Len()) req1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(b0), &b) } return req1, nil }
func (f *FetchServer) decodeResponse(resp *http.Response) (resp1 *http.Response, err error) { if resp.StatusCode != 200 { return resp, nil } var hdrLen uint16 if err = binary.Read(resp.Body, binary.BigEndian, &hdrLen); err != nil { return } hdrBuf := make([]byte, hdrLen) if _, err = io.ReadFull(resp.Body, hdrBuf); err != nil { return } resp1, err = http.ReadResponse(bufio.NewReader(flate.NewReader(bytes.NewReader(hdrBuf))), resp.Request) if err != nil { return } const cookieKey string = "Set-Cookie" if cookie := resp1.Header.Get(cookieKey); cookie != "" { parts := strings.Split(cookie, ", ") parts1 := make([]string, 0) for i := 0; i < len(parts); i++ { c := parts[i] if i == 0 || strings.Contains(strings.Split(c, ";")[0], "=") { parts1 = append(parts1, c) } else { parts1[len(parts1)-1] = parts1[len(parts1)-1] + ", " + c } } resp1.Header.Del(cookieKey) for i := 0; i < len(parts1); i++ { resp1.Header.Add(cookieKey, parts1[i]) } } if resp1.StatusCode >= 400 { switch { case resp.Body == nil: break case resp1.Body == nil: resp1.Body = resp.Body default: b, _ := ioutil.ReadAll(resp1.Body) if b != nil && len(b) > 0 { resp1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(b), resp.Body) } else { resp1.Body = resp.Body } } } else { resp1.Body = resp.Body } return }
func (f *FetchServer) encodeRequest(req *http.Request) (*http.Request, error) { var err error var b bytes.Buffer w, err := flate.NewWriter(&b, flate.BestCompression) if err != nil { return nil, err } fmt.Fprintf(w, "%s %s HTTP/1.1\r\n", req.Method, req.URL.String()) req.Header.WriteSubset(w, reqWriteExcludeHeader) fmt.Fprintf(w, "X-Urlfetch-Password: %s\r\n", f.Password) io.WriteString(w, "\r\n") if err != nil { return nil, err } w.Close() b0 := make([]byte, 2) binary.BigEndian.PutUint16(b0, uint16(b.Len())) req1 := &http.Request{ Proto: "HTTP/1.1", ProtoMajor: 1, ProtoMinor: 1, Method: "POST", URL: f.URL, Host: f.URL.Host, Header: http.Header{ "User-Agent": []string{"B"}, }, } if req.ContentLength > 0 { req1.ContentLength = int64(len(b0)+b.Len()) + req.ContentLength req1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(b0), &b, req.Body) } else { req1.ContentLength = int64(len(b0) + b.Len()) req1.Body = httpproxy.NewMultiReadCloser(bytes.NewReader(b0), &b) } return req1, nil }