use of org.jboss.netty.handler.codec.http.HttpChunkTrailer in project camel by apache.
the class HttpClientChannelHandler method messageReceived.
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent messageEvent) throws Exception {
// store response, as this channel handler is created per pipeline
Object msg = messageEvent.getMessage();
// it may be a chunked message
if (msg instanceof HttpChunk) {
HttpChunk chunk = (HttpChunk) msg;
if (LOG.isTraceEnabled()) {
LOG.trace("HttpChunk received: {} isLast: {}", chunk, chunk.isLast());
}
if (msg instanceof HttpChunkTrailer) {
// chunk trailer only has headers
HttpChunkTrailer trailer = (HttpChunkTrailer) msg;
for (Map.Entry<String, String> entry : trailer.trailingHeaders()) {
if (LOG.isTraceEnabled()) {
LOG.trace("Adding trailing header {}={}", entry.getKey(), entry.getValue());
}
response.headers().add(entry.getKey(), entry.getValue());
}
} else {
// append chunked content
buffer.writeBytes(chunk.getContent());
if (LOG.isTraceEnabled()) {
LOG.trace("Wrote {} bytes to chunk buffer", buffer.writerIndex());
}
}
if (chunk.isLast()) {
// the content is a copy of the buffer with the actual data we wrote to it
int end = buffer.writerIndex();
ChannelBuffer copy = buffer.copy(0, end);
// the copy must not be readable when the content was chunked, so set the index to the end
copy.setIndex(end, end);
response.setContent(copy);
// we get the all the content now, so call super to process the received message
super.messageReceived(ctx, messageEvent);
}
} else if (msg instanceof HttpResponse) {
response = (HttpResponse) msg;
Exchange exchange = super.getExchange(ctx);
if (!HttpHeaders.isKeepAlive(response)) {
// just want to make sure we close the channel if the keepAlive is not true
exchange.setProperty(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true);
}
if (LOG.isTraceEnabled()) {
LOG.trace("HttpResponse received: {} chunked:", response, response.isChunked());
}
if (response.getStatus().getCode() == HttpResponseStatus.CONTINUE.getCode()) {
if (LOG.isTraceEnabled()) {
LOG.trace("HttpResponse received: {}: {}", response, response.getStatus());
}
} else if (!response.isChunked()) {
// the response is not chunked so we have all the content
super.messageReceived(ctx, messageEvent);
} else {
// the response is chunkced so use a dynamic buffer to receive the content in chunks
buffer = ChannelBuffers.dynamicBuffer();
}
} else {
// ignore not supported message
if (LOG.isTraceEnabled() && msg != null) {
LOG.trace("Ignoring non supported response message of type {} -> {}", msg.getClass(), msg);
}
}
}
use of org.jboss.netty.handler.codec.http.HttpChunkTrailer in project load-balancer by RestComm.
the class HttpResponseHandler method handleHttpResponse.
private void handleHttpResponse(ChannelHandlerContext ctx, final MessageEvent e) throws Exception {
if (e.getMessage() instanceof HttpChunkTrailer) {
HttpChunkTrailer chunk = (HttpChunkTrailer) e.getMessage();
balancerRunner.balancerContext.httpBytesToClient.addAndGet(chunk.getContent().capacity());
if (chunk.isLast())
readingChunks = false;
AdvancedChannel ac = HttpChannelAssociations.channels.get(new AdvancedChannel(e.getChannel()));
Channel channel = null;
if (ac != null)
channel = ac.getChannel();
if (channel != null) {
if (logger.isDebugEnabled())
logger.debug("Send chunked response from : " + e.getChannel().getRemoteAddress() + " to : " + channel.getRemoteAddress() + " capacity : " + chunk.getContent().capacity());
channel.write(chunk);
}
} else if (!readingChunks || !(e.getMessage() instanceof DefaultHttpChunk)) {
response = (HttpResponse) e.getMessage();
int stsusCode = response.getStatus().getCode();
if (stsusCode > 399 && stsusCode < 600) {
AdvancedChannel ac = HttpChannelAssociations.channels.get(new AdvancedChannel(e.getChannel()));
if (ac != null && ac.isCheckNeed()) {
InetSocketAddress address = (InetSocketAddress) e.getChannel().getRemoteAddress();
InvocationContext invocationContext = balancerRunner.getLatestInvocationContext();
KeySip keySip = new KeySip(address.getHostString(), address.getPort(), false);
Node currNode = invocationContext.sipNodeMap(false).get(keySip);
if (currNode != null) {
currNode.setBad(true);
String instanseId = currNode.getProperties().get(Protocol.RESTCOMM_INSTANCE_ID);
if (instanseId != null)
invocationContext.httpNodeMap.get(new KeyHttp(currNode.getProperties().get(Protocol.RESTCOMM_INSTANCE_ID))).setBad(true);
logger.error("Error code [" + stsusCode + "] detected in HTTP response. From node : " + currNode + ". This node will marked as bad.");
String currInstanceId = (String) currNode.getProperties().get("Restcomm-Instance-Id");
if (currInstanceId != null)
logger.warn("Node : " + invocationContext.httpNodeMap.remove(new KeyHttp(currInstanceId)) + " from httpNodeMap");
// invocationContext.badSipNodeMap(false).put(keySip, currNode);
invocationContext.balancerAlgorithm.nodeRemoved(currNode);
}
// TODO CHECK REQUEST AND REMOVE NODE
}
}
updateStatistic(response);
balancerRunner.balancerContext.httpBytesToClient.addAndGet(response.getContent().capacity());
if (response.isChunked()) {
readingChunks = true;
}
AdvancedChannel ac = HttpChannelAssociations.channels.get(new AdvancedChannel(e.getChannel()));
Channel channel = null;
if (ac != null)
channel = ac.getChannel();
if (channel != null) {
if (logger.isDebugEnabled())
logger.debug("Send response from : " + e.getChannel().getRemoteAddress() + " to : " + channel.getRemoteAddress() + " capacity : " + response.getContent().capacity());
channel.write(response);
}
Set<String> headers = response.getHeaderNames();
if (headers.contains("Sec-WebSocket-Protocol")) {
if (response.getHeader("Sec-WebSocket-Protocol").equalsIgnoreCase("sip")) {
if (logger.isDebugEnabled()) {
logger.debug("WebSocket response");
}
wsVersion = response.getHeader(Names.SEC_WEBSOCKET_VERSION);
// Modify the Server pipeline
ChannelPipeline p = channel.getPipeline();
websocketModifyServerPipelineFactory = new WebsocketModifyServerPipelineFactory();
websocketModifyServerPipelineFactory.upgradeServerPipelineFactory(p, wsVersion);
}
}
} else {
HttpChunk chunk = (HttpChunk) e.getMessage();
balancerRunner.balancerContext.httpBytesToClient.addAndGet(chunk.getContent().capacity());
if (chunk.isLast())
readingChunks = false;
AdvancedChannel ac = HttpChannelAssociations.channels.get(new AdvancedChannel(e.getChannel()));
Channel channel = null;
if (ac != null)
channel = ac.getChannel();
if (channel != null) {
if (logger.isDebugEnabled())
logger.debug("Send chunked response from : " + e.getChannel().getRemoteAddress() + " to : " + channel.getRemoteAddress() + " capacity : " + chunk.getContent().capacity());
channel.write(chunk);
}
}
}
use of org.jboss.netty.handler.codec.http.HttpChunkTrailer in project databus by linkedin.
the class FooterAwareHttpChunkAggregator method messageReceived.
@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
Object msg = e.getMessage();
HttpMessage currentMessage = this.currentMessage;
if (msg instanceof HttpMessage) {
HttpMessage m = (HttpMessage) msg;
if (m.isChunked()) {
// A chunked message - remove 'Transfer-Encoding' header,
// initialize the cumulative buffer, and wait for incoming chunks.
List<String> encodings = m.getHeaders(HttpHeaders.Names.TRANSFER_ENCODING);
encodings.remove(HttpHeaders.Values.CHUNKED);
if (encodings.isEmpty()) {
m.removeHeader(HttpHeaders.Names.TRANSFER_ENCODING);
}
m.setContent(ChannelBuffers.dynamicBuffer(e.getChannel().getConfig().getBufferFactory()));
this.currentMessage = m;
} else {
// Not a chunked message - pass through.
this.currentMessage = null;
ctx.sendUpstream(e);
}
} else if (msg instanceof HttpChunk) {
// Sanity check
if (currentMessage == null) {
throw new IllegalStateException("received " + HttpChunk.class.getSimpleName() + " without " + HttpMessage.class.getSimpleName());
}
// Merge the received chunk into the content of the current message.
HttpChunk chunk = (HttpChunk) msg;
ChannelBuffer content = currentMessage.getContent();
if (content.readableBytes() > maxContentLength - chunk.getContent().readableBytes()) {
throw new TooLongFrameException("HTTP content length exceeded " + maxContentLength + " bytes.");
}
content.writeBytes(chunk.getContent());
if (chunk.isLast()) {
this.currentMessage = null;
currentMessage.setHeader(HttpHeaders.Names.CONTENT_LENGTH, String.valueOf(content.readableBytes()));
if (chunk instanceof HttpChunkTrailer) {
HttpChunkTrailer chunkTrailer = (HttpChunkTrailer) chunk;
for (Entry<String, String> footer : chunkTrailer.getHeaders()) {
currentMessage.setHeader(footer.getKey(), footer.getValue());
}
}
Channels.fireMessageReceived(ctx, currentMessage, e.getRemoteAddress());
}
} else {
// Neither HttpMessage or HttpChunk
ctx.sendUpstream(e);
}
}
use of org.jboss.netty.handler.codec.http.HttpChunkTrailer in project databus by linkedin.
the class TestResponseProcessors method testRegisterExceptionAfterStartCase3.
@Test
public void testRegisterExceptionAfterStartCase3() throws Exception {
TestAbstractQueue queue = new TestAbstractQueue();
TestConnectionStateMessage stateMsg = new TestConnectionStateMessage();
HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
RegisterHttpResponseProcessor processor = new RegisterHttpResponseProcessor(null, queue, stateMsg, null);
ChannelBuffer buf = getRegisterResponse();
HttpChunk httpChunk = new DefaultHttpChunk(buf);
HttpChunkTrailer httpChunkTrailer = new DefaultHttpChunkTrailer();
processor.startResponse(httpResponse);
processor.addChunk(httpChunk);
processor.addTrailer(httpChunkTrailer);
processor.channelException(new Exception("dummy exception"));
processor.finishResponse();
Assert.assertEquals("Error Handled", true, processor._errorHandled);
Assert.assertEquals("Processor Response State", AbstractHttpResponseProcessorDecorator.ResponseStatus.CHUNKS_FINISHED, processor._responseStatus);
Assert.assertEquals("Actor Queue Size", 1, queue.getMessages().size());
Assert.assertEquals("Expected ConnectionStateMessage", "TestConnectionStateMessage", queue.getMessages().get(0).getClass().getSimpleName());
TestConnectionStateMessage gotMsg = (TestConnectionStateMessage) (queue.getMessages().get(0));
Assert.assertEquals("Expected ConnectionStateMessage State", TestConnectionStateMessage.State.REGISTER_RESPONSE_ERROR, gotMsg._state);
Assert.assertEquals("No More CHunks", true, (null == stateMsg._registerResponse));
}
use of org.jboss.netty.handler.codec.http.HttpChunkTrailer in project databus by linkedin.
the class TestResponseProcessors method testTargetSCNOtherException.
@Test
public void testTargetSCNOtherException() throws Exception {
TestAbstractQueue queue = new TestAbstractQueue();
TestConnectionStateMessage stateMsg = new TestConnectionStateMessage();
DefaultHttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
httpResponse.setHeader(DatabusHttpHeaders.DATABUS_ERROR_CAUSE_CLASS_HEADER, "Other Dummy Error");
TestRemoteExceptionHandler remoteExHandler = new TestRemoteExceptionHandler();
remoteExHandler._exType = ExceptionType.OTHER_EXCEPTION;
Checkpoint cp = new Checkpoint();
cp.setConsumptionMode(DbusClientMode.BOOTSTRAP_CATCHUP);
BootstrapTargetScnHttpResponseProcessor processor = new BootstrapTargetScnHttpResponseProcessor(null, queue, stateMsg, cp, remoteExHandler, null);
ChannelBuffer buf = getScnResponse();
HttpChunk httpChunk = new DefaultHttpChunk(buf);
HttpChunkTrailer httpChunkTrailer = new DefaultHttpChunkTrailer();
processor.startResponse(httpResponse);
processor.addChunk(httpChunk);
processor.addTrailer(httpChunkTrailer);
processor.finishResponse();
Assert.assertEquals("Error Handled", false, processor._errorHandled);
Assert.assertEquals("Processor Response State", AbstractHttpResponseProcessorDecorator.ResponseStatus.CHUNKS_FINISHED, processor._responseStatus);
Assert.assertEquals("Actor Queue Size", 1, queue.getMessages().size());
Assert.assertEquals("Expected ConnectionStateMessage", "TestConnectionStateMessage", queue.getMessages().get(0).getClass().getSimpleName());
TestConnectionStateMessage gotMsg = (TestConnectionStateMessage) (queue.getMessages().get(0));
Assert.assertEquals("Expected ConnectionStateMessage State", TestConnectionStateMessage.State.TARGETSCN_RESPONSE_ERROR, gotMsg._state);
Assert.assertEquals("No response", true, (null == stateMsg._cp));
}
Aggregations