Commit d3e5b177 authored by Fabrice de Gans-Riberi's avatar Fabrice de Gans-Riberi Committed by Commit Bot

Add tests for the fuchsia.oldhttp service.

This CL adds tests for the fuchsia.oldhttp service Chromium
implementation. These tests ensure the service is capable of sending
URL requests, receiving a response and/or an error code as expected.
The service implementation files have been moved around under a single
directory for consistency.

Bug: 874155
Change-Id: Iae843adc62db054a17125cea10b17771c127b801
Reviewed-on: https://chromium-review.googlesource.com/c/1239627Reviewed-by: default avatarMatt Menke <mmenke@chromium.org>
Reviewed-by: default avatarBruce Dawson <brucedawson@chromium.org>
Reviewed-by: default avatarKevin Marshall <kmarshall@chromium.org>
Commit-Queue: Fabrice de Gans-Riberi <fdegans@chromium.org>
Cr-Commit-Position: refs/heads/master@{#600938}
parent d713bb2e
......@@ -749,6 +749,7 @@ group("gn_all") {
"//webrunner:archive_sources",
"//webrunner:webrunner_unittests",
"//webrunner/net_http:http_pkg",
"//webrunner/net_http:http_service_tests",
]
}
......
......@@ -21,6 +21,7 @@
#include "base/threading/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "build/build_config.h"
#include "net/base/net_errors.h"
#include "net/base/proxy_delegate.h"
#include "net/base/url_util.h"
......@@ -1553,6 +1554,9 @@ ProxyResolutionService::CreateSystemProxyConfigService(
#elif defined(OS_ANDROID)
return std::make_unique<ProxyConfigServiceAndroid>(
main_task_runner, base::ThreadTaskRunnerHandle::Get());
#elif defined(OS_FUCHSIA)
// TODO(crbug.com/889195): Implement a system proxy service for Fuchsia.
return std::make_unique<ProxyConfigServiceDirect>();
#else
LOG(WARNING) << "Failed to choose a system proxy settings fetcher "
"for this platform.";
......
......@@ -10,15 +10,14 @@ import("//build/util/process_version.gni")
import("//testing/test.gni")
import("//tools/grit/repack.gni")
executable("http_service") {
component("http_lib") {
sources = [
"service/http_service_impl.cc",
"service/http_service_impl.h",
"service/http_service_main.cc",
"service/url_loader_impl.cc",
"service/url_loader_impl.h",
"http_service_impl.cc",
"http_service_impl.h",
"url_loader_impl.cc",
"url_loader_impl.h",
]
deps = [
public_deps = [
"//base:base",
"//net:net",
"//third_party/fuchsia-sdk/sdk:oldhttp",
......@@ -26,6 +25,15 @@ executable("http_service") {
]
}
executable("http_service") {
sources = [
"http_service_main.cc",
]
deps = [
":http_lib",
]
}
fuchsia_package("http_pkg") {
binary = ":http_service"
package_name_override = "http"
......@@ -36,3 +44,18 @@ fuchsia_package_runner("http_pkg_runner") {
package = ":http_pkg"
package_name_override = "http"
}
test("http_service_tests") {
sources = [
"http_service_test_main.cc",
"http_service_unittest.cc",
]
deps = [
":http_lib",
"//net:test_support",
"//testing/gtest",
]
data = [
"testdata/",
]
}
......@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webrunner/net_http/service/http_service_impl.h"
#include "webrunner/net_http/http_service_impl.h"
#include "net/url_request/url_request_context_builder.h"
#include "webrunner/net_http/service/url_loader_impl.h"
#include "webrunner/net_http/url_loader_impl.h"
namespace net {
namespace net_http {
HttpServiceImpl::HttpServiceImpl() {
// TODO: Set the right options in the URLRequestContextBuilder.
......@@ -19,8 +19,8 @@ void HttpServiceImpl::CreateURLLoader(
fidl::InterfaceRequest<fuchsia::net::oldhttp::URLLoader> request) {
// The URLLoaderImpl objects lifespan is tied to their binding, which is set
// in their constructor.
URLRequestContextBuilder builder;
net::URLRequestContextBuilder builder;
new URLLoaderImpl(builder.Build(), std::move(request));
}
} // namespace net
} // namespace net_http
......@@ -2,15 +2,15 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBRUNNER_NET_HTTP_SERVICE_HTTP_SERVICE_IMPL_H_
#define WEBRUNNER_NET_HTTP_SERVICE_HTTP_SERVICE_IMPL_H_
#ifndef WEBRUNNER_NET_HTTP_HTTP_SERVICE_IMPL_H_
#define WEBRUNNER_NET_HTTP_HTTP_SERVICE_IMPL_H_
#include <fuchsia/net/oldhttp/cpp/fidl.h>
#include <lib/fidl/cpp/interface_request.h>
#include "net/url_request/url_request_context.h"
namespace net {
namespace net_http {
// Implements the Fuchsia HttpService API, using the //net library.
class HttpServiceImpl : public ::fuchsia::net::oldhttp::HttpService {
......@@ -27,6 +27,6 @@ class HttpServiceImpl : public ::fuchsia::net::oldhttp::HttpService {
DISALLOW_COPY_AND_ASSIGN(HttpServiceImpl);
};
} // namespace net
} // namespace net_http
#endif // WEBRUNNER_NET_HTTP_SERVICE_HTTP_SERVICE_IMPL_H_
#endif // WEBRUNNER_NET_HTTP_HTTP_SERVICE_IMPL_H_
......@@ -10,7 +10,7 @@
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "webrunner/net_http/service/http_service_impl.h"
#include "webrunner/net_http/http_service_impl.h"
int main(int argc, char** argv) {
// Instantiate various global structures.
......@@ -23,7 +23,7 @@ int main(int argc, char** argv) {
// publish the HTTP service into it.
base::fuchsia::ServiceDirectory* directory =
base::fuchsia::ServiceDirectory::GetDefault();
net::HttpServiceImpl http_service;
net_http::HttpServiceImpl http_service;
base::fuchsia::ScopedServiceBinding<::fuchsia::net::oldhttp::HttpService>
binding(directory, &http_service);
......
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "base/at_exit.h"
#include "base/bind.h"
#include "base/command_line.h"
#include "base/message_loop/message_loop.h"
#include "base/task/task_scheduler/task_scheduler.h"
#include "testing/gtest/include/gtest/gtest.h"
int main(int argc, char** argv) {
// Instantiate various global structures.
base::TaskScheduler::CreateAndStartWithDefaultParams("HTTP Service Test");
base::CommandLine::Init(argc, argv);
base::MessageLoopForIO loop;
base::AtExitManager exit_manager;
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <fuchsia/net/oldhttp/cpp/fidl.h>
#include <lib/fidl/cpp/binding.h>
#include "base/fuchsia/component_context.h"
#include "base/fuchsia/scoped_service_binding.h"
#include "base/fuchsia/service_directory.h"
#include "base/run_loop.h"
#include "net/base/net_errors.h"
#include "net/test/embedded_test_server/default_handlers.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webrunner/net_http/http_service_impl.h"
#include "webrunner/net_http/url_loader_impl.h"
namespace net_http {
namespace oldhttp = ::fuchsia::net::oldhttp;
namespace {
const base::FilePath::CharType kTestFilePath[] =
FILE_PATH_LITERAL("webrunner/net_http/testdata");
// Capacity, in bytes, for buffers used to read data off the URLResponse.
const size_t kBufferCapacity = 1024;
using ResponseHeaders = std::multimap<std::string, std::string>;
class HttpServiceTest : public ::testing::Test {
public:
HttpServiceTest() : binding_(&http_service_server_) {
// Initialize the test server.
test_server_.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL(kTestFilePath)));
net::test_server::RegisterDefaultHandlers(&test_server_);
}
protected:
void SetUp() override {
ASSERT_TRUE(test_server_.Start());
// Bind the service with the client-side interface.
binding_.Bind(http_service_interface_.NewRequest());
}
void TearDown() override {
// Disconnect the client and wait for the service to shut down.
base::RunLoop run_loop;
binding_.set_error_handler([&run_loop]() { run_loop.Quit(); });
http_service_interface_.Unbind();
run_loop.Run();
binding_.set_error_handler(nullptr);
// Check there are no pending requests.
EXPECT_EQ(URLLoaderImpl::GetNumActiveRequestsForTests(), 0);
}
// Helper method to start |request| on |url_loader|
void ExecuteRequest(const oldhttp::URLLoaderPtr& url_loader,
oldhttp::URLRequest request) {
base::RunLoop run_loop;
url_loader->Start(std::move(request),
[this, &run_loop](oldhttp::URLResponse response) {
run_loop.Quit();
url_response_ = std::move(response);
});
run_loop.Run();
}
net::EmbeddedTestServer* http_test_server() { return &test_server_; }
oldhttp::HttpServicePtr& http_service() { return http_service_interface_; }
oldhttp::URLResponse& url_response() { return url_response_; }
private:
net::EmbeddedTestServer test_server_;
HttpServiceImpl http_service_server_;
oldhttp::HttpServicePtr http_service_interface_;
fidl::Binding<oldhttp::HttpService> binding_;
oldhttp::URLResponse url_response_;
DISALLOW_COPY_AND_ASSIGN(HttpServiceTest);
};
void CheckResponseStream(const oldhttp::URLResponse& response,
const std::string& expected_response) {
EXPECT_TRUE(response.body->is_stream());
zx::socket stream = std::move(response.body->stream());
size_t offset = 0;
while (true) {
std::array<char, kBufferCapacity> buffer;
size_t size = 0;
zx_status_t result = stream.read(0, buffer.data(), kBufferCapacity, &size);
if (result == ZX_ERR_SHOULD_WAIT) {
zx_signals_t observed;
stream.wait_one(ZX_SOCKET_READABLE | ZX_SOCKET_PEER_CLOSED,
zx::time::infinite(), &observed);
if (observed & ZX_SOCKET_READABLE) {
// Attempt to read again now that the socket is readable.
continue;
} else if (observed & ZX_SOCKET_PEER_CLOSED) {
// Done reading.
break;
} else {
NOTREACHED();
}
} else if (result == ZX_ERR_PEER_CLOSED) {
// Done reading.
break;
}
EXPECT_EQ(result, ZX_OK);
EXPECT_TRUE(std::equal(buffer.begin(), buffer.begin() + size,
expected_response.begin() + offset));
offset += size;
}
EXPECT_EQ(offset, expected_response.length());
}
void CheckResponseBuffer(const oldhttp::URLResponse& response,
const std::string& expected_response) {
EXPECT_TRUE(response.body->is_buffer());
fuchsia::mem::Buffer mem_buffer = std::move(response.body->buffer());
size_t response_size = mem_buffer.size;
EXPECT_EQ(mem_buffer.size, expected_response.length());
std::array<char, kBufferCapacity> buffer;
size_t offset = 0;
while (offset != mem_buffer.size) {
size_t length = std::min(response_size - offset, kBufferCapacity);
zx_status_t result = mem_buffer.vmo.read(buffer.data(), offset, length);
EXPECT_EQ(result, ZX_OK);
EXPECT_TRUE(std::equal(buffer.begin(), buffer.begin() + response_size,
expected_response.begin() + offset));
offset += response_size;
}
EXPECT_EQ(offset, expected_response.length());
}
void CheckResponseHeaders(const oldhttp::URLResponse& response,
ResponseHeaders* expected_headers) {
for (auto& header : response.headers.get()) {
const std::string header_name = header.name->data();
const std::string header_value = header.value->data();
auto iter = std::find_if(expected_headers->begin(), expected_headers->end(),
[&header_name, &header_value](auto& elt) -> bool {
return elt.first.compare(header_name) == 0 &&
elt.second.compare(header_value) == 0;
});
EXPECT_NE(iter, expected_headers->end())
<< "Unexpected header: \"" << header_name << "\" with value: \""
<< header_value << "\".";
if (iter != expected_headers->end()) {
expected_headers->erase(iter);
}
}
EXPECT_TRUE(expected_headers->empty());
}
} // namespace
// Check a basic end-to-end request resolution with the response being streamed
// is handled properly.
TEST_F(HttpServiceTest, BasicRequestStream) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/simple.html").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 200u);
CheckResponseStream(url_response(), "hello");
}
// Check a basic end-to-end request resolution with the response being
// buffered is handled properly.
TEST_F(HttpServiceTest, BasicRequestBuffer) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/simple.html").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::BUFFER;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 200u);
CheckResponseBuffer(url_response(), "hello");
}
// Check network request headers are received properly.
TEST_F(HttpServiceTest, RequestWithHeaders) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/with-headers.html").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 200u);
CheckResponseStream(
url_response(),
"This file is boring; all the action's in the .mock-http-headers.\n");
ResponseHeaders expected_headers = {
{"Cache-Control", "private"},
{"Content-Type", "text/html; charset=ISO-8859-1"},
{"X-Multiple-Entries", "a"},
{"X-Multiple-Entries", "b"},
};
CheckResponseHeaders(url_response(), &expected_headers);
}
// Check duplicate network request headers are received properly.
TEST_F(HttpServiceTest, RequestWithDuplicateHeaders) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url =
http_test_server()->GetURL("/with-duplicate-headers.html").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 200u);
CheckResponseStream(
url_response(),
"This file is boring; all the action's in the .mock-http-headers.\n");
ResponseHeaders expected_headers = {
{"Cache-Control", "private"},
{"Content-Type", "text/html; charset=ISO-8859-1"},
{"X-Multiple-Entries", "a"},
{"X-Multiple-Entries", "a"},
{"X-Multiple-Entries", "b"},
};
CheckResponseHeaders(url_response(), &expected_headers);
}
// Check a request with automatic redirect resolution is handled properly.
TEST_F(HttpServiceTest, AutoRedirect) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/redirect-test.html").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
request.auto_follow_redirects = true;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 200u);
EXPECT_EQ(url_response().url,
http_test_server()->GetURL("/with-headers.html").spec());
}
// Check a request with manual redirect resolution is handled properly.
TEST_F(HttpServiceTest, ManualRedirect) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
std::string request_url =
http_test_server()->GetURL("/redirect-test.html").spec();
oldhttp::URLRequest request;
request.url = request_url;
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
request.auto_follow_redirects = false;
ExecuteRequest(url_loader, std::move(request));
std::string final_url =
http_test_server()->GetURL("/with-headers.html").spec();
EXPECT_EQ(url_response().status_code, 302u);
EXPECT_EQ(url_response().url, request_url);
EXPECT_EQ(url_response().redirect_url, final_url);
base::RunLoop run_loop;
url_loader->FollowRedirect(
[&run_loop, &final_url](oldhttp::URLResponse response) {
EXPECT_EQ(response.status_code, 200u);
EXPECT_EQ(response.url, final_url);
run_loop.Quit();
});
run_loop.Run();
}
// Check HTTP error codes are properly populated.
TEST_F(HttpServiceTest, HttpErrorCode) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()
->base_url()
.Resolve("/non_existent_cooper.html")
.spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 404u);
}
// Check network error codes are properly populated.
TEST_F(HttpServiceTest, InvalidURL) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = "ht\\tp://test.test/";
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().error->code, net::ERR_INVALID_URL);
}
// Ensure the service can handle multiple concurrent requests.
TEST_F(HttpServiceTest, MultipleRequests) {
oldhttp::URLLoaderPtr url_loaders[100];
for (int i = 0; i < 100; i++) {
http_service()->CreateURLLoader(url_loaders[i].NewRequest());
}
base::RunLoop run_loop;
int requests_done = 0;
for (int i = 0; i < 100; i++) {
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/simple.html").spec();
request.method = "GET";
request.response_body_mode = (i % 2) == 0
? oldhttp::ResponseBodyMode::STREAM
: oldhttp::ResponseBodyMode::BUFFER;
url_loaders[i]->Start(
std::move(request),
[&requests_done, &run_loop](oldhttp::URLResponse response) {
EXPECT_EQ(response.status_code, 200u);
if (response.body->is_buffer()) {
CheckResponseBuffer(response, "hello");
} else {
CheckResponseStream(response, "hello");
}
requests_done++;
if (requests_done == 100) {
// Last request signals the run_loop to exit.
run_loop.Quit();
}
});
}
run_loop.Run();
}
// Check QueryStatus works as expected when a request is loading.
// Also checks the request is properly deleted after the binding is destroyed.
TEST_F(HttpServiceTest, QueryStatus) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/hung-after-headers").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
// In socket mode, we should still get the response headers.
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().status_code, 200u);
base::RunLoop run_loop;
url_loader->QueryStatus([&run_loop](oldhttp::URLLoaderStatus status) {
EXPECT_TRUE(status.is_loading);
run_loop.Quit();
});
run_loop.Run();
}
// Check the response error is properly set if the server disconnects early.
TEST_F(HttpServiceTest, CloseSocket) {
oldhttp::URLLoaderPtr url_loader;
http_service()->CreateURLLoader(url_loader.NewRequest());
oldhttp::URLRequest request;
request.url = http_test_server()->GetURL("/close-socket").spec();
request.method = "GET";
request.response_body_mode = oldhttp::ResponseBodyMode::STREAM;
ExecuteRequest(url_loader, std::move(request));
EXPECT_EQ(url_response().error->code, net::ERR_EMPTY_RESPONSE);
}
} // namespace net_http
HTTP/1.1 302 Redirect
Location: with-headers.html
Cache-Control: max-age=10000
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 5
This file is boring; all the action's in the .mock-http-headers.
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=ISO-8859-1
X-Multiple-Entries: a
X-Multiple-Entries: a
X-Multiple-Entries: b
This file is boring; all the action's in the .mock-http-headers.
HTTP/1.1 200 OK
Cache-Control: private
Content-Type: text/html; charset=ISO-8859-1
X-Multiple-Entries: a
X-Multiple-Entries: b
......@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "webrunner/net_http/service/url_loader_impl.h"
#include "webrunner/net_http/url_loader_impl.h"
#include "base/fuchsia/fuchsia_logging.h"
#include "base/message_loop/message_loop_current.h"
......@@ -12,7 +12,7 @@
#include "net/http/http_response_headers.h"
#include "net/url_request/redirect_info.h"
namespace net {
namespace net_http {
namespace oldhttp = ::fuchsia::net::oldhttp;
......@@ -21,7 +21,11 @@ namespace {
// server responses.
const size_t kReadCapacity = 1024;
// Converts |buffer| into a URLBody with the body set to a buffer.
// The number of active requests. Used for testing.
int g_active_requests = 0;
// Converts |buffer| into a URLBody with the body set to a buffer. Returns
// nullptr when an error occurs.
oldhttp::URLBodyPtr CreateURLBodyFromBuffer(net::GrowableIOBuffer* buffer) {
oldhttp::URLBodyPtr body = oldhttp::URLBody::New();
......@@ -31,7 +35,13 @@ oldhttp::URLBodyPtr CreateURLBodyFromBuffer(net::GrowableIOBuffer* buffer) {
::fuchsia::mem::Buffer mem_buffer;
mem_buffer.size = total_size;
zx_status_t result =
mem_buffer.vmo.write(buffer->StartOfBuffer(), 0, total_size);
zx::vmo::create(total_size, ZX_VMO_NON_RESIZABLE, &mem_buffer.vmo);
if (result != ZX_OK) {
ZX_DLOG(WARNING, result) << "zx_vmo_create";
return nullptr;
}
result = mem_buffer.vmo.write(buffer->StartOfBuffer(), 0, total_size);
if (result != ZX_OK) {
ZX_DLOG(WARNING, result) << "zx_vmo_write";
return nullptr;
......@@ -48,7 +58,7 @@ int NetErrorToHttpError(int net_error) {
}
oldhttp::HttpErrorPtr BuildError(int net_error) {
if (net_error == OK) {
if (net_error == net::OK) {
return nullptr;
}
......@@ -58,11 +68,11 @@ oldhttp::HttpErrorPtr BuildError(int net_error) {
return error;
}
std::unique_ptr<UploadDataStream> UploadDataStreamFromZxSocket(
std::unique_ptr<net::UploadDataStream> UploadDataStreamFromZxSocket(
zx::socket stream) {
// TODO(http://crbug.com/875534): Write a ZxStreamUploadStream class.
std::unique_ptr<ChunkedUploadDataStream> upload_stream =
std::make_unique<ChunkedUploadDataStream>(0);
std::unique_ptr<net::ChunkedUploadDataStream> upload_stream =
std::make_unique<net::ChunkedUploadDataStream>(0);
char buffer[kReadCapacity];
size_t size = 0;
zx_status_t result = ZX_OK;
......@@ -82,10 +92,10 @@ std::unique_ptr<UploadDataStream> UploadDataStreamFromZxSocket(
return upload_stream;
}
std::unique_ptr<UploadDataStream> UploadDataStreamFromMemBuffer(
std::unique_ptr<net::UploadDataStream> UploadDataStreamFromMemBuffer(
fuchsia::mem::Buffer mem_buffer) {
// TODO(http://crbug.com/875534): Write a ZxMemBufferUploadStream class.
std::unique_ptr<ChunkedUploadDataStream> upload_stream =
std::unique_ptr<net::ChunkedUploadDataStream> upload_stream =
std::make_unique<net::ChunkedUploadDataStream>(0);
char buffer[kReadCapacity];
......@@ -108,29 +118,36 @@ std::unique_ptr<UploadDataStream> UploadDataStreamFromMemBuffer(
} // namespace
URLLoaderImpl::URLLoaderImpl(std::unique_ptr<URLRequestContext> context,
URLLoaderImpl::URLLoaderImpl(std::unique_ptr<net::URLRequestContext> context,
fidl::InterfaceRequest<oldhttp::URLLoader> request)
: binding_(this, std::move(request)),
context_(std::move(context)),
buffer_(new GrowableIOBuffer()),
buffer_(new net::GrowableIOBuffer()),
write_watch_(FROM_HERE) {
binding_.set_error_handler([this] { delete this; });
g_active_requests++;
}
URLLoaderImpl::~URLLoaderImpl() = default;
URLLoaderImpl::~URLLoaderImpl() {
g_active_requests--;
}
int URLLoaderImpl::GetNumActiveRequestsForTests() {
return g_active_requests;
}
void URLLoaderImpl::Start(oldhttp::URLRequest request, Callback callback) {
if (net_request_) {
callback(BuildResponse(ERR_IO_PENDING));
callback(BuildResponse(net::ERR_IO_PENDING));
return;
}
done_callback_ = std::move(callback);
net_error_ = OK;
net_error_ = net::OK;
// Create the URLRequest and set this object as the delegate.
net_request_ = context_->CreateRequest(GURL(request.url.get()),
RequestPriority::MEDIUM, this);
net::RequestPriority::MEDIUM, this);
net_request_->set_method(request.method);
// Set extra headers.
......@@ -145,7 +162,7 @@ void URLLoaderImpl::Start(oldhttp::URLRequest request, Callback callback) {
false);
}
std::unique_ptr<UploadDataStream> upload_stream;
std::unique_ptr<net::UploadDataStream> upload_stream;
// Set body.
if (request.body) {
if (request.body->is_stream()) {
......@@ -157,7 +174,7 @@ void URLLoaderImpl::Start(oldhttp::URLRequest request, Callback callback) {
}
if (!upload_stream) {
std::move(done_callback_)(BuildResponse(ERR_ACCESS_DENIED));
std::move(done_callback_)(BuildResponse(net::ERR_ACCESS_DENIED));
return;
}
net_request_->set_upload(std::move(upload_stream));
......@@ -173,7 +190,7 @@ void URLLoaderImpl::Start(oldhttp::URLRequest request, Callback callback) {
void URLLoaderImpl::FollowRedirect(Callback callback) {
if (!net_request_ || auto_follow_redirects_ ||
!net_request_->is_redirecting()) {
callback(BuildResponse(ERR_INVALID_HANDLE));
callback(BuildResponse(net::ERR_INVALID_HANDLE));
}
done_callback_ = std::move(callback);
......@@ -195,15 +212,15 @@ void URLLoaderImpl::QueryStatus(QueryStatusCallback callback) {
callback(std::move(status));
}
void URLLoaderImpl::OnReceivedRedirect(URLRequest* request,
const RedirectInfo& redirect_info,
void URLLoaderImpl::OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) {
DCHECK_EQ(net_request_.get(), request);
// Follow redirect depending on policy.
*defer_redirect = !auto_follow_redirects_;
if (!auto_follow_redirects_) {
oldhttp::URLResponse response = BuildResponse(OK);
oldhttp::URLResponse response = BuildResponse(net::OK);
response.redirect_method = redirect_info.new_method;
response.redirect_url = redirect_info.new_url.spec();
response.redirect_referrer = redirect_info.new_referrer;
......@@ -211,35 +228,35 @@ void URLLoaderImpl::OnReceivedRedirect(URLRequest* request,
}
}
void URLLoaderImpl::OnAuthRequired(URLRequest* request,
AuthChallengeInfo* auth_info) {
void URLLoaderImpl::OnAuthRequired(net::URLRequest* request,
net::AuthChallengeInfo* auth_info) {
NOTIMPLEMENTED();
DCHECK_EQ(net_request_.get(), request);
request->CancelAuth();
}
void URLLoaderImpl::OnCertificateRequested(
URLRequest* request,
SSLCertRequestInfo* cert_request_info) {
net::URLRequest* request,
net::SSLCertRequestInfo* cert_request_info) {
NOTIMPLEMENTED();
DCHECK_EQ(net_request_.get(), request);
request->ContinueWithCertificate(nullptr, nullptr);
}
void URLLoaderImpl::OnSSLCertificateError(URLRequest* request,
const SSLInfo& ssl_info,
void URLLoaderImpl::OnSSLCertificateError(net::URLRequest* request,
const net::SSLInfo& ssl_info,
bool fatal) {
NOTIMPLEMENTED();
DCHECK_EQ(net_request_.get(), request);
request->Cancel();
}
void URLLoaderImpl::OnResponseStarted(URLRequest* request, int net_error) {
void URLLoaderImpl::OnResponseStarted(net::URLRequest* request, int net_error) {
DCHECK_EQ(net_request_.get(), request);
net_error_ = net_error;
// Return early if the request failed.
if (net_error_ != OK) {
if (net_error_ != net::OK) {
std::move(done_callback_)(BuildResponse(net_error_));
return;
}
......@@ -251,10 +268,10 @@ void URLLoaderImpl::OnResponseStarted(URLRequest* request, int net_error) {
zx_status_t result = zx::socket::create(0, &read_socket, &write_socket_);
if (result != ZX_OK) {
ZX_DLOG(WARNING, result) << "zx_socket_create";
std::move(done_callback_)(BuildResponse(ERR_INSUFFICIENT_RESOURCES));
std::move(done_callback_)(BuildResponse(net::ERR_INSUFFICIENT_RESOURCES));
return;
}
oldhttp::URLResponse response = BuildResponse(OK);
oldhttp::URLResponse response = BuildResponse(net::OK);
response.body = oldhttp::URLBody::New();
response.body->set_stream(std::move(read_socket));
std::move(done_callback_)(std::move(response));
......@@ -267,7 +284,7 @@ void URLLoaderImpl::OnResponseStarted(URLRequest* request, int net_error) {
ReadNextBuffer();
}
void URLLoaderImpl::OnReadCompleted(URLRequest* request, int bytes_read) {
void URLLoaderImpl::OnReadCompleted(net::URLRequest* request, int bytes_read) {
DCHECK_EQ(net_request_.get(), request);
if (WriteResponseBytes(bytes_read)) {
ReadNextBuffer();
......@@ -293,7 +310,7 @@ void URLLoaderImpl::ReadNextBuffer() {
int net_result;
do {
net_result = net_request_->Read(buffer_.get(), kReadCapacity);
if (net_result == ERR_IO_PENDING) {
if (net_result == net::ERR_IO_PENDING) {
return;
}
} while (WriteResponseBytes(net_result));
......@@ -330,11 +347,12 @@ bool URLLoaderImpl::WriteResponseBytes(int result) {
// In buffer mode, build the response and call the callback.
oldhttp::URLBodyPtr body = CreateURLBodyFromBuffer(buffer_.get());
if (body) {
oldhttp::URLResponse response = BuildResponse(result);
oldhttp::URLResponse response = BuildResponse(net::OK);
response.body = std::move(body);
std::move(done_callback_)(std::move(response));
} else {
std::move(done_callback_)(BuildResponse(ERR_INSUFFICIENT_RESOURCES));
std::move(done_callback_)(
BuildResponse(net::ERR_INSUFFICIENT_RESOURCES));
}
}
return false;
......@@ -345,9 +363,9 @@ bool URLLoaderImpl::WriteResponseBytes(int result) {
DCHECK(response_body_mode_ == oldhttp::ResponseBodyMode::STREAM ||
response_body_mode_ == oldhttp::ResponseBodyMode::BUFFER_OR_STREAM);
// In socket mode, attempt to write to the socket.
zx_status_t zx_result =
zx_status_t status =
write_socket_.write(0, buffer_->data(), result, nullptr);
if (zx_result == ZX_ERR_SHOULD_WAIT) {
if (status == ZX_ERR_SHOULD_WAIT) {
// Wait until the socket is writable again.
buffered_bytes_ = result;
base::MessageLoopCurrentForIO::Get()->WatchZxHandle(
......@@ -355,9 +373,9 @@ bool URLLoaderImpl::WriteResponseBytes(int result) {
ZX_SOCKET_WRITABLE | ZX_SOCKET_PEER_CLOSED, &write_watch_, this);
return false;
}
if (result != ZX_OK) {
if (status != ZX_OK) {
// Something went wrong, attempt to shut down the socket and close it.
ZX_DLOG(WARNING, result) << "zx_socket_write";
ZX_DLOG(WARNING, status) << "zx_socket_write";
write_socket_ = zx::socket();
return false;
}
......@@ -411,4 +429,4 @@ oldhttp::URLResponse URLLoaderImpl::BuildResponse(int net_error) {
return response;
}
} // namespace net
\ No newline at end of file
} // namespace net_http
\ No newline at end of file
......@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WEBRUNNER_NET_HTTP_SERVICE_URL_LOADER_IMPL_H_
#define WEBRUNNER_NET_HTTP_SERVICE_URL_LOADER_IMPL_H_
#ifndef WEBRUNNER_NET_HTTP_URL_LOADER_IMPL_H_
#define WEBRUNNER_NET_HTTP_URL_LOADER_IMPL_H_
#include <fuchsia/net/oldhttp/cpp/fidl.h>
#include <fuchsia/sys/cpp/fidl.h>
......@@ -15,7 +15,7 @@
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
namespace net {
namespace net_http {
// URLLoader implementation. This class manages one network request per
// instance. Internally, this class uses a |net::URLRequest| object to handle
......@@ -23,16 +23,19 @@ namespace net {
// |binding_|.
// TODO(https://crbug.com/875532): Implement cache-mode.
class URLLoaderImpl : public ::fuchsia::net::oldhttp::URLLoader,
public URLRequest::Delegate,
public net::URLRequest::Delegate,
base::MessagePumpForIO::ZxHandleWatcher {
public:
using Callback = ::fuchsia::net::oldhttp::URLLoader::StartCallback;
URLLoaderImpl(
std::unique_ptr<URLRequestContext> context,
std::unique_ptr<net::URLRequestContext> context,
::fidl::InterfaceRequest<::fuchsia::net::oldhttp::URLLoader> request);
~URLLoaderImpl() override;
// Returns the number of active requests. Used for testing.
static int GetNumActiveRequestsForTests();
private:
// URLLoader methods:
void Start(::fuchsia::net::oldhttp::URLRequest request,
......@@ -42,18 +45,19 @@ class URLLoaderImpl : public ::fuchsia::net::oldhttp::URLLoader,
callback) override;
// URLRequest::Delegate methods:
void OnReceivedRedirect(URLRequest* request,
const RedirectInfo& redirect_info,
void OnReceivedRedirect(net::URLRequest* request,
const net::RedirectInfo& redirect_info,
bool* defer_redirect) override;
void OnAuthRequired(URLRequest* request,
AuthChallengeInfo* auth_info) override;
void OnCertificateRequested(URLRequest* request,
SSLCertRequestInfo* cert_request_info) override;
void OnSSLCertificateError(URLRequest* request,
const SSLInfo& ssl_info,
void OnAuthRequired(net::URLRequest* request,
net::AuthChallengeInfo* auth_info) 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;
void OnResponseStarted(URLRequest* request, int net_error) override;
void OnReadCompleted(URLRequest* request, int bytes_read) override;
void OnResponseStarted(net::URLRequest* request, int net_error) override;
void OnReadCompleted(net::URLRequest* request, int bytes_read) override;
// MessagePumpForIO::ZxHandleWatcher method:
void OnZxHandleSignalled(zx_handle_t handle, zx_signals_t signals) override;
......@@ -77,10 +81,10 @@ class URLLoaderImpl : public ::fuchsia::net::oldhttp::URLLoader,
::fidl::Binding<::fuchsia::net::oldhttp::URLLoader> binding_;
// Holds the net::URLRequestContext associated with the |net_request_|
std::unique_ptr<URLRequestContext> context_;
std::unique_ptr<net::URLRequestContext> context_;
// Holds the net::URLRequest used to perform the network operation.
std::unique_ptr<URLRequest> net_request_;
std::unique_ptr<net::URLRequest> net_request_;
// Callback from a Start or FollowRedirect call.
Callback done_callback_;
......@@ -116,6 +120,6 @@ class URLLoaderImpl : public ::fuchsia::net::oldhttp::URLLoader,
DISALLOW_COPY_AND_ASSIGN(URLLoaderImpl);
};
} // namespace net
} // namespace net_http
#endif // WEBRUNNER_NET_HTTP_SERVICE_URL_LOADER_IMPL_H_
\ No newline at end of file
#endif // WEBRUNNER_NET_HTTP_URL_LOADER_IMPL_H_
\ No newline at end of file
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