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

org.asyncflows.protocol.http.server.HttpExchange Maven / Gradle / Ivy

There is a newer version: 0.1.1
Show newest version
/*
 * Copyright (c) 2018 Konstantin Plotnikov
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal in the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

package org.asyncflows.protocol.http.server;

import org.asyncflows.io.AChannel;
import org.asyncflows.io.AInput;
import org.asyncflows.io.AOutput;
import org.asyncflows.protocol.http.common.Scope;
import org.asyncflows.protocol.http.common.headers.HttpHeaders;
import org.asyncflows.core.Promise;
import org.asyncflows.core.function.ACloseable;

import java.net.SocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;

/**
 * The interface represent a context of the single HTTP exchange.
 * Note that it is a low level interface. The higher-level API
 * is supposed to be provided over it.
 */
public interface HttpExchange extends ACloseable {
    /**
     * The key on server scope that allows getting the server address.
     */
    Scope.Key SERVER_ADDRESS = new Scope.Key<>(HttpExchange.class, "serverAddress");

    /**
     * Get request scope, the scope is available for the lifetime of the request. It could be used to store information
     * by filters along to request handling chain.
     *
     * @return the request scope
     */
    Scope getExchangeScope();

    /**
     * Get request scope, the scope is available for the lifetime of the request. It could be used to store information
     * by filters along to request handling chain.
     *
     * @return the request scope
     */
    Scope getServerScope();

    /**
     * @return the request method
     */
    String getMethod();

    /**
     * The effective request URL represents all information needed to route the request. This information is computed
     * according to RFC 7230, Section 5.5.
     * The information about path, host, and protocol should be taken from this URL.
     *
     * @return the effective request URL
     */
    URI getRequestUri();

    /**
     * @return the remote IP address (this is a hop address, so it might return a proxy address)
     */
    SocketAddress getRemoteAddress();

    /**
     * @return the local IP address (this is a hop address, so it returns address beyond a nat in
     * the case of port forwarding).
     */
    SocketAddress getLocalAddress();

    /**
     * @return the request headers
     */
    HttpHeaders getRequestHeaders();

    /**
     * Get input stream. When the first read request is scheduled for input, "101 continue" request
     * is sent for HTTP 1.1 case if needed.
     *
     * @return the input, always non-null but might be zero-size.
     */
    AInput getInput();

    /**
     * @return the length of input, if it is known.
     */
    Long getInputLength();

    /**
     * Do intermediate response (except for protocol switching). In practice, "100 continue" is sent automatically,
     * as soon as input starts to be read. So intermediate response could be just "102 processing" from WebDAV,
     * or some other extension over HTTP.
     *
     * @param status  the status code
     * @param reason  the status reason (null for the default text)
     * @param headers the headers
     * @return the promise for output stream that correspond to content mode the promise might resolve to null,
     * if the response should not have a content basing on request and .
     */
    Promise intermediateResponse(int status, String reason, HttpHeaders headers);

    /**
     * Start responding. This is most generic version of the response method.
     *
     * @param status  the status code`
     * @param reason  the status reason (null for the default text)
     * @param headers the headers
     * @param length  the length or null
     * @return the promise for output stream that correspond to content mode the promise might resolve to null,
     * if the response should not have a content basing on request or response code.
     */
    Promise> respond(int status, String reason, HttpHeaders headers, Long length);

    /**
     * Start responding with the default reason message.
     *
     * @param status  the status line
     * @param headers the headers
     * @param length  the length or null
     * @return the promise for output stream that correspond to content mode the promise might resolve to null,
     * if the response should not have a content basing on request and .
     */
    Promise> respond(int status, HttpHeaders headers, Long length);

    /**
     * Start responding with unknown length and default status message.
     *
     * @param status  the status line
     * @param headers the headers
     * @return the promise for output stream that correspond to content mode the promise might resolve to null,
     * if the response should not have a content basing on request and .
     */
    Promise> respond(int status, HttpHeaders headers);

    /**
     * Read trailers.
     *
     * @return the promise that resolves when trailers are available or it is known that they will not be available.
     * the promise might resolve to null, if trailers are not supported by the current entity.
     */
    Promise readTrailers();

    /**
     * In case when HTTP connect request is handled or protocol upgrade happened, this method allows to receive
     * the rest of the underlying connection for the switched protocol after replying normally. The connection
     * returns only after the both input and output are closed, so they would not interfere.
     *
     * @param status  the status line
     * @param reason  the status reason (null for the default text)
     * @param headers the headers
     * @return a channel for the switched protocol
     */
    Promise> switchProtocol(int status, String reason, HttpHeaders headers);

    // TODO HTTP2 push: Promise pushRequest(URI uri) ?
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy