コード例 #1
0
ファイル: ssh.go プロジェクト: juju2013/gsnova
func (conn *SSHConnection) Request(sess *SessionConnection, ev event.Event) (err error, res event.Event) {
	f := func(local, remote net.Conn, ch chan int) {
		io.Copy(remote, local)
		local.Close()
		remote.Close()
		ch <- 1
	}
	switch ev.GetType() {
	case event.HTTP_REQUEST_EVENT_TYPE:
		req := ev.(*event.HTTPRequestEvent)
		if err := conn.initProxyConn(req.RawReq.Host, sess.Type == HTTPS_TUNNEL); nil != err {
			return err, nil
		}
		if sess.Type == HTTPS_TUNNEL {
			log.Printf("Session[%d]Request %s\n", req.GetHash(), util.GetURLString(req.RawReq, true))
			sess.LocalRawConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
			ch := make(chan int)
			go f(sess.LocalRawConn, conn.proxy_conn, ch)
			go f(conn.proxy_conn, sess.LocalRawConn, ch)
			<-ch
			<-ch
			conn.Close()
			sess.State = STATE_SESSION_CLOSE
		} else {
			log.Printf("Session[%d]Request %s\n", req.GetHash(), util.GetURLString(req.RawReq, true))
			err := req.RawReq.Write(conn.proxy_conn)
			if nil != err {
				conn.ssh_conn.CloseConn()
				return err, nil
			}
			conn.proxy_conn.SetReadDeadline(time.Now().Add(10 * time.Second))
			resp, err := http.ReadResponse(conn.proxy_conn_reader, req.RawReq)
			if err != nil {
				conn.ssh_conn.CloseConn()
				return err, nil
			}
			var zero time.Time
			conn.proxy_conn.SetReadDeadline(zero)
			err = resp.Write(sess.LocalRawConn)
			if nil == err {
				err = resp.Body.Close()
			}
			if nil != err || !util.IsResponseKeepAlive(resp) || !util.IsRequestKeepAlive(req.RawReq) {
				sess.LocalRawConn.Close()
				conn.Close()
				sess.State = STATE_SESSION_CLOSE
			} else {
				sess.State = STATE_RECV_HTTP
			}
		}
	default:
	}
	return nil, nil
}
コード例 #2
0
ファイル: gae.go プロジェクト: juju2013/gsnova
func (gae *GAEHttpConnection) doRangeFetch(req *http.Request, firstChunkRes *http.Response) {
	task := new(rangeFetchTask)
	task.FetchLimit = int(gae_cfg.FetchLimitSize)
	task.FetchWorkerNum = int(gae_cfg.ConcurrentRangeFetcher)
	task.SessionID = gae.sess.SessionID
	//	task.TaskValidation = func() bool {
	//		return !util.IsDeadConnection(gae.sess.LocalRawConn)
	//	}
	gae.rangeWorker = task
	fetch := func(preq *http.Request) (*http.Response, error) {
		ev := new(event.HTTPRequestEvent)
		ev.FromRequest(preq)
		ev.SetHash(gae.sess.SessionID)
		err, xres := gae.requestEvent(gaeHttpClient, gae.sess, ev)
		if nil != err {
			//try again
			err, xres = gae.requestEvent(gaeHttpClient, gae.sess, ev)
		}
		if nil == err {
			httpresev := xres.(*event.HTTPResponseEvent)
			httpres := httpresev.ToResponse()
			return httpres, err
		}
		return nil, err
	}
	pres, err := task.SyncGet(req, firstChunkRes, fetch)
	if nil == err {
		err = pres.Write(gae.sess.LocalRawConn)
		if nil != err {
			task.Close()
			gae.rangeWorker = nil
		}
		if nil != pres.Body {
			pres.Body.Close()
		}
	}
	if nil != err {
		log.Printf("Session[%d]Range task failed for reason:%v\n", gae.sess.SessionID, err)
	}
	if nil != err || !util.IsResponseKeepAlive(pres) || !util.IsRequestKeepAlive(req) {
		gae.sess.LocalRawConn.Close()
		gae.sess.State = STATE_SESSION_CLOSE
		gae.Close()
	}
}
コード例 #3
0
ファイル: forward.go プロジェクト: juju2013/gsnova
func (auto *ForwardConnection) Request(conn *SessionConnection, ev event.Event) (err error, res event.Event) {
	f := func(local, remote net.Conn) {
		n, err := io.Copy(remote, local)
		if nil != err {
			local.Close()
			remote.Close()
		}
		auto.forwardChan <- int(n)
	}
	//L:
	auto.closed = false
	switch ev.GetType() {
	case event.HTTP_REQUEST_EVENT_TYPE:
		req := ev.(*event.HTTPRequestEvent)
		addr := req.RawReq.Host
		if !strings.Contains(addr, ":") {
			if conn.Type == HTTPS_TUNNEL {
				addr = net.JoinHostPort(addr, "443")
			} else {
				addr = net.JoinHostPort(addr, "80")
			}
		}
		err = auto.initForwardConn(addr, conn.Type == HTTPS_TUNNEL)
		if nil != err {
			log.Printf("Failed to connect forward address for %s.\n", addr)
			return err, nil
		}
		if conn.Type == HTTPS_TUNNEL {
			log.Printf("Session[%d]Request %s\n", req.GetHash(), util.GetURLString(req.RawReq, true))
			if !auto.manager.overProxy || strings.HasPrefix(auto.conn_url.Scheme, "socks") {
				conn.LocalRawConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
			} else {
				auto.writeHttpRequest(req.RawReq)
			}
			go f(conn.LocalRawConn, auto.forward_conn)
			go f(auto.forward_conn, conn.LocalRawConn)
			atomic.AddInt32(&total_forwared_routine_num, 2)
			<-auto.forwardChan
			<-auto.forwardChan
			atomic.AddInt32(&total_forwared_routine_num, -2)
			auto.Close()
			conn.State = STATE_SESSION_CLOSE
		} else {
			log.Printf("Session[%d]Request %s\n", req.GetHash(), util.GetURLString(req.RawReq, true))
			if auto.manager.inject_crlf {
				log.Printf("Session[%d]Inject CRLF for %s", ev.GetHash(), req.RawReq.Host)
				auto.forward_conn.Write(CRLFs)
			}

			err := auto.writeHttpRequest(req.RawReq)
			if nil != err {
				return err, nil
			}
			if common.DebugEnable {
				var tmp bytes.Buffer
				req.RawReq.Write(&tmp)
				log.Printf("Session[%d]Send request \n%s\n", ev.GetHash(), tmp.String())
			}
			resp, err := http.ReadResponse(auto.buf_forward_conn, req.RawReq)
			if err != nil {
				log.Printf("Session[%d]Recv response with error %v\n", ev.GetHash(), err)
				return err, nil
			}
			//log.Printf("Session[%d]Recv response  %v\n", ev.GetHash(), resp)
			err = resp.Write(conn.LocalRawConn)
			resp.Body.Close()

			if common.DebugEnable {
				var tmp bytes.Buffer
				resp.Write(&tmp)
				log.Printf("Session[%d]Recv response \n%s\n", ev.GetHash(), tmp.String())
			}
			if nil != err || !util.IsResponseKeepAlive(resp) || !util.IsRequestKeepAlive(req.RawReq) {
				conn.LocalRawConn.Close()
				auto.Close()
				conn.State = STATE_SESSION_CLOSE
			} else {
				conn.State = STATE_RECV_HTTP
			}
		}
	default:
	}
	return nil, nil
}
コード例 #4
0
ファイル: google.go プロジェクト: juju2013/gsnova
func (google *GoogleConnection) Request(conn *SessionConnection, ev event.Event) (err error, res event.Event) {
	f := func(local, remote net.Conn, ch chan int) {
		io.Copy(remote, local)
		ch <- 1
		local.Close()
		remote.Close()
	}
	//L:
	switch ev.GetType() {

	case event.HTTP_REQUEST_EVENT_TYPE:
		req := ev.(*event.HTTPRequestEvent)
		if conn.Type == HTTPS_TUNNEL {
			var proxyConn net.Conn
			if len(googleLocalProxy) > 0 {
				proxyURL, _ := url.Parse(googleLocalProxy)
				proxyConn, err = net.Dial("tcp", proxyURL.Host)
				addr, _ := getLocalHostMapping(GOOGLE_HTTPS)

				connreq := req.RawReq
				connreq.Host = addr
				if nil == err {
					connreq.Write(proxyConn)
				}
			} else {
				addr := getGoogleHostport(true)
				proxyConn, err = net.DialTimeout("tcp", addr, connTimeoutSecs)
				if nil != err {
					//try again
					addr = getGoogleHostport(true)
					proxyConn, err = net.DialTimeout("tcp", addr, connTimeoutSecs)
				}
			}

			log.Printf("Session[%d]Request %s\n", req.GetHash(), util.GetURLString(req.RawReq, true))
			if nil == err {
				if len(googleLocalProxy) > 0 {
				} else {
					conn.LocalRawConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
				}
			} else {
				return fmt.Errorf("No google proxy reachable:%v", err), nil
			}
			ch := make(chan int)
			go f(conn.LocalRawConn, proxyConn, ch)
			go f(proxyConn, conn.LocalRawConn, ch)
			atomic.AddInt32(&total_google_routine_num, 2)
			<-ch
			<-ch
			atomic.AddInt32(&total_google_routine_num, -2)
			proxyConn.Close()
			google.Close()
			conn.State = STATE_SESSION_CLOSE
		} else {
			google.proxyAddr = req.RawReq.Host
			log.Printf("Session[%d]Request %s\n", req.GetHash(), util.GetURLString(req.RawReq, true))
			req.RawReq.URL.Scheme = "http"
			req.RawReq.RequestURI = ""
			var resp *http.Response
			tryProxy := func() (*http.Response, error) {
				if google.manager == httpGoogleManager {
					return httpGoogleClient.Do(req.RawReq)
				}
				return httpsGoogleClient.Do(req.RawReq)
			}
			resp, err = tryProxy()
			if nil != err && strings.EqualFold(req.Method, "GET") {
				//try proxy again
				resp, err = tryProxy()
			}
			if nil != err {
				var tmp bytes.Buffer
				req.RawReq.Write(&tmp)
				log.Printf("Session[%d]Request error:%v\n%s\n", req.GetHash(), err, tmp.String())
				return err, nil
			}
			err = resp.Write(conn.LocalRawConn)
			if nil != err || !util.IsResponseKeepAlive(resp) || !util.IsRequestKeepAlive(req.RawReq) {
				conn.LocalRawConn.Close()
				conn.State = STATE_SESSION_CLOSE
			} else {
				log.Printf("Session[%d]Res %d %v\n", req.GetHash(), resp.StatusCode, resp.Header)
				conn.State = STATE_RECV_HTTP
			}
		}
	default:
	}
	return nil, nil
}
コード例 #5
0
ファイル: gae.go プロジェクト: juju2013/gsnova
func (gae *GAEHttpConnection) Request(conn *SessionConnection, ev event.Event) (err error, res event.Event) {
	gae.closed = false
	gae.sess = conn
	if gae.over_tunnel {
		return gae.requestOverTunnel(conn, ev)
	}
	if nil == gae.gaeAuth {
		gae.gaeAuth = gae.manager.auths.Select().(*GAEAuth)
	}
	if ev.GetType() == event.HTTP_REQUEST_EVENT_TYPE {
		httpreq := ev.(*event.HTTPRequestEvent)
		if strings.EqualFold(httpreq.Method, "CONNECT") {
			//			//try https over tunnel
			//			if gae.gaeAuth.support_tunnel {
			//				gae.over_tunnel = true
			//				return gae.requestOverTunnel(conn, ev)
			//			}
			log.Printf("Session[%d]Request %s\n", httpreq.GetHash(), util.GetURLString(httpreq.RawReq, true))
			conn.LocalRawConn.Write([]byte("HTTP/1.1 200 Connection established\r\n\r\n"))
			tlscfg, err := common.TLSConfig(httpreq.GetHeader("Host"))
			if nil != err {
				return err, nil
			}
			conn.LocalRawConn = tls.Server(conn.LocalRawConn, tlscfg)
			conn.LocalBufferConn = bufio.NewReader(conn.LocalRawConn)
			conn.State = STATE_RECV_HTTP
			conn.Type = HTTPS_TUNNEL
			return nil, nil
		} else {
			if httpreq.Content.Len() == 0 {
				body := make([]byte, httpreq.RawReq.ContentLength)
				io.ReadFull(httpreq.RawReq.Body, body)
				httpreq.Content.Write(body)
			}
			scheme := "http://"
			if conn.Type == HTTPS_TUNNEL {
				scheme = "https://"
			}
			if !strings.HasPrefix(httpreq.Url, scheme) {
				httpreq.Url = scheme + httpreq.RawReq.Host + httpreq.Url
			}

			log.Printf("Session[%d]Request %s\n", httpreq.GetHash(), util.GetURLString(httpreq.RawReq, true))
			var httpres *http.Response
			if strings.EqualFold(httpreq.Method, "GET") {
				if hostPatternMatched(gae_cfg.InjectRange, httpreq.RawReq.Host) || gae.inject_range {
					//conn.State = STATE_RECV_HTTP
					gae.doRangeFetch(httpreq.RawReq, nil)
					return nil, nil
				}
			}
			err, res = gae.requestEvent(gaeHttpClient, conn, ev)
			if nil != err {
				//try again
				err, res = gae.requestEvent(gaeHttpClient, conn, ev)
			}
			if nil != err || nil == res {
				return
			}
			conn.State = STATE_RECV_HTTP
			httpresev := res.(*event.HTTPResponseEvent)
			if httpresev.Status == 403 {
				log.Printf("ERROR:Session[%d]Request %s %s is forbidon\n", httpreq.GetHash(), httpreq.Method, httpreq.RawReq.Host)
			}
			httpres, err = gae.handleHttpRes(conn, httpreq, httpresev)
			//			if nil != httpres {
			//				log.Printf("Session[%d]Response %d %v\n", httpreq.GetHash(), httpres.StatusCode, httpres.Header)
			//			}
			if nil != err || !util.IsResponseKeepAlive(httpres) || !util.IsRequestKeepAlive(httpreq.RawReq) {
				conn.LocalRawConn.Close()
				conn.State = STATE_SESSION_CLOSE
				gae.Close()
			}
			return err, nil
		}
	}
	return gae.requestEvent(gaeHttpClient, conn, ev)
}