Commit abc0bae3 authored by mef's avatar mef Committed by Commit bot

[Cronet] Continue UrlRequest with NULL certificate if Client cert is requested.

TEST=CronetUrlRequestTest.testMockClientCertificateRequested
BUG=558420

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

Cr-Commit-Position: refs/heads/master@{#361130}
parent 24634402
...@@ -257,6 +257,14 @@ void CronetURLRequestAdapter::OnReceivedRedirect( ...@@ -257,6 +257,14 @@ void CronetURLRequestAdapter::OnReceivedRedirect(
*defer_redirect = true; *defer_redirect = true;
} }
void CronetURLRequestAdapter::OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) {
DCHECK(context_->IsOnNetworkThread());
// Cronet does not support client certificates.
request->ContinueWithCertificate(nullptr, nullptr);
}
void CronetURLRequestAdapter::OnSSLCertificateError( void CronetURLRequestAdapter::OnSSLCertificateError(
net::URLRequest* request, net::URLRequest* request,
const net::SSLInfo& ssl_info, const net::SSLInfo& ssl_info,
......
...@@ -28,6 +28,7 @@ class SingleThreadTaskRunner; ...@@ -28,6 +28,7 @@ class SingleThreadTaskRunner;
namespace net { namespace net {
class HttpRequestHeaders; class HttpRequestHeaders;
class HttpResponseHeaders; class HttpResponseHeaders;
class SSLCertRequestInfo;
class SSLInfo; class SSLInfo;
class UploadDataStream; class UploadDataStream;
} // namespace net } // namespace net
...@@ -118,6 +119,9 @@ class CronetURLRequestAdapter : public net::URLRequest::Delegate { ...@@ -118,6 +119,9 @@ class CronetURLRequestAdapter : public net::URLRequest::Delegate {
void OnReceivedRedirect(net::URLRequest* request, void OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& redirect_info, const net::RedirectInfo& redirect_info,
bool* defer_redirect) override; bool* defer_redirect) override;
void OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) override;
void OnSSLCertificateError(net::URLRequest* request, void OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& ssl_info, const net::SSLInfo& ssl_info,
bool fatal) override; bool fatal) override;
......
...@@ -553,6 +553,22 @@ public class CronetUrlRequestTest extends CronetTestBase { ...@@ -553,6 +553,22 @@ public class CronetUrlRequestTest extends CronetTestBase {
assertEquals(callback.mResponseStep, ResponseStep.ON_RESPONSE_STARTED); assertEquals(callback.mResponseStep, ResponseStep.ON_RESPONSE_STARTED);
} }
/**
* Tests that request continues when client certificate is requested.
*/
@SmallTest
@Feature({"Cronet"})
public void testMockClientCertificateRequested() throws Exception {
TestUrlRequestCallback callback = startAndWaitForComplete(
MockUrlRequestJobFactory.getMockUrlForClientCertificateRequest());
assertNotNull(callback.mResponseInfo);
assertEquals(200, callback.mResponseInfo.getHttpStatusCode());
assertEquals("data", callback.mResponseAsString);
assertEquals(0, callback.mRedirectCount);
assertNull(callback.mError);
assertFalse(callback.mOnErrorCalled);
}
/** /**
* Tests that an SSL cert error will be reported via {@link UrlRequest#onFailed}. * Tests that an SSL cert error will be reported via {@link UrlRequest#onFailed}.
*/ */
......
...@@ -49,6 +49,13 @@ ScopedJavaLocalRef<jstring> GetMockUrlForSSLCertificateError( ...@@ -49,6 +49,13 @@ ScopedJavaLocalRef<jstring> GetMockUrlForSSLCertificateError(
return base::android::ConvertUTF8ToJavaString(jenv, url.spec()); return base::android::ConvertUTF8ToJavaString(jenv, url.spec());
} }
ScopedJavaLocalRef<jstring> GetMockUrlForClientCertificateRequest(
JNIEnv* jenv,
const JavaParamRef<jclass>& jcaller) {
GURL url(net::URLRequestMockDataJob::GetMockUrlForClientCertificateRequest());
return base::android::ConvertUTF8ToJavaString(jenv, url.spec());
}
bool RegisterMockUrlRequestJobFactory(JNIEnv* env) { bool RegisterMockUrlRequestJobFactory(JNIEnv* env) {
return RegisterNativesImpl(env); return RegisterNativesImpl(env);
} }
......
...@@ -53,6 +53,14 @@ public final class MockUrlRequestJobFactory { ...@@ -53,6 +53,14 @@ public final class MockUrlRequestJobFactory {
return nativeGetMockUrlForData(data, dataRepeatCount); return nativeGetMockUrlForData(data, dataRepeatCount);
} }
/**
* Constructs a mock URL that will request client certificate and return
* the string "data" as the response.
*/
public static String getMockUrlForClientCertificateRequest() {
return nativeGetMockUrlForClientCertificateRequest();
}
/** /**
* Constructs a mock URL that will fail with an SSL certificate error. * Constructs a mock URL that will fail with an SSL certificate error.
*/ */
...@@ -67,5 +75,7 @@ public final class MockUrlRequestJobFactory { ...@@ -67,5 +75,7 @@ public final class MockUrlRequestJobFactory {
private static native String nativeGetMockUrlForData(String data, private static native String nativeGetMockUrlForData(String data,
int dataRepeatCount); int dataRepeatCount);
private static native String nativeGetMockUrlForClientCertificateRequest();
private static native String nativeGetMockUrlForSSLCertificateError(); private static native String nativeGetMockUrlForSSLCertificateError();
} }
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "net/http/http_request_headers.h" #include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/http/http_util.h" #include "net/http/http_util.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/url_request_filter.h" #include "net/url_request/url_request_filter.h"
namespace net { namespace net {
...@@ -47,16 +48,25 @@ int GetRepeatCountFromRequest(const URLRequest& request) { ...@@ -47,16 +48,25 @@ int GetRepeatCountFromRequest(const URLRequest& request) {
return repeat_count; return repeat_count;
} }
// Gets the requestcert flag from URL.
bool GetRequestClientCertificate(const URLRequest& request) {
std::string ignored_value;
return GetValueForKeyInQuery(request.url(), "requestcert", &ignored_value);
}
GURL GetMockUrl(const std::string& scheme, GURL GetMockUrl(const std::string& scheme,
const std::string& hostname, const std::string& hostname,
const std::string& data, const std::string& data,
int data_repeat_count) { int data_repeat_count,
bool request_client_certificate) {
DCHECK_GT(data_repeat_count, 0); DCHECK_GT(data_repeat_count, 0);
std::string url(scheme + "://" + hostname + "/"); std::string url(scheme + "://" + hostname + "/");
url.append("?data="); url.append("?data=");
url.append(data); url.append(data);
url.append("&repeat="); url.append("&repeat=");
url.append(base::IntToString(data_repeat_count)); url.append(base::IntToString(data_repeat_count));
if (request_client_certificate)
url += "&requestcert=1";
return GURL(url); return GURL(url);
} }
...@@ -71,7 +81,8 @@ class MockJobInterceptor : public URLRequestInterceptor { ...@@ -71,7 +81,8 @@ class MockJobInterceptor : public URLRequestInterceptor {
NetworkDelegate* network_delegate) const override { NetworkDelegate* network_delegate) const override {
return new URLRequestMockDataJob(request, network_delegate, return new URLRequestMockDataJob(request, network_delegate,
GetDataFromRequest(*request), GetDataFromRequest(*request),
GetRepeatCountFromRequest(*request)); GetRepeatCountFromRequest(*request),
GetRequestClientCertificate(*request));
} }
private: private:
...@@ -83,9 +94,11 @@ class MockJobInterceptor : public URLRequestInterceptor { ...@@ -83,9 +94,11 @@ class MockJobInterceptor : public URLRequestInterceptor {
URLRequestMockDataJob::URLRequestMockDataJob(URLRequest* request, URLRequestMockDataJob::URLRequestMockDataJob(URLRequest* request,
NetworkDelegate* network_delegate, NetworkDelegate* network_delegate,
const std::string& data, const std::string& data,
int data_repeat_count) int data_repeat_count,
bool request_client_certificate)
: URLRequestJob(request, network_delegate), : URLRequestJob(request, network_delegate),
data_offset_(0), data_offset_(0),
request_client_certificate_(request_client_certificate),
weak_factory_(this) { weak_factory_(this) {
DCHECK_GT(data_repeat_count, 0); DCHECK_GT(data_repeat_count, 0);
for (int i = 0; i < data_repeat_count; ++i) { for (int i = 0; i < data_repeat_count; ++i) {
...@@ -121,6 +134,13 @@ int URLRequestMockDataJob::GetResponseCode() const { ...@@ -121,6 +134,13 @@ int URLRequestMockDataJob::GetResponseCode() const {
return info.headers->response_code(); return info.headers->response_code();
} }
void URLRequestMockDataJob::ContinueWithCertificate(
X509Certificate* client_cert,
SSLPrivateKey* client_private_key) {
DCHECK(request_client_certificate_);
NotifyHeadersComplete();
}
// Public virtual version. // Public virtual version.
void URLRequestMockDataJob::GetResponseInfo(HttpResponseInfo* info) { void URLRequestMockDataJob::GetResponseInfo(HttpResponseInfo* info) {
// Forward to private const version. // Forward to private const version.
...@@ -145,6 +165,11 @@ void URLRequestMockDataJob::StartAsync() { ...@@ -145,6 +165,11 @@ void URLRequestMockDataJob::StartAsync() {
return; return;
set_expected_content_size(data_.length()); set_expected_content_size(data_.length());
if (request_client_certificate_) {
scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
NotifyCertificateRequested(request_all.get());
return;
}
NotifyHeadersComplete(); NotifyHeadersComplete();
} }
...@@ -176,12 +201,16 @@ GURL URLRequestMockDataJob::GetMockHttpsUrl(const std::string& data, ...@@ -176,12 +201,16 @@ GURL URLRequestMockDataJob::GetMockHttpsUrl(const std::string& data,
return GetMockHttpsUrlForHostname(kMockHostname, data, repeat_count); return GetMockHttpsUrlForHostname(kMockHostname, data, repeat_count);
} }
GURL URLRequestMockDataJob::GetMockUrlForClientCertificateRequest() {
return GetMockUrl("https", kMockHostname, "data", 1, true);
}
// static // static
GURL URLRequestMockDataJob::GetMockHttpUrlForHostname( GURL URLRequestMockDataJob::GetMockHttpUrlForHostname(
const std::string& hostname, const std::string& hostname,
const std::string& data, const std::string& data,
int repeat_count) { int repeat_count) {
return GetMockUrl("http", hostname, data, repeat_count); return GetMockUrl("http", hostname, data, repeat_count, false);
} }
// static // static
...@@ -189,7 +218,7 @@ GURL URLRequestMockDataJob::GetMockHttpsUrlForHostname( ...@@ -189,7 +218,7 @@ GURL URLRequestMockDataJob::GetMockHttpsUrlForHostname(
const std::string& hostname, const std::string& hostname,
const std::string& data, const std::string& data,
int repeat_count) { int repeat_count) {
return GetMockUrl("https", hostname, data, repeat_count); return GetMockUrl("https", hostname, data, repeat_count, false);
} }
} // namespace net } // namespace net
...@@ -15,18 +15,23 @@ namespace net { ...@@ -15,18 +15,23 @@ namespace net {
class URLRequest; class URLRequest;
// Mock data job, which synchronously returns data repeated multiple times. // Mock data job, which synchronously returns data repeated multiple times. If
// |request_client_certificate| is true, then this job will request client
// certificate before proceeding.
class URLRequestMockDataJob : public URLRequestJob { class URLRequestMockDataJob : public URLRequestJob {
public: public:
URLRequestMockDataJob(URLRequest* request, URLRequestMockDataJob(URLRequest* request,
NetworkDelegate* network_delegate, NetworkDelegate* network_delegate,
const std::string& data, const std::string& data,
int data_repeat_count); int data_repeat_count,
bool request_client_certificate);
void Start() override; void Start() override;
bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override; bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
int GetResponseCode() const override; int GetResponseCode() const override;
void GetResponseInfo(HttpResponseInfo* info) override; void GetResponseInfo(HttpResponseInfo* info) override;
void ContinueWithCertificate(X509Certificate* client_cert,
SSLPrivateKey* client_private_key) override;
// Adds the testing URLs to the URLRequestFilter. // Adds the testing URLs to the URLRequestFilter.
static void AddUrlHandler(); static void AddUrlHandler();
...@@ -38,6 +43,10 @@ class URLRequestMockDataJob : public URLRequestJob { ...@@ -38,6 +43,10 @@ class URLRequestMockDataJob : public URLRequestJob {
static GURL GetMockHttpUrl(const std::string& data, int repeat_count); static GURL GetMockHttpUrl(const std::string& data, int repeat_count);
static GURL GetMockHttpsUrl(const std::string& data, int repeat_count); static GURL GetMockHttpsUrl(const std::string& data, int repeat_count);
// Constructs Mock URL which will request client certificate and return the
// word "data" as the response.
static GURL GetMockUrlForClientCertificateRequest();
// URLRequestFailedJob must be added as a handler for |hostname| for // URLRequestFailedJob must be added as a handler for |hostname| for
// the returned URL to return |net_error|. // the returned URL to return |net_error|.
static GURL GetMockHttpUrlForHostname(const std::string& hostname, static GURL GetMockHttpUrlForHostname(const std::string& hostname,
...@@ -55,6 +64,7 @@ class URLRequestMockDataJob : public URLRequestJob { ...@@ -55,6 +64,7 @@ class URLRequestMockDataJob : public URLRequestJob {
std::string data_; std::string data_;
size_t data_offset_; size_t data_offset_;
bool request_client_certificate_;
base::WeakPtrFactory<URLRequestMockDataJob> weak_factory_; base::WeakPtrFactory<URLRequestMockDataJob> weak_factory_;
}; };
......
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