| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | package http | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	"bufio" | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 	"io" | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | 	"net" | 
					
						
							| 
									
										
										
										
											2015-12-14 16:26:29 +00:00
										 |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2015-12-14 16:26:29 +00:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 	"sync" | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-20 20:55:45 +02:00
										 |  |  | 	"v2ray.com/core/app" | 
					
						
							|  |  |  | 	"v2ray.com/core/app/dispatcher" | 
					
						
							|  |  |  | 	"v2ray.com/core/common" | 
					
						
							|  |  |  | 	v2io "v2ray.com/core/common/io" | 
					
						
							| 
									
										
										
										
											2016-10-16 14:22:21 +02:00
										 |  |  | 	"v2ray.com/core/common/loader" | 
					
						
							| 
									
										
										
										
											2016-08-20 20:55:45 +02:00
										 |  |  | 	"v2ray.com/core/common/log" | 
					
						
							|  |  |  | 	v2net "v2ray.com/core/common/net" | 
					
						
							|  |  |  | 	"v2ray.com/core/proxy" | 
					
						
							|  |  |  | 	"v2ray.com/core/proxy/registry" | 
					
						
							|  |  |  | 	"v2ray.com/core/transport/internet" | 
					
						
							|  |  |  | 	"v2ray.com/core/transport/ray" | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 16:46:31 +02:00
										 |  |  | // Server is a HTTP proxy server. | 
					
						
							|  |  |  | type Server struct { | 
					
						
							| 
									
										
										
										
											2016-01-03 23:30:37 +01:00
										 |  |  | 	sync.Mutex | 
					
						
							| 
									
										
										
										
											2016-01-31 17:01:28 +01:00
										 |  |  | 	accepting        bool | 
					
						
							|  |  |  | 	packetDispatcher dispatcher.PacketDispatcher | 
					
						
							| 
									
										
										
										
											2016-08-25 21:55:49 +02:00
										 |  |  | 	config           *ServerConfig | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | 	tcpListener      *internet.TCPHub | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 	meta             *proxy.InboundHandlerMeta | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-25 21:55:49 +02:00
										 |  |  | func NewServer(config *ServerConfig, packetDispatcher dispatcher.PacketDispatcher, meta *proxy.InboundHandlerMeta) *Server { | 
					
						
							| 
									
										
										
										
											2016-05-29 16:46:31 +02:00
										 |  |  | 	return &Server{ | 
					
						
							| 
									
										
										
										
											2016-01-31 17:01:28 +01:00
										 |  |  | 		packetDispatcher: packetDispatcher, | 
					
						
							|  |  |  | 		config:           config, | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 		meta:             meta, | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 16:46:31 +02:00
										 |  |  | func (this *Server) Port() v2net.Port { | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 	return this.meta.Port | 
					
						
							| 
									
										
										
										
											2016-01-19 23:41:40 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 16:46:31 +02:00
										 |  |  | func (this *Server) Close() { | 
					
						
							| 
									
										
										
										
											2016-01-03 23:30:37 +01:00
										 |  |  | 	this.accepting = false | 
					
						
							|  |  |  | 	if this.tcpListener != nil { | 
					
						
							| 
									
										
										
										
											2016-01-04 00:33:25 +01:00
										 |  |  | 		this.Lock() | 
					
						
							| 
									
										
										
										
											2016-01-27 22:11:31 +01:00
										 |  |  | 		this.tcpListener.Close() | 
					
						
							| 
									
										
										
										
											2016-01-03 23:30:37 +01:00
										 |  |  | 		this.tcpListener = nil | 
					
						
							|  |  |  | 		this.Unlock() | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-04 00:38:22 +02:00
										 |  |  | func (this *Server) Start() error { | 
					
						
							| 
									
										
										
										
											2016-01-19 23:41:40 +01:00
										 |  |  | 	if this.accepting { | 
					
						
							| 
									
										
										
										
											2016-06-04 00:38:22 +02:00
										 |  |  | 		return nil | 
					
						
							| 
									
										
										
										
											2016-01-19 23:41:40 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | 	tcpListener, err := internet.ListenTCP(this.meta.Address, this.meta.Port, this.handleConnection, this.meta.StreamSettings) | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-06-04 14:25:13 +02:00
										 |  |  | 		log.Error("HTTP: Failed listen on ", this.meta.Address, ":", this.meta.Port, ": ", err) | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 		return err | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-01-04 08:41:01 +01:00
										 |  |  | 	this.Lock() | 
					
						
							| 
									
										
										
										
											2016-01-03 23:30:37 +01:00
										 |  |  | 	this.tcpListener = tcpListener | 
					
						
							| 
									
										
										
										
											2016-01-04 08:41:01 +01:00
										 |  |  | 	this.Unlock() | 
					
						
							| 
									
										
										
										
											2016-01-03 23:30:37 +01:00
										 |  |  | 	this.accepting = true | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	return nil | 
					
						
							| 
									
										
										
										
											2015-12-14 16:26:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 23:53:38 +01:00
										 |  |  | func parseHost(rawHost string, defaultPort v2net.Port) (v2net.Destination, error) { | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 	port := defaultPort | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	host, rawPort, err := net.SplitHostPort(rawHost) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		if addrError, ok := err.(*net.AddrError); ok && strings.Contains(addrError.Err, "missing port") { | 
					
						
							|  |  |  | 			host = rawHost | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2016-09-20 11:53:05 +02:00
										 |  |  | 			return v2net.Destination{}, err | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		intPort, err := strconv.Atoi(rawPort) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-09-20 11:53:05 +02:00
										 |  |  | 			return v2net.Destination{}, err | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		port = v2net.Port(intPort) | 
					
						
							| 
									
										
										
										
											2015-12-14 16:26:29 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	if ip := net.ParseIP(host); ip != nil { | 
					
						
							| 
									
										
										
										
											2015-12-16 23:53:38 +01:00
										 |  |  | 		return v2net.TCPDestination(v2net.IPAddress(ip), port), nil | 
					
						
							| 
									
										
										
										
											2015-12-15 00:53:40 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-16 23:53:38 +01:00
										 |  |  | 	return v2net.TCPDestination(v2net.DomainAddress(host), port), nil | 
					
						
							| 
									
										
										
										
											2015-12-14 16:26:29 +00:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | func (this *Server) handleConnection(conn internet.Connection) { | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 	defer conn.Close() | 
					
						
							| 
									
										
										
										
											2016-07-10 15:34:14 +02:00
										 |  |  | 	timedReader := v2net.NewTimeOutReader(this.config.Timeout, conn) | 
					
						
							| 
									
										
										
										
											2016-07-16 13:22:34 +02:00
										 |  |  | 	reader := bufio.NewReaderSize(timedReader, 2048) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	request, err := http.ReadRequest(reader) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-06-03 20:21:46 +02:00
										 |  |  | 		if err != io.EOF { | 
					
						
							|  |  |  | 			log.Warning("HTTP: Failed to read http request: ", err) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-02 00:57:08 +02:00
										 |  |  | 	log.Info("HTTP: Request to Method [", request.Method, "] Host [", request.Host, "] with URL [", request.URL, "]") | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	defaultPort := v2net.Port(80) | 
					
						
							|  |  |  | 	if strings.ToLower(request.URL.Scheme) == "https" { | 
					
						
							|  |  |  | 		defaultPort = v2net.Port(443) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	host := request.Host | 
					
						
							|  |  |  | 	if len(host) == 0 { | 
					
						
							|  |  |  | 		host = request.URL.Host | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	dest, err := parseHost(host, defaultPort) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2016-06-02 00:57:08 +02:00
										 |  |  | 		log.Warning("HTTP: Malformed proxy host (", host, "): ", err) | 
					
						
							| 
									
										
										
										
											2016-01-11 12:35:28 +01:00
										 |  |  | 		return | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-05 15:02:15 +02:00
										 |  |  | 	log.Access(conn.RemoteAddr(), request.URL, log.AccessAccepted, "") | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | 	session := &proxy.SessionInfo{ | 
					
						
							| 
									
										
										
										
											2016-08-14 23:20:23 +02:00
										 |  |  | 		Source:      v2net.DestinationFromAddr(conn.RemoteAddr()), | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | 		Destination: dest, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	if strings.ToUpper(request.Method) == "CONNECT" { | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | 		this.handleConnect(request, session, reader, conn) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	} else { | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | 		this.handlePlainHTTP(request, session, reader, conn) | 
					
						
							| 
									
										
										
										
											2015-12-16 15:52:40 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-12-15 22:13:09 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | func (this *Server) handleConnect(request *http.Request, session *proxy.SessionInfo, reader io.Reader, writer io.Writer) { | 
					
						
							| 
									
										
										
										
											2015-12-16 15:52:40 +01:00
										 |  |  | 	response := &http.Response{ | 
					
						
							|  |  |  | 		Status:        "200 OK", | 
					
						
							|  |  |  | 		StatusCode:    200, | 
					
						
							|  |  |  | 		Proto:         "HTTP/1.1", | 
					
						
							|  |  |  | 		ProtoMajor:    1, | 
					
						
							|  |  |  | 		ProtoMinor:    1, | 
					
						
							|  |  |  | 		Header:        http.Header(make(map[string][]string)), | 
					
						
							|  |  |  | 		Body:          nil, | 
					
						
							|  |  |  | 		ContentLength: 0, | 
					
						
							|  |  |  | 		Close:         false, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-07-16 13:22:34 +02:00
										 |  |  | 	response.Write(writer) | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | 	ray := this.packetDispatcher.DispatchToOutbound(this.meta, session) | 
					
						
							| 
									
										
										
										
											2015-12-16 15:52:40 +01:00
										 |  |  | 	this.transport(reader, writer, ray) | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-29 16:46:31 +02:00
										 |  |  | func (this *Server) transport(input io.Reader, output io.Writer, ray ray.InboundRay) { | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	var wg sync.WaitGroup | 
					
						
							|  |  |  | 	wg.Add(2) | 
					
						
							|  |  |  | 	defer wg.Wait() | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-16 15:52:40 +01:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2016-04-18 19:01:24 +02:00
										 |  |  | 		v2reader := v2io.NewAdaptiveReader(input) | 
					
						
							|  |  |  | 		defer v2reader.Release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		v2io.Pipe(v2reader, ray.InboundInput()) | 
					
						
							| 
									
										
										
										
											2016-04-18 18:44:10 +02:00
										 |  |  | 		ray.InboundInput().Close() | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 		wg.Done() | 
					
						
							| 
									
										
										
										
											2015-12-16 15:52:40 +01:00
										 |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2016-04-18 19:01:24 +02:00
										 |  |  | 		v2writer := v2io.NewAdaptiveWriter(output) | 
					
						
							|  |  |  | 		defer v2writer.Release() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 		v2io.Pipe(ray.InboundOutput(), v2writer) | 
					
						
							| 
									
										
										
										
											2016-04-18 18:44:10 +02:00
										 |  |  | 		ray.InboundOutput().Release() | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 		wg.Done() | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-12-15 16:00:47 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-20 23:27:06 +01:00
										 |  |  | // @VisibleForTesting | 
					
						
							|  |  |  | func StripHopByHopHeaders(request *http.Request) { | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	// Strip hop-by-hop header basaed on RFC: | 
					
						
							|  |  |  | 	// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.5.1 | 
					
						
							|  |  |  | 	// https://www.mnot.net/blog/2011/07/11/what_proxies_must_do | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	request.Header.Del("Proxy-Connection") | 
					
						
							|  |  |  | 	request.Header.Del("Proxy-Authenticate") | 
					
						
							|  |  |  | 	request.Header.Del("Proxy-Authorization") | 
					
						
							|  |  |  | 	request.Header.Del("TE") | 
					
						
							|  |  |  | 	request.Header.Del("Trailers") | 
					
						
							|  |  |  | 	request.Header.Del("Transfer-Encoding") | 
					
						
							|  |  |  | 	request.Header.Del("Upgrade") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// TODO: support keep-alive | 
					
						
							|  |  |  | 	connections := request.Header.Get("Connection") | 
					
						
							|  |  |  | 	request.Header.Set("Connection", "close") | 
					
						
							|  |  |  | 	if len(connections) == 0 { | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, h := range strings.Split(connections, ",") { | 
					
						
							|  |  |  | 		request.Header.Del(strings.TrimSpace(h)) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-02 00:57:08 +02:00
										 |  |  | func (this *Server) GenerateResponse(statusCode int, status string) *http.Response { | 
					
						
							|  |  |  | 	hdr := http.Header(make(map[string][]string)) | 
					
						
							|  |  |  | 	hdr.Set("Connection", "close") | 
					
						
							|  |  |  | 	return &http.Response{ | 
					
						
							|  |  |  | 		Status:        status, | 
					
						
							|  |  |  | 		StatusCode:    statusCode, | 
					
						
							|  |  |  | 		Proto:         "HTTP/1.1", | 
					
						
							|  |  |  | 		ProtoMajor:    1, | 
					
						
							|  |  |  | 		ProtoMinor:    1, | 
					
						
							|  |  |  | 		Header:        hdr, | 
					
						
							|  |  |  | 		Body:          nil, | 
					
						
							|  |  |  | 		ContentLength: 0, | 
					
						
							|  |  |  | 		Close:         false, | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | func (this *Server) handlePlainHTTP(request *http.Request, session *proxy.SessionInfo, reader *bufio.Reader, writer io.Writer) { | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	if len(request.URL.Host) <= 0 { | 
					
						
							| 
									
										
										
										
											2016-06-02 00:57:08 +02:00
										 |  |  | 		response := this.GenerateResponse(400, "Bad Request") | 
					
						
							| 
									
										
										
										
											2016-07-16 13:22:34 +02:00
										 |  |  | 		response.Write(writer) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	request.Host = request.URL.Host | 
					
						
							| 
									
										
										
										
											2016-02-20 23:27:06 +01:00
										 |  |  | 	StripHopByHopHeaders(request) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-14 17:08:01 +02:00
										 |  |  | 	ray := this.packetDispatcher.DispatchToOutbound(this.meta, session) | 
					
						
							| 
									
										
										
										
											2016-04-18 18:44:10 +02:00
										 |  |  | 	defer ray.InboundInput().Close() | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 	defer ray.InboundOutput().Release() | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 	var finish sync.WaitGroup | 
					
						
							|  |  |  | 	finish.Add(1) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	go func() { | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 		defer finish.Done() | 
					
						
							|  |  |  | 		requestWriter := v2io.NewBufferedWriter(v2io.NewChainWriter(ray.InboundInput())) | 
					
						
							|  |  |  | 		err := request.Write(requestWriter) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			log.Warning("HTTP: Failed to write request: ", err) | 
					
						
							|  |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		requestWriter.Flush() | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	finish.Add(1) | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		defer finish.Done() | 
					
						
							| 
									
										
										
										
											2016-05-25 22:36:52 +02:00
										 |  |  | 		responseReader := bufio.NewReader(v2io.NewChanReader(ray.InboundOutput())) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 		response, err := http.ReadResponse(responseReader, request) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 			log.Warning("HTTP: Failed to read response: ", err) | 
					
						
							| 
									
										
										
										
											2016-06-02 00:57:08 +02:00
										 |  |  | 			response = this.GenerateResponse(503, "Service Unavailable") | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		responseWriter := v2io.NewBufferedWriter(writer) | 
					
						
							|  |  |  | 		err = response.Write(responseWriter) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			log.Warning("HTTP: Failed to write response: ", err) | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 			return | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 		responseWriter.Flush() | 
					
						
							| 
									
										
										
										
											2015-12-31 23:34:08 +00:00
										 |  |  | 	}() | 
					
						
							| 
									
										
										
										
											2016-05-25 09:32:26 +02:00
										 |  |  | 	finish.Wait() | 
					
						
							| 
									
										
										
										
											2015-10-28 12:13:27 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2016-05-07 14:08:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | type ServerFactory struct{} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-10-02 23:43:58 +02:00
										 |  |  | func (this *ServerFactory) StreamCapability() v2net.NetworkList { | 
					
						
							|  |  |  | 	return v2net.NetworkList{ | 
					
						
							|  |  |  | 		Network: []v2net.Network{v2net.Network_RawTCP}, | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func (this *ServerFactory) Create(space app.Space, rawConfig interface{}, meta *proxy.InboundHandlerMeta) (proxy.InboundHandler, error) { | 
					
						
							|  |  |  | 	if !space.HasApp(dispatcher.APP_ID) { | 
					
						
							| 
									
										
										
										
											2016-08-18 08:21:20 +02:00
										 |  |  | 		return nil, common.ErrBadConfiguration | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	return NewServer( | 
					
						
							| 
									
										
										
										
											2016-08-25 21:55:49 +02:00
										 |  |  | 		rawConfig.(*ServerConfig), | 
					
						
							| 
									
										
										
										
											2016-06-14 22:54:08 +02:00
										 |  |  | 		space.GetApp(dispatcher.APP_ID).(dispatcher.PacketDispatcher), | 
					
						
							|  |  |  | 		meta), nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-05-07 14:08:27 +02:00
										 |  |  | func init() { | 
					
						
							| 
									
										
										
										
											2016-10-16 14:22:21 +02:00
										 |  |  | 	registry.MustRegisterInboundHandlerCreator(loader.GetType(new(ServerConfig)), new(ServerFactory)) | 
					
						
							| 
									
										
										
										
											2016-05-07 14:08:27 +02:00
										 |  |  | } |