func (d *directChannel) read() { defer d.Close() for { c := d.conn if nil == c { return } c.SetReadDeadline(time.Now().Add(d.ReadTimeout())) b := make([]byte, 1500) n, err := c.Read(b) if n > 0 { var ev event.Event if !d.udpProxyConn { ev = &event.TCPChunkEvent{Content: b[0:n]} } else { ev = &event.UDPEvent{Content: b[0:n]} } //log.Printf("######recv %T", ev) ev.SetId(d.sid) proxy.HandleEvent(ev) } if nil != err { if !d.udpProxyConn { closeEv := &event.ConnCloseEvent{} closeEv.SetId(d.sid) proxy.HandleEvent(closeEv) } return } } }
func (p *DirectProxy) Serve(session *proxy.ProxySession, ev event.Event) error { if nil == session.Remote || session.Remote.C.Closed() { switch ev.(type) { case *event.TCPOpenEvent: case *event.HTTPRequestEvent: case *event.UDPEvent: default: session.Close() return fmt.Errorf("Can NOT create direct channel by event:%T", ev) } c, err := newDirectChannel(ev, &p.conf) if nil != err { session.Close() return err } session.Remote = &proxy.RemoteChannel{ Addr: c.addr, DirectIO: true, } session.Remote.C = c if c.httpsProxyConn { session.Hijacked = true return nil } } if nil == session.Remote { return fmt.Errorf("No remote connected.") } switch ev.(type) { case *event.UDPEvent: session.Remote.WriteRaw(ev.(*event.UDPEvent).Content) case *event.ConnCloseEvent: session.Remote.Close() case *event.TCPOpenEvent: case *event.ConnTestEvent: //do nothing case *event.TCPChunkEvent: session.Remote.WriteRaw(ev.(*event.TCPChunkEvent).Content) case *event.HTTPRequestEvent: req := ev.(*event.HTTPRequestEvent) content := req.HTTPEncode() _, err := session.Remote.WriteRaw(content) if nil != err { closeEv := &event.ConnCloseEvent{} closeEv.SetId(ev.GetId()) proxy.HandleEvent(closeEv) return err } return nil default: log.Printf("Invalid event type:%T to process", ev) } return nil }
func (p *RejectProxy) Serve(session *proxy.ProxySession, ev event.Event) error { if _, ok := ev.(*event.HTTPRequestEvent); ok { forbidden := &event.HTTPResponseEvent{} forbidden.SetId(ev.GetId()) forbidden.StatusCode = 404 proxy.HandleEvent(forbidden) } else { session.Close() } return nil }
func (p *GAEProxy) Serve(session *proxy.ProxySession, ev event.Event) error { if nil == session.Remote { session.SetRemoteChannel(p.cs.Select()) //session.Remote = p.cs.Select() if session.Remote == nil { session.Close() return fmt.Errorf("No proxy channel in PaasProxy") } } switch ev.(type) { case *event.ConnCloseEvent: case *event.ConnTestEvent: //session.Channel.Write(ev) case *event.HTTPRequestEvent: req := ev.(*event.HTTPRequestEvent) if strings.EqualFold(ev.(*event.HTTPRequestEvent).Method, "Connect") { session.SSLHijacked = true return nil } else { if session.SSLHijacked { req.URL = "https://" + req.Headers.Get("Host") + req.URL } else { req.URL = "http://" + req.Headers.Get("Host") + req.URL defer session.Close() } rangeFetch := false rangeHeader := req.Headers.Get("Range") if len(rangeHeader) > 0 { rangeFetch = true } // if !rangeFetch && strings.EqualFold(req.Method, "Get") && len(p.injectRangeRegex) > 0 && proxy.MatchPatterns(req.GetHost(), p.injectRangeRegex) { // rangeFetch = true // } adjustResp := func(r *event.HTTPResponseEvent) { r.Headers.Del("Transfer-Encoding") lenh := r.Headers.Get("Content-Length") if len(lenh) == 0 { r.Headers.Set("Content-Length", fmt.Sprintf("%d", len(r.Content))) } } if !rangeFetch { rev, err := session.Remote.Request(req) if nil != err { log.Printf("[ERROR]%v", err) session.Close() return err } rev.SetId(req.GetId()) switch rev.(type) { case *event.NotifyEvent: rerr := rev.(*event.NotifyEvent) if rerr.Code == event.ErrTooLargeResponse { log.Printf("[Range]Recv too large response") rangeFetch = true } else { log.Printf("[ERROR]:%d(%s)", rerr.Code, rerr.Reason) session.Close() return nil } case *event.HTTPResponseEvent: res := rev.(*event.HTTPResponseEvent) //log.Printf("#### %s %d %v %d", req.URL, res.StatusCode, res.Headers, len(res.Content)) adjustResp(res) //res.Headers.Set("Content-Length", fmt.Sprintf("%d", len(res.Content))) proxy.HandleEvent(rev) return nil default: log.Printf("Invalid event type:%T to process", ev) session.Close() return nil } } if rangeFetch { fetcher := &proxy.RangeFetcher{ SingleFetchLimit: 256 * 1024, ConcurrentFetcher: 3, C: session.Remote, } rev, err := fetcher.Fetch(req) if nil != err { log.Printf("[ERROR]%v", err) } if nil != rev { adjustResp(rev) proxy.HandleEvent(rev) } } return nil } default: session.Close() log.Printf("Invalid event type:%T to process", ev) } return nil }