
io.higgs.http.client.Request Maven / Gradle / Ivy
package io.higgs.http.client;
import io.higgs.core.StaticUtil;
import io.higgs.http.client.future.Reader;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.codec.http.multipart.DiskFileUpload;
import io.netty.util.concurrent.GenericFutureListener;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.*;
/**
* @author Courtney Robinson
*/
public class Request {
protected final Response response;
protected final Map queryParams = new HashMap<>();
protected final FutureResponse future;
protected final EventLoopGroup group;
private final HttpMethod method;
protected HttpRequest request;
protected URI uri;
protected HttpHeaders headers;
protected Channel channel;
protected String userAgent = "Mozilla/5.0 (compatible; HiggsBoson/0.0.1; +https://github.com/zcourts/higgs)";
protected List cookies = new ArrayList<>();
private HttpVersion version;
private Set redirectStatusCodes = new HashSet<>();
private URI originalUri;
public Request(EventLoopGroup group, URI uri, HttpMethod method, HttpVersion version, Reader responseReader) {
if (responseReader == null) {
throw new IllegalArgumentException("A response reader is required, can't process the response otherwise");
}
response = new Response(this, responseReader);
deleteTempFileOnExit(true);
baseDirectory(null);
this.uri = uri;
this.group = group;
this.method = method;
this.version = version;
//ignore uri.getRawPath, it's overwritten later in #configure()
newNettyRequest(uri, method, version);
future = new FutureResponse(group);
}
private void newNettyRequest(URI uri, HttpMethod method, HttpVersion version) {
request = new DefaultFullHttpRequest(version, method, uri.getRawPath());
headers = request.headers();
headers.set(HttpHeaders.Names.REFERER, originalUri == null ? uri.toString() : originalUri.toString());
}
/**
* Automatically follow redirect responses for the given status codes
*
* @param codes the status codes to treat as redirects
* @return this
*/
public Request redirectOn(int... codes) {
for (int code : codes) {
redirectStatusCodes.add(code);
}
return this;
}
/**
* @return the set of status codes this request's responses should be redirected on
*/
public Set redirectOn() {
return redirectStatusCodes;
}
/**
* Makes the request to the server
*
* @return A Future which is notified when the response is acknowledged by the server.
* It doesn't mean the entire contents of the response has been received, just that it's started.
*/
public FutureResponse execute() {
String scheme = uri.getScheme() == null ? "http" : uri.getScheme();
String host = uri.getHost() == null ? "localhost" : uri.getHost();
int port = uri.getPort();
if (port == -1) {
if ("http".equalsIgnoreCase(scheme)) {
port = 80;
} else if ("https".equalsIgnoreCase(scheme)) {
port = 443;
}
}
boolean ssl = "https".equalsIgnoreCase(scheme);
headers.set(HttpHeaders.Names.HOST, host);
try {
configure();
Bootstrap bootstrap = new Bootstrap();
bootstrap
.group(group)
.channel(NioSocketChannel.class)
.handler(new ClientIntializer(ssl, response, future));
//connect
ChannelFuture cf = bootstrap.connect(host, port);
channel = cf.channel();
cf.addListener(new GenericFutureListener() {
@Override
public void operationComplete(ChannelFuture f) throws Exception {
if (f.isSuccess()) {
makeTheRequest();
} else {
future.setFailure(f.cause());
}
}
});
} catch (Throwable e) {
future.setFailure(e);
}
return future;
}
protected ChannelFuture makeTheRequest() {
return StaticUtil.write(channel, request);
}
protected void configure() throws Exception {
headers.set(HttpHeaders.Names.COOKIE, ClientCookieEncoder.encode(cookies));
QueryStringEncoder encoder = new QueryStringEncoder(uri.getRawPath());
QueryStringDecoder decoder = new QueryStringDecoder(uri);
//add url params first
for (Map.Entry> e : decoder.parameters().entrySet()) {
if (e.getKey() != null) {
for (String val : e.getValue()) {
encoder.addParam(e.getKey(), val == null ? "" : val);
}
}
}
//now add any cofnigured params overwriting existing ones
for (Map.Entry e : queryParams.entrySet()) {
if (e.getKey() != null) {
encoder.addParam(e.getKey(), e.getValue() == null ? "" : e.getValue().toString());
}
}
request.setUri(new URI(encoder.toString()).getRawPath());
}
public Request userAgent(String agent) {
if (agent != null) {
userAgent = agent;
}
return this;
}
/**
* @param baseDir system temp directory by default
*/
public void baseDirectory(String baseDir) {
DiskFileUpload.baseDirectory = baseDir;
}
/**
* @param delete should delete temp file on exit (on normal exit) if true
*/
public void deleteTempFileOnExit(boolean delete) {
DiskFileUpload.deleteOnExitTemporaryFile = delete;
}
/**
* Set a header on this request
*
* @return this
*/
public Request header(String name, Object value) {
headers.set(name, value);
return this;
}
/**
* Set a header on this request
*
* @return this
*/
public Request header(String name, Iterable> value) {
headers.set(name, value);
return this;
}
/**
* Set a header on this request
*
* @return this
*/
public Request header(String name, String value) {
headers.set(name, value);
return this;
}
public HttpHeaders headers() {
return headers;
}
/**
* Adds a query string parameter to the request
*
* @param name the name of the query string
* @param value the value
* @return this
*/
public Request query(String name, Object value) {
queryParams.put(name, value);
return this;
}
/**
* Adds a cookie to this request
*
* @param cookie the cookie to add
* @return this
*/
public Request cookie(Cookie cookie) {
if (cookie != null) {
cookies.add(cookie);
}
return this;
}
/**
* Adds a cookie with the given name and value
*
* @param name the name
* @param value the value
* @return this
*/
public Request cookie(String name, Object value) {
if (name != null) {
Cookie cookie = new DefaultCookie(name, value == null ? null : value.toString());
cookies.add(cookie);
}
return this;
}
/**
* @return List of Cookies set in this request
*/
public List cookies() {
return cookies;
}
public void shutdown() {
group.shutdownGracefully();
}
/**
* @return The resposne generated for this request
*/
public Response response() {
return response;
}
/**
* @return The URI this request was first made to or NULL if the response did not result in a redirect
*/
public URI originalUri() {
return originalUri;
}
public URI url() {
return uri;
}
public Request url(String url) throws URISyntaxException {
if (url == null) {
throw new IllegalArgumentException("NULL url provided");
}
originalUri = uri;
if (url.startsWith("http")) {
this.uri = new URI(url);
} else {
this.uri = uri.resolve(url);
}
newNettyRequest(uri, method, version);
return this;
}
public HttpRequest nettyRequest() {
return request;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy