123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492 |
- /*
- * Copyright [2020] [MaxKey of copyright http://www.maxkey.top]
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
- package org.maxkey.client.http;
- import java.io.*;
- import java.net.*;
- import java.nio.charset.*;
- import java.util.*;
- import java.util.concurrent.*;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.maxkey.client.oauth.exceptions.*;
- import org.maxkey.client.utils.HttpsTrusts;
- import org.maxkey.client.utils.JsonUtils;
- /**
- * Represents an HTTP Request object
- *
- */
- public class Request
- {
- private static Log _log = LogFactory.getLog(Request. class );
- public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
- private static final String CONTENT_LENGTH = "Content-Length";
- private static final String CONTENT_TYPE = "Content-Type";
- private static RequestTuner NOOP = new RequestTuner() {
- @Override public void tune(Request request){}
- };
-
-
- private String url;
- private HttpVerb verb;
- private ParameterList querystringParams;
- private ParameterList bodyParams;
- private Map<String, String> headers;
- private String payload = null;
- private HttpURLConnection connection;
- private String charset;
- private byte[] bytePayload = null;
- private boolean connectionKeepAlive = false;
- private boolean followRedirects = true;
- private Long connectTimeout = null;
- private Long readTimeout = null;
- private String realm;
- /**
- * Creates a new Http Request
- *
- * @param verb Http Verb (GET, POST, etc)
- * @param url url with optional querystring parameters.
- */
- public Request(HttpVerb verb, String url)
- {
- this.verb = verb;
- this.url = url;
- this.querystringParams = new ParameterList();
- this.bodyParams = new ParameterList();
- this.headers = new HashMap<String, String>();
- }
- /**
- * Execute the request and return a {@link Response}
- *
- * @return Http Response
- * @throws RuntimeException
- * if the connection cannot be created.
- */
- public Response send(RequestTuner tuner)
- {
- try
- {
- createConnection();
- return doSend(tuner);
- }
- catch (Exception e)
- {
- throw new OAuthConnectionException(e);
- }
- }
- public Response send()
- {
- return send(NOOP);
- }
- private void createConnection() throws IOException
- {
- String completeUrl = getCompleteUrl();
- _log.debug("verb method : "+verb);
- _log.debug("completeUrl : "+completeUrl);
-
- if (connection == null)
- {
- System.setProperty("http.keepAlive", connectionKeepAlive ? "true" : "false");
- connection = (HttpURLConnection) new URL(completeUrl).openConnection();
- if(completeUrl.trim().startsWith("https")){
- HttpsTrusts.beforeConnection();
- }
-
- connection.setInstanceFollowRedirects(followRedirects);
- }
- }
- /**
- * Returns the complete url (host + resource + encoded querystring parameters).
- *
- * @return the complete url.
- */
- public String getCompleteUrl()
- {
- return querystringParams.appendTo(url);
- }
- Response doSend(RequestTuner tuner) throws IOException
- {
- connection.setRequestMethod(this.verb.name());
- if (connectTimeout != null)
- {
- connection.setConnectTimeout(connectTimeout.intValue());
- }
- if (readTimeout != null)
- {
- connection.setReadTimeout(readTimeout.intValue());
- }
- addHeaders(connection);
- if (verb.equals(HttpVerb.PUT) || verb.equals(HttpVerb.POST))
- {
- addBody(connection, getByteBodyContents());
- }
- tuner.tune(this);
- return new Response(connection);
- }
- void addHeaders(HttpURLConnection conn)
- {
- for (String key : headers.keySet())
- conn.setRequestProperty(key, headers.get(key));
- }
- void addBody(HttpURLConnection conn, byte[] content) throws IOException
- {
- conn.setRequestProperty(CONTENT_LENGTH, String.valueOf(content.length));
- // Set default content type if none is set.
- if (conn.getRequestProperty(CONTENT_TYPE) == null)
- {
- conn.setRequestProperty(CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
- }
- conn.setDoOutput(true);
- conn.getOutputStream().write(content);
- }
- /**
- * Add an HTTP Header to the Request
- *
- * @param key the header name
- * @param value the header value
- */
- public void addHeader(String key, String value)
- {
- this.headers.put(key, value);
- }
- /**
- * Add a body Parameter (for POST/ PUT Requests)
- *
- * @param key the parameter name
- * @param value the parameter value
- */
- public void addBodyParameter(String key, String value)
- {
- this.bodyParams.add(key, value);
- }
- /**
- * Add a QueryString parameter
- *
- * @param key the parameter name
- * @param value the parameter value
- */
- public void addQuerystringParameter(String key, String value)
- {
- this.querystringParams.add(key, value);
- }
- public void addParameter(String key, String value) {
- if (hasBodyContent()) {
- bodyParams.add(key, value);
- } else {
- querystringParams.add(key, value);
- }
- }
-
- protected boolean hasBodyContent() {
- return verb == HttpVerb.PUT || verb == HttpVerb.POST;
- }
- /**
- * Add body payload.
- *
- * This method is used when the HTTP body is not a form-url-encoded string,
- * but another thing. Like for example XML.
- *
- * Note: The contents are not part of the OAuth signature
- *
- * @param payload the body of the request
- */
- public void addPayload(String payload)
- {
- this.payload = payload;
- }
- /**
- * Overloaded version for byte arrays
- *
- * @param payload
- */
- public void addPayload(byte[] payload)
- {
- this.bytePayload = payload.clone();
- }
- /**
- * set REST Content
- *
- * @param content
- */
- public void addRestContent(String content)
- {
- this.payload = content;
- }
-
- /**
- * set REST Content
- *
- * @param content
- */
- public void addRestObject(Object content)
- {
- try {
- this.bytePayload = JsonUtils.gson2Json(content).getBytes("UTF-8");
- } catch (UnsupportedEncodingException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
-
- /**
- * set REST Content
- *
- * @param content
- */
- public void addRestContent(byte[] content)
- {
- this.bytePayload = content.clone();
- }
- /**
- * Get a {@link ParameterList} with the query string parameters.
- *
- * @return a {@link ParameterList} containing the query string parameters.
- * @throws OAuthException if the request URL is not valid.
- */
- public ParameterList getQueryStringParams()
- {
- try
- {
- ParameterList result = new ParameterList();
- String queryString = new URL(url).getQuery();
- result.addQuerystring(queryString);
- result.addAll(querystringParams);
- return result;
- }
- catch (MalformedURLException mue)
- {
- throw new OAuthException("Malformed URL", mue);
- }
- }
- /**
- * Obtains a {@link ParameterList} of the body parameters.
- *
- * @return a {@link ParameterList}containing the body parameters.
- */
- public ParameterList getBodyParams()
- {
- return bodyParams;
- }
- /**
- * Obtains the URL of the HTTP Request.
- *
- * @return the original URL of the HTTP Request
- */
- public String getUrl()
- {
- return url;
- }
- /**
- * Returns the URL without the port and the query string part.
- *
- * @return the OAuth-sanitized URL
-
- public String getSanitizedUrl()
- {
- return url.replaceAll("\\?.*", "").replace("\\:\\d{4}", "");
- }
- */
- /**
- * Returns the URL without the port and the query string part.
- *
- * @return the OAuth-sanitized URL
- */
- public String getSanitizedUrl() {
- if (url.startsWith("http://") && (url.endsWith(":80") || url.contains(":80/"))) {
- return url.replaceAll("\\?.*", "").replaceAll(":80", "");
- } else if (url.startsWith("https://") && (url.endsWith(":443") || url.contains(":443/"))) {
- return url.replaceAll("\\?.*", "").replaceAll(":443", "");
- } else {
- return url.replaceAll("\\?.*", "");
- }
- }
- /**
- * Returns the body of the request
- *
- * @return form encoded string
- * @throws OAuthException if the charset chosen is not supported
- */
- public String getBodyContents()
- {
- try
- {
- return new String(getByteBodyContents(),getCharset());
- }
- catch(UnsupportedEncodingException uee)
- {
- throw new OAuthException("Unsupported Charset: "+charset, uee);
- }
- }
- byte[] getByteBodyContents()
- {
- if (bytePayload != null) return bytePayload;
- String body = (payload != null) ? payload : bodyParams.asFormUrlEncodedString();
-
- _log.debug("getByteBodyContents : "+body);
- try
- {
- return body.getBytes(getCharset());
- }
- catch(UnsupportedEncodingException uee)
- {
- throw new OAuthException("Unsupported Charset: "+getCharset(), uee);
- }
- }
- /**
- * Returns the HTTP Verb
- *
- * @return the verb
- */
- public HttpVerb getVerb()
- {
- return verb;
- }
-
- public void setRealm(String realm) {
- this.realm = realm;
- }
- public String getRealm() {
- return realm;
- }
-
- /**
- * Returns the connection headers as a {@link Map}
- *
- * @return map of headers
- */
- public Map<String, String> getHeaders()
- {
- return headers;
- }
- /**
- * Returns the connection charset. Defaults to {@link Charset} defaultCharset if not set
- *
- * @return charset
- */
- public String getCharset()
- {
- return charset == null ? Charset.defaultCharset().name() : charset;
- }
- /**
- * Sets the connect timeout for the underlying {@link HttpURLConnection}
- *
- * @param duration duration of the timeout
- *
- * @param unit unit of time (milliseconds, seconds, etc)
- */
- public void setConnectTimeout(int duration, TimeUnit unit)
- {
- this.connectTimeout = unit.toMillis(duration);
- }
- /**
- * Sets the read timeout for the underlying {@link HttpURLConnection}
- *
- * @param duration duration of the timeout
- *
- * @param unit unit of time (milliseconds, seconds, etc)
- */
- public void setReadTimeout(int duration, TimeUnit unit)
- {
- this.readTimeout = unit.toMillis(duration);
- }
- /**
- * Set the charset of the body of the request
- *
- * @param charsetName name of the charset of the request
- */
- public void setCharset(String charsetName)
- {
- this.charset = charsetName;
- }
- /**
- * Sets whether the underlying Http Connection is persistent or not.
- *
- * @see http://download.oracle.com/javase/1.5.0/docs/guide/net/http-keepalive.html
- * @param connectionKeepAlive
- */
-
- @Deprecated
- public void setConnectionKeepAlive(boolean connectionKeepAlive){
- this.connectionKeepAlive = connectionKeepAlive;
- }
-
- /**
- *
- * @param connectionKeepAlive
- * true or false
- */
- public void setConnectionKeepAlive(String connectionKeepAlive){
- System.setProperty("http.keepAlive", connectionKeepAlive);
- }
- /**
- * Sets whether the underlying Http Connection follows redirects or not.
- *
- * Defaults to true (follow redirects)
- *
- * @see http://docs.oracle.com/javase/6/docs/api/java/net/HttpURLConnection.html#setInstanceFollowRedirects(boolean)
- * @param followRedirects
- */
- public void setFollowRedirects(boolean followRedirects)
- {
- this.followRedirects = followRedirects;
- }
- /*
- * We need this in order to stub the connection object for test cases
- */
- void setConnection(HttpURLConnection connection)
- {
- this.connection = connection;
- }
- @Override
- public String toString()
- {
- return String.format("@Request(%s %s)", getVerb(), getUrl());
- }
- }
|