jsimple.oauth.model.OAuthRequest Maven / Gradle / Ivy
/*
* The MIT License (MIT)
*
* Copyright (c) 2012-2015 Microsoft Mobile. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*
* This file is based on or incorporates material from the Scribe Java OAuth
* library https://github.com/fernandezpablo85/scribe-java (collectively, "Third
* Party Code"). Microsoft Mobile is not the original author of the Third Party
* Code.
*
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package jsimple.oauth.model;
import jsimple.io.File;
import jsimple.io.IOUtils;
import jsimple.io.InputStream;
import jsimple.io.OutputStream;
import jsimple.logging.Logger;
import jsimple.logging.LoggerFactory;
import jsimple.net.*;
import jsimple.oauth.exceptions.OAuthConnectionException;
import jsimple.oauth.exceptions.OAuthException;
import jsimple.util.*;
import org.jetbrains.annotations.Nullable;
/**
* The representation of an OAuth HttpRequest.
*
* @author Pablo Fernandez
*/
public class OAuthRequest {
final static Logger logger = LoggerFactory.getLogger("OAuthRequest");
private String url;
private String verb;
private ParameterList queryStringParams;
private ParameterList bodyParams;
private Map headers;
private @Nullable ByteArrayRange bytePayload = null;
private @Nullable String stringPayload = null;
private @Nullable File filePayload = null;
private @Nullable HttpRequest httpRequest = null;
private @Nullable int timeout = -1;
private Map oauthParameters;
public static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded";
private static final String OAUTH_PREFIX = "oauth_";
/**
* Construct an OAuthRequest to apply to specified verb against the specified resource URL.
*
* @param verb HTTP verb/method
* @param url resource URL
*/
public OAuthRequest(String verb, String url) {
this.verb = verb;
this.url = url;
this.queryStringParams = new ParameterList();
this.bodyParams = new ParameterList();
this.headers = new HashMap();
this.oauthParameters = new HashMap();
}
/**
* Construct an OAuthRequest to apply to specified verb against the specified resource.
*
* @param verb HTTP verb/method
* @param baseUrl base URL, including server/port and optionally start of path; this should NOT end with a /
* character
* @param resourcePath path to resource on server, which will be appended to baseUrl
*/
public OAuthRequest(String verb, String baseUrl, TextualPath resourcePath) {
this(verb, baseUrl + UrlEncoder.encode(resourcePath));
}
/**
* Adds an OAuth parameter.
*
* @param key name of the parameter
* @param value value of the parameter
* @throws IllegalArgumentException if the parameter is not an OAuth parameter
*/
public void addOAuthParameter(String key, String value) {
oauthParameters.put(checkKey(key), value);
}
private String checkKey(String key) {
if (key.startsWith(OAUTH_PREFIX) || key.equals(OAuthConstants.SCOPE)) {
return key;
} else {
throw new ProgrammerError("OAuth parameters must either be '{}' or start with '{}'", OAuthConstants.SCOPE,
OAUTH_PREFIX);
}
}
/**
* Returns the {@link Map} containing the key-value pair of parameters.
*
* @return parameters as map
*/
public Map getOauthParameters() {
return oauthParameters;
}
@Override public String toString() {
return "@OAuthRequest(" + getVerb() + ", " + getUrl() + ")";
}
/**
* Execute the request and return a {@link jsimple.oauth.model.OAuthResponse}
*
* @return Http Response
* @throws RuntimeException if the connection cannot be created.
*/
public OAuthResponse send() {
try {
createConnection();
return doSend();
} catch (Exception e) {
throw new OAuthConnectionException(e);
}
}
private void createConnection() {
String completeUrl = getCompleteUrl();
if (httpRequest == null)
httpRequest = HttpRequest.create(completeUrl);
}
/**
* Returns the complete url (host + resource + encoded querystring parameters).
*
* @return the complete url.
*/
public String getCompleteUrl() {
return queryStringParams.appendTo(url);
}
OAuthResponse doSend() {
HttpRequest httpReq = httpRequest;
assert httpReq != null : "nullness";
httpReq.setMethod(this.verb);
if (timeout != -1)
httpReq.setTimeout(timeout);
for (String key : headers.keySet())
httpReq.setHeader(key, headers.get(key));
if (verb.equals("PUT") || verb.equals("POST"))
addBody(httpReq);
try {
OAuthResponse response;
if (logger.isTraceEnabled()) {
long startTime = SystemUtils.getCurrentTimeMillis();
response = new OAuthResponse(httpReq.send());
long duration = SystemUtils.getCurrentTimeMillis() - startTime;
logger.trace("{} {}; took {}ms", verb, getUrl(), duration);
} else response = new OAuthResponse(httpReq.send());
return response;
} catch (UnknownHostException e) {
throw new OAuthException("The IP address of a host could not be determined.", e);
}
}
private void addBody(HttpRequest httpReq) {
// Set default content type if none is set
if (httpReq.getHeader(HttpRequest.HEADER_CONTENT_TYPE) == null)
httpReq.setHeader(HttpRequest.HEADER_CONTENT_TYPE, DEFAULT_CONTENT_TYPE);
if (filePayload != null) {
Long filePayloadSize = filePayload.getSize();
httpReq.setHeader(HttpRequest.HEADER_CONTENT_LENGTH, filePayloadSize.toString());
InputStream fileStream = filePayload.openForRead();
try {
OutputStream bodyStream = httpReq.createRequestBodyStream();
try {
fileStream.copyTo(bodyStream);
} finally {
bodyStream.close();
}
} finally {
fileStream.close();
}
} else {
ByteArrayRange byteArrayRange = getByteBodyContents();
Integer byteArrayRangeLength = byteArrayRange.getLength();
httpReq.setHeader(HttpRequest.HEADER_CONTENT_LENGTH, byteArrayRangeLength.toString());
OutputStream bodyStream = httpReq.createRequestBodyStream();
try {
bodyStream.write(byteArrayRange);
} finally {
bodyStream.close();
}
}
}
/**
* 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 query string parameter
*
* @param key the parameter name
* @param value the parameter value
*/
public void addQueryStringParameter(String key, String value) {
this.queryStringParams.add(key, value);
}
/**
* Add the passed parameters to the query string
*
* @param params parameters
*/
public void addQueryStringParameters(HttpRequestParams params) {
for (String name : params.getNames())
addQueryStringParameter(name, params.getValue(name));
}
/**
* 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.stringPayload = payload;
}
/**
* Overloaded version for byte arrays
*
* @param payload
*/
public void addPayload(byte[] payload) {
addPayload(new ByteArrayRange(payload));
}
/**
* Overloaded version for byte arrays
*
* @param payload
*/
public void addPayload(ByteArrayRange payload) {
this.bytePayload = payload;
}
/**
* Overloaded version for byte arrays
*
* @param filePayload
*/
public void addPayload(File filePayload) {
this.filePayload = filePayload;
}
/**
* Get a {@link jsimple.oauth.model.ParameterList} with the query string parameters.
*
* @return a {@link jsimple.oauth.model.ParameterList} containing the query string parameters.
* @throws jsimple.oauth.exceptions.OAuthException if the request URL is not valid.
*/
public ParameterList getQueryStringParams() {
ParameterList result = new ParameterList();
@Nullable String queryString = new Url(url).getQuery();
result.addQueryString(queryString);
result.addAll(queryStringParams);
return result;
}
/**
* Obtains a {@link jsimple.oauth.model.ParameterList} of the body parameters.
*
* @return a {@link jsimple.oauth.model.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() {
// Old code: return url.replaceAll("\\?.*", "").replace("\\:\\d{4}", "");
String sanitizedUrl = url;
int queryStringStart = url.indexOf('?');
if (queryStringStart != -1)
sanitizedUrl = sanitizedUrl.substring(0, queryStringStart);
int colonStart = url.indexOf(':');
if (colonStart != -1)
sanitizedUrl = sanitizedUrl.substring(0, colonStart);
return sanitizedUrl;
}
ByteArrayRange getByteBodyContents() {
if (bytePayload != null)
return bytePayload;
String body = (stringPayload != null) ? stringPayload : bodyParams.asFormUrlEncodedString();
return IOUtils.toUtf8BytesFromString(body);
}
/**
* Returns the HTTP Verb
*
* @return the verb
*/
public String getVerb() {
return verb;
}
/**
* Returns the connection headers as a {@link java.util.Map}
*
* @return map of headers
*/
public Map getHeaders() {
return headers;
}
/**
* Sets the timeout for the underlying {@link jsimple.net.HttpRequest}
*
* @param timeoutInMillis duration of the timeout
*/
public void setTimeout(int timeoutInMillis) {
this.timeout = timeoutInMillis;
}
/**
* We need this in order to stub the connection object for test cases
*
* @param httpRequest
*/
void setHttpRequest(HttpRequest httpRequest) {
this.httpRequest = httpRequest;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy