Exemple #1
0
func (s *Session) doProxy(xReq *PxReq, w http.ResponseWriter) (err error) {
	var req *http.Request
	var resp *http.Response

	req, err = NewRequest(s.dMethod, xReq.url, s.body)
	req.Header = xReq.header

	if log.V(3) {
		dumpHeader("<- Header/ActualReq", req.Header)
	}

	resp, err = http_client.Do(req)

	if log.V(1) {
		if resp != nil {
			log.Infof("%s %s %s [%d] %s", s.aAddr, s.aMethod, s.dUserAgent, resp.StatusCode, xReq.url.String())
		} else {
			log.Infof("%s %s %s [Err] %s", s.aAddr, s.aMethod, s.dUserAgent, xReq.url.String())
		}
	}
	if log.V(3) && resp != nil {
		dumpHeader("-> Header/OriginalResp", resp.Header)
	}

	if resp != nil && resp.Body != nil {
		defer resp.Body.Close()
	}
	if err != nil {
		if e, y := err.(*url.Error); y && e.Err == err30xRedirect {
			s.redirected, err = true, nil
		} else {
			return dumpError(err)
		}
	}

	err = s.processOutputHeader(xReq, resp, w)
	if err != nil {
		err = s.avoidCountryRedirect(xReq, w)
		return
	}

	pMethod := determineHandler(resp.Header.Get("Content-Type"))

	if pMethod == HD_unknown || resp.ContentLength > maxAcceptedLength {
		w.WriteHeader(resp.StatusCode)
		io.Copy(w, resp.Body)
	} else {
		err = pMethod.processText(s, w, resp)
	}
	return
}
Exemple #2
0
func (s *Session) processOutputHeader(xReq *PxReq, resp *http.Response, w http.ResponseWriter) (err error) {
	defer func() {
		if e := recover(); e != nil {
			err = e.(error)
		}
	}()
	wHeader := w.Header()
	for k, array := range resp.Header {
		switch k {
		case "Set-Cookie":
			continue
		case "Location":
			targetUrl := array[0]
			nextUrl := s.processRedirect(targetUrl)
			if log.V(1) {
				log.Infof("Cook redirection %s -> %s", targetUrl, nextUrl)
			}
			wHeader.Set(k, nextUrl)
		default:
			// Alt-Svc, Alternate-Protocol
			if strings.HasPrefix(k, "Alt") {
				continue
			}
			for _, v := range array {
				wHeader.Add(k, v)
			}
		}
	}
	wHeader.Set("Server", "ezgoo")
	var alterCookiePath = xReq.nondefault == 0xf
	for _, ck := range resp.Cookies() {
		if alterCookiePath {
			if ck.Domain == NULL || strings.HasPrefix(ck.Domain, ".") {
				// prevent ck.path==/!.some-host
				ck.Path = fmt.Sprintf("/!%s%s", xReq.url.Host, ck.Path)
			} else {
				ck.Path = fmt.Sprintf("/!%s%s", ck.Domain, ck.Path)
			}
		}
		if v := cookieString(ck, &s.plainHost, true); v != NULL {
			wHeader.Add("Set-Cookie", v)
		}
	}
	return
}
Exemple #3
0
func (p Handler) processText(s *Session, w http.ResponseWriter, resp *http.Response) (err error) {
	var (
		zr      *gzip.Reader
		zw      *gzip.Writer
		body    []byte
		gzipped bool   = resp.Header.Get("Content-Encoding") == "gzip"
		reqHost string = resp.Request.URL.Host
		reqPath string = resp.Request.URL.Path
	)
	if resp.ContentLength != 0 && resp.Request.Method != "HEAD" {
		if gzipped {
			zr, err = gzip.NewReader(resp.Body)
			if err == nil {
				body, err = ioutil.ReadAll(zr)
				if !consumeError(&err) {
					return dumpError(err)
				}
			}
		} else {
			body, err = ioutil.ReadAll(resp.Body)
			if !consumeError(&err) {
				return dumpError(err)
			}
		}
	}

	w.Header().Del("Content-Length")
	w.Header().Set("Content-Encoding", "gzip")
	w.WriteHeader(resp.StatusCode)

	if len(body) <= 0 {
		return
	}

	var (
		rules           []ReRule
		bodyExtraHeader string
	)

	switch p {
	case HD_html:
		rules = reRules.Html
	case HD_javascript:
		rules = reRules.Js
	case HD_json:
		rules = reRules.Json
	case HD_css:
		rules = reRules.Css
	}

	if log.V(5) {
		log.Infof("Original entity %s\n%s", reqPath, string(body))
	}

	if s.abusing {
		imgSrc := fmt.Sprintf(`<img src="/!%s/sorry`, reqHost)
		body = bytes.Replace(body, []byte(`<img src="/sorry`), []byte(imgSrc), 1)
		rules = nil
	}

	for i, r := range rules {
		if r.PathRe != nil && r.PathRe.FindString(reqPath) == NULL {
			if log.V(4) {
				log.Infof("re.%d=[%s] pathRe=deny", i, r.ContentPattern.Pattern)
			}
			continue
		}
		if log.V(4) {
			log.Infof("re.%d=[%s] applied", i, r.ContentPattern.Pattern)
		}
		if r.Scheme&0xff > 0 {
			body = r.ContentRe.Replace(body, r.Replacement)
		}
		if r.Scheme&0xff00 > 0 {
			bodyExtraHeader += r.InsertHeader
		}
	}

	zw = gzip.NewWriter(w)
	if len(bodyExtraHeader) > 0 {
		zw.Write([]byte(bodyExtraHeader))
	}
	zw.Write(body)
	err = zw.Flush()
	return
}