@@ -116,7 +116,10 @@ internal class HttpBin {
116116            . childChannelInitializer  {  channel in 
117117                channel. pipeline. configureHTTPServerPipeline ( withPipeliningAssistance:  true ,  withErrorHandling:  true ) . flatMap  { 
118118                    if  let  simulateProxy =  simulateProxy { 
119-                         return  channel. pipeline. addHandler ( HTTPProxySimulator ( option:  simulateProxy) ,  position:  . first) 
119+                         let  responseEncoder  =  HTTPResponseEncoder ( ) 
120+                         let  requestDecoder  =  ByteToMessageHandler ( HTTPRequestDecoder ( leftOverBytesStrategy:  . forwardBytes) ) 
121+ 
122+                         return  channel. pipeline. addHandlers ( [ responseEncoder,  requestDecoder,  HTTPProxySimulator ( option:  simulateProxy,  encoder:  responseEncoder,  decoder:  requestDecoder) ] ,  position:  . first) 
120123                    }  else  { 
121124                        return  channel. eventLoop. makeSucceededFuture ( ( ) ) 
122125                    } 
@@ -138,43 +141,54 @@ internal class HttpBin {
138141} 
139142
140143final  class  HTTPProxySimulator :  ChannelInboundHandler ,  RemovableChannelHandler  { 
141-     typealias  InboundIn  =  ByteBuffer 
142-     typealias  InboundOut  =  ByteBuffer 
143-     typealias  OutboundOut  =  ByteBuffer 
144+     typealias  InboundIn  =  HTTPServerRequestPart 
145+     typealias  InboundOut  =  HTTPServerResponsePart 
146+     typealias  OutboundOut  =  HTTPServerResponsePart 
144147
145148    enum  Option  { 
146149        case  plaintext
147150        case  tls
148151    } 
149152
150153    let  option :  Option 
154+     let  encoder :  HTTPResponseEncoder 
155+     let  decoder :  ByteToMessageHandler < HTTPRequestDecoder > 
156+     var  head :  HTTPResponseHead 
151157
152-     init ( option:  Option )  { 
158+     init ( option:  Option ,  encoder :   HTTPResponseEncoder ,  decoder :   ByteToMessageHandler < HTTPRequestDecoder > )  { 
153159        self . option =  option
160+         self . encoder =  encoder
161+         self . decoder =  decoder
162+         self . head =  HTTPResponseHead ( version:  . init( major:  1 ,  minor:  1 ) ,  status:  . ok,  headers:  . init( [ ( " Content-Length " ,  " 0 " ) ,  ( " Connection " ,  " close " ) ] ) ) 
154163    } 
155164
156165    func  channelRead( context:  ChannelHandlerContext ,  data:  NIOAny )  { 
157-         let  response  =  """ 
158-         HTTP/1.1 200 OK \r \n \ 
159-         Content-Length: 0 \r \n \ 
160-         Connection: close \r \n \ 
161-          \r \n 
162-          """ 
163-         var  buffer  =  self . unwrapInboundIn ( data) 
164-         let  request  =  buffer. readString ( length:  buffer. readableBytes) !
165-         if  request. hasPrefix ( " CONNECT " )  { 
166-             var  buffer  =  context. channel. allocator. buffer ( capacity:  0 ) 
167-             buffer. writeString ( response) 
168-             context. write ( self . wrapInboundOut ( buffer) ,  promise:  nil ) 
169-             context. flush ( ) 
166+         let  request  =  self . unwrapInboundIn ( data) 
167+         switch  request { 
168+         case  . head( let  head) : 
169+             guard  head. method ==  . CONNECT else  { 
170+                 fatalError ( " Expected a CONNECT request " ) 
171+             } 
172+             if  head. headers. contains ( name:  " proxy-authorization " )  { 
173+                 if  head. headers [ " proxy-authorization " ] . first !=  " Basic YWxhZGRpbjpvcGVuc2VzYW1l "  { 
174+                     self . head. status =  . proxyAuthenticationRequired
175+                 } 
176+             } 
177+         case  . body: 
178+             ( ) 
179+         case  . end: 
180+             context. write ( self . wrapOutboundOut ( . head( self . head) ) ,  promise:  nil ) 
181+             context. writeAndFlush ( self . wrapOutboundOut ( . end( nil ) ) ,  promise:  nil ) 
182+ 
170183            context. channel. pipeline. removeHandler ( self ,  promise:  nil ) 
184+             context. channel. pipeline. removeHandler ( self . decoder,  promise:  nil ) 
185+             context. channel. pipeline. removeHandler ( self . encoder,  promise:  nil ) 
186+ 
171187            switch  self . option { 
172188            case  . tls: 
173189                _ =  HttpBin . configureTLS ( channel:  context. channel) 
174190            case  . plaintext:  break 
175191            } 
176-         }  else  { 
177-             fatalError ( " Expected a CONNECT request " ) 
178192        } 
179193    } 
180194} 
0 commit comments