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

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

/*
 * 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.DataObject;
import io.vertx.codegen.annotations.GenIgnore;
import io.vertx.codegen.json.annotations.JsonGen;
import io.vertx.core.MultiMap;
import io.vertx.core.VertxException;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.*;

import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import static io.vertx.codegen.annotations.GenIgnore.PERMITTED_TYPE;

/**
 * Options describing how an {@link HttpClient} will connect to make a request.
 *
 * @author Julien Viet
 */
@DataObject
@JsonGen(publicConverter = false)
public class RequestOptions extends HttpConnectOptions {

  /**
   * The default value for server method = {@code null}
   */
  public static final SocketAddress DEFAULT_SERVER = null;

  /**
   * The default value for HTTP method = {@link HttpMethod#GET}
   */
  public static final HttpMethod DEFAULT_HTTP_METHOD = HttpMethod.GET;

  /**
   * The default value for host name = {@code null}
   */
  public static final String DEFAULT_HOST = null;

  /**
   * The default value for port = {@code null}
   */
  public static final Integer DEFAULT_PORT = null;

  /**
   * The default value for SSL = {@code null}
   */
  public static final Boolean DEFAULT_SSL = null;

  /**
   * The default request URI = {@code "/"}
   */
  public static final String DEFAULT_URI = "/";

  /**
   * Follow redirection by default = {@code false}
   */
  public static final boolean DEFAULT_FOLLOW_REDIRECTS = false;

  /**
   * The default request timeout = {@code -1L} (disabled)
   */
  public static final long DEFAULT_TIMEOUT = -1L;

  /**
   * The default connect timeout = {@code -1L} (disabled)
   */
  public static final long DEFAULT_CONNECT_TIMEOUT = -1L;

  /**
   * The default idle timeout = {@code -1L} (disabled)
   */
  public static final long DEFAULT_IDLE_TIMEOUT = -1L;

  private HttpMethod method;
  private String uri;
  private MultiMap headers;
  private boolean followRedirects;
  private long timeout;
  private long idleTimeout;
  private String traceOperation;
  private String routingKey;

  /**
   * Default constructor
   */
  public RequestOptions() {
    super();
  }

  /**
   * Copy constructor
   *
   * @param other  the options to copy
   */
  public RequestOptions(RequestOptions other) {
    super(other);
    setMethod(other.method);
    setURI(other.uri);
    setFollowRedirects(other.followRedirects);
    setIdleTimeout(other.idleTimeout);
    setTimeout(other.timeout);
    if (other.headers != null) {
      setHeaders(MultiMap.caseInsensitiveMultiMap().setAll(other.headers));
    }
    setTraceOperation(other.traceOperation);
  }

  /**
   * Create options from JSON
   *
   * @param json the JSON
   */
  public RequestOptions(JsonObject json) {
    super(json);
    RequestOptionsConverter.fromJson(json, this);
    String method = json.getString("method");
    if (method != null) {
      setMethod(HttpMethod.valueOf(method));
    }
    JsonObject headers = json.getJsonObject("headers");
    if (headers != null) {
      for (Map.Entry entry : headers) {
        Object value = entry.getValue();
        if (value instanceof String) {
          this.addHeader(entry.getKey(), (String) value);
        } else if (value instanceof Iterable) {
          for (Object subValue : ((Iterable) value)) {
            if (subValue instanceof String) {
              this.addHeader(entry.getKey(), (String) subValue);
            }
          }
        }
      }
    }
  }

  @Override
  protected void init() {
    super.init();
    method = DEFAULT_HTTP_METHOD;
    uri = DEFAULT_URI;
    followRedirects = DEFAULT_FOLLOW_REDIRECTS;
    timeout = DEFAULT_TIMEOUT;
    idleTimeout = DEFAULT_IDLE_TIMEOUT;
    traceOperation = null;
  }

  public RequestOptions setProxyOptions(ProxyOptions proxyOptions) {
    super.setProxyOptions(proxyOptions);
    return this;
  }

  public RequestOptions setServer(Address server) {
    super.setServer(server);
    return this;
  }

  /**
   * Get the HTTP method to be used by the client request.
   *
   * @return  the HTTP method
   */
  @GenIgnore
  public HttpMethod getMethod() {
    return method;
  }

  /**
   * Set the HTTP method to be used by the client request.
   *
   * @return a reference to this, so the API can be used fluently
   */
  @GenIgnore
  public RequestOptions setMethod(HttpMethod method) {
    this.method = method;
    return this;
  }

  public RequestOptions setHost(String host) {
    super.setHost(host);
    return this;
  }

  public RequestOptions setPort(Integer port) {
    super.setPort(port);
    return this;
  }

  public RequestOptions setSsl(Boolean ssl) {
    super.setSsl(ssl);
    return this;
  }

  public RequestOptions setSslOptions(ClientSSLOptions sslOptions) {
    super.setSslOptions(sslOptions);
    return this;
  }

  /**
   * @return the request relative URI
   */
  public String getURI() {
    return uri;
  }

  /**
   * Set the request relative URI.
   *
   * @param uri  the relative uri
   * @return a reference to this, so the API can be used fluently
   */
  public RequestOptions setURI(String uri) {
    this.uri = uri;
    return this;
  }

  /**
   * @return {@code true} when the client should follow redirection
   */
  public Boolean getFollowRedirects() {
    return followRedirects;
  }

  /**
   * Set whether to follow HTTP redirect
   *
   * @param followRedirects  whether to follow redirect
   * @return a reference to this, so the API can be used fluently
   */
  public RequestOptions setFollowRedirects(Boolean followRedirects) {
    this.followRedirects = followRedirects;
    return this;
  }

  /**
   * @see #setTimeout(long)
   */
  public long getTimeout() {
    return timeout;
  }

  /**
   * Sets both connect and idle timeouts for the request
   *
   * 
    *
  • connect timeout: if the request is not obtained from the client within the timeout period, the {@code Future} * obtained from the client is failed with a {@link java.util.concurrent.TimeoutException}.
  • *
  • idle timeout: 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.
  • *
* * The connect and idle timeouts can be set separately using {@link #setConnectTimeout(long)} and {@link #setIdleTimeout(long)} */ public RequestOptions setTimeout(long timeout) { this.timeout = timeout; return this; } public RequestOptions setConnectTimeout(long timeout) { super.setConnectTimeout(timeout); return this; } /** * @return 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} */ public long getIdleTimeout() { return idleTimeout; } /** * 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. * *

The timeout starts after a connection is obtained from the client, similar to calling * {@link HttpClientRequest#idleTimeout(long)}. * * @param timeout the amount of time in milliseconds. * @return a reference to this, so the API can be used fluently */ public RequestOptions setIdleTimeout(long timeout) { this.idleTimeout = timeout; return this; } private URL parseUrl(String surl) { // Note - parsing a URL this way is slower than specifying host, port and relativeURI try { return new URL(surl); } catch (MalformedURLException e) { throw new VertxException("Invalid url: " + surl, e); } } /** * Parse an absolute URI to use, this will update the {@code ssl}, {@code host}, * {@code port} and {@code uri} fields. * * @param absoluteURI the uri to use * @return a reference to this, so the API can be used fluently */ public RequestOptions setAbsoluteURI(String absoluteURI) { Objects.requireNonNull(absoluteURI, "Cannot set a null absolute URI"); URL url = parseUrl(absoluteURI); return setAbsoluteURI(url); } /** * Like {@link #setAbsoluteURI(String)} but using an {@link URL} parameter. * * @param url the uri to use * @return a reference to this, so the API can be used fluently */ @GenIgnore(PERMITTED_TYPE) public RequestOptions setAbsoluteURI(URL url) { Objects.requireNonNull(url, "Cannot set a null absolute URI"); Boolean ssl = Boolean.FALSE; int port = url.getPort(); String relativeUri = url.getPath().isEmpty() ? "/" + url.getFile() : url.getFile(); String protocol = url.getProtocol(); switch (protocol) { case "http": if (port == -1) { port = 80; } break; case "https": { ssl = Boolean.TRUE; if (port == -1) { port = 443; } break; } default: throw new IllegalArgumentException(); } setURI(relativeUri); setPort(port); setSsl(ssl); setHost(url.getHost()); return this; } /** * Add a request header. * * @param key the header key * @param value the header value * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions addHeader(String key, String value) { return addHeader((CharSequence) key, value); } /** * Add a request header. * * @param key the header key * @param value the header value * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions addHeader(CharSequence key, CharSequence value) { checkHeaders(); Objects.requireNonNull(key, "no null key accepted"); Objects.requireNonNull(value, "no null value accepted"); headers.add(key, value); return this; } @GenIgnore public RequestOptions addHeader(CharSequence key, Iterable values) { checkHeaders(); Objects.requireNonNull(key, "no null key accepted"); Objects.requireNonNull(values, "no null values accepted"); headers.add(key, values); return this; } /** * Set a request header. * * @param key the header key * @param value the header value * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions putHeader(String key, String value) { return putHeader((CharSequence) key, value); } /** * Set a request header. * * @param key the header key * @param value the header value * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions putHeader(CharSequence key, CharSequence value) { checkHeaders(); headers.set(key, value); return this; } @GenIgnore public RequestOptions putHeader(CharSequence key, Iterable values) { checkHeaders(); headers.set(key, values); return this; } /** * Add a request header. * * @param key the header key * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions removeHeader(String key) { return removeHeader((CharSequence) key); } /** * Add a request header. * * @param key the header key * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions removeHeader(CharSequence key) { if (headers != null) { headers.remove(key); } return this; } /** * Set request headers from a multi-map. * * @param headers the headers * @return a reference to this, so the API can be used fluently */ @GenIgnore public RequestOptions setHeaders(MultiMap headers) { this.headers = headers; return this; } /** * Get the request headers * * @return the headers */ @GenIgnore public MultiMap getHeaders() { return headers; } private void checkHeaders() { if (headers == null) { headers = HttpHeaders.headers(); } } /** * @return the trace operation override */ public String getTraceOperation() { return traceOperation; } /** * Override the operation the tracer use for this request. When no operation is set, the HTTP method is used * instead. * * @param op the override * @return a reference to this, so the API can be used fluently */ public RequestOptions setTraceOperation(String op) { this.traceOperation = op; return this; } /** * Return the routing key, the routing key can be used by a Vert.x client side sticky load balancer to * pin the request to a remote HTTP server. * * @return the routing key */ public String getRoutingKey() { return routingKey; } /** * Set the routing key, the routing key can be used by a Vert.x client side sticky load balancer * to pin the request to a remote HTTP server. * * @param key the routing key * @return a reference to this, so the API can be used fluently */ public RequestOptions setRoutingKey(String key) { this.routingKey = key; return this; } public JsonObject toJson() { JsonObject json = super.toJson(); RequestOptionsConverter.toJson(this, json); if (method != null) { json.put("method", method.name()); } if (this.headers != null) { JsonObject headers = new JsonObject(); for (String name : this.headers.names()) { List values = this.headers.getAll(name); if (values.size() == 1) { headers.put(name, values.iterator().next()); } else { headers.put(name, values); } } json.put("headers", headers); } return json; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy