Buffet: Implement fake HTTP transport to help write unit tests
Created fake Transport and Connection classes to help test
HTTP communications in Buffet. Now, when a fake transport
class is created a number of HTTP request handlers can be
registered, which will be called when a request to a web
server is made. These handlers can reply to the caller on
server's behalf and can provide response based on the
request data and parameters.
Removed 'static' from http::Request::range_value_omitted due
to a build break in debug (-O0) build. Static members should
be generally initialized in a .cc file, not header.
Fixed a bug in chromeos::url::GetQueryStringParameters() when
called on an empty string.
Finally, added 'bind_lamda.h' header file that adds the
ability to use lambdas in base::Bind() calls.
BUG=chromium:367377
TEST=Unit tests pass.
Change-Id: Ib4c070f676069f208b9df4da069ff3a29f8f656f
Reviewed-on: https://chromium-review.googlesource.com/197157
Reviewed-by: Christopher Wiley <wiley@chromium.org>
Commit-Queue: Alex Vakulenko <avakulenko@chromium.org>
Tested-by: Alex Vakulenko <avakulenko@chromium.org>
diff --git a/buffet/http_connection_fake.cc b/buffet/http_connection_fake.cc
new file mode 100644
index 0000000..6731aeb
--- /dev/null
+++ b/buffet/http_connection_fake.cc
@@ -0,0 +1,87 @@
+// Copyright 2014 The Chromium OS 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 "buffet/http_connection_fake.h"
+
+#include <base/logging.h>
+
+#include "buffet/http_request.h"
+#include "buffet/mime_utils.h"
+#include "buffet/string_utils.h"
+
+using namespace chromeos;
+using namespace chromeos::http::fake;
+
+Connection::Connection(const std::string& url, const std::string& method,
+ std::shared_ptr<http::Transport> transport) :
+ http::Connection(transport), request_(url, method) {
+ VLOG(1) << "fake::Connection created: " << method;
+}
+
+Connection::~Connection() {
+ VLOG(1) << "fake::Connection destroyed";
+}
+
+bool Connection::SendHeaders(const HeaderList& headers) {
+ request_.AddHeaders(headers);
+ return true;
+}
+
+bool Connection::WriteRequestData(const void* data, size_t size) {
+ request_.AddData(data, size);
+ return true;
+}
+
+bool Connection::FinishRequest() {
+ request_.AddHeaders({{request_header::kContentLength,
+ std::to_string(request_.GetData().size())}});
+ fake::Transport* transport = dynamic_cast<fake::Transport*>(transport_.get());
+ CHECK(transport) << "Expecting a fake transport";
+ auto handler = transport->GetHandler(request_.GetURL(), request_.GetMethod());
+ if (handler.is_null()) {
+ response_.ReplyText(status_code::NotFound,
+ "<html><body>Not found</body></html>",
+ mime::text::kHtml);
+ } else {
+ handler.Run(request_, &response_);
+ }
+ return true;
+}
+
+int Connection::GetResponseStatusCode() const {
+ return response_.GetStatusCode();
+}
+
+std::string Connection::GetResponseStatusText() const {
+ return response_.GetStatusText();
+}
+
+std::string Connection::GetProtocolVersion() const {
+ return response_.GetProtocolVersion();
+}
+
+std::string Connection::GetResponseHeader(
+ const std::string& header_name) const {
+ return response_.GetHeader(header_name);
+}
+
+uint64_t Connection::GetResponseDataSize() const {
+ return response_.GetData().size();
+}
+
+bool Connection::ReadResponseData(void* data, size_t buffer_size,
+ size_t* size_read) {
+ size_t size_to_read = GetResponseDataSize() - response_data_ptr_;
+ if (size_to_read > buffer_size)
+ size_to_read = buffer_size;
+ memcpy(data, response_.GetData().data() + response_data_ptr_, size_to_read);
+ if (size_read)
+ *size_read = size_to_read;
+ response_data_ptr_ += size_to_read;
+ return true;
+}
+
+std::string Connection::GetErrorMessage() const {
+ return std::string();
+}