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

io.vertx.core.http.HttpClientRequest Maven / Gradle / Ivy

There is a newer version: 5.0.0.CR1
Show newest version
/*
 * Copyright (c) 2011-2019 Contributors to the Eclipse Foundation
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 * which is available at https://www.apache.org/licenses/LICENSE-2.0.
 *
 * SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 */

package io.vertx.core.http;

import io.vertx.codegen.annotations.*;
import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.MultiMap;
import io.vertx.core.buffer.Buffer;
import io.vertx.core.net.HostAndPort;
import io.vertx.core.net.NetSocket;
import io.vertx.core.streams.ReadStream;
import io.vertx.core.streams.WriteStream;

import java.util.function.Function;

/**
 * Represents a client-side HTTP request.
 * 

* Instances are created by an {@link HttpClient} instance, via one of the methods corresponding to the * specific HTTP methods, or the generic request methods. On creation the request will not have been written to the * wire. *

* Once a request has been obtained, headers can be set on it, and data can be written to its body if required. Once * you are ready to send the request, one of the {@link #end()} methods should be called. *

* Nothing is actually sent until the request has been internally assigned an HTTP connection. *

* The {@link HttpClient} instance will return an instance of this class immediately, even if there are no HTTP * connections available in the pool. Any requests sent before a connection is assigned will be queued * internally and actually sent when an HTTP connection becomes available from the pool. *

* The headers of the request are queued for writing either when the {@link #end()} method is called, or, when the first * part of the body is written, whichever occurs first. *

* This class supports both chunked and non-chunked HTTP. *

* It implements {@link io.vertx.core.streams.WriteStream} so it can be used with * {@link io.vertx.core.streams.Pipe} to pipe data with flow control. *

* An example of using this class is as follows: *

* * @author Tim Fox */ @VertxGen public interface HttpClientRequest extends WriteStream { @Override HttpClientRequest exceptionHandler(Handler handler); @Override HttpClientRequest setWriteQueueMaxSize(int maxSize); @Override HttpClientRequest drainHandler(Handler handler); /** * Override the request authority, when using HTTP/1.x this overrides the request {@code host} header, when using * HTTP/2 this sets the {@code authority} pseudo header. When the port is a negative value, the default * scheme port will be used. * *

The default request authority is the server host and port when connecting to the server. * * @param authority override the request authority * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest authority(HostAndPort authority); /** * Set the host value of the HTTP/1.1 {@code host} header or HTTP/2 {@code authority} pseudo header *

The initial value is the same as the server socket address host. *

Keep in mind that changing this value won't change the actual server socket address for this request. * * @param host the host part of the HTTP/1.1 {@code host} header or HTTP/2 {@code authority} pseudo header * @return a reference to this, so the API can be used fluently * @deprecated instead use {@link #authority(HostAndPort)} */ @Deprecated @Fluent HttpClientRequest setHost(String host); /** * @return the host value of the HTTP/1.1 {@code host} header or HTTP/2 {@code authority} pseudo header */ @Deprecated String getHost(); /** * Set the port value of the HTTP/1.1 {@code host} header or HTTP/2 {@code authority} pseudo header * *

Keep in mind that this won't change the actual server socket address for this request. *

The initial value is the same than the server socket address port. * * @param port the port part of the HTTP/1.1 {@code host} header or HTTP/2 {@code authority} pseudo header * @return a reference to this, so the API can be used fluently * @deprecated instead use {@link #authority(HostAndPort)} */ @Deprecated @Fluent HttpClientRequest setPort(int port); /** * @return the port value of the HTTP/1.1 {@code host} header or HTTP/2 {@code authority} pseudo header */ @Deprecated int getPort(); /** * Set the request to follow HTTP redirects up to {@link HttpClientOptions#getMaxRedirects()}. * * @param followRedirects {@code true} to follow HTTP redirects * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest setFollowRedirects(boolean followRedirects); /** * @return whether HTTP redirections should be followed */ boolean isFollowRedirects(); /** * Set the max number of HTTP redirects this request will follow. The default is {@code 0} which means * no redirects. * * @param maxRedirects the number of HTTP redirect to follow * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest setMaxRedirects(int maxRedirects); /** * @return the maximum number of HTTP redirections to follow */ int getMaxRedirects(); /** * @return the number of followed redirections for the current HTTP request */ int numberOfRedirections(); /** * If chunked is true then the request will be set into HTTP chunked mode * * @param chunked true if chunked encoding * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest setChunked(boolean chunked); /** * @return Is the request chunked? */ boolean isChunked(); /** * The HTTP method for the request. */ HttpMethod getMethod(); /** * Set the HTTP method for this request. * * @param method the HTTP method * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest setMethod(HttpMethod method); /** * @return the absolute URI corresponding to the HTTP request */ String absoluteURI(); /** * @return The URI of the request. */ String getURI(); /** * Set the request uri. * * @param uri the request uri * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest setURI(String uri); /** * @return The path part of the uri. For example /somepath/somemorepath/someresource.foo */ String path(); /** * @return the query part of the uri. For example someparam=32&someotherparam=x */ String query(); /** * @return The HTTP headers */ @CacheReturn MultiMap headers(); /** * Put an HTTP header * * @param name The header name * @param value The header value * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest putHeader(String name, String value); /** * Like {@link #putHeader(String, String)} but using CharSequence */ @GenIgnore(GenIgnore.PERMITTED_TYPE) @Fluent HttpClientRequest putHeader(CharSequence name, CharSequence value); /** * Put an HTTP header with multiple values * * @param name The header name * @param values The header values * @return @return a reference to this, so the API can be used fluently */ @GenIgnore(GenIgnore.PERMITTED_TYPE) @Fluent HttpClientRequest putHeader(String name, Iterable values); /** * Like {@link #putHeader(String, Iterable)} but using CharSequence */ @GenIgnore(GenIgnore.PERMITTED_TYPE) @Fluent HttpClientRequest putHeader(CharSequence name, Iterable values); /** * Set the trace operation of this request. * * @param op the operation * @return @return a reference to this, so the API can be used fluently */ HttpClientRequest traceOperation(String op); /** * @return the trace operation of this request */ String traceOperation(); /** * @return the HTTP version for this request */ HttpVersion version(); /** * Write a {@link String} to the request body, encoded as UTF-8. * * @param chunk the data chunk * @return a future completed with the result * @throws java.lang.IllegalStateException when no response handler is set */ Future write(String chunk); /** * Same as {@link #write(String)} but with an {@code handler} called when the operation completes */ void write(String chunk, Handler> handler); /** * Write a {@link String} to the request body, encoded using the encoding {@code enc}. * * @param chunk the data chunk * @param enc the encoding * @return a future completed with the result * @throws java.lang.IllegalStateException when no response handler is set */ Future write(String chunk, String enc); /** * Same as {@link #write(String,String)} but with an {@code handler} called when the operation completes */ void write(String chunk, String enc, Handler> handler); /** * If you send an HTTP request with the header {@code Expect} set to the value {@code 100-continue} * and the server responds with an interim HTTP response with a status code of {@code 100} and a Continue handler * has been set using this method, then the {@code handler} will be called. *

* You can then continue to write data to the request body and later end it. This is normally used in conjunction with * the {@link #sendHead()} method to force the request header to be written before the request has ended. * * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest continueHandler(@Nullable Handler handler); /** * If the server responds with an interim HTTP response with a status code of {@code 103} and a Early Hints handler * has been set using this method, then the {@code handler} will be called. * * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest earlyHintsHandler(@Nullable Handler handler); @Fluent HttpClientRequest redirectHandler(@Nullable Function> handler); /** * Forces the head of the request to be written before {@link #end()} is called on the request or any data is * written to it. *

* This is normally used to implement HTTP 100-continue handling, see {@link #continueHandler(io.vertx.core.Handler)} for * more information. * * @return a reference to this, so the API can be used fluently * @throws java.lang.IllegalStateException when no response handler is set */ Future sendHead(); /** * Like {@link #sendHead()} but with an handler after headers have been sent. The handler will be called with * the {@link HttpVersion} if it can be determined or null otherwise.

*/ @Fluent HttpClientRequest sendHead(Handler> completionHandler); /** * Create an HTTP tunnel to the server. * *

Send HTTP request headers to the server, then configures the transport to exchange * raw buffers when the server replies with an appropriate response: * *

    *
  • {@code 200} for HTTP {@code CONNECT} method
  • *
  • {@code 101} for HTTP/1.1 {@code GET} with {@code Upgrade} {@code connection} header
  • *
* *

The {@code handler} is called after response headers are received. * *

Use {@link HttpClientResponse#netSocket} to get a {@link NetSocket} for interacting * more conveniently with the server. * *

HTTP/1.1 pipe-lined requests are not supported.f * * @param handler the response completion handler */ void connect(Handler> handler); /** * Like {@link #connect(Handler)} but returns a {@code Future} of the asynchronous result */ Future connect(); /** * Set a callback for the associated {@link HttpClientResponse}. * *

This method does not modify the current request being sent. * * @param handler the completion handler * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest response(Handler> handler); /** * @return a future of the {@link HttpClientResponse}, see {@link #response(Handler)} */ Future response(); /** * Send the request with an empty body. * * @param handler the completion handler for the {@link HttpClientResponse} */ default void send(Handler> handler) { response(handler); end(); } /** * Like {@link #send(Handler)} but returns a {@code Future} of the asynchronous result */ default Future send() { end(); return response(); } /** * Send the request with a string {@code body}. * * @param handler the completion handler for the {@link HttpClientResponse} */ default void send(String body, Handler> handler) { response(handler); end(body); } /** * Like {@link #send(String, Handler)} but returns a {@code Future} of the asynchronous result */ default Future send(String body) { end(body); return response(); } /** * Send the request with a buffer {@code body}. * * @param handler the completion handler for the {@link HttpClientResponse} */ default void send(Buffer body, Handler> handler) { response(handler); end(body); } /** * Like {@link #send(Buffer, Handler)} but returns a {@code Future} of the asynchronous result */ default Future send(Buffer body) { end(body); return response(); } /** * Send the request with a stream {@code body}. * *

If the {@link HttpHeaders#CONTENT_LENGTH} is set then the request assumes this is the * length of the {stream}, otherwise the request will set a chunked {@link HttpHeaders#CONTENT_ENCODING}. * * @param handler the completion handler for the {@link HttpClientResponse} */ default void send(ReadStream body, Handler> handler) { MultiMap headers = headers(); if (headers == null || !headers.contains(HttpHeaders.CONTENT_LENGTH)) { setChunked(true); } response(handler); body.pipeTo(this); } /** * Like {@link #send(ReadStream, Handler)} but returns a {@code Future} of the asynchronous result */ default Future send(ReadStream body) { MultiMap headers = headers(); if (headers == null || !headers.contains(HttpHeaders.CONTENT_LENGTH)) { setChunked(true); } body.pipeTo(this); return response(); } /** * Same as {@link #end(Buffer)} but writes a String in UTF-8 encoding * * @param chunk the data chunk * @return a future completed with the result * @throws java.lang.IllegalStateException when no response handler is set */ Future end(String chunk); /** * Same as {@link #end(String)} but with an {@code handler} called when the operation completes */ void end(String chunk, Handler> handler); /** * Same as {@link #end(Buffer)} but writes a String with the specified encoding * * @param chunk the data chunk * @param enc the encoding * @return a future completed with the result * @throws java.lang.IllegalStateException when no response handler is set */ Future end(String chunk, String enc); /** * Same as {@link #end(String,String)} but with an {@code handler} called when the operation completes */ void end(String chunk, String enc, Handler> handler); /** * Same as {@link #end()} but writes some data to the request body before ending. If the request is not chunked and * no other data has been written then the {@code Content-Length} header will be automatically set * * @return a future completed with the result * @throws java.lang.IllegalStateException when no response handler is set */ @Override Future end(Buffer chunk); /** * Same as {@link #end(String)} but with an {@code handler} called when the operation completes */ @Override void end(Buffer chunk, Handler> handler); /** * Ends the request. If no data has been written to the request body, and {@link #sendHead()} has not been called then * the actual request won't get written until this method gets called. *

* Once the request has ended, it cannot be used any more, * * @return a future completed with the result * @throws java.lang.IllegalStateException when no response handler is set */ @Override Future end(); /** * Same as {@link #end()} but with an {@code handler} called when the operation completes */ @Override void end(Handler> handler); /** * Like {@link #idleTimeout(long)} but with a confusing name (hence the deprecation). * * @deprecated instead use {@link #idleTimeout(long)} */ @Deprecated @Fluent HttpClientRequest setTimeout(long timeout); /** * Sets the amount of time after which, if the request does not return any data within the timeout period, * the request/response is closed and the related futures are failed with a {@link java.util.concurrent.TimeoutException}, * e.g. {@code Future} or {@code Future} response body. * * @param timeout the amount of time in milliseconds. * @return a reference to this, so the API can be used fluently */ @Fluent default HttpClientRequest idleTimeout(long timeout) { return setTimeout(timeout); } /** * Set a push handler for this request.

* * The handler is called when the client receives a push promise from the server. The handler can be called * multiple times, for each push promise.

* * The handler is called with a read-only {@link HttpClientRequest}, the following methods can be called:

* *

    *
  • {@link HttpClientRequest#getMethod()}
  • *
  • {@link HttpClientRequest#getURI()}
  • *
  • {@link HttpClientRequest#headers()}
  • *
* * In addition the handler should call the {@link HttpClientRequest#response(Handler)} method to set an handler to * process the response.

* * @param handler the handler * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest pushHandler(Handler handler); /** * Reset this stream with the error code {@code 0}. * * @see #reset(long) */ default boolean reset() { return reset(0L); } /** * Reset this request: *

*

    *
  • for HTTP/2, this performs send an HTTP/2 reset frame with the specified error {@code code}
  • *
  • for HTTP/1.x, this closes the connection when the current request is inflight
  • *
*

* When the request has not yet been sent, the request will be aborted and false is returned as indicator. *

* * @param code the error code * @return {@code true} when reset has been performed */ boolean reset(long code); /** * Reset this request: *

*

    *
  • for HTTP/2, send an HTTP/2 reset frame with the specified error {@code code}
  • *
  • for HTTP/1.x, close the connection when the current request is inflight
  • *
*

* When the request has not yet been sent, the request will be aborted and {@code false} is returned as indicator. *

* * @param code the error code * @param cause an optional cause that can be attached to the error code * @return true when reset has been performed */ boolean reset(long code, Throwable cause); /** * @return the {@link HttpConnection} associated with this request */ @CacheReturn HttpConnection connection(); /** * Write an HTTP/2 frame to the request, allowing to extend the HTTP/2 protocol.

* * The frame is sent immediatly and is not subject to flow control.

* * This method must be called after the request headers have been sent and only for the protocol HTTP/2. * The {@link #sendHead(Handler)} should be used for this purpose. * * @param type the 8-bit frame type * @param flags the 8-bit frame flags * @param payload the frame payload * @return a reference to this, so the API can be used fluently */ @Fluent HttpClientRequest writeCustomFrame(int type, int flags, Buffer payload); /** * @return the id of the stream of this response, {@literal -1} when it is not yet determined, i.e * the request has not been yet sent or it is not supported HTTP/1.x */ default int streamId() { return -1; } /** * Like {@link #writeCustomFrame(int, int, Buffer)} but with an {@link HttpFrame}. * * @param frame the frame to write */ @Fluent default HttpClientRequest writeCustomFrame(HttpFrame frame) { return writeCustomFrame(frame.type(), frame.flags(), frame.payload()); } /** * Sets the priority of the associated stream. *

* This is not implemented for HTTP/1.x. * * @param streamPriority the priority of this request's stream */ @Fluent default HttpClientRequest setStreamPriority(StreamPriority streamPriority) { return this; } /** * @return the priority of the associated HTTP/2 stream for HTTP/2 otherwise {@code null} */ StreamPriority getStreamPriority(); }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy