Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[Cronet] Continue UrlRequest with NULL certificate if Client cert is …
Browse files Browse the repository at this point in the history
…requested.

TEST=CronetUrlRequestTest.testMockClientCertificateRequested
BUG=558420

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

Cr-Commit-Position: refs/heads/master@{#361130}
(cherry picked from commit abc0bae)

Fixed M48 compilation errors.

[email protected]

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

Cr-Commit-Position: refs/branch-heads/2564@{#216}
Cr-Branched-From: 1283eca-refs/heads/master@{#359700}
  • Loading branch information
efimki committed Dec 3, 2015
1 parent 71fe916 commit e586fe0
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 7 deletions.
8 changes: 8 additions & 0 deletions components/cronet/android/cronet_url_request_adapter.cc
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,14 @@ void CronetURLRequestAdapter::OnReceivedRedirect(
*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);
}

void CronetURLRequestAdapter::OnSSLCertificateError(
net::URLRequest* request,
const net::SSLInfo& ssl_info,
Expand Down
4 changes: 4 additions & 0 deletions components/cronet/android/cronet_url_request_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ class SingleThreadTaskRunner;
namespace net {
class HttpRequestHeaders;
class HttpResponseHeaders;
class SSLCertRequestInfo;
class SSLInfo;
class UploadDataStream;
} // namespace net
Expand Down Expand Up @@ -118,6 +119,9 @@ class CronetURLRequestAdapter : public net::URLRequest::Delegate {
void OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) override;
void OnCertificateRequested(
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) override;
void OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,22 @@ public void testMockReadDataAsyncError() throws Exception {
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}.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ ScopedJavaLocalRef<jstring> GetMockUrlForSSLCertificateError(
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) {
return RegisterNativesImpl(env);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ public static String getMockUrlForData(String data, int 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.
*/
Expand All @@ -67,5 +75,7 @@ public static String getMockUrlForSSLCertificateError() {
private static native String nativeGetMockUrlForData(String data,
int dataRepeatCount);

private static native String nativeGetMockUrlForClientCertificateRequest();

private static native String nativeGetMockUrlForSSLCertificateError();
}
38 changes: 33 additions & 5 deletions net/test/url_request/url_request_mock_data_job.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/ssl/ssl_cert_request_info.h"
#include "net/url_request/url_request_filter.h"

namespace net {
Expand Down Expand Up @@ -47,16 +48,25 @@ int GetRepeatCountFromRequest(const URLRequest& request) {
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,
const std::string& hostname,
const std::string& data,
int data_repeat_count) {
int data_repeat_count,
bool request_client_certificate) {
DCHECK_GT(data_repeat_count, 0);
std::string url(scheme + "://" + hostname + "/");
url.append("?data=");
url.append(data);
url.append("&repeat=");
url.append(base::IntToString(data_repeat_count));
if (request_client_certificate)
url += "&requestcert=1";
return GURL(url);
}

Expand All @@ -71,7 +81,8 @@ class MockJobInterceptor : public URLRequestInterceptor {
NetworkDelegate* network_delegate) const override {
return new URLRequestMockDataJob(request, network_delegate,
GetDataFromRequest(*request),
GetRepeatCountFromRequest(*request));
GetRepeatCountFromRequest(*request),
GetRequestClientCertificate(*request));
}

private:
Expand All @@ -83,9 +94,11 @@ class MockJobInterceptor : public URLRequestInterceptor {
URLRequestMockDataJob::URLRequestMockDataJob(URLRequest* request,
NetworkDelegate* network_delegate,
const std::string& data,
int data_repeat_count)
int data_repeat_count,
bool request_client_certificate)
: URLRequestJob(request, network_delegate),
data_offset_(0),
request_client_certificate_(request_client_certificate),
weak_factory_(this) {
DCHECK_GT(data_repeat_count, 0);
for (int i = 0; i < data_repeat_count; ++i) {
Expand Down Expand Up @@ -121,6 +134,12 @@ int URLRequestMockDataJob::GetResponseCode() const {
return info.headers->response_code();
}

void URLRequestMockDataJob::ContinueWithCertificate(
X509Certificate* client_cert) {
DCHECK(request_client_certificate_);
NotifyHeadersComplete();
}

// Public virtual version.
void URLRequestMockDataJob::GetResponseInfo(HttpResponseInfo* info) {
// Forward to private const version.
Expand All @@ -145,6 +164,11 @@ void URLRequestMockDataJob::StartAsync() {
return;

set_expected_content_size(data_.length());
if (request_client_certificate_) {
scoped_refptr<SSLCertRequestInfo> request_all(new SSLCertRequestInfo());
NotifyCertificateRequested(request_all.get());
return;
}
NotifyHeadersComplete();
}

Expand Down Expand Up @@ -176,20 +200,24 @@ GURL URLRequestMockDataJob::GetMockHttpsUrl(const std::string& data,
return GetMockHttpsUrlForHostname(kMockHostname, data, repeat_count);
}

GURL URLRequestMockDataJob::GetMockUrlForClientCertificateRequest() {
return GetMockUrl("https", kMockHostname, "data", 1, true);
}

// static
GURL URLRequestMockDataJob::GetMockHttpUrlForHostname(
const std::string& hostname,
const std::string& data,
int repeat_count) {
return GetMockUrl("http", hostname, data, repeat_count);
return GetMockUrl("http", hostname, data, repeat_count, false);
}

// static
GURL URLRequestMockDataJob::GetMockHttpsUrlForHostname(
const std::string& hostname,
const std::string& data,
int repeat_count) {
return GetMockUrl("https", hostname, data, repeat_count);
return GetMockUrl("https", hostname, data, repeat_count, false);
}

} // namespace net
13 changes: 11 additions & 2 deletions net/test/url_request/url_request_mock_data_job.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,18 +15,22 @@ namespace net {

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 {
public:
URLRequestMockDataJob(URLRequest* request,
NetworkDelegate* network_delegate,
const std::string& data,
int data_repeat_count);
int data_repeat_count,
bool request_client_certificate);

void Start() override;
bool ReadRawData(IOBuffer* buf, int buf_size, int* bytes_read) override;
int GetResponseCode() const override;
void GetResponseInfo(HttpResponseInfo* info) override;
void ContinueWithCertificate(X509Certificate* client_cert) override;

// Adds the testing URLs to the URLRequestFilter.
static void AddUrlHandler();
Expand All @@ -38,6 +42,10 @@ class URLRequestMockDataJob : public URLRequestJob {
static GURL GetMockHttpUrl(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
// the returned URL to return |net_error|.
static GURL GetMockHttpUrlForHostname(const std::string& hostname,
Expand All @@ -55,6 +63,7 @@ class URLRequestMockDataJob : public URLRequestJob {

std::string data_;
size_t data_offset_;
bool request_client_certificate_;
base::WeakPtrFactory<URLRequestMockDataJob> weak_factory_;
};

Expand Down

0 comments on commit e586fe0

Please sign in to comment.