func (v *VMessOutboundHandler) handleRequest(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, payload *buf.Buffer, input buf.Reader, finish *sync.Mutex) { defer finish.Unlock() writer := bufio.NewWriter(conn) defer writer.Release() session.EncodeRequestHeader(request, writer) bodyWriter := session.EncodeRequestBody(request, writer) defer bodyWriter.Release() if !payload.IsEmpty() { if err := bodyWriter.Write(payload); err != nil { log.Info("VMess|Outbound: Failed to write payload. Disabling connection reuse.", err) conn.SetReusable(false) } payload.Release() } writer.SetCached(false) if err := buf.PipeUntilEOF(input, bodyWriter); err != nil { conn.SetReusable(false) } if request.Option.Has(protocol.RequestOptionChunkStream) { err := bodyWriter.Write(buf.NewLocal(8)) if err != nil { conn.SetReusable(false) } } return }
func (this *VMessOutboundHandler) handleRequest(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, payload *alloc.Buffer, input v2io.Reader, finish *sync.Mutex) { defer finish.Unlock() writer := v2io.NewBufferedWriter(conn) defer writer.Release() session.EncodeRequestHeader(request, writer) bodyWriter := session.EncodeRequestBody(writer) var streamWriter v2io.Writer = v2io.NewAdaptiveWriter(bodyWriter) if request.Option.Has(protocol.RequestOptionChunkStream) { streamWriter = vmessio.NewAuthChunkWriter(streamWriter) } if !payload.IsEmpty() { if err := streamWriter.Write(payload); err != nil { conn.SetReusable(false) } } writer.SetCached(false) err := v2io.Pipe(input, streamWriter) if err != io.EOF { conn.SetReusable(false) } if request.Option.Has(protocol.RequestOptionChunkStream) { err := streamWriter.Write(alloc.NewLocalBuffer(32).Clear()) if err != nil { conn.SetReusable(false) } } streamWriter.Release() return }
func (v *VMessOutboundHandler) handleResponse(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, dest v2net.Destination, output buf.Writer, finish *sync.Mutex) { defer finish.Unlock() reader := bufio.NewReader(conn) defer reader.Release() header, err := session.DecodeResponseHeader(reader) if err != nil { conn.SetReusable(false) log.Warning("VMess|Outbound: Failed to read response from ", request.Destination(), ": ", err) return } v.handleCommand(dest, header.Command) conn.SetReusable(header.Option.Has(protocol.ResponseOptionConnectionReuse)) reader.SetCached(false) bodyReader := session.DecodeResponseBody(request, reader) defer bodyReader.Release() if err := buf.PipeUntilEOF(bodyReader, output); err != nil { conn.SetReusable(false) } return }
func (this *VMessOutboundHandler) handleResponse(session *encoding.ClientSession, conn internet.Connection, request *protocol.RequestHeader, dest v2net.Destination, output v2io.Writer, finish *sync.Mutex) { defer finish.Unlock() reader := v2io.NewBufferedReader(conn) defer reader.Release() header, err := session.DecodeResponseHeader(reader) if err != nil { conn.SetReusable(false) log.Warning("VMess|Outbound: Failed to read response from ", request.Destination(), ": ", err) return } go this.handleCommand(dest, header.Command) if !header.Option.Has(protocol.ResponseOptionConnectionReuse) { conn.SetReusable(false) } reader.SetCached(false) decryptReader := session.DecodeResponseBody(reader) var bodyReader v2io.Reader if request.Option.Has(protocol.RequestOptionChunkStream) { bodyReader = vmessio.NewAuthChunkReader(decryptReader) } else { bodyReader = v2io.NewAdaptiveReader(decryptReader) } err = v2io.Pipe(bodyReader, output) if err != io.EOF { conn.SetReusable(false) } bodyReader.Release() return }