All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.reactivex.netty.protocol.http.client.internal.RawRequest Maven / Gradle / Ivy

There is a newer version: 0.5.3-rc.2
Show newest version
/*
 * Copyright 2016 Netflix, Inc.
 *
 * Licensed 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.reactivex.netty.protocol.http.client.internal;

import io.netty.handler.codec.http.DefaultHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpRequest;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.LastHttpContent;
import io.netty.handler.codec.http.cookie.ClientCookieEncoder;
import io.netty.handler.codec.http.cookie.Cookie;
import io.reactivex.netty.channel.Connection;
import io.reactivex.netty.channel.FlushSelectorOperator;
import rx.Observable;
import rx.functions.Func1;

import java.util.Date;
import java.util.Map;
import java.util.Map.Entry;

public final class RawRequest {

    private final Redirector redirector;
    private final HttpRequest headers;
    @SuppressWarnings("rawtypes")
    private final Observable content;
    private final Func1 flushSelector;
    private final boolean hasTrailers;

    @SuppressWarnings("rawtypes")
    private RawRequest(HttpRequest headers, Observable content, Func1 flushSelector, boolean hasTrailers,
                       Redirector redirector) {
        this.headers = headers;
        this.content = content;
        this.flushSelector = flushSelector;
        this.hasTrailers = hasTrailers;
        this.redirector = redirector;
    }

    public RawRequest addHeader(CharSequence name, Object value) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().add(name, value);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest addHeaders(Map> headers) {
        HttpRequest headersCopy = _copyHeaders();
        for (Entry> header : headers.entrySet()) {
            headersCopy.headers().add(header.getKey(), header.getValue());
        }
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest addHeaderValues(CharSequence name, Iterable values) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().add(name, values);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest addCookie(Cookie cookie) {
        String cookieHeader = ClientCookieEncoder.STRICT.encode(cookie);
        return addHeader(HttpHeaderNames.COOKIE, cookieHeader);
    }

    public RawRequest addDateHeader(CharSequence name, Date value) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().add(name, value);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest addDateHeader(CharSequence name, Iterable values) {
        HttpRequest headersCopy = _copyHeaders();
        for (Date value : values) {
            headersCopy.headers().add(name, value);
        }
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setDateHeader(CharSequence name, Date value) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().set(name, value);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setHeader(CharSequence name, Object value) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().set(name, value);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setHeaders(Map> headers) {
        HttpRequest headersCopy = _copyHeaders();
        for (Entry> header : headers.entrySet()) {
            headersCopy.headers().set(header.getKey(), header.getValue());
        }
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setHeaderValues(CharSequence name, Iterable values) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().set(name, values);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setDateHeader(CharSequence name, Iterable values) {
        HttpRequest headersCopy = _copyHeaders();
        boolean addNow = false;
        for (Date value : values) {
            if (addNow) {
                headersCopy.headers().add(name, value);
            } else {
                headersCopy.headers().set(name, value);
                addNow = true;
            }
        }
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setKeepAlive(boolean keepAlive) {
        HttpRequest headersCopy = _copyHeaders();
        HttpUtil.setKeepAlive(headersCopy, keepAlive);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setTransferEncodingChunked() {
        HttpRequest headersCopy = _copyHeaders();
        HttpUtil.setTransferEncodingChunked(headersCopy, true);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest removeHeader(CharSequence name) {
        HttpRequest headersCopy = _copyHeaders();
        headersCopy.headers().remove(name);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setMethod(HttpMethod method) {
        HttpRequest headersCopy = _copyHeaders(headers.uri(), method);
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest setUri(String uri) {
        HttpRequest headersCopy = _copyHeaders(uri, headers.method());
        return new RawRequest<>(headersCopy, content, flushSelector, hasTrailers, redirector);
    }

    public RawRequest followRedirect(Redirector redirectHandler) {
        return new RawRequest<>(headers, content, flushSelector, hasTrailers, redirectHandler);
    }

    @SuppressWarnings({"rawtypes", "unchecked"})
    public Observable asObservable(Connection connection) {
        Observable toReturn = Observable.just(headers);

        if (null != content) {
            if (null == flushSelector) {
                toReturn = toReturn.concatWith(content);
            } else {
                toReturn = toReturn.concatWith(content.lift(new FlushSelectorOperator(flushSelector, connection)));
            }
        }

        if (!hasTrailers) {
            toReturn = toReturn.concatWith(Observable.just(LastHttpContent.EMPTY_LAST_CONTENT));
        }

        return toReturn;
    }

    private HttpRequest _copyHeaders() {
        return _copyHeaders(headers.uri(), headers.method());
    }

    private HttpRequest _copyHeaders(String uri, HttpMethod method) {
        final HttpRequest newHeaders = new DefaultHttpRequest(headers.protocolVersion(), method, uri);
        // TODO: May be we can optimize this by not copying
        for (Entry header : headers.headers()) {
            newHeaders.headers().set(header.getKey(), header.getValue());
        }
        return newHeaders;
    }

    public static  RawRequest create(HttpVersion version, HttpMethod httpMethod, String uri,
                                                 Redirector redirectHandler) {
        final HttpRequest headers = new DefaultHttpRequest(version, httpMethod, uri);
        return create(headers, null, null, false, redirectHandler);
    }

    @SuppressWarnings("rawtypes")
    public static  RawRequest create(HttpRequest headers, Observable content, boolean hasTrailers,
                                                 Redirector redirectHandler) {
        return create(headers, content, null, hasTrailers, redirectHandler);
    }

    @SuppressWarnings("rawtypes")
    public static  RawRequest  create(HttpRequest headers, Observable content,
                                                  Func1 flushSelector, boolean hasTrailers,
                                                  Redirector redirectHandler) {
        return new RawRequest<>(headers, content, flushSelector, hasTrailers, redirectHandler);
    }

    public HttpRequest getHeaders() {
        return headers;
    }

    @SuppressWarnings("rawtypes")
    public Observable getContent() {
        return content;
    }

    public Func1 getFlushSelector() {
        return flushSelector;
    }

    public boolean hasTrailers() {
        return hasTrailers;
    }

    public Redirector getRedirector() {
        return redirector;
    }
}