package org.limewire.rest.oauth;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpRequest;
import org.apache.http.NameValuePair;
import org.apache.http.RequestLine;
import org.apache.http.message.BasicHeader;
import org.apache.http.message.BasicNameValuePair;
import org.limewire.logging.Log;
import org.limewire.logging.LogFactory;
import org.limewire.rest.RestUtils;
/**
* A representation of an HTTP request using the OAuth protocol.
*/
public class OAuthRequest {
public static final String OAUTH_CONSUMER_KEY = "oauth_consumer_key";
public static final String OAUTH_TOKEN = "oauth_token";
public static final String OAUTH_SIGNATURE_METHOD = "oauth_signature_method";
public static final String OAUTH_SIGNATURE = "oauth_signature";
public static final String OAUTH_TIMESTAMP = "oauth_timestamp";
public static final String OAUTH_NONCE = "oauth_nonce";
public static final String OAUTH_VERSION = "oauth_version";
public static final String AUTH_HEADER = "Authorization";
public static final String AUTH_SCHEME = "OAuth";
public static final String AUTH_REALM = "realm";
private static final Pattern AUTH_PATTERN = Pattern.compile("\\s*(\\w*)\\s+(.*)");
private static final Log LOG = LogFactory.getLog(OAuthRequest.class);
private final String method;
private final String uri;
private final Map<String, String> parameterMap;
/**
* Constructs an OAuthRequest for the specified HTTP request.
*/
public OAuthRequest(HttpRequest request) {
RequestLine requestLine = request.getRequestLine();
method = requestLine.getMethod();
uri = RestUtils.getBaseUri(requestLine.getUri());
parameterMap = new HashMap<String, String>();
parseAuthHeaderParameters(request);
parseQueryParameters(request);
}
/**
* Parses the parameters from the Authorization header. The realm is
* included as a parameter. If the header doesn't start with "OAuth",
* then the parameters are ignored.
*/
private void parseAuthHeaderParameters(HttpRequest request) {
Header[] headers = request.getHeaders(AUTH_HEADER);
for (Header header : headers) {
String authorization = header.getValue();
Matcher m = AUTH_PATTERN.matcher(authorization);
if (m.matches()) {
// First element must be OAuth.
if (AUTH_SCHEME.equalsIgnoreCase(m.group(1))) {
// Extract name/value pairs.
Header temp = new BasicHeader(AUTH_HEADER, m.group(2));
HeaderElement[] elements = temp.getElements();
for (HeaderElement element : elements) {
String name = RestUtils.percentDecode(element.getName());
String value = RestUtils.percentDecode(element.getValue());
parameterMap.put(name, value);
}
}
}
}
}
/**
* Parses the query parameters in the specified HTTP request, and adds
* them to the parameter map.
*/
private void parseQueryParameters(HttpRequest request) {
try {
String uriStr = request.getRequestLine().getUri();
Map<String, String> queryMap = RestUtils.getQueryParams(uriStr);
for (String key : queryMap.keySet()) {
String value = queryMap.get(key);
value = (value == null) ? "" : value;
parameterMap.put(RestUtils.percentDecode(key), RestUtils.percentDecode(value));
}
} catch (IOException ex) {
LOG.debugf(ex, "Unable to parse query parms {0}", ex.getMessage());
}
}
/**
* Returns the HTTP method.
*/
public String getMethod() {
return method;
}
/**
* Returns the URI of the request.
*/
public String getUri() {
return uri;
}
/**
* Returns the value for the specified request parameter name. If the
* parameter is not found, then null is returned.
*/
public String getParameter(String name) {
return parameterMap.get(name);
}
/**
* Returns the long value for the specified request parameter name. If
* the parameter is not found, or cannot be parsed into a long, then the
* specified default value is returned.
*/
public long getParameter(String name, long defaultValue) {
String value = parameterMap.get(name);
if (value != null) {
try {
return Long.parseLong(value);
} catch (NumberFormatException ex) {
return defaultValue;
}
} else {
return defaultValue;
}
}
/**
* Returns a List of name/value pairs representing the request parameters.
*/
public List<NameValuePair> getParameters() {
List<NameValuePair> parameters = new ArrayList<NameValuePair>();
for (Map.Entry<String, String> entry : parameterMap.entrySet()) {
parameters.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
}
return parameters;
}
}