package com.github.scribejava.core.model; import com.github.scribejava.core.exceptions.OAuthException; import java.io.File; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URL; import java.nio.charset.Charset; import java.util.HashMap; import java.util.Map; /** * The representation of an OAuth HttpRequest. */ public class OAuthRequest { private static final String OAUTH_PREFIX = "oauth_"; private final String url; private final Verb verb; private final ParameterList querystringParams = new ParameterList(); private final ParameterList bodyParams = new ParameterList(); private final Map<String, String> headers = new HashMap<>(); private String charset; private String stringPayload; private byte[] byteArrayPayload; private File filePayload; private final Map<String, String> oauthParameters = new HashMap<>(); private String realm; /** * Default constructor. * * @param verb Http verb/method * @param url resource URL */ public OAuthRequest(Verb verb, String url) { this.verb = verb; this.url = url; } /** * 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) || key.equals(OAuthConstants.REALM)) { return key; } else { throw new IllegalArgumentException( String.format("OAuth parameters must either be '%s', '%s' or start with '%s'", OAuthConstants.SCOPE, OAuthConstants.REALM, OAUTH_PREFIX)); } } public Map<String, String> getOauthParameters() { return oauthParameters; } public void setRealm(String realm) { this.realm = realm; } public String getRealm() { return realm; } /** * Returns the complete url (host + resource + encoded querystring parameters). * * @return the complete url. */ public String getCompleteUrl() { return querystringParams.appendTo(url); } /** * 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 (verb.isPermitBody()) { bodyParams.add(key, value); } else { querystringParams.add(key, value); } } /** * Set 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 setPayload(String payload) { resetPayload(); stringPayload = payload; } /** * Overloaded version for byte arrays * * @param payload byte[] */ public void setPayload(byte[] payload) { resetPayload(); byteArrayPayload = payload.clone(); } /** * Overloaded version for File * * @param payload File */ public void setPayload(File payload) { resetPayload(); filePayload = payload; } private void resetPayload() { stringPayload = null; byteArrayPayload = null; filePayload = null; } /** * 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 { final ParameterList result = new ParameterList(); final 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() { 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 (set in {@link #setPayload(java.lang.String)}) * * @return form encoded string */ public String getStringPayload() { return stringPayload; } /** * @return the body of the request (set in {@link #setPayload(byte[])} or in * {@link #addBodyParameter(java.lang.String, java.lang.String)} ) */ public byte[] getByteArrayPayload() { if (byteArrayPayload != null) { return byteArrayPayload; } final String body = bodyParams.asFormUrlEncodedString(); try { return body.getBytes(getCharset()); } catch (UnsupportedEncodingException uee) { throw new OAuthException("Unsupported Charset: " + getCharset(), uee); } } public File getFilePayload() { return filePayload; } @Override public String toString() { return String.format("@Request(%s %s)", getVerb(), getUrl()); } public Verb getVerb() { return verb; } public Map<String, String> getHeaders() { return headers; } public String getCharset() { return charset == null ? Charset.defaultCharset().name() : charset; } /** * Set the charset of the body of the request * * @param charsetName name of the charset of the request */ public void setCharset(String charsetName) { charset = charsetName; } public interface ResponseConverter<T> { T convert(Response response) throws IOException; } }