@@ -2,6 +2,7 @@ package http
22
33import (
44 "bufio"
5+ "bytes"
56 "context"
67 "encoding/base64"
78 "io"
@@ -275,7 +276,7 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri
275276
276277 responseDone := func () error {
277278 responseReader := bufio .NewReaderSize (& buf.BufferedReader {Reader : link .Reader }, buf .Size )
278- response , err := http . ReadResponse (responseReader , request )
279+ response , err := readResponseAndHandle100Continue (responseReader , request , writer )
279280 if err == nil {
280281 http_proto .RemoveHopByHopHeaders (response .Header )
281282 if response .ContentLength >= 0 {
@@ -319,6 +320,38 @@ func (s *Server) handlePlainHTTP(ctx context.Context, request *http.Request, wri
319320 return result
320321}
321322
323+ // Sometimes, server might send 1xx response to client
324+ // it should not be processed by http proxy handler, just forward it to client
325+ func readResponseAndHandle100Continue (r * bufio.Reader , req * http.Request , writer io.Writer ) (* http.Response , error ) {
326+ // have a little look of response
327+ peekBytes , err := r .Peek (56 )
328+ if err == nil || err == bufio .ErrBufferFull {
329+ str := string (peekBytes )
330+ ResponseLine := strings .Split (str , "\r \n " )[0 ]
331+ _ , status , _ := strings .Cut (ResponseLine , " " )
332+ // only handle 1xx response
333+ if strings .HasPrefix (status , "1" ) {
334+ ResponseHeader1xx := []byte {}
335+ // read until \r\n\r\n (end of http response header)
336+ for {
337+ data , err := r .ReadSlice ('\n' )
338+ if err != nil {
339+ return nil , newError ("failed to read http 1xx response" ).Base (err ).AtError ()
340+ }
341+ ResponseHeader1xx = append (ResponseHeader1xx , data ... )
342+ if bytes .Equal (ResponseHeader1xx [len (ResponseHeader1xx )- 4 :], []byte {'\r' , '\n' , '\r' , '\n' }) {
343+ break
344+ }
345+ if len (ResponseHeader1xx ) > 1024 {
346+ return nil , newError ("too big http 1xx response" ).AtError ()
347+ }
348+ }
349+ writer .Write (ResponseHeader1xx )
350+ }
351+ }
352+ return http .ReadResponse (r , req )
353+ }
354+
322355func init () {
323356 common .Must (common .RegisterConfig ((* ServerConfig )(nil ), func (ctx context.Context , config interface {}) (interface {}, error ) {
324357 return NewServer (ctx , config .(* ServerConfig ))
0 commit comments