Commit d8bc364a authored by mef@chromium.org's avatar mef@chromium.org

Add method getAllHeaders to get HttpUrlRequest response headers. It handles...

Add method getAllHeaders to get HttpUrlRequest response headers. It handles multiple headers with the same name.
For compatibility with HttpUrlConnection it includes Http status line as value for NULL key.

BUG=390267

Review URL: https://codereview.chromium.org/423163007

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@287597 0039d316-1c4b-4281-b951-d872f2087c98
parent de6ebd22
...@@ -476,7 +476,6 @@ class HttpUrlConnectionUrlRequest implements HttpUrlRequest { ...@@ -476,7 +476,6 @@ class HttpUrlConnectionUrlRequest implements HttpUrlRequest {
return mContentType; return mContentType;
} }
@Override @Override
public String getHeader(String name) { public String getHeader(String name) {
if (mConnection == null) { if (mConnection == null) {
...@@ -492,6 +491,14 @@ class HttpUrlConnectionUrlRequest implements HttpUrlRequest { ...@@ -492,6 +491,14 @@ class HttpUrlConnectionUrlRequest implements HttpUrlRequest {
return null; return null;
} }
@Override
public Map<String, List<String>> getAllHeaders() {
if (mConnection == null) {
throw new IllegalStateException("Response headers not available");
}
return mConnection.getHeaderFields();
}
private void validateNotStarted() { private void validateNotStarted() {
if (mStarted) { if (mStarted) {
throw new IllegalStateException("Request already started"); throw new IllegalStateException("Request already started");
......
...@@ -7,6 +7,8 @@ package org.chromium.net; ...@@ -7,6 +7,8 @@ package org.chromium.net;
import java.io.IOException; import java.io.IOException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.util.List;
import java.util.Map;
/** /**
* HTTP request (GET or POST). * HTTP request (GET or POST).
...@@ -134,6 +136,12 @@ public interface HttpUrlRequest { ...@@ -134,6 +136,12 @@ public interface HttpUrlRequest {
*/ */
String getHeader(String name); String getHeader(String name);
/**
* Returns an unmodifiable map of the response-header fields and values.
* The null key is mapped to the HTTP status line for compatibility with
* HttpUrlConnection.
*/
Map<String, List<String>> getAllHeaders();
/** /**
* Returns the exception that occurred while executing the request of null * Returns the exception that occurred while executing the request of null
......
...@@ -15,7 +15,9 @@ import java.net.UnknownHostException; ...@@ -15,7 +15,9 @@ import java.net.UnknownHostException;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.channels.ReadableByteChannel; import java.nio.channels.ReadableByteChannel;
import java.nio.channels.WritableByteChannel; import java.nio.channels.WritableByteChannel;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
...@@ -276,6 +278,14 @@ public class UrlRequest { ...@@ -276,6 +278,14 @@ public class UrlRequest {
return nativeGetHeader(mUrlRequestPeer, name); return nativeGetHeader(mUrlRequestPeer, name);
} }
// All response headers.
public Map<String, List<String>> getAllHeaders() {
validateHeadersAvailable();
ResponseHeadersMap result = new ResponseHeadersMap();
nativeGetAllHeaders(mUrlRequestPeer, result);
return result;
}
/** /**
* A callback invoked when the first chunk of the response has arrived. * A callback invoked when the first chunk of the response has arrived.
*/ */
...@@ -335,6 +345,19 @@ public class UrlRequest { ...@@ -335,6 +345,19 @@ public class UrlRequest {
} }
} }
/**
* Appends header |name| with value |value| to |headersMap|.
*/
@SuppressWarnings("unused")
@CalledByNative
private void onAppendResponseHeader(ResponseHeadersMap headersMap,
String name, String value) {
if (!headersMap.containsKey(name)) {
headersMap.put(name, new ArrayList<String>());
}
headersMap.get(name).add(value);
}
private void validateNotRecycled() { private void validateNotRecycled() {
if (mRecycled) { if (mRecycled) {
throw new IllegalStateException("Accessing recycled request"); throw new IllegalStateException("Accessing recycled request");
...@@ -389,4 +412,11 @@ public class UrlRequest { ...@@ -389,4 +412,11 @@ public class UrlRequest {
private native long nativeGetContentLength(long urlRequestPeer); private native long nativeGetContentLength(long urlRequestPeer);
private native String nativeGetHeader(long urlRequestPeer, String name); private native String nativeGetHeader(long urlRequestPeer, String name);
private native void nativeGetAllHeaders(long urlRequestPeer,
ResponseHeadersMap headers);
// Explicit class to work around JNI-generator generics confusion.
private class ResponseHeadersMap extends HashMap<String, List<String>> {
}
} }
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "jni/UrlRequest_jni.h" #include "jni/UrlRequest_jni.h"
#include "net/base/net_errors.h" #include "net/base/net_errors.h"
#include "net/base/request_priority.h" #include "net/base/request_priority.h"
#include "net/http/http_response_headers.h"
using base::android::ConvertUTF8ToJavaString; using base::android::ConvertUTF8ToJavaString;
...@@ -307,4 +308,36 @@ static jstring GetHeader( ...@@ -307,4 +308,36 @@ static jstring GetHeader(
} }
} }
static void GetAllHeaders(JNIEnv* env,
jobject object,
jlong urlRequestPeer,
jobject headersMap) {
URLRequestPeer* request = reinterpret_cast<URLRequestPeer*>(urlRequestPeer);
if (request == NULL)
return;
net::HttpResponseHeaders* headers = request->GetResponseHeaders();
if (headers == NULL)
return;
void* iter = NULL;
std::string header_name;
std::string header_value;
while (headers->EnumerateHeaderLines(&iter, &header_name, &header_value)) {
ScopedJavaLocalRef<jstring> name =
ConvertUTF8ToJavaString(env, header_name);
ScopedJavaLocalRef<jstring> value =
ConvertUTF8ToJavaString(env, header_value);
Java_UrlRequest_onAppendResponseHeader(
env, object, headersMap, name.Release(), value.Release());
}
// Some implementations (notably HttpURLConnection) include a mapping for the
// null key; in HTTP's case, this maps to the HTTP status line.
ScopedJavaLocalRef<jstring> status_line =
ConvertUTF8ToJavaString(env, headers->GetStatusLine());
Java_UrlRequest_onAppendResponseHeader(
env, object, headersMap, NULL, status_line.Release());
}
} // namespace cronet } // namespace cronet
...@@ -98,6 +98,7 @@ public class CronetSampleActivity extends Activity { ...@@ -98,6 +98,7 @@ public class CronetSampleActivity extends Activity {
public void onResponseStarted(HttpUrlRequest request) { public void onResponseStarted(HttpUrlRequest request) {
Log.i(TAG, "****** Response Started, content length is " Log.i(TAG, "****** Response Started, content length is "
+ request.getContentLength()); + request.getContentLength());
Log.i(TAG, "*** Headers Are *** " + request.getAllHeaders());
} }
@Override @Override
......
...@@ -67,6 +67,13 @@ std::string URLRequestPeer::GetHeader(const std::string &name) const { ...@@ -67,6 +67,13 @@ std::string URLRequestPeer::GetHeader(const std::string &name) const {
return value; return value;
} }
net::HttpResponseHeaders* URLRequestPeer::GetResponseHeaders() const {
if (url_request_ == NULL) {
return NULL;
}
return url_request_->response_headers();
}
void URLRequestPeer::Start() { void URLRequestPeer::Start() {
context_->GetNetworkTaskRunner()->PostTask( context_->GetNetworkTaskRunner()->PostTask(
FROM_HERE, FROM_HERE,
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
namespace net { namespace net {
class GrowableIOBuffer; class GrowableIOBuffer;
class HttpResponseHeaders;
class UploadDataStream; class UploadDataStream;
} // namespace net } // namespace net
...@@ -90,6 +91,9 @@ class URLRequestPeer : public net::URLRequest::Delegate { ...@@ -90,6 +91,9 @@ class URLRequestPeer : public net::URLRequest::Delegate {
// Returns the value of the specified response header. // Returns the value of the specified response header.
std::string GetHeader(const std::string& name) const; std::string GetHeader(const std::string& name) const;
// Get all response headers, as a HttpResponseHeaders object.
net::HttpResponseHeaders* GetResponseHeaders() const;
// Returns the overall number of bytes read. // Returns the overall number of bytes read.
size_t bytes_read() const { return bytes_read_; } size_t bytes_read() const { return bytes_read_; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment