RequestHandlepublic class RequestHandle extends Object RequestHandle: handles a request session that may include multiple
redirects, HTTP authentication requests, etc.
{@hide} |
Fields Summary |
---|
private String | mUrl | private android.net.WebAddress | mUri | private String | mMethod | private Map | mHeaders | private RequestQueue | mRequestQueue | private Request | mRequest | private InputStream | mBodyProvider | private int | mBodyLength | private int | mRedirectCount | private Connection | mConnection | private static final String | AUTHORIZATION_HEADER | private static final String | PROXY_AUTHORIZATION_HEADER | public static final int | MAX_REDIRECT_COUNT |
Constructors Summary |
---|
public RequestHandle(RequestQueue requestQueue, String url, android.net.WebAddress uri, String method, Map headers, InputStream bodyProvider, int bodyLength, Request request)Creates a new request session.
if (headers == null) {
headers = new HashMap<String, String>();
}
mHeaders = headers;
mBodyProvider = bodyProvider;
mBodyLength = bodyLength;
mMethod = method == null? "GET" : method;
mUrl = url;
mUri = uri;
mRequestQueue = requestQueue;
mRequest = request;
| public RequestHandle(RequestQueue requestQueue, String url, android.net.WebAddress uri, String method, Map headers, InputStream bodyProvider, int bodyLength, Request request, Connection conn)Creates a new request session with a given Connection. This connection
is used during a synchronous load to handle this request.
this(requestQueue, url, uri, method, headers, bodyProvider, bodyLength,
request);
mConnection = conn;
|
Methods Summary |
---|
private java.lang.String | H(java.lang.String param)
if (param != null) {
try {
MessageDigest md5 = MessageDigest.getInstance("MD5");
byte[] d = md5.digest(param.getBytes());
if (d != null) {
return bufferToHex(d);
}
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
}
return null;
| private java.lang.String | KD(java.lang.String secret, java.lang.String data)
return H(secret + ":" + data);
| public static java.lang.String | authorizationHeader(boolean isProxy)
if (!isProxy) {
return AUTHORIZATION_HEADER;
} else {
return PROXY_AUTHORIZATION_HEADER;
}
| private java.lang.String | bufferToHex(byte[] buffer)
final char hexChars[] =
{ '0",'1",'2",'3",'4",'5",'6",'7",'8",'9",'a",'b",'c",'d",'e",'f" };
if (buffer != null) {
int length = buffer.length;
if (length > 0) {
StringBuilder hex = new StringBuilder(2 * length);
for (int i = 0; i < length; ++i) {
byte l = (byte) (buffer[i] & 0x0F);
byte h = (byte)((buffer[i] & 0xF0) >> 4);
hex.append(hexChars[h]);
hex.append(hexChars[l]);
}
return hex.toString();
} else {
return "";
}
}
return null;
| public void | cancel()Cancels this request
if (mRequest != null) {
mRequest.cancel();
}
| public static java.lang.String | computeBasicAuthResponse(java.lang.String username, java.lang.String password)
Assert.assertNotNull(username);
Assert.assertNotNull(password);
// encode username:password to base64
return new String(Base64.encodeBase64((username + ':" + password).getBytes()));
| private java.lang.String | computeCnonce()Computes a random cnonce value based on the current time.
Random rand = new Random();
int nextInt = rand.nextInt();
nextInt = (nextInt == Integer.MIN_VALUE) ?
Integer.MAX_VALUE : Math.abs(nextInt);
return Integer.toString(nextInt, 16);
| private java.lang.String | computeDigest(java.lang.String A1, java.lang.String A2, java.lang.String nonce, java.lang.String QOP, java.lang.String nc, java.lang.String cnonce)
if (HttpLog.LOGV) {
HttpLog.v("computeDigest(): QOP: " + QOP);
}
if (QOP == null) {
return KD(H(A1), nonce + ":" + H(A2));
} else {
if (QOP.equalsIgnoreCase("auth")) {
return KD(H(A1), nonce + ":" + nc + ":" + cnonce + ":" + QOP + ":" + H(A2));
}
}
return null;
| private java.lang.String | computeDigestAuthResponse(java.lang.String username, java.lang.String password, java.lang.String realm, java.lang.String nonce, java.lang.String QOP, java.lang.String algorithm, java.lang.String opaque)
Assert.assertNotNull(username);
Assert.assertNotNull(password);
Assert.assertNotNull(realm);
String A1 = username + ":" + realm + ":" + password;
String A2 = mMethod + ":" + mUrl;
// because we do not preemptively send authorization headers, nc is always 1
String nc = "00000001";
String cnonce = computeCnonce();
String digest = computeDigest(A1, A2, nonce, QOP, nc, cnonce);
String response = "";
response += "username=" + doubleQuote(username) + ", ";
response += "realm=" + doubleQuote(realm) + ", ";
response += "nonce=" + doubleQuote(nonce) + ", ";
response += "uri=" + doubleQuote(mUrl) + ", ";
response += "response=" + doubleQuote(digest) ;
if (opaque != null) {
response += ", opaque=" + doubleQuote(opaque);
}
if (algorithm != null) {
response += ", algorithm=" + algorithm;
}
if (QOP != null) {
response += ", qop=" + QOP + ", nc=" + nc + ", cnonce=" + doubleQuote(cnonce);
}
return response;
| private void | createAndQueueNewRequest()Creates and queues new request.
// mConnection is non-null if and only if the requests are synchronous.
if (mConnection != null) {
RequestHandle newHandle = mRequestQueue.queueSynchronousRequest(
mUrl, mUri, mMethod, mHeaders, mRequest.mEventHandler,
mBodyProvider, mBodyLength);
mRequest = newHandle.mRequest;
mConnection = newHandle.mConnection;
newHandle.processRequest();
return;
}
mRequest = mRequestQueue.queueRequest(
mUrl, mUri, mMethod, mHeaders, mRequest.mEventHandler,
mBodyProvider,
mBodyLength).mRequest;
| private java.lang.String | doubleQuote(java.lang.String param)"Double-quotes" the argument.
if (param != null) {
return "\"" + param + "\"";
}
return null;
| public java.lang.String | getMethod()
return mMethod;
| public int | getRedirectCount()
return mRedirectCount;
| public void | handleSslErrorResponse(boolean proceed)Handles SSL error(s) on the way down from the user (the user
has already provided their feedback).
if (mRequest != null) {
mRequest.handleSslErrorResponse(proceed);
}
| public boolean | isRedirectMax()
return mRedirectCount >= MAX_REDIRECT_COUNT;
| public void | pauseRequest(boolean pause)Pauses the loading of this request. For example, called from the WebCore thread
when the plugin can take no more data.
if (mRequest != null) {
mRequest.setLoadingPaused(pause);
}
| public void | processRequest()
if (mConnection != null) {
mConnection.processRequests(mRequest);
}
| public void | setRedirectCount(int count)
mRedirectCount = count;
| private void | setupAuthResponse()
try {
if (mBodyProvider != null) mBodyProvider.reset();
} catch (java.io.IOException ex) {
if (HttpLog.LOGV) {
HttpLog.v("setupAuthResponse() failed to reset body provider");
}
}
createAndQueueNewRequest();
| public void | setupBasicAuthResponse(boolean isProxy, java.lang.String username, java.lang.String password)Create and queue an HTTP authentication-response (basic) request.
String response = computeBasicAuthResponse(username, password);
if (HttpLog.LOGV) {
HttpLog.v("setupBasicAuthResponse(): response: " + response);
}
mHeaders.put(authorizationHeader(isProxy), "Basic " + response);
setupAuthResponse();
| public void | setupDigestAuthResponse(boolean isProxy, java.lang.String username, java.lang.String password, java.lang.String realm, java.lang.String nonce, java.lang.String QOP, java.lang.String algorithm, java.lang.String opaque)Create and queue an HTTP authentication-response (digest) request.
String response = computeDigestAuthResponse(
username, password, realm, nonce, QOP, algorithm, opaque);
if (HttpLog.LOGV) {
HttpLog.v("setupDigestAuthResponse(): response: " + response);
}
mHeaders.put(authorizationHeader(isProxy), "Digest " + response);
setupAuthResponse();
| public boolean | setupRedirect(java.lang.String redirectTo, int statusCode, java.util.Map cacheHeaders)Create and queue a redirect request.
if (HttpLog.LOGV) {
HttpLog.v("RequestHandle.setupRedirect(): redirectCount " +
mRedirectCount);
}
// be careful and remove authentication headers, if any
mHeaders.remove(AUTHORIZATION_HEADER);
mHeaders.remove(PROXY_AUTHORIZATION_HEADER);
if (++mRedirectCount == MAX_REDIRECT_COUNT) {
// Way too many redirects -- fail out
if (HttpLog.LOGV) HttpLog.v(
"RequestHandle.setupRedirect(): too many redirects " +
mRequest);
mRequest.error(EventHandler.ERROR_REDIRECT_LOOP,
com.android.internal.R.string.httpErrorRedirectLoop);
return false;
}
if (mUrl.startsWith("https:") && redirectTo.startsWith("http:")) {
// implement http://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3
if (HttpLog.LOGV) {
HttpLog.v("blowing away the referer on an https -> http redirect");
}
mHeaders.remove("Referer");
}
mUrl = redirectTo;
try {
mUri = new WebAddress(mUrl);
} catch (ParseException e) {
e.printStackTrace();
}
// update the "Cookie" header based on the redirected url
mHeaders.remove("Cookie");
String cookie = CookieManager.getInstance().getCookie(mUri);
if (cookie != null && cookie.length() > 0) {
mHeaders.put("Cookie", cookie);
}
if ((statusCode == 302 || statusCode == 303) && mMethod.equals("POST")) {
if (HttpLog.LOGV) {
HttpLog.v("replacing POST with GET on redirect to " + redirectTo);
}
mMethod = "GET";
}
/* Only repost content on a 307. If 307, reset the body
provider so we can replay the body */
if (statusCode == 307) {
try {
if (mBodyProvider != null) mBodyProvider.reset();
} catch (java.io.IOException ex) {
if (HttpLog.LOGV) {
HttpLog.v("setupRedirect() failed to reset body provider");
}
return false;
}
} else {
mHeaders.remove("Content-Type");
mBodyProvider = null;
}
// Update the cache headers for this URL
mHeaders.putAll(cacheHeaders);
createAndQueueNewRequest();
return true;
| public void | waitUntilComplete()
mRequest.waitUntilComplete();
|
|