diff --git a/buffet/http_utils_unittest.cc b/buffet/http_utils_unittest.cc
index c04f498..1453b86 100644
--- a/buffet/http_utils_unittest.cc
+++ b/buffet/http_utils_unittest.cc
@@ -2,18 +2,224 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
+#include <base/values.h>
 #include <gtest/gtest.h>
 
 #include "buffet/bind_lambda.h"
 #include "buffet/http_utils.h"
 #include "buffet/http_transport_fake.h"
 #include "buffet/mime_utils.h"
+#include "buffet/string_utils.h"
 #include "buffet/url_utils.h"
 
 using namespace chromeos;
 using namespace chromeos::http;
 
-static const char fake_url[] = "http://localhost";
+static const char kFakeUrl[] = "http://localhost";
+static const char kEchoUrl[] = "http://localhost/echo";
+static const char kMethodEchoUrl[] = "http://localhost/echo/method";
+
+///////////////////// Generic helper request handlers /////////////////////////
+// Returns the request data back with the same content type.
+static void EchoDataHandler(const fake::ServerRequest& request,
+                            fake::ServerResponse* response) {
+  response->Reply(status_code::Ok, request.GetData(),
+                  request.GetHeader(request_header::kContentType).c_str());
+};
+
+// Returns the request method as a plain text response.
+static void EchoMethodHandler(const fake::ServerRequest& request,
+                              fake::ServerResponse* response) {
+  response->ReplyText(status_code::Ok, request.GetMethod(), mime::text::kPlain);
+};
+
+///////////////////////////////////////////////////////////////////////////////
+TEST(HttpUtils, SendRequest_BinaryData) {
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kEchoUrl, request_type::kPost,
+                        base::Bind(EchoDataHandler));
+
+  // Test binary data round-tripping.
+  std::vector<unsigned char> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F};
+  auto response = http::SendRequest(request_type::kPost, kEchoUrl,
+                                    custom_data.data(), custom_data.size(),
+                                    mime::application::kOctet_stream,
+                                    HeaderList(), transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::application::kOctet_stream, response->GetContentType());
+  EXPECT_EQ(custom_data.size(), response->GetData().size());
+  EXPECT_EQ(custom_data, response->GetData());
+}
+
+TEST(HttpUtils, SendRequest_Post) {
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));
+
+  // Test binary data round-tripping.
+  std::vector<unsigned char> custom_data{0xFF, 0x00, 0x80, 0x40, 0xC0, 0x7F};
+
+  // Check the correct HTTP method used.
+  auto response = http::SendRequest(request_type::kPost, kMethodEchoUrl,
+                                    custom_data.data(), custom_data.size(),
+                                    mime::application::kOctet_stream,
+                                    HeaderList(), transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
+  EXPECT_EQ(request_type::kPost, response->GetDataAsString());
+}
+
+TEST(HttpUtils, SendRequest_Get) {
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));
+
+  auto response = http::SendRequest(request_type::kGet, kMethodEchoUrl,
+                                    nullptr, 0, nullptr,
+                                    HeaderList(), transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
+  EXPECT_EQ(request_type::kGet, response->GetDataAsString());
+}
+
+TEST(HttpUtils, SendRequest_Put) {
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));
+
+  auto response = http::SendRequest(request_type::kPut, kMethodEchoUrl,
+                                    nullptr, 0, nullptr,
+                                    HeaderList(), transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
+  EXPECT_EQ(request_type::kPut, response->GetDataAsString());
+}
+
+TEST(HttpUtils, SendRequest_NotFound) {
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  // Test failed response (URL not found).
+  auto response = http::SendRequest(request_type::kGet, "http://blah.com",
+                                    nullptr, 0, nullptr,
+                                    HeaderList(), transport);
+  EXPECT_FALSE(response->IsSuccessful());
+  EXPECT_EQ(status_code::NotFound, response->GetStatusCode());
+}
+
+TEST(HttpUtils, SendRequest_Headers) {
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+
+  static const char json_echo_url[] = "http://localhost/echo/json";
+  auto JsonEchoHandler = [](const fake::ServerRequest& request,
+                            fake::ServerResponse* response) {
+    base::DictionaryValue json;
+    json.SetString("method", request.GetMethod());
+    json.SetString("data", request.GetDataAsString());
+    for (auto&& pair : request.GetHeaders()) {
+      json.SetString("header." + pair.first, pair.second);
+    }
+    response->ReplyJson(status_code::Ok, &json);
+  };
+  transport->AddHandler(json_echo_url, "*",
+                        base::Bind(JsonEchoHandler));
+  auto response = http::SendRequest(
+      request_type::kPost, json_echo_url, "abcd", 4,
+      mime::application::kOctet_stream, {
+        {request_header::kCookie, "flavor=vanilla"},
+        {request_header::kIfMatch, "*"},
+      }, transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::application::kJson, response->GetContentType());
+  auto json = ParseJsonResponse(response.get(), nullptr, nullptr);
+  std::string value;
+  EXPECT_TRUE(json->GetString("method", &value));
+  EXPECT_EQ(request_type::kPost, value);
+  EXPECT_TRUE(json->GetString("data", &value));
+  EXPECT_EQ("abcd", value);
+  EXPECT_TRUE(json->GetString("header.Cookie", &value));
+  EXPECT_EQ("flavor=vanilla", value);
+  EXPECT_TRUE(json->GetString("header.Content-Type", &value));
+  EXPECT_EQ(mime::application::kOctet_stream, value);
+  EXPECT_TRUE(json->GetString("header.Content-Length", &value));
+  EXPECT_EQ("4", value);
+  EXPECT_TRUE(json->GetString("header.If-Match", &value));
+  EXPECT_EQ("*", value);
+}
+
+TEST(HttpUtils, Get) {
+  // Sends back the "?test=..." portion of URL.
+  // So if we do GET "http://localhost?test=blah", this handler responds
+  // with "blah" as text/plain.
+  auto GetHandler = [](const fake::ServerRequest& request,
+                       fake::ServerResponse* response) {
+    EXPECT_EQ(request_type::kGet, request.GetMethod());
+    EXPECT_EQ("0", request.GetHeader(request_header::kContentLength));
+    EXPECT_EQ("", request.GetHeader(request_header::kContentType));
+    response->ReplyText(status_code::Ok, request.GetFormField("test"),
+                        mime::text::kPlain);
+  };
+
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kFakeUrl, request_type::kGet, base::Bind(GetHandler));
+  transport->AddHandler(kMethodEchoUrl, "*", base::Bind(EchoMethodHandler));
+
+  // Make sure Get/GetAsString actually do the GET request
+  auto response = http::Get(kMethodEchoUrl, transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
+  EXPECT_EQ(request_type::kGet, response->GetDataAsString());
+  EXPECT_EQ(request_type::kGet, http::GetAsString(kMethodEchoUrl, transport));
+
+  for (std::string data : {"blah", "some data", ""}) {
+    std::string url = url::AppendQueryParam(kFakeUrl, "test", data);
+    EXPECT_EQ(data, http::GetAsString(url, transport));
+  }
+}
+
+TEST(HttpUtils, Head) {
+  auto HeadHandler = [](const fake::ServerRequest& request,
+                        fake::ServerResponse* response) {
+    EXPECT_EQ(request_type::kHead, request.GetMethod());
+    EXPECT_EQ("0", request.GetHeader(request_header::kContentLength));
+    EXPECT_EQ("", request.GetHeader(request_header::kContentType));
+    response->ReplyText(status_code::Ok, "blah",
+                        mime::text::kPlain);
+  };
+
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kFakeUrl, request_type::kHead, base::Bind(HeadHandler));
+
+  auto response = http::Head(kFakeUrl, transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::text::kPlain, response->GetContentType());
+  EXPECT_EQ("", response->GetDataAsString()); // Must not have actual body.
+  EXPECT_EQ("4", response->GetHeader(request_header::kContentLength));
+}
+
+TEST(HttpUtils, PostBinary) {
+  auto Handler = [](const fake::ServerRequest& request,
+                    fake::ServerResponse* response) {
+    EXPECT_EQ(request_type::kPost, request.GetMethod());
+    EXPECT_EQ("256", request.GetHeader(request_header::kContentLength));
+    EXPECT_EQ(mime::application::kOctet_stream,
+              request.GetHeader(request_header::kContentType));
+    auto&& data = request.GetData();
+    EXPECT_EQ(256, data.size());
+
+    // Sum up all the bytes.
+    int sum = std::accumulate(data.begin(), data.end(), 0);
+    EXPECT_EQ(32640, sum); // sum(i, i => [0, 255]) = 32640.
+    response->ReplyText(status_code::Ok, "", mime::text::kPlain);
+  };
+
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(Handler));
+
+  /// Fill the data buffer with bytes from 0x00 to 0xFF.
+  std::vector<unsigned char> data(256);
+  unsigned char counter = 0xFF;
+  std::generate(data.begin(), data.end(), [&counter]() { return ++counter; });
+
+  auto response = http::PostBinary(kFakeUrl, data.data(), data.size(),
+                                   transport);
+  EXPECT_TRUE(response->IsSuccessful());
+}
 
 TEST(HttpUtils, PostText) {
   std::string fake_data = "Some data";
@@ -21,37 +227,108 @@
                                  fake::ServerResponse* response) {
     EXPECT_EQ(request_type::kPost, request.GetMethod());
     EXPECT_EQ(fake_data.size(),
-              atoi(request.GetHeader(request_header::kContentLength).c_str()));
+              std::stoul(request.GetHeader(request_header::kContentLength)));
     EXPECT_EQ(mime::text::kPlain,
               request.GetHeader(request_header::kContentType));
-    response->Reply(status_code::Ok, request.GetData(), mime::text::kPlain);
+    response->ReplyText(status_code::Ok, request.GetDataAsString(),
+                       mime::text::kPlain);
   };
 
   std::shared_ptr<fake::Transport> transport(new fake::Transport);
-  transport->AddHandler(fake_url, request_type::kPost, base::Bind(PostHandler));
+  transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(PostHandler));
 
-  auto response = http::PostText(fake_url, fake_data.c_str(),
+  auto response = http::PostText(kFakeUrl, fake_data.c_str(),
                                  mime::text::kPlain, transport);
   EXPECT_TRUE(response->IsSuccessful());
   EXPECT_EQ(mime::text::kPlain, response->GetContentType());
   EXPECT_EQ(fake_data, response->GetDataAsString());
 }
 
-TEST(HttpUtils, Get) {
-  auto GetHandler = [](const fake::ServerRequest& request,
-                       fake::ServerResponse* response) {
-    EXPECT_EQ(request_type::kGet, request.GetMethod());
-    EXPECT_EQ("0", request.GetHeader(request_header::kContentLength));
-    EXPECT_EQ("", request.GetHeader(request_header::kContentType));
-    response->ReplyText(status_code::Ok, request.GetFormField("test"),
-                       mime::text::kPlain);
-  };
-
+TEST(HttpUtils, PostFormData) {
   std::shared_ptr<fake::Transport> transport(new fake::Transport);
-  transport->AddHandler(fake_url, request_type::kGet, base::Bind(GetHandler));
+  transport->AddHandler(kFakeUrl, request_type::kPost,
+                        base::Bind(EchoDataHandler));
 
-  for (std::string data : {"blah", "some data", ""}) {
-    std::string url = url::AppendQueryParam(fake_url, "test", data);
-    EXPECT_EQ(data, http::GetAsString(url, transport));
-  }
+  auto response = http::PostFormData(kFakeUrl, {
+                      {"key", "value"},
+                      {"field", "field value"},
+                  }, transport);
+  EXPECT_TRUE(response->IsSuccessful());
+  EXPECT_EQ(mime::application::kWwwFormUrlEncoded, response->GetContentType());
+  EXPECT_EQ("key=value&field=field+value", response->GetDataAsString());
 }
+
+TEST(HttpUtils, PostPatchJson) {
+  auto JsonHandler = [](const fake::ServerRequest& request,
+                        fake::ServerResponse* response) {
+    EXPECT_EQ(mime::application::kJson,
+              request.GetHeader(request_header::kContentType));
+    base::DictionaryValue json;
+    json.SetString("method", request.GetMethod());
+    json.SetString("data", request.GetDataAsString());
+    response->ReplyJson(status_code::Ok, &json);
+  };
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kFakeUrl, "*", base::Bind(JsonHandler));
+
+  base::DictionaryValue json;
+  json.SetString("key1", "val1");
+  json.SetString("key2", "val2");
+  std::string value;
+
+  // Test POST
+  auto response = http::PostJson(kFakeUrl, &json, transport);
+  auto resp_json = http::ParseJsonResponse(response.get(), nullptr, nullptr);
+  EXPECT_NE(nullptr, resp_json.get());
+  EXPECT_TRUE(resp_json->GetString("method", &value));
+  EXPECT_EQ(request_type::kPost, value);
+  EXPECT_TRUE(resp_json->GetString("data", &value));
+  EXPECT_EQ("{\"key1\":\"val1\",\"key2\":\"val2\"}", value);
+
+  // Test PATCH
+  response = http::PatchJson(kFakeUrl, &json, transport);
+  resp_json = http::ParseJsonResponse(response.get(), nullptr, nullptr);
+  EXPECT_NE(nullptr, resp_json.get());
+  EXPECT_TRUE(resp_json->GetString("method", &value));
+  EXPECT_EQ(request_type::kPatch, value);
+  EXPECT_TRUE(resp_json->GetString("data", &value));
+  EXPECT_EQ("{\"key1\":\"val1\",\"key2\":\"val2\"}", value);
+}
+
+TEST(HttpUtils, ParseJsonResponse) {
+  auto JsonHandler = [](const fake::ServerRequest& request,
+                        fake::ServerResponse* response) {
+    base::DictionaryValue json;
+    json.SetString("data", request.GetFormField("value"));
+    int status_code = std::stoi(request.GetFormField("code"));
+    response->ReplyJson(status_code, &json);
+  };
+  std::shared_ptr<fake::Transport> transport(new fake::Transport);
+  transport->AddHandler(kFakeUrl, request_type::kPost, base::Bind(JsonHandler));
+
+  // Test valid JSON responses (with success or error codes).
+  for (auto&& item : {"200;data", "400;wrong", "500;Internal Server error"}) {
+    auto pair = string_utils::SplitAtFirst(item, ';');
+    auto response = http::PostFormData(kFakeUrl, {
+                      {"code", pair.first},
+                      {"value", pair.second},
+                    }, transport);
+    int code = 0;
+    auto json = http::ParseJsonResponse(response.get(), &code, nullptr);
+    EXPECT_NE(nullptr, json.get());
+    std::string value;
+    EXPECT_TRUE(json->GetString("data", &value));
+    EXPECT_EQ(pair.first, std::to_string(code));
+    EXPECT_EQ(pair.second, value);
+  }
+
+  // Test invalid (non-JSON) reponse.
+  auto response = http::Get("http://bad.url", transport);
+  EXPECT_EQ(status_code::NotFound, response->GetStatusCode());
+  EXPECT_EQ(mime::text::kHtml, response->GetContentType());
+  int code = 0;
+  auto json = http::ParseJsonResponse(response.get(), &code, nullptr);
+  EXPECT_EQ(nullptr, json.get());
+  EXPECT_EQ(status_code::NotFound, code);
+}
+
