/*
* Copyright 2011 The Netty Project
*
* The Netty Project licenses this file to you under the Apache License,
* version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*/
package io.netty.handler.codec.http;
import io.netty.buffer.ChannelBuffer;
import io.netty.buffer.ChannelBuffers;
import io.netty.channel.ChannelInboundHandlerContext;
import io.netty.channel.ChannelOutboundHandlerContext;
import io.netty.handler.codec.MessageToMessageCodec;
import io.netty.handler.codec.embedder.EncoderEmbedder;
import io.netty.util.internal.QueueFactory;
import java.util.Queue;
/**
* Encodes the content of the outbound {@link HttpResponse} and {@link HttpChunk}.
* The original content is replaced with the new content encoded by the
* {@link EncoderEmbedder}, which is created by {@link #beginEncode(HttpMessage, String)}.
* Once encoding is finished, the value of the 'Content-Encoding' header
* is set to the target content encoding, as returned by
* {@link #beginEncode(HttpMessage, String)}.
* Also, the 'Content-Length' header is updated to the length of the
* encoded content. If there is no supported or allowed encoding in the
* corresponding {@link HttpRequest}'s {@code "Accept-Encoding"} header,
* {@link #beginEncode(HttpMessage, String)} should return {@code null} so that
* no encoding occurs (i.e. pass-through).
*
* Please note that this is an abstract class. You have to extend this class
* and implement {@link #beginEncode(HttpMessage, String)} properly to make
* this class functional. For example, refer to the source code of
* {@link HttpContentCompressor}.
*
* This handler must be placed after {@link HttpMessageEncoder} in the pipeline
* so that this handler can intercept HTTP responses before {@link HttpMessageEncoder}
* converts them into {@link ChannelBuffer}s.
*/
public abstract class HttpContentEncoder extends MessageToMessageCodec {
private final Queue acceptEncodingQueue = QueueFactory.createQueue();
private volatile EncoderEmbedder encoder;
/**
* Creates a new instance.
*/
protected HttpContentEncoder() {
}
@Override
public boolean isDecodable(Object msg) throws Exception {
return msg instanceof HttpMessage;
}
@Override
public HttpMessage decode(ChannelInboundHandlerContext ctx, HttpMessage msg)
throws Exception {
String acceptedEncoding = msg.getHeader(HttpHeaders.Names.ACCEPT_ENCODING);
if (acceptedEncoding == null) {
acceptedEncoding = HttpHeaders.Values.IDENTITY;
}
boolean offered = acceptEncodingQueue.offer(acceptedEncoding);
assert offered;
return msg;
}
@Override
public boolean isEncodable(Object msg) throws Exception {
return msg instanceof HttpMessage || msg instanceof HttpChunk;
}
@Override
public Object encode(ChannelOutboundHandlerContext