@@ -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