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

aQute.bnd.http.HttpRequest Maven / Gradle / Ivy

The newest version!
package aQute.bnd.http;

import java.io.File;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URL;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.osgi.util.promise.Promise;

import aQute.bnd.service.url.TaggedData;
import aQute.lib.converter.TypeReference;
import aQute.service.reporter.Reporter;

/**
 * Builds up a request
 *
 * @param 
 */
public class HttpRequest {
	String				verb			= "GET";
	boolean				isIdemPotent	= true;
	Object				upload;
	Type				download;
	Map	headers			= new HashMap<>();
	long				timeout			= -1;
	HttpClient			client;
	String				ifNoneMatch;
	long				ifModifiedSince;
	long				ifUnmodifiedSince;
	URL					url;
	int					redirects		= 10;
	String				ifMatch;
	boolean				cached;
	long				maxStale;
	Reporter			reporter;
	File				useCacheFile;
	boolean				updateTag;
	int					retries;
	long				retryDelay;

	HttpRequest(HttpClient client) {
		this.client = client;
		this.retries = client.retries;
		this.retryDelay = client.retryDelay;
	}

	/**
	 * Convert the result to a specific type
	 */
	@SuppressWarnings("unchecked")
	public  HttpRequest get(Class type) {
		this.download = type;
		return (HttpRequest) this;
	}

	/**
	 * Convert the result to a specific type
	 */
	@SuppressWarnings("unchecked")
	public  HttpRequest get(TypeReference type) {
		this.download = type.getType();
		return (HttpRequest) this;
	}

	/**
	 * Convert the result to a specific type
	 */
	@SuppressWarnings("unchecked")
	public HttpRequest get(Type type) {
		this.download = type;
		return (HttpRequest) this;
	}

	/**
	 * Set the HTTP verb. The methods GET, HEAD, PUT and DELETE are idempotent.
	 * Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so
	 * are inherently idempotent.
	 */

	public HttpRequest verb(String verb) {
		this.verb = verb;
		return switch (verb.toUpperCase(Locale.ROOT)) {
			case "GET", "HEAD", "PUT", "DELETE", "OPTIONS", "TRACE" -> idemPotent(true);
			default -> idemPotent(false);
		};
	}

	/**
	 * Set the verb/method to put
	 */
	public HttpRequest put() {
		return verb("PUT");
	}

	/**
	 * Set the verb/method to head
	 */
	public HttpRequest head() {
		return verb("HEAD");
	}

	/**
	 * Set the verb/method to get
	 */
	public HttpRequest get() {
		return verb("GET");
	}

	/**
	 * Set the verb/method to post
	 */
	public HttpRequest post() {
		return verb("POST");
	}

	/**
	 * Set the verb/method to option
	 */
	public HttpRequest option() {
		return verb("OPTIONS");
	}

	/**
	 * Set the verb/method to option
	 */
	public HttpRequest trace() {
		return verb("TRACE");
	}

	/**
	 * Set the verb/method to delete
	 */
	public HttpRequest delete() {
		return verb("DELETE");
	}

	/**
	 * Set the object to upload. Can be of several types:
	 * 
    *
  • InputStream – copied verbatim *
  • String – content sent *
  • byte[] – content sent *
  • File – content sent *
  • Otherwise assumes DTO and encodes in JSON *
*/ public HttpRequest upload(Object upload) { this.upload = upload; return this; } /** * Add headers to request */ public HttpRequest headers(Map map) { headers.putAll(map); return this; } /** * Add header to request */ public HttpRequest headers(String key, String value) { headers.put(key, value); return this; } /** * Set timeout in ms */ public HttpRequest timeout(long timeoutInMs) { this.timeout = timeoutInMs; return this; } public HttpRequest ifNoneMatch(String etag) { this.ifNoneMatch = etag; return this; } public HttpRequest ifModifiedSince(long epochTime) { this.ifModifiedSince = epochTime; return this; } public HttpRequest maxRedirects(int n) { this.redirects = n; return this; } public T go(URL url) throws Exception { this.url = url; return client.send(this); } public T go(URI url) throws Exception { return go(url.toURL()); } public HttpRequest age(int n, TimeUnit tu) { this.headers.put("Age", "" + tu.toSeconds(n)); return this; } public Promise async(URL url) { this.url = url; return client.sendAsync(this); } public Promise async(URI uri) { try { return async(uri.toURL()); } catch (MalformedURLException e) { return client.promiseFactory() .failed(e); } } @Override public String toString() { return "HttpRequest [verb=" + verb + ", upload=" + upload + ", download=" + download + ", headers=" + headers + ", timeout=" + timeout + ", client=" + client + ", url=" + url + "]"; } public HttpRequest ifUnmodifiedSince(long ifNotModifiedSince) { this.ifUnmodifiedSince = ifNotModifiedSince; return this; } public HttpRequest ifMatch(String etag) { this.ifMatch = etag; return this; } public HttpRequest asTag() { return get(TaggedData.class); } public HttpRequest asString() { return get(String.class); } public boolean isCache() { return ("GET".equalsIgnoreCase(verb) && cached) || download == File.class; } public HttpRequest useCache(long maxStale) { this.maxStale = maxStale; this.cached = true; return get(File.class); } public HttpRequest useCache() { return useCache(-1); } public HttpRequest useCache(File file) { this.useCacheFile = file; return useCache(-1); } public HttpRequest useCache(File file, long maxStale) { this.useCacheFile = file; return useCache(maxStale); } public HttpRequest report(Reporter reporter) { this.reporter = reporter; return this; } public HttpRequest timeout(long timeout, TimeUnit unit) { this.timeout = unit.toMillis(timeout); return this; } public boolean isTagResult() { return download == null || download == TaggedData.class; } public HttpRequest updateTag() { updateTag = true; return this; } /** * Set the number of retries. Retries are only attempted when the method * verb implies idempotency, or it is explicitly set to be idempotent, see * {@link #idemPotent(boolean)}. * * @param retries number of retries, default is 3. * @return this */ public HttpRequest retries(int retries) { this.retries = retries; return this; } public HttpRequest retryDelay(int retryDelay) { this.retryDelay = TimeUnit.SECONDS.toMillis(retryDelay); return this; } /** * Idempotent Methods *

* Methods can also have the property of "idempotence" in that (aside from * error or expiration issues) the side-effects of N > 0 identical requests * is the same as for a single request. The methods GET, HEAD, PUT and * DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD * NOT have side effects, and so are inherently idempotent. *

* The {@link #verb(String)} method will set the idempotency according to * this specification. This method can then override the default * idempotency. * * @param isIdemPotent if the to be used method is idempotent. (Is * overridden if the method verb is set after this method!) * @return this */ public HttpRequest idemPotent(boolean isIdemPotent) { this.isIdemPotent = isIdemPotent; return this; } }