
org.testifyproject.netty.handler.codec.http.HttpServerUpgradeHandler Maven / Gradle / Ivy
/*
* Copyright 2014 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 org.testifyproject.testifyprojectpliance with the License. You may obtain a
* copy of the License at:
*
* http://www.apache.org.testifyproject/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 org.testifyproject.testifyproject.netty.handler.codec.http;
import static org.testifyproject.testifyproject.netty.util.AsciiString.containsContentEqualsIgnoreCase;
import static org.testifyproject.testifyproject.netty.util.AsciiString.containsAllContentEqualsIgnoreCase;
import org.testifyproject.testifyproject.netty.buffer.Unpooled;
import org.testifyproject.testifyproject.netty.channel.ChannelFuture;
import org.testifyproject.testifyproject.netty.channel.ChannelFutureListener;
import org.testifyproject.testifyproject.netty.channel.ChannelHandlerContext;
import org.testifyproject.testifyproject.netty.util.ReferenceCountUtil;
import org.testifyproject.testifyproject.netty.util.ReferenceCounted;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import static org.testifyproject.testifyproject.netty.handler.codec.http.HttpResponseStatus.SWITCHING_PROTOCOLS;
import static org.testifyproject.testifyproject.netty.handler.codec.http.HttpVersion.HTTP_1_1;
import static org.testifyproject.testifyproject.netty.util.internal.ObjectUtil.checkNotNull;
/**
* A server-side handler that receives HTTP requests and optionally performs a protocol switch if
* the requested protocol is supported. Once an upgrade is performed, this handler removes itself
* from the pipeline.
*/
public class HttpServerUpgradeHandler extends HttpObjectAggregator {
/**
* The source codec that is used in the pipeline initially.
*/
public interface SourceCodec {
/**
* Removes this codec (i.e. all associated handlers) from the pipeline.
*/
void upgradeFrom(ChannelHandlerContext ctx);
}
/**
* A codec that the source can be upgraded to.
*/
public interface UpgradeCodec {
/**
* Gets all protocol-specific headers required by this protocol for a successful upgrade.
* Any supplied header will be required to appear in the {@link HttpHeaderNames#CONNECTION} header as well.
*/
Collection requiredUpgradeHeaders();
/**
* Adds any headers to the 101 Switching protocols response that are appropriate for this protocol.
*/
void prepareUpgradeResponse(ChannelHandlerContext ctx, FullHttpRequest upgradeRequest,
FullHttpResponse upgradeResponse);
/**
* Performs an HTTP protocol upgrade from the source codec. This method is responsible for
* adding all handlers required for the new protocol.
*
* @param ctx the context for the current handler.
* @param upgradeRequest the request that triggered the upgrade to this protocol. The
* upgraded protocol is responsible for sending the response.
* @param upgradeResponse a 101 Switching Protocols response that is populated with the
* {@link HttpHeaderNames#CONNECTION} and {@link HttpHeaderNames#UPGRADE} headers.
* The protocol is required to send this before sending any other frames back to the client.
* The headers may be augmented as necessary by the protocol before sending.
*/
void upgradeTo(ChannelHandlerContext ctx, FullHttpRequest upgradeRequest, FullHttpResponse upgradeResponse);
}
/**
* Creates a new {@link UpgradeCodec} for the requested protocol name.
*/
public interface UpgradeCodecFactory {
/**
* Invoked by {@link HttpServerUpgradeHandler} for all the requested protocol names in the order of
* the client preference. The first non-{@code null} {@link UpgradeCodec} returned by this method
* will be selected.
*
* @return a new {@link UpgradeCodec}, or {@code null} if the specified protocol name is not supported
*/
UpgradeCodec newUpgradeCodec(CharSequence protocol);
}
/**
* User event that is fired to notify about the org.testifyproject.testifyprojectpletion of an HTTP upgrade
* to another protocol. Contains the original upgrade request so that the response
* (if required) can be sent using the new protocol.
*/
public static final class UpgradeEvent implements ReferenceCounted {
private final CharSequence protocol;
private final FullHttpRequest upgradeRequest;
private UpgradeEvent(CharSequence protocol, FullHttpRequest upgradeRequest) {
this.protocol = protocol;
this.upgradeRequest = upgradeRequest;
}
/**
* The protocol that the channel has been upgraded to.
*/
public CharSequence protocol() {
return protocol;
}
/**
* Gets the request that triggered the protocol upgrade.
*/
public FullHttpRequest upgradeRequest() {
return upgradeRequest;
}
@Override
public int refCnt() {
return upgradeRequest.refCnt();
}
@Override
public UpgradeEvent retain() {
upgradeRequest.retain();
return this;
}
@Override
public UpgradeEvent retain(int increment) {
upgradeRequest.retain(increment);
return this;
}
@Override
public UpgradeEvent touch() {
upgradeRequest.touch();
return this;
}
@Override
public UpgradeEvent touch(Object hint) {
upgradeRequest.touch(hint);
return this;
}
@Override
public boolean release() {
return upgradeRequest.release();
}
@Override
public boolean release(int org.testifyproject.testifyprojectcrement) {
return upgradeRequest.release();
}
@Override
public String toString() {
return "UpgradeEvent [protocol=" + protocol + ", upgradeRequest=" + upgradeRequest + ']';
}
}
private final SourceCodec sourceCodec;
private final UpgradeCodecFactory upgradeCodecFactory;
private boolean handlingUpgrade;
/**
* Constructs the upgrader with the supported codecs.
*
* The handler instantiated by this constructor will reject an upgrade request with non-empty content.
* It should not be a concern because an upgrade request is most likely a GET request.
* If you have a client that sends a non-GET upgrade request, please consider using
* {@link #HttpServerUpgradeHandler(SourceCodec, UpgradeCodecFactory, int)} to specify the maximum
* length of the content of an upgrade request.
*
*
* @param sourceCodec the codec that is being used initially
* @param upgradeCodecFactory the factory that creates a new upgrade codec
* for one of the requested upgrade protocols
*/
public HttpServerUpgradeHandler(SourceCodec sourceCodec, UpgradeCodecFactory upgradeCodecFactory) {
this(sourceCodec, upgradeCodecFactory, 0);
}
/**
* Constructs the upgrader with the supported codecs.
*
* @param sourceCodec the codec that is being used initially
* @param upgradeCodecFactory the factory that creates a new upgrade codec
* for one of the requested upgrade protocols
* @param maxContentLength the maximum length of the content of an upgrade request
*/
public HttpServerUpgradeHandler(
SourceCodec sourceCodec, UpgradeCodecFactory upgradeCodecFactory, int maxContentLength) {
super(maxContentLength);
this.sourceCodec = checkNotNull(sourceCodec, "sourceCodec");
this.upgradeCodecFactory = checkNotNull(upgradeCodecFactory, "upgradeCodecFactory");
}
@Override
protected void org.testifyproject.testifyprojectcode(ChannelHandlerContext ctx, HttpObject msg, List
© 2015 - 2025 Weber Informatics LLC | Privacy Policy