org.xbib.netty.http.client.api.Request Maven / Gradle / Ivy
package org.xbib.netty.http.client.api;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.buffer.ByteBufUtil;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.handler.codec.http.DefaultHttpHeaders;
import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpHeaderValues;
import io.netty.handler.codec.http.HttpHeaders;
import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpUtil;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
import io.netty.handler.codec.http2.HttpConversionUtil;
import io.netty.util.AsciiString;
import org.xbib.net.PercentEncoder;
import org.xbib.net.PercentEncoders;
import org.xbib.net.URL;
import org.xbib.netty.http.common.HttpAddress;
import org.xbib.netty.http.common.HttpParameters;
import org.xbib.netty.http.common.HttpResponse;
import org.xbib.netty.http.common.cookie.Cookie;
import java.nio.charset.Charset;
import java.nio.charset.MalformedInputException;
import java.nio.charset.StandardCharsets;
import java.nio.charset.UnmappableCharacterException;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;
/**
* HTTP client request.
*/
public final class Request {
private final URL url;
private final HttpVersion httpVersion;
private final HttpMethod httpMethod;
private final HttpHeaders headers;
private final Collection cookies;
private final ByteBuf content;
private final List bodyData;
private final long timeoutInMillis;
private final boolean followRedirect;
private final int maxRedirects;
private int redirectCount;
private final boolean isBackOff;
private final BackOff backOff;
private CompletableFuture completableFuture;
private ResponseListener responseListener;
private Request(URL url, HttpVersion httpVersion, HttpMethod httpMethod,
HttpHeaders headers, Collection cookies, ByteBuf content, List bodyData,
long timeoutInMillis, boolean followRedirect, int maxRedirect, int redirectCount,
boolean isBackOff, BackOff backOff, ResponseListener responseListener) {
this.url = url;
this.httpVersion = httpVersion;
this.httpMethod = httpMethod;
this.headers = headers;
this.cookies = cookies;
this.content = content;
this.bodyData = bodyData;
this.timeoutInMillis = timeoutInMillis;
this.followRedirect = followRedirect;
this.maxRedirects = maxRedirect;
this.redirectCount = redirectCount;
this.isBackOff = isBackOff;
this.backOff = backOff;
this.responseListener = responseListener;
}
public URL url() {
return url;
}
public String absolute() {
return url.toExternalForm();
}
public String relative() {
return url.relativeReference();
}
public HttpVersion httpVersion() {
return httpVersion;
}
public HttpMethod httpMethod() {
return httpMethod;
}
public HttpHeaders headers() {
return headers;
}
public Collection cookies() {
return cookies;
}
public ByteBuf content() {
return content;
}
public List getBodyData() {
return bodyData;
}
/**
* Return the timeout in milliseconds per request.
* This overrides the read timeout of the client.
* @return timeout timeout in milliseconds
*/
public long getTimeoutInMillis() {
return timeoutInMillis;
}
public boolean isFollowRedirect() {
return followRedirect;
}
public boolean isBackOff() {
return isBackOff;
}
public BackOff getBackOff() {
return backOff;
}
public boolean canRedirect() {
if (!followRedirect) {
return false;
}
if (redirectCount >= maxRedirects) {
return false;
}
redirectCount = redirectCount + 1;
return true;
}
public void release() {
if (content != null) {
content.release();
}
}
@Override
public String toString() {
return "Request[url=" + url +
",version=" + httpVersion +
",method=" + httpMethod +
",headers=" + headers.entries() +
",content=" + (content != null && content.readableBytes() >= 16 ?
content.copy(0, 16).toString(StandardCharsets.UTF_8) + "..." :
content != null ? content.toString(StandardCharsets.UTF_8) : "") +
"]";
}
public Request setCompletableFuture(CompletableFuture completableFuture) {
this.completableFuture = completableFuture;
return this;
}
public CompletableFuture getCompletableFuture() {
return completableFuture;
}
public void setResponseListener(ResponseListener responseListener) {
this.responseListener = responseListener;
}
public void onResponse(HttpResponse httpResponse) {
if (responseListener != null) {
responseListener.onResponse(httpResponse);
}
if (completableFuture != null) {
completableFuture.complete(this);
}
}
public static Builder get() {
return builder(HttpMethod.GET);
}
public static Builder put() {
return builder(HttpMethod.PUT);
}
public static Builder post() {
return builder(HttpMethod.POST);
}
public static Builder delete() {
return builder(HttpMethod.DELETE);
}
public static Builder head() {
return builder(HttpMethod.HEAD);
}
public static Builder patch() {
return builder(HttpMethod.PATCH);
}
public static Builder trace() {
return builder(HttpMethod.TRACE);
}
public static Builder options() {
return builder(HttpMethod.OPTIONS);
}
public static Builder connect() {
return builder(HttpMethod.CONNECT);
}
public static Builder builder(HttpMethod httpMethod) {
return builder(PooledByteBufAllocator.DEFAULT, httpMethod);
}
public static Builder builder(HttpMethod httpMethod, Request request) {
return builder(PooledByteBufAllocator.DEFAULT, httpMethod)
.setVersion(request.httpVersion)
.url(request.url)
.setHeaders(request.headers)
.content(request.content)
.setResponseListener(request.responseListener);
}
public static Builder builder(ByteBufAllocator allocator, HttpMethod httpMethod) {
return new Builder(allocator).setMethod(httpMethod);
}
public static class Builder {
private static final HttpMethod DEFAULT_METHOD = HttpMethod.GET;
private static final HttpVersion DEFAULT_HTTP_VERSION = HttpVersion.HTTP_1_1;
private static final String DEFAULT_USER_AGENT = UserAgent.getUserAgent();
private static final URL DEFAULT_URL = URL.from("http://localhost");
private static final boolean DEFAULT_GZIP = true;
private static final boolean DEFAULT_KEEPALIVE = true;
private static final boolean DEFAULT_FOLLOW_REDIRECT = true;
private static final long DEFAULT_TIMEOUT_MILLIS = -1L;
private static final int DEFAULT_MAX_REDIRECT = 10;
private static final HttpVersion HTTP_2_0 = HttpVersion.valueOf("HTTP/2.0");
private static final String DEFAULT_FORM_CONTENT_TYPE = "application/x-www-form-urlencoded; charset=utf-8";
private final ByteBufAllocator allocator;
private final List removeHeaders;
private final Collection cookies;
private PercentEncoder encoder;
private HttpMethod httpMethod;
private HttpHeaders headers;
private HttpVersion httpVersion;
private String userAgent;
private boolean keepalive;
private boolean gzip;
private URL url;
private CharSequence contentType;
private HttpParameters uriParameters;
private HttpParameters formParameters;
private ByteBuf content;
private List bodyData;
private long timeoutInMillis;
private boolean followRedirect;
private int maxRedirects;
private boolean enableBackOff;
private BackOff backOff;
private ResponseListener responseListener;
Builder(ByteBufAllocator allocator) {
this.allocator = allocator;
this.httpMethod = DEFAULT_METHOD;
this.httpVersion = DEFAULT_HTTP_VERSION;
this.userAgent = DEFAULT_USER_AGENT;
this.gzip = DEFAULT_GZIP;
this.keepalive = DEFAULT_KEEPALIVE;
this.url = DEFAULT_URL;
this.timeoutInMillis = DEFAULT_TIMEOUT_MILLIS;
this.followRedirect = DEFAULT_FOLLOW_REDIRECT;
this.maxRedirects = DEFAULT_MAX_REDIRECT;
this.headers = new DefaultHttpHeaders();
this.removeHeaders = new ArrayList<>();
this.cookies = new HashSet<>();
this.bodyData = new ArrayList<>();
charset(StandardCharsets.UTF_8);
}
public Builder charset(Charset charset) {
this.encoder = PercentEncoders.getQueryEncoder(charset);
this.formParameters = new HttpParameters(DEFAULT_FORM_CONTENT_TYPE);
this.uriParameters = new HttpParameters(DEFAULT_FORM_CONTENT_TYPE);
return this;
}
public Builder setMethod(HttpMethod httpMethod) {
this.httpMethod = httpMethod;
return this;
}
public Builder enableHttp1() {
this.httpVersion = HttpVersion.HTTP_1_1;
return this;
}
public Builder enableHttp2() {
this.httpVersion = HTTP_2_0;
return this;
}
public Builder setVersion(HttpVersion httpVersion) {
this.httpVersion = httpVersion;
return this;
}
public Builder setVersion(String httpVersion) {
this.httpVersion = HttpVersion.valueOf(httpVersion);
return this;
}
public Builder setTimeoutInMillis(long timeoutInMillis) {
this.timeoutInMillis = timeoutInMillis;
return this;
}
public Builder remoteAddress(HttpAddress httpAddress) {
this.url = URL.builder()
.scheme(httpAddress.isSecure() ? "https" : "http")
.host(httpAddress.getInetSocketAddress().getHostString())
.port(httpAddress.getInetSocketAddress().getPort())
.build();
this.httpVersion = httpAddress.getVersion();
return this;
}
public Builder url(String url) {
return url(URL.from(url));
}
public Builder url(URL url) {
this.url = url;
return this;
}
public Builder setHeaders(Map headers) {
headers.forEach(this::addHeader);
return this;
}
public Builder setHeaders(HttpHeaders headers) {
this.headers = headers;
return this;
}
public Builder addHeader(String name, Object value) {
this.headers.add(name, value);
return this;
}
public Builder setHeader(String name, Object value) {
this.headers.set(name, value);
return this;
}
public Builder removeHeader(String name) {
removeHeaders.add(name);
return this;
}
public Builder contentType(CharSequence contentType) {
Objects.requireNonNull(contentType);
this.contentType = contentType;
addHeader(HttpHeaderNames.CONTENT_TYPE, contentType);
return this;
}
public Builder contentType(CharSequence contentType, Charset charset) {
Objects.requireNonNull(contentType);
Objects.requireNonNull(charset);
this.contentType = contentType;
charset(charset);
addHeader(HttpHeaderNames.CONTENT_TYPE, contentType + "; charset=" + charset.name().toLowerCase());
return this;
}
public Builder setParameters(Map parameters) {
parameters.forEach(this::addParameter);
return this;
}
@SuppressWarnings("unchecked")
public Builder addParameter(String name, Object value) {
Objects.requireNonNull(name);
Objects.requireNonNull(value);
Collection
© 2015 - 2025 Weber Informatics LLC | Privacy Policy