Unexpected I/O exception on channel java.lang.IllegalStateException: Invalid Status Code 502

Request DefaultFullHttpRequest(decodeResult: success, version: HTTP/1.1, content: EmptyByteBufBE)

My Scala file:

val httpProtocol = http
.baseURL(“http://IP”)
.wsBaseURL(“ws://IP”)
.header(“Pragma”,“no-cache”)
.header(“Cache-Control”,“no-cache”)
.header(“Upgrade”,“websocket”)
.header(“Sec-WebSocket-Version”,“13”)
.header(“User-Agent”,“Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36”)
.header(“Accept-Encoding”,“gzip, deflate”)
.header(“Accept-Language”,“en-US,en;q=0.8,hi;q=0.6”)
.header(“Sec-WebSocket-Extensions”,“permessage-deflate; client_max_window_bits”)
.header(“Connection”,“Upgrade”)
.header(“Upgrade”,“websocket”)

val scn = scenario(“WebSocket”)
.feed(feeder)
.exec(ws(“Client Connection”).open(“URL”).check(wsAwait.within(300).until(1).regex(".reexp.")))
.pause(2)
.exec(ws(“Client Connection Close”).close)
setUp(scn.inject(atOnceUsers(1)).protocols(httpProtocol))

}

Please provide an actionable reproducer so we can investigate. Nothing we can do without one.

Thanks,

This is a websocket based request using gatling.

i am setting all the headers manually as mentioned in scenario/scala file.
But NGINX which proxies my application is rejecting the gatling request with HTTP 502 error.

I am surprised,if Gatling is adding any additional headers which are not accepted by NGINX ?
Is there any other setting i have to do on gatling side so websocket request works ?

The same request with the same headers is working with a local tool built on Browser + Jquery.

the log says:

07:00:09.988 [WARN ] o.a.n.h.WebSocketHandler - onError
java.lang.IllegalStateException: Invalid Status Code 502
at org.asynchttpclient.ws.WebSocketUpgradeHandler.onCompleted(WebSocketUpgradeHandler.java:81)
at org.asynchttpclient.netty.handler.WebSocketHandler$UpgradeCallback.call(WebSocketHandler.java:98)
at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.channelRead(AsyncHttpClientHandler.java:71)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:335)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:312)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:286)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:335)
at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:335)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1302)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:745)
07:00:09.989 [ERROR] o.a.n.h.WebSocketHandler - onError
java.lang.IllegalStateException: Invalid Status Code 502
at org.asynchttpclient.ws.WebSocketUpgradeHandler.onCompleted(WebSocketUpgradeHandler.java:81)
at org.asynchttpclient.netty.handler.WebSocketHandler.handleException(WebSocketHandler.java:206)
at org.asynchttpclient.netty.handler.AsyncHttpClientHandler.exceptionCaught(AsyncHttpClientHandler.java:200)
at io.netty.channel.AbstractChannelHandlerContext.invokeExceptionCaught(AbstractChannelHandlerContext.java:280)
at io.netty.channel.AbstractChannelHandlerContext.notifyHandlerException(AbstractChannelHandlerContext.java:843)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:358)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:335)
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438)
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:312)
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:286)
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:335)
at io.netty.handler.logging.LoggingHandler.channelRead(LoggingHandler.java:248)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:335)
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1302)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:356)
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:342)
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:131)
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:646)
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:581)
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:498)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:460)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:131)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:138)
at java.lang.Thread.run(Thread.java:745)
07:00:09.989 [DEBUG] o.a.n.c.ChannelManager - Closing Channel [id: 0x776bdc95, L:/#####:42682 ! R:/######:80]
07:00:09.989 [DEBUG] o.a.n.h.WebSocketHandler - Channel Closed: [id: 0x776bdc95, L:/#######:42682 ! R:/########:80] with attribute INSTANCE
07:00:12.006 [DEBUG] i.g.c.a.Exit - End user #1

07:00:12.007 [DEBUG] i.g.c.c.Controller - End user #1

The issue with gatling is , it is sending the custome header value is CamelCase,If Server Side validation is CaseSensitive then gatling request fails.

I don’t know which custom header you’re referring to, but quoting RFC2616:
“Each header field consists of a name followed by a colon (”:") and the field value. Field names are case-insensitive."

If your server deals with HTTP headers in a case sensitive manner, it’s buggy.

It is said,By definition only header field names are case sensitive not values.


Upgrade: WebSocket

Header name here: Upgrade can be in any case but the value WebSocket is case sensitive.
if server is validating the value “websocket” and gatling sending it like “WebSocket” even my scenario file contains “websocket”

I’m pretty sure we don’t rewrite header values (nor names). Please provide a reproducer.

Then, why would you have Gatling send an Upgrade header in a request??? It’s a response header!