Search in sources :

Example 1 with HttpRequestMethod

use of io.servicetalk.http.api.HttpRequestMethod in project servicetalk by apple.

the class HttpRequestDecoder method decodeHttpMethod.

private static HttpRequestMethod decodeHttpMethod(final ByteBuf buffer, final int start, final int length) {
    final String methodName = buffer.toString(start, length, US_ASCII);
    final HttpRequestMethod method = HttpRequestMethod.of(methodName);
    if (method != null) {
        return method;
    }
    try {
        return HttpRequestMethod.of(methodName, NONE);
    } catch (IllegalArgumentException cause) {
        throw new StacklessDecoderException("Invalid start-line: HTTP request method must follow a valid token format", cause);
    }
}
Also used : HttpRequestMethod(io.servicetalk.http.api.HttpRequestMethod)

Example 2 with HttpRequestMethod

use of io.servicetalk.http.api.HttpRequestMethod in project servicetalk by apple.

the class H2ToStH1ServerDuplexHandler method channelRead.

@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) {
    if (msg instanceof Http2HeadersFrame) {
        Http2HeadersFrame headersFrame = (Http2HeadersFrame) msg;
        Http2Headers h2Headers = headersFrame.headers();
        final HttpRequestMethod httpMethod;
        final String path;
        if (!readHeaders) {
            closeHandler.protocolPayloadBeginInbound(ctx);
            CharSequence method = h2Headers.getAndRemove(METHOD.value());
            CharSequence pathSequence = h2Headers.getAndRemove(PATH.value());
            if (pathSequence == null || method == null) {
                throw new IllegalArgumentException("a request must have " + METHOD + " and " + PATH + " headers");
            }
            path = pathSequence.toString();
            httpMethod = sequenceToHttpRequestMethod(method);
            readHeaders = true;
        } else {
            httpMethod = null;
            path = null;
        }
        if (headersFrame.isEndStream()) {
            if (httpMethod != null) {
                fireFullRequest(ctx, h2Headers, httpMethod, path);
            } else {
                ctx.fireChannelRead(h2TrailersToH1TrailersServer(h2Headers));
            }
            closeHandler.protocolPayloadEndInbound(ctx);
        } else if (httpMethod == null) {
            throw new IllegalArgumentException("a request must have " + METHOD + " and " + PATH + " headers");
        } else {
            ctx.fireChannelRead(newRequestMetaData(HTTP_2_0, httpMethod, path, h2HeadersToH1HeadersServer(h2Headers, httpMethod, false)));
        }
    } else if (msg instanceof Http2DataFrame) {
        readDataFrame(ctx, msg);
    } else {
        ctx.fireChannelRead(msg);
    }
}
Also used : HttpRequestMethod(io.servicetalk.http.api.HttpRequestMethod) Http2DataFrame(io.netty.handler.codec.http2.Http2DataFrame) Http2HeadersFrame(io.netty.handler.codec.http2.Http2HeadersFrame) Http2Headers(io.netty.handler.codec.http2.Http2Headers)

Example 3 with HttpRequestMethod

use of io.servicetalk.http.api.HttpRequestMethod in project servicetalk by apple.

the class H2ToStH1ServerDuplexHandler method sequenceToHttpRequestMethod.

private static HttpRequestMethod sequenceToHttpRequestMethod(CharSequence sequence) {
    String strMethod = sequence.toString();
    HttpRequestMethod reqMethod = HttpRequestMethod.of(strMethod);
    return reqMethod != null ? reqMethod : HttpRequestMethod.of(strMethod, NONE);
}
Also used : HttpRequestMethod(io.servicetalk.http.api.HttpRequestMethod)

Example 4 with HttpRequestMethod

use of io.servicetalk.http.api.HttpRequestMethod in project servicetalk by apple.

the class HttpResponseEncoder method isContentAlwaysEmpty.

@Override
protected boolean isContentAlwaysEmpty(HttpResponseMetaData msg) {
    // Peek from the queue here as sanitizeHeadersBeforeEncode is responsible for poll.
    final HttpRequestMethod method = methodQueue.peek();
    if (HEAD.equals(method)) {
        return true;
    }
    // Correctly handle special cases as stated in:
    // https://tools.ietf.org/html/rfc7230#section-3.3.3
    final HttpResponseStatus status = msg.status();
    if (status.statusClass() == INFORMATIONAL_1XX) {
        if (status.code() == SWITCHING_PROTOCOLS.code()) {
            // See https://tools.ietf.org/html/draft-ietf-hybi-thewebsocketprotocol-00#section-1.2
            return msg.headers().contains(SEC_WEBSOCKET_VERSION);
        }
        return true;
    }
    return status.code() == NO_CONTENT.code() || status.code() == NOT_MODIFIED.code();
}
Also used : HttpRequestMethod(io.servicetalk.http.api.HttpRequestMethod) HttpResponseStatus(io.servicetalk.http.api.HttpResponseStatus)

Example 5 with HttpRequestMethod

use of io.servicetalk.http.api.HttpRequestMethod in project servicetalk by apple.

the class HttpResponseEncoder method sanitizeHeadersBeforeEncode.

@Override
protected void sanitizeHeadersBeforeEncode(HttpResponseMetaData msg, boolean isAlwaysEmpty) {
    // This method has side effects on the methodQueue for the following reasons:
    // - createMessage will not necessarily fire a message up the pipeline.
    // - the trigger points on the queue are currently symmetric for the request/response decoder and
    // request/response encoder. We may use header information on the response decoder side, and the queue
    // interaction is conditional (1xx responses don't touch the queue).
    // - unit tests exist which verify these side effects occur, so if behavior of the internal classes changes the
    // unit test should catch it.
    // - this is the rough equivalent of what is done in Netty in terms of sequencing. Instead of trying to
    // iterate a decoded list it makes some assumptions about the base class ordering of events.
    HttpRequestMethod method = methodQueue.poll();
    HttpHeaders headers = msg.headers();
    if (isAlwaysEmpty) {
        final HttpResponseStatus status = msg.status();
        if (status.statusClass() == INFORMATIONAL_1XX || status.code() == NO_CONTENT.code()) {
            // Stripping Content-Length:
            // See https://tools.ietf.org/html/rfc7230#section-3.3.2
            headers.remove(CONTENT_LENGTH);
            // Stripping Transfer-Encoding:
            // See https://tools.ietf.org/html/rfc7230#section-3.3.1
            headers.remove(TRANSFER_ENCODING);
        }
    } else if (CONNECT.equals(method) && msg.status().statusClass() == SUCCESSFUL_2XX) {
        // Stripping Content-Length:
        // See https://tools.ietf.org/html/rfc7230#section-3.3.2
        headers.remove(CONTENT_LENGTH);
        // Stripping Transfer-Encoding:
        // See https://tools.ietf.org/html/rfc7230#section-3.3.1
        headers.remove(TRANSFER_ENCODING);
    }
}
Also used : HttpRequestMethod(io.servicetalk.http.api.HttpRequestMethod) HttpHeaders(io.servicetalk.http.api.HttpHeaders) HttpResponseStatus(io.servicetalk.http.api.HttpResponseStatus)

Aggregations

HttpRequestMethod (io.servicetalk.http.api.HttpRequestMethod)6 HttpResponseStatus (io.servicetalk.http.api.HttpResponseStatus)2 ChannelPipeline (io.netty.channel.ChannelPipeline)1 Http2DataFrame (io.netty.handler.codec.http2.Http2DataFrame)1 Http2Headers (io.netty.handler.codec.http2.Http2Headers)1 Http2HeadersFrame (io.netty.handler.codec.http2.Http2HeadersFrame)1 HttpHeaders (io.servicetalk.http.api.HttpHeaders)1 CopyByteBufHandlerChannelInitializer (io.servicetalk.transport.netty.internal.CopyByteBufHandlerChannelInitializer)1 ArrayDeque (java.util.ArrayDeque)1