コード例 #1
0
ファイル: direct.go プロジェクト: yinqiwen/gsnova
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

}
コード例 #2
0
ファイル: reject.go プロジェクト: yinqiwen/gsnova
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
}
コード例 #3
0
ファイル: paas.go プロジェクト: yinqiwen/gsnova
func (p *PaasProxy) 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.TCPChunkEvent:
		session.Remote.Write(ev)
	case *event.ConnTestEvent:
		session.Remote.Write(ev)
	case *event.UDPEvent:
		session.Remote.Write(ev)
	case *event.TCPOpenEvent:
		session.Remote.Write(ev)
	case *event.ConnCloseEvent:
		session.Remote.Write(ev)
	case *event.HTTPRequestEvent:
		if strings.EqualFold(ev.(*event.HTTPRequestEvent).Method, "Connect") {
			session.Hijacked = true
			host := ev.(*event.HTTPRequestEvent).Headers.Get("Host")
			tcpOpen := &event.TCPOpenEvent{Addr: host}
			tcpOpen.SetId(ev.GetId())
			session.Remote.Write(tcpOpen)
		} else {
			session.Remote.Write(ev)
		}
	default:
		session.Close()
		log.Printf("Invalid event type:%T to process", ev)
	}
	return nil

}
コード例 #4
0
ファイル: gae.go プロジェクト: yinqiwen/gsnova
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

}