You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2015/03/25 01:02:10 UTC
[01/12] mesos git commit: Re-ordered decoder callbacks to be in
execution order.
Repository: mesos
Updated Branches:
refs/heads/master 9b14ba2e4 -> a0d201b71
Re-ordered decoder callbacks to be in execution order.
Review: https://reviews.apache.org/r/32343
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/595e0615
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/595e0615
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/595e0615
Branch: refs/heads/master
Commit: 595e0615e8529637eb4a6328c7e09729efe932ec
Parents: 2622b01
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 13:58:41 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/src/decoder.hpp | 260 ++++++++++++++++---------------
1 file changed, 131 insertions(+), 129 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/595e0615/3rdparty/libprocess/src/decoder.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/decoder.hpp b/3rdparty/libprocess/src/decoder.hpp
index 25b0228..4b3c53f 100644
--- a/3rdparty/libprocess/src/decoder.hpp
+++ b/3rdparty/libprocess/src/decoder.hpp
@@ -29,12 +29,6 @@ public:
: s(_s), failure(false), request(NULL)
{
settings.on_message_begin = &DataDecoder::on_message_begin;
- settings.on_header_field = &DataDecoder::on_header_field;
- settings.on_header_value = &DataDecoder::on_header_value;
- settings.on_url = &DataDecoder::on_url;
- settings.on_body = &DataDecoder::on_body;
- settings.on_headers_complete = &DataDecoder::on_headers_complete;
- settings.on_message_complete = &DataDecoder::on_message_complete;
#if !(HTTP_PARSER_VERSION_MAJOR >= 2)
settings.on_path = &DataDecoder::on_path;
@@ -42,6 +36,13 @@ public:
settings.on_query_string = &DataDecoder::on_query_string;
#endif
+ settings.on_url = &DataDecoder::on_url;
+ settings.on_header_field = &DataDecoder::on_header_field;
+ settings.on_header_value = &DataDecoder::on_header_value;
+ settings.on_headers_complete = &DataDecoder::on_headers_complete;
+ settings.on_body = &DataDecoder::on_body;
+ settings.on_message_complete = &DataDecoder::on_message_complete;
+
http_parser_init(&parser, HTTP_REQUEST);
parser.data = this;
@@ -100,82 +101,31 @@ private:
return 0;
}
- static int on_headers_complete(http_parser* p)
- {
- DataDecoder* decoder = (DataDecoder*) p->data;
-
- // Add final header.
- decoder->request->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
-
- decoder->request->method =
- http_method_str((http_method) decoder->parser.method);
-
- decoder->request->keepAlive = http_should_keep_alive(&decoder->parser);
-
- return 0;
- }
-
- static int on_message_complete(http_parser* p)
+#if !(HTTP_PARSER_VERSION_MAJOR >= 2)
+ static int on_path(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
-// std::cout << "http::Request:" << std::endl;
-// std::cout << " method: " << decoder->request->method << std::endl;
-// std::cout << " path: " << decoder->request->path << std::endl;
-
- // Parse the query key/values.
- Try<hashmap<std::string, std::string>> decoded =
- http::query::decode(decoder->query);
-
- if (decoded.isError()) {
- return 1;
- }
-
- decoder->request->query = decoded.get();
-
- Option<std::string> encoding =
- decoder->request->headers.get("Content-Encoding");
- if (encoding.isSome() && encoding.get() == "gzip") {
- Try<std::string> decompressed = gzip::decompress(decoder->request->body);
- if (decompressed.isError()) {
- return 1;
- }
- decoder->request->body = decompressed.get();
- decoder->request->headers["Content-Length"] =
- decoder->request->body.length();
- }
-
- decoder->requests.push_back(decoder->request);
- decoder->request = NULL;
+ assert(decoder->request != NULL);
+ decoder->request->path.append(data, length);
return 0;
}
- static int on_header_field(http_parser* p, const char* data, size_t length)
+ static int on_query_string(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
assert(decoder->request != NULL);
-
- if (decoder->header != HEADER_FIELD) {
- decoder->request->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
- }
-
- decoder->field.append(data, length);
- decoder->header = HEADER_FIELD;
-
+ decoder->query.append(data, length);
return 0;
}
- static int on_header_value(http_parser* p, const char* data, size_t length)
+ static int on_fragment(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
assert(decoder->request != NULL);
- decoder->value.append(data, length);
- decoder->header = HEADER_VALUE;
+ decoder->request->fragment.append(data, length);
return 0;
}
+#endif // !(HTTP_PARSER_VERSION_MAJOR >= 2)
static int on_url(http_parser* p, const char* data, size_t length)
{
@@ -213,31 +163,48 @@ private:
return result;
}
-#if !(HTTP_PARSER_VERSION_MAJOR >= 2)
- static int on_path(http_parser* p, const char* data, size_t length)
+ static int on_header_field(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
assert(decoder->request != NULL);
- decoder->request->path.append(data, length);
+
+ if (decoder->header != HEADER_FIELD) {
+ decoder->request->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
+ }
+
+ decoder->field.append(data, length);
+ decoder->header = HEADER_FIELD;
+
return 0;
}
- static int on_query_string(http_parser* p, const char* data, size_t length)
+ static int on_header_value(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
assert(decoder->request != NULL);
- decoder->query.append(data, length);
+ decoder->value.append(data, length);
+ decoder->header = HEADER_VALUE;
return 0;
}
- static int on_fragment(http_parser* p, const char* data, size_t length)
+ static int on_headers_complete(http_parser* p)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
- decoder->request->fragment.append(data, length);
+
+ // Add final header.
+ decoder->request->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
+
+ decoder->request->method =
+ http_method_str((http_method) decoder->parser.method);
+
+ decoder->request->keepAlive = http_should_keep_alive(&decoder->parser);
+
return 0;
}
-#endif // !(HTTP_PARSER_VERSION_MAJOR >= 2)
static int on_body(http_parser* p, const char* data, size_t length)
{
@@ -247,6 +214,40 @@ private:
return 0;
}
+ static int on_message_complete(http_parser* p)
+ {
+ DataDecoder* decoder = (DataDecoder*) p->data;
+// std::cout << "http::Request:" << std::endl;
+// std::cout << " method: " << decoder->request->method << std::endl;
+// std::cout << " path: " << decoder->request->path << std::endl;
+
+ // Parse the query key/values.
+ Try<hashmap<std::string, std::string>> decoded =
+ http::query::decode(decoder->query);
+
+ if (decoded.isError()) {
+ return 1;
+ }
+
+ decoder->request->query = decoded.get();
+
+ Option<std::string> encoding =
+ decoder->request->headers.get("Content-Encoding");
+ if (encoding.isSome() && encoding.get() == "gzip") {
+ Try<std::string> decompressed = gzip::decompress(decoder->request->body);
+ if (decompressed.isError()) {
+ return 1;
+ }
+ decoder->request->body = decompressed.get();
+ decoder->request->headers["Content-Length"] =
+ decoder->request->body.length();
+ }
+
+ decoder->requests.push_back(decoder->request);
+ decoder->request = NULL;
+ return 0;
+ }
+
const network::Socket s; // The socket this decoder is associated with.
bool failure;
@@ -276,12 +277,6 @@ public:
: failure(false), header(HEADER_FIELD), response(NULL)
{
settings.on_message_begin = &ResponseDecoder::on_message_begin;
- settings.on_header_field = &ResponseDecoder::on_header_field;
- settings.on_header_value = &ResponseDecoder::on_header_value;
- settings.on_url = &ResponseDecoder::on_url;
- settings.on_body = &ResponseDecoder::on_body;
- settings.on_headers_complete = &ResponseDecoder::on_headers_complete;
- settings.on_message_complete = &ResponseDecoder::on_message_complete;
#if !(HTTP_PARSER_VERSION_MAJOR >=2)
settings.on_path = &ResponseDecoder::on_path;
@@ -289,6 +284,13 @@ public:
settings.on_query_string = &ResponseDecoder::on_query_string;
#endif
+ settings.on_url = &ResponseDecoder::on_url;
+ settings.on_header_field = &ResponseDecoder::on_header_field;
+ settings.on_header_value = &ResponseDecoder::on_header_value;
+ settings.on_headers_complete = &ResponseDecoder::on_headers_complete;
+ settings.on_body = &ResponseDecoder::on_body;
+ settings.on_message_complete = &ResponseDecoder::on_message_complete;
+
http_parser_init(&parser, HTTP_RESPONSE);
parser.data = this;
@@ -339,46 +341,25 @@ private:
return 0;
}
- static int on_headers_complete(http_parser* p)
+#if !(HTTP_PARSER_VERSION_MAJOR >= 2)
+ static int on_path(http_parser* p, const char* data, size_t length)
{
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
-
- // Add final header.
- decoder->response->headers[decoder->field] = decoder->value;
- decoder->field.clear();
- decoder->value.clear();
-
return 0;
}
- static int on_message_complete(http_parser* p)
+ static int on_query_string(http_parser* p, const char* data, size_t length)
{
- ResponseDecoder* decoder = (ResponseDecoder*) p->data;
-
- // Get the response status string.
- if (http::statuses.contains(decoder->parser.status_code)) {
- decoder->response->status = http::statuses[decoder->parser.status_code];
- } else {
- decoder->failure = true;
- return 1;
- }
+ return 0;
+ }
- // We can only provide the gzip encoding.
- Option<std::string> encoding =
- decoder->response->headers.get("Content-Encoding");
- if (encoding.isSome() && encoding.get() == "gzip") {
- Try<std::string> decompressed = gzip::decompress(decoder->response->body);
- if (decompressed.isError()) {
- decoder->failure = true;
- return 1;
- }
- decoder->response->body = decompressed.get();
- decoder->response->headers["Content-Length"] =
- decoder->response->body.length();
- }
+ static int on_fragment(http_parser* p, const char* data, size_t length)
+ {
+ return 0;
+ }
+#endif // !(HTTP_PARSER_VERSION_MAJOR >= 2)
- decoder->responses.push_back(decoder->response);
- decoder->response = NULL;
+ static int on_url(http_parser* p, const char* data, size_t length)
+ {
return 0;
}
@@ -408,33 +389,54 @@ private:
return 0;
}
- static int on_url(http_parser* p, const char* data, size_t length)
+ static int on_headers_complete(http_parser* p)
{
- return 0;
- }
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
-#if !(HTTP_PARSER_VERSION_MAJOR >= 2)
- static int on_path(http_parser* p, const char* data, size_t length)
- {
- return 0;
- }
+ // Add final header.
+ decoder->response->headers[decoder->field] = decoder->value;
+ decoder->field.clear();
+ decoder->value.clear();
- static int on_query_string(http_parser* p, const char* data, size_t length)
- {
return 0;
}
- static int on_fragment(http_parser* p, const char* data, size_t length)
+ static int on_body(http_parser* p, const char* data, size_t length)
{
+ ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+ assert(decoder->response != NULL);
+ decoder->response->body.append(data, length);
return 0;
}
-#endif // !(HTTP_PARSER_VERSION_MAJOR >= 2)
- static int on_body(http_parser* p, const char* data, size_t length)
+ static int on_message_complete(http_parser* p)
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
- decoder->response->body.append(data, length);
+
+ // Get the response status string.
+ if (http::statuses.contains(decoder->parser.status_code)) {
+ decoder->response->status = http::statuses[decoder->parser.status_code];
+ } else {
+ decoder->failure = true;
+ return 1;
+ }
+
+ // We can only provide the gzip encoding.
+ Option<std::string> encoding =
+ decoder->response->headers.get("Content-Encoding");
+ if (encoding.isSome() && encoding.get() == "gzip") {
+ Try<std::string> decompressed = gzip::decompress(decoder->response->body);
+ if (decompressed.isError()) {
+ decoder->failure = true;
+ return 1;
+ }
+ decoder->response->body = decompressed.get();
+ decoder->response->headers["Content-Length"] =
+ decoder->response->body.length();
+ }
+
+ decoder->responses.push_back(decoder->response);
+ decoder->response = NULL;
return 0;
}
[05/12] mesos git commit: Moved http::initialize from header to .cpp
file.
Posted by bm...@apache.org.
Moved http::initialize from header to .cpp file.
Review: https://reviews.apache.org/r/32337
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/dab7bdb2
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/dab7bdb2
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/dab7bdb2
Branch: refs/heads/master
Commit: dab7bdb26c3fcabc5552fb85579686c46a2eff65
Parents: 0a5e973
Author: Benjamin Mahler <be...@gmail.com>
Authored: Tue Mar 17 12:30:26 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 61 ++++-------------------
3rdparty/libprocess/src/http.cpp | 51 +++++++++++++++++--
2 files changed, 58 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/dab7bdb2/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index 1b40b4f..a96bc28 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -38,6 +38,16 @@ class Future;
namespace http {
+// Status code reason strings, from the HTTP1.1 RFC:
+// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
+extern hashmap<uint16_t, std::string> statuses;
+
+// Initializes 'statuses'.
+// TODO(bmahler): Provide a function that returns the string for
+// a status code instead!
+void initialize();
+
+
struct Request
{
// TODO(benh): Add major/minor version.
@@ -696,57 +706,6 @@ Future<Response> post(
const Option<std::string>& body = None(),
const Option<std::string>& contentType = None());
-
-// Status code reason strings, from the HTTP1.1 RFC:
-// http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html
-extern hashmap<uint16_t, std::string> statuses;
-
-
-inline void initialize()
-{
- statuses[100] = "100 Continue";
- statuses[101] = "101 Switching Protocols";
- statuses[200] = "200 OK";
- statuses[201] = "201 Created";
- statuses[202] = "202 Accepted";
- statuses[203] = "203 Non-Authoritative Information";
- statuses[204] = "204 No Content";
- statuses[205] = "205 Reset Content";
- statuses[206] = "206 Partial Content";
- statuses[300] = "300 Multiple Choices";
- statuses[301] = "301 Moved Permanently";
- statuses[302] = "302 Found";
- statuses[303] = "303 See Other";
- statuses[304] = "304 Not Modified";
- statuses[305] = "305 Use Proxy";
- statuses[307] = "307 Temporary Redirect";
- statuses[400] = "400 Bad Request";
- statuses[401] = "401 Unauthorized";
- statuses[402] = "402 Payment Required";
- statuses[403] = "403 Forbidden";
- statuses[404] = "404 Not Found";
- statuses[405] = "405 Method Not Allowed";
- statuses[406] = "406 Not Acceptable";
- statuses[407] = "407 Proxy Authentication Required";
- statuses[408] = "408 Request Time-out";
- statuses[409] = "409 Conflict";
- statuses[410] = "410 Gone";
- statuses[411] = "411 Length Required";
- statuses[412] = "412 Precondition Failed";
- statuses[413] = "413 Request Entity Too Large";
- statuses[414] = "414 Request-URI Too Large";
- statuses[415] = "415 Unsupported Media Type";
- statuses[416] = "416 Requested range not satisfiable";
- statuses[417] = "417 Expectation Failed";
- statuses[500] = "500 Internal Server Error";
- statuses[501] = "501 Not Implemented";
- statuses[502] = "502 Bad Gateway";
- statuses[503] = "503 Service Unavailable";
- statuses[504] = "504 Gateway Time-out";
- statuses[505] = "505 HTTP Version not supported";
-}
-
-
} // namespace http {
} // namespace process {
http://git-wip-us.apache.org/repos/asf/mesos/blob/dab7bdb2/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index 1865546..3d2b541 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -45,6 +45,54 @@ namespace process {
namespace http {
+hashmap<uint16_t, string> statuses;
+
+
+void initialize()
+{
+ statuses[100] = "100 Continue";
+ statuses[101] = "101 Switching Protocols";
+ statuses[200] = "200 OK";
+ statuses[201] = "201 Created";
+ statuses[202] = "202 Accepted";
+ statuses[203] = "203 Non-Authoritative Information";
+ statuses[204] = "204 No Content";
+ statuses[205] = "205 Reset Content";
+ statuses[206] = "206 Partial Content";
+ statuses[300] = "300 Multiple Choices";
+ statuses[301] = "301 Moved Permanently";
+ statuses[302] = "302 Found";
+ statuses[303] = "303 See Other";
+ statuses[304] = "304 Not Modified";
+ statuses[305] = "305 Use Proxy";
+ statuses[307] = "307 Temporary Redirect";
+ statuses[400] = "400 Bad Request";
+ statuses[401] = "401 Unauthorized";
+ statuses[402] = "402 Payment Required";
+ statuses[403] = "403 Forbidden";
+ statuses[404] = "404 Not Found";
+ statuses[405] = "405 Method Not Allowed";
+ statuses[406] = "406 Not Acceptable";
+ statuses[407] = "407 Proxy Authentication Required";
+ statuses[408] = "408 Request Time-out";
+ statuses[409] = "409 Conflict";
+ statuses[410] = "410 Gone";
+ statuses[411] = "411 Length Required";
+ statuses[412] = "412 Precondition Failed";
+ statuses[413] = "413 Request Entity Too Large";
+ statuses[414] = "414 Request-URI Too Large";
+ statuses[415] = "415 Unsupported Media Type";
+ statuses[416] = "416 Requested range not satisfiable";
+ statuses[417] = "417 Expectation Failed";
+ statuses[500] = "500 Internal Server Error";
+ statuses[501] = "501 Not Implemented";
+ statuses[502] = "502 Bad Gateway";
+ statuses[503] = "503 Service Unavailable";
+ statuses[504] = "504 Gateway Time-out";
+ statuses[505] = "505 HTTP Version not supported";
+}
+
+
bool Request::accepts(const string& encoding) const
{
// See RFC 2616, section 14.3 for the details.
@@ -253,8 +301,6 @@ Future<Nothing> Pipe::Writer::readerClosed()
}
-hashmap<uint16_t, string> statuses;
-
namespace query {
Try<hashmap<std::string, std::string>> decode(const std::string& query)
@@ -551,6 +597,5 @@ Future<Response> post(
return post(url, headers, body, contentType);
}
-
} // namespace http {
} // namespace process {
[11/12] mesos git commit: Removed http::put and added a TODO.
Posted by bm...@apache.org.
Removed http::put and added a TODO.
Review: https://reviews.apache.org/r/32349
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/91034cdd
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/91034cdd
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/91034cdd
Branch: refs/heads/master
Commit: 91034cddcd5158a0920352a00901952bfce93931
Parents: 103b6ea
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 14:34:20 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:48:22 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 13 ++++---------
3rdparty/libprocess/src/http.cpp | 14 --------------
2 files changed, 4 insertions(+), 23 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/91034cdd/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index 616f380..faffae7 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -521,6 +521,10 @@ std::ostream& operator << (
const URL& url);
+// TODO(bmahler): Consolidate these functions into a single
+// http::request function that takes a 'Request' object.
+
+
// Asynchronously sends an HTTP GET request to the specified URL
// and returns the HTTP response of type 'BODY' once the entire
// response is received.
@@ -559,15 +563,6 @@ Future<Response> post(
const Option<std::string>& body = None(),
const Option<std::string>& contentType = None());
-
-// Asynchronously sends an HTTP PUT request to the specified URL and
-// returns the HTTP response.
-Future<Response> put(
- const URL& url,
- const Option<hashmap<std::string, std::string>>& headers = None(),
- const Option<std::string>& body = None(),
- const Option<std::string>& contentType = None());
-
} // namespace http {
} // namespace process {
http://git-wip-us.apache.org/repos/asf/mesos/blob/91034cdd/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index 248db85..150ff33 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -746,19 +746,5 @@ Future<Response> post(
return post(url, headers, body, contentType);
}
-
-Future<Response> put(
- const URL& url,
- const Option<hashmap<string, string>>& headers,
- const Option<string>& body,
- const Option<string>& contentType)
-{
- if (body.isNone() && contentType.isSome()) {
- return Failure("Attempted to do a PUT with a Content-Type but no body");
- }
-
- return internal::request(url, "PUT", headers, body, contentType);
-}
-
} // namespace http {
} // namespace process {
[12/12] mesos git commit: Re-ordered and updated documentation for
http::get/post/put.
Posted by bm...@apache.org.
Re-ordered and updated documentation for http::get/post/put.
Review: https://reviews.apache.org/r/32348
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/103b6ea3
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/103b6ea3
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/103b6ea3
Branch: refs/heads/master
Commit: 103b6ea318abe1b515ba1a48da589a93f2da5757
Parents: 50fd69a
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 14:23:35 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:48:22 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 46 ++++++++++---------
3rdparty/libprocess/src/http.cpp | 56 +++++++++++------------
2 files changed, 53 insertions(+), 49 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/103b6ea3/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index 332f939..616f380 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -521,24 +521,27 @@ std::ostream& operator << (
const URL& url);
-// Asynchronously sends an HTTP GET request to the specified URL and
-// returns the HTTP response.
+// Asynchronously sends an HTTP GET request to the specified URL
+// and returns the HTTP response of type 'BODY' once the entire
+// response is received.
Future<Response> get(
const URL& url,
const Option<hashmap<std::string, std::string>>& headers = None());
-// Asynchronously sends an HTTP PUT request to the specified URL and
-// returns the HTTP response.
-Future<Response> put(
- const URL& url,
- const Option<hashmap<std::string, std::string>>& headers = None(),
- const Option<std::string>& body = None(),
- const Option<std::string>& contentType = None());
+// Asynchronously sends an HTTP GET request to the process with the
+// given UPID and returns the HTTP response of type 'BODY' once the
+// entire response is received.
+Future<Response> get(
+ const UPID& upid,
+ const Option<std::string>& path = None(),
+ const Option<std::string>& query = None(),
+ const Option<hashmap<std::string, std::string>>& headers = None());
-// Asynchronously sends an HTTP POST request to the specified URL and
-// returns the HTTP response.
+// Asynchronously sends an HTTP POST request to the specified URL
+// and returns the HTTP response of type 'BODY' once the entire
+// response is received.
Future<Response> post(
const URL& url,
const Option<hashmap<std::string, std::string>>& headers = None(),
@@ -546,17 +549,9 @@ Future<Response> post(
const Option<std::string>& contentType = None());
-// Asynchronously sends an HTTP GET request to the process with the
-// given UPID and returns the HTTP response from the process.
-Future<Response> get(
- const UPID& upid,
- const Option<std::string>& path = None(),
- const Option<std::string>& query = None(),
- const Option<hashmap<std::string, std::string>>& headers = None());
-
-
// Asynchronously sends an HTTP POST request to the process with the
-// given UPID and returns the HTTP response from the process.
+// given UPID and returns the HTTP response of type 'BODY' once the
+// entire response is received.
Future<Response> post(
const UPID& upid,
const Option<std::string>& path = None(),
@@ -564,6 +559,15 @@ Future<Response> post(
const Option<std::string>& body = None(),
const Option<std::string>& contentType = None());
+
+// Asynchronously sends an HTTP PUT request to the specified URL and
+// returns the HTTP response.
+Future<Response> put(
+ const URL& url,
+ const Option<hashmap<std::string, std::string>>& headers = None(),
+ const Option<std::string>& body = None(),
+ const Option<std::string>& contentType = None());
+
} // namespace http {
} // namespace process {
http://git-wip-us.apache.org/repos/asf/mesos/blob/103b6ea3/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index a7eeee9..248db85 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -687,34 +687,6 @@ Future<Response> get(
}
-Future<Response> put(
- const URL& url,
- const Option<hashmap<string, string>>& headers,
- const Option<string>& body,
- const Option<string>& contentType)
-{
- if (body.isNone() && contentType.isSome()) {
- return Failure("Attempted to do a PUT with a Content-Type but no body");
- }
-
- return internal::request(url, "PUT", headers, body, contentType);
-}
-
-
-Future<Response> post(
- const URL& url,
- const Option<hashmap<string, string>>& headers,
- const Option<string>& body,
- const Option<string>& contentType)
-{
- if (body.isNone() && contentType.isSome()) {
- return Failure("Attempted to do a POST with a Content-Type but no body");
- }
-
- return internal::request(url, "POST", headers, body, contentType);
-}
-
-
Future<Response> get(
const UPID& upid,
const Option<string>& path,
@@ -744,6 +716,20 @@ Future<Response> get(
Future<Response> post(
+ const URL& url,
+ const Option<hashmap<string, string>>& headers,
+ const Option<string>& body,
+ const Option<string>& contentType)
+{
+ if (body.isNone() && contentType.isSome()) {
+ return Failure("Attempted to do a POST with a Content-Type but no body");
+ }
+
+ return internal::request(url, "POST", headers, body, contentType);
+}
+
+
+Future<Response> post(
const UPID& upid,
const Option<string>& path,
const Option<hashmap<string, string>>& headers,
@@ -760,5 +746,19 @@ Future<Response> post(
return post(url, headers, body, contentType);
}
+
+Future<Response> put(
+ const URL& url,
+ const Option<hashmap<string, string>>& headers,
+ const Option<string>& body,
+ const Option<string>& contentType)
+{
+ if (body.isNone() && contentType.isSome()) {
+ return Failure("Attempted to do a PUT with a Content-Type but no body");
+ }
+
+ return internal::request(url, "PUT", headers, body, contentType);
+}
+
} // namespace http {
} // namespace process {
[09/12] mesos git commit: Removed use of 'assert' in decoder.hpp.
Posted by bm...@apache.org.
Removed use of 'assert' in decoder.hpp.
Review: https://reviews.apache.org/r/32345
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/50fd69ab
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/50fd69ab
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/50fd69ab
Branch: refs/heads/master
Commit: 50fd69ab25bc59e332330afb0848dffda78f60b0
Parents: 595e061
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 14:19:21 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:19 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/src/decoder.hpp | 44 ++++++++++++++++++++------------
1 file changed, 27 insertions(+), 17 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/50fd69ab/3rdparty/libprocess/src/decoder.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/decoder.hpp b/3rdparty/libprocess/src/decoder.hpp
index 4b3c53f..b3a667c 100644
--- a/3rdparty/libprocess/src/decoder.hpp
+++ b/3rdparty/libprocess/src/decoder.hpp
@@ -3,6 +3,8 @@
#include <http_parser.h>
+#include <glog/logging.h>
+
#include <deque>
#include <string>
#include <vector>
@@ -81,14 +83,15 @@ private:
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(!decoder->failure);
+ CHECK(!decoder->failure);
decoder->header = HEADER_FIELD;
decoder->field.clear();
decoder->value.clear();
decoder->query.clear();
- assert(decoder->request == NULL);
+ CHECK(decoder->request == NULL);
+
decoder->request = new http::Request();
decoder->request->headers.clear();
decoder->request->method.clear();
@@ -105,7 +108,7 @@ private:
static int on_path(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
decoder->request->path.append(data, length);
return 0;
}
@@ -113,7 +116,7 @@ private:
static int on_query_string(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
decoder->query.append(data, length);
return 0;
}
@@ -121,7 +124,7 @@ private:
static int on_fragment(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
decoder->request->fragment.append(data, length);
return 0;
}
@@ -130,7 +133,7 @@ private:
static int on_url(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
decoder->request->url.append(data, length);
int result = 0;
@@ -166,7 +169,7 @@ private:
static int on_header_field(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
if (decoder->header != HEADER_FIELD) {
decoder->request->headers[decoder->field] = decoder->value;
@@ -183,7 +186,7 @@ private:
static int on_header_value(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
decoder->value.append(data, length);
decoder->header = HEADER_VALUE;
return 0;
@@ -193,6 +196,8 @@ private:
{
DataDecoder* decoder = (DataDecoder*) p->data;
+ CHECK_NOTNULL(decoder->request);
+
// Add final header.
decoder->request->headers[decoder->field] = decoder->value;
decoder->field.clear();
@@ -209,7 +214,7 @@ private:
static int on_body(http_parser* p, const char* data, size_t length)
{
DataDecoder* decoder = (DataDecoder*) p->data;
- assert(decoder->request != NULL);
+ CHECK_NOTNULL(decoder->request);
decoder->request->body.append(data, length);
return 0;
}
@@ -217,9 +222,6 @@ private:
static int on_message_complete(http_parser* p)
{
DataDecoder* decoder = (DataDecoder*) p->data;
-// std::cout << "http::Request:" << std::endl;
-// std::cout << " method: " << decoder->request->method << std::endl;
-// std::cout << " path: " << decoder->request->path << std::endl;
// Parse the query key/values.
Try<hashmap<std::string, std::string>> decoded =
@@ -229,10 +231,13 @@ private:
return 1;
}
+ CHECK_NOTNULL(decoder->request);
+
decoder->request->query = decoded.get();
Option<std::string> encoding =
decoder->request->headers.get("Content-Encoding");
+
if (encoding.isSome() && encoding.get() == "gzip") {
Try<std::string> decompressed = gzip::decompress(decoder->request->body);
if (decompressed.isError()) {
@@ -324,13 +329,14 @@ private:
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(!decoder->failure);
+ CHECK(!decoder->failure);
decoder->header = HEADER_FIELD;
decoder->field.clear();
decoder->value.clear();
- assert(decoder->response == NULL);
+ CHECK(decoder->response == NULL);
+
decoder->response = new http::Response();
decoder->response->status.clear();
decoder->response->headers.clear();
@@ -366,7 +372,7 @@ private:
static int on_header_field(http_parser* p, const char* data, size_t length)
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
+ CHECK_NOTNULL(decoder->response);
if (decoder->header != HEADER_FIELD) {
decoder->response->headers[decoder->field] = decoder->value;
@@ -383,7 +389,7 @@ private:
static int on_header_value(http_parser* p, const char* data, size_t length)
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
+ CHECK_NOTNULL(decoder->response);
decoder->value.append(data, length);
decoder->header = HEADER_VALUE;
return 0;
@@ -393,6 +399,8 @@ private:
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+ CHECK_NOTNULL(decoder->response);
+
// Add final header.
decoder->response->headers[decoder->field] = decoder->value;
decoder->field.clear();
@@ -404,7 +412,7 @@ private:
static int on_body(http_parser* p, const char* data, size_t length)
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
- assert(decoder->response != NULL);
+ CHECK_NOTNULL(decoder->response);
decoder->response->body.append(data, length);
return 0;
}
@@ -413,6 +421,8 @@ private:
{
ResponseDecoder* decoder = (ResponseDecoder*) p->data;
+ CHECK_NOTNULL(decoder->response);
+
// Get the response status string.
if (http::statuses.contains(decoder->parser.status_code)) {
decoder->response->status = http::statuses[decoder->parser.status_code];
[04/12] mesos git commit: Moved http::Request::accepts from header
into cpp file.
Posted by bm...@apache.org.
Moved http::Request::accepts from header into cpp file.
Review: https://reviews.apache.org/r/32336
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/0a5e973a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/0a5e973a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/0a5e973a
Branch: refs/heads/master
Commit: 0a5e973a95f83c97557c180d2f4426e181f4caeb
Parents: 9b14ba2
Author: Benjamin Mahler <be...@gmail.com>
Authored: Tue Mar 17 12:26:00 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 63 +--------------------
3rdparty/libprocess/src/http.cpp | 68 +++++++++++++++++++++++
2 files changed, 69 insertions(+), 62 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/0a5e973a/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index 2b36698..1b40b4f 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -25,7 +25,6 @@
#include <stout/memory.hpp>
#include <stout/none.hpp>
#include <stout/nothing.hpp>
-#include <stout/numify.hpp>
#include <stout/option.hpp>
#include <stout/stringify.hpp>
#include <stout/strings.hpp>
@@ -62,67 +61,7 @@ struct Request
// Returns whether the encoding is considered acceptable in the request.
// TODO(bmahler): Consider this logic being in decoder.hpp, and having the
// Request contain a member variable for each popular HTTP 1.0/1.1 header.
- bool accepts(const std::string& encoding) const
- {
- // See RFC 2616, section 14.3 for the details.
- Option<std::string> accepted = headers.get("Accept-Encoding");
-
- if (accepted.isNone()) {
- return false;
- }
-
- // Remove spaces and tabs for easier parsing.
- accepted = strings::remove(accepted.get(), " ");
- accepted = strings::remove(accepted.get(), "\t");
- accepted = strings::remove(accepted.get(), "\n");
-
- // From RFC 2616:
- // 1. If the content-coding is one of the content-codings listed in
- // the Accept-Encoding field, then it is acceptable, unless it is
- // accompanied by a qvalue of 0. (As defined in section 3.9, a
- // qvalue of 0 means "not acceptable.")
- // 2. The special "*" symbol in an Accept-Encoding field matches any
- // available content-coding not explicitly listed in the header
- // field.
-
- // First we'll look for the encoding specified explicitly, then '*'.
- std::vector<std::string> candidates;
- candidates.push_back(encoding); // Rule 1.
- candidates.push_back("*"); // Rule 2.
-
- foreach (std::string& candidate, candidates) {
- // Is the candidate one of the accepted encodings?
- foreach (const std::string& _encoding,
- strings::tokenize(accepted.get(), ",")) {
- if (strings::startsWith(_encoding, candidate)) {
- // Is there a 0 q value? Ex: 'gzip;q=0.0'.
- const std::map<std::string, std::vector<std::string> >& values =
- strings::pairs(_encoding, ";", "=");
-
- // Look for { "q": ["0"] }.
- if (values.count("q") == 0 || values.find("q")->second.size() != 1) {
- // No q value, or malformed q value.
- return true;
- }
-
- // Is the q value > 0?
- Try<double> value = numify<double>(values.find("q")->second[0]);
- return value.isSome() && value.get() > 0;
- }
- }
- }
-
- // NOTE: 3 and 4 are partially ignored since we can only provide gzip.
- // 3. If multiple content-codings are acceptable, then the acceptable
- // content-coding with the highest non-zero qvalue is preferred.
- // 4. The "identity" content-coding is always acceptable, unless
- // specifically refused because the Accept-Encoding field includes
- // "identity;q=0", or because the field includes "*;q=0" and does
- // not explicitly include the "identity" content-coding. If the
- // Accept-Encoding field-value is empty, then only the "identity"
- // encoding is acceptable.
- return false;
- }
+ bool accepts(const std::string& encoding) const;
};
http://git-wip-us.apache.org/repos/asf/mesos/blob/0a5e973a/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index 276cecd..1865546 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -6,6 +6,7 @@
#include <cstring>
#include <deque>
#include <iostream>
+#include <map>
#include <queue>
#include <string>
#include <vector>
@@ -16,16 +17,20 @@
#include <process/owned.hpp>
#include <process/socket.hpp>
+#include <stout/foreach.hpp>
#include <stout/ip.hpp>
#include <stout/lambda.hpp>
#include <stout/net.hpp>
#include <stout/nothing.hpp>
+#include <stout/numify.hpp>
#include <stout/option.hpp>
+#include <stout/strings.hpp>
#include <stout/try.hpp>
#include "decoder.hpp"
using std::deque;
+using std::map;
using std::queue;
using std::string;
using std::vector;
@@ -39,6 +44,69 @@ using process::network::Socket;
namespace process {
namespace http {
+
+bool Request::accepts(const string& encoding) const
+{
+ // See RFC 2616, section 14.3 for the details.
+ Option<string> accepted = headers.get("Accept-Encoding");
+
+ if (accepted.isNone()) {
+ return false;
+ }
+
+ // Remove spaces and tabs for easier parsing.
+ accepted = strings::remove(accepted.get(), " ");
+ accepted = strings::remove(accepted.get(), "\t");
+ accepted = strings::remove(accepted.get(), "\n");
+
+ // From RFC 2616:
+ // 1. If the content-coding is one of the content-codings listed in
+ // the Accept-Encoding field, then it is acceptable, unless it is
+ // accompanied by a qvalue of 0. (As defined in section 3.9, a
+ // qvalue of 0 means "not acceptable.")
+ // 2. The special "*" symbol in an Accept-Encoding field matches any
+ // available content-coding not explicitly listed in the header
+ // field.
+
+ // First we'll look for the encoding specified explicitly, then '*'.
+ vector<string> candidates;
+ candidates.push_back(encoding); // Rule 1.
+ candidates.push_back("*"); // Rule 2.
+
+ foreach (const string& candidate, candidates) {
+ // Is the candidate one of the accepted encodings?
+ foreach (const string& _encoding, strings::tokenize(accepted.get(), ",")) {
+ if (strings::startsWith(_encoding, candidate)) {
+ // Is there a 0 q value? Ex: 'gzip;q=0.0'.
+ const map<string, vector<string> >& values =
+ strings::pairs(_encoding, ";", "=");
+
+ // Look for { "q": ["0"] }.
+ if (values.count("q") == 0 || values.find("q")->second.size() != 1) {
+ // No q value, or malformed q value.
+ return true;
+ }
+
+ // Is the q value > 0?
+ Try<double> value = numify<double>(values.find("q")->second[0]);
+ return value.isSome() && value.get() > 0;
+ }
+ }
+ }
+
+ // NOTE: 3 and 4 are partially ignored since we can only provide gzip.
+ // 3. If multiple content-codings are acceptable, then the acceptable
+ // content-coding with the highest non-zero qvalue is preferred.
+ // 4. The "identity" content-coding is always acceptable, unless
+ // specifically refused because the Accept-Encoding field includes
+ // "identity;q=0", or because the field includes "*;q=0" and does
+ // not explicitly include the "identity" content-coding. If the
+ // Accept-Encoding field-value is empty, then only the "identity"
+ // encoding is acceptable.
+ return false;
+}
+
+
Pipe::Reader Pipe::reader() const
{
return Pipe::Reader(data);
[03/12] mesos git commit: Fixed a copy/paste naming mistake in
decoder_tests.cpp.
Posted by bm...@apache.org.
Fixed a copy/paste naming mistake in decoder_tests.cpp.
Review: https://reviews.apache.org/r/32341
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/39426df6
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/39426df6
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/39426df6
Branch: refs/heads/master
Commit: 39426df6a9656be14d4b711d9f1db0dee4b65c13
Parents: 7d37e4a
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 11:44:35 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/src/tests/decoder_tests.cpp | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/39426df6/3rdparty/libprocess/src/tests/decoder_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/decoder_tests.cpp b/3rdparty/libprocess/src/tests/decoder_tests.cpp
index d65f5cf..b996f00 100644
--- a/3rdparty/libprocess/src/tests/decoder_tests.cpp
+++ b/3rdparty/libprocess/src/tests/decoder_tests.cpp
@@ -119,11 +119,11 @@ TEST(Decoder, Response)
"\r\n"
"hi";
- deque<Response*> requests = decoder.decode(data.data(), data.length());
+ deque<Response*> responses = decoder.decode(data.data(), data.length());
ASSERT_FALSE(decoder.failed());
- ASSERT_EQ(1, requests.size());
+ ASSERT_EQ(1, responses.size());
- Response* response = requests[0];
+ Response* response = responses[0];
EXPECT_EQ("200 OK", response->status);
EXPECT_EQ(Response::BODY, response->type);
[10/12] mesos git commit: Added a wrapper for HttpProcess to prevent
segfaults during test failures.
Posted by bm...@apache.org.
Added a wrapper for HttpProcess to prevent segfaults during test failures.
Review: https://reviews.apache.org/r/32350
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/a0d201b7
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/a0d201b7
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/a0d201b7
Branch: refs/heads/master
Commit: a0d201b711e56b9fdec464f2d4cb25c2a8a06a79
Parents: 91034cd
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 15:32:54 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:48:22 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/src/tests/http_tests.cpp | 103 ++++++++++------------
1 file changed, 49 insertions(+), 54 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/a0d201b7/3rdparty/libprocess/src/tests/http_tests.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/tests/http_tests.cpp b/3rdparty/libprocess/src/tests/http_tests.cpp
index 17fb092..e254506 100644
--- a/3rdparty/libprocess/src/tests/http_tests.cpp
+++ b/3rdparty/libprocess/src/tests/http_tests.cpp
@@ -38,10 +38,19 @@ using testing::EndsWith;
using testing::Invoke;
using testing::Return;
+
class HttpProcess : public Process<HttpProcess>
{
public:
- HttpProcess()
+ HttpProcess() {}
+
+ MOCK_METHOD1(body, Future<http::Response>(const http::Request&));
+ MOCK_METHOD1(pipe, Future<http::Response>(const http::Request&));
+ MOCK_METHOD1(get, Future<http::Response>(const http::Request&));
+ MOCK_METHOD1(post, Future<http::Response>(const http::Request&));
+
+protected:
+ virtual void initialize()
{
route("/auth", None(), &HttpProcess::auth);
route("/body", None(), &HttpProcess::body);
@@ -59,24 +68,33 @@ public:
}
return http::OK();
}
-
- MOCK_METHOD1(body, Future<http::Response>(const http::Request&));
- MOCK_METHOD1(pipe, Future<http::Response>(const http::Request&));
- MOCK_METHOD1(get, Future<http::Response>(const http::Request&));
- MOCK_METHOD1(post, Future<http::Response>(const http::Request&));
};
-TEST(HTTP, auth)
+class Http
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
+public:
+ Http() : process(new HttpProcess())
+ {
+ spawn(process.get());
+ }
+
+ ~Http()
+ {
+ terminate(process.get());
+ wait(process.get());
+ }
- HttpProcess process;
+ Owned<HttpProcess> process;
+};
- spawn(process);
+
+TEST(HTTP, auth)
+{
+ Http http;
// Test the case where there is no auth.
- Future<http::Response> noAuthFuture = http::get(process.self(), "auth");
+ Future<http::Response> noAuthFuture = http::get(http.process->self(), "auth");
AWAIT_READY(noAuthFuture);
EXPECT_EQ(http::statuses[401], noAuthFuture.get().status);
@@ -88,7 +106,7 @@ TEST(HTTP, auth)
headers["Authorization"] = "Basic " + base64::encode("testuser:wrongpass");
Future<http::Response> wrongAuthFuture =
- http::get(process.self(), "auth", None(), headers);
+ http::get(http.process->self(), "auth", None(), headers);
AWAIT_READY(wrongAuthFuture);
EXPECT_EQ(http::statuses[401], wrongAuthFuture.get().status);
@@ -99,23 +117,16 @@ TEST(HTTP, auth)
headers["Authorization"] = "Basic " + base64::encode("testuser:testpass");
Future<http::Response> rightAuthFuture =
- http::get(process.self(), "auth", None(), headers);
+ http::get(http.process->self(), "auth", None(), headers);
AWAIT_READY(rightAuthFuture);
EXPECT_EQ(http::statuses[200], rightAuthFuture.get().status);
-
- terminate(process);
- wait(process);
}
TEST(HTTP, Endpoints)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HttpProcess process;
-
- spawn(process);
+ Http http;
// First hit '/body' (using explicit sockets and HTTP/1.0).
Try<Socket> create = Socket::create();
@@ -123,17 +134,17 @@ TEST(HTTP, Endpoints)
Socket socket = create.get();
- AWAIT_READY(socket.connect(process.self().address));
+ AWAIT_READY(socket.connect(http.process->self().address));
std::ostringstream out;
- out << "GET /" << process.self().id << "/body"
+ out << "GET /" << http.process->self().id << "/body"
<< " HTTP/1.0\r\n"
<< "Connection: Keep-Alive\r\n"
<< "\r\n";
const string& data = out.str();
- EXPECT_CALL(process, body(_))
+ EXPECT_CALL(*http.process, body(_))
.WillOnce(Return(http::OK()));
AWAIT_READY(socket.send(data));
@@ -149,11 +160,11 @@ TEST(HTTP, Endpoints)
ok.reader = pipe.reader();
Future<Nothing> request;
- EXPECT_CALL(process, pipe(_))
+ EXPECT_CALL(*http.process, pipe(_))
.WillOnce(DoAll(FutureSatisfy(&request),
Return(ok)));
- Future<http::Response> future = http::get(process.self(), "pipe");
+ Future<http::Response> future = http::get(http.process->self(), "pipe");
AWAIT_READY(request);
@@ -166,9 +177,6 @@ TEST(HTTP, Endpoints)
EXPECT_EQ(http::statuses[200], future.get().status);
EXPECT_SOME_EQ("chunked", future.get().headers.get("Transfer-Encoding"));
EXPECT_EQ("Hello World\n", future.get().body);
-
- terminate(process);
- wait(process);
}
@@ -353,31 +361,24 @@ http::Response validateGetWithQuery(const http::Request& request)
TEST(HTTP, Get)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HttpProcess process;
+ Http http;
- spawn(process);
-
- EXPECT_CALL(process, get(_))
+ EXPECT_CALL(*http.process, get(_))
.WillOnce(Invoke(validateGetWithoutQuery));
- Future<http::Response> noQueryFuture = http::get(process.self(), "get");
+ Future<http::Response> noQueryFuture = http::get(http.process->self(), "get");
AWAIT_READY(noQueryFuture);
ASSERT_EQ(http::statuses[200], noQueryFuture.get().status);
- EXPECT_CALL(process, get(_))
+ EXPECT_CALL(*http.process, get(_))
.WillOnce(Invoke(validateGetWithQuery));
Future<http::Response> queryFuture =
- http::get(process.self(), "get", "foo=bar");
+ http::get(http.process->self(), "get", "foo=bar");
AWAIT_READY(queryFuture);
ASSERT_EQ(http::statuses[200], queryFuture.get().status);
-
- terminate(process);
- wait(process);
}
@@ -395,23 +396,19 @@ http::Response validatePost(const http::Request& request)
TEST(HTTP, Post)
{
- ASSERT_TRUE(GTEST_IS_THREADSAFE);
-
- HttpProcess process;
-
- spawn(process);
+ Http http;
// Test the case where there is a content type but no body.
Future<http::Response> future =
- http::post(process.self(), "post", None(), None(), "text/plain");
+ http::post(http.process->self(), "post", None(), None(), "text/plain");
AWAIT_EXPECT_FAILED(future);
- EXPECT_CALL(process, post(_))
+ EXPECT_CALL(*http.process, post(_))
.WillOnce(Invoke(validatePost));
future = http::post(
- process.self(),
+ http.process->self(),
"post",
None(),
"This is the payload.",
@@ -424,19 +421,17 @@ TEST(HTTP, Post)
hashmap<string, string> headers;
headers["Content-Type"] = "text/plain";
- EXPECT_CALL(process, post(_))
+ EXPECT_CALL(*http.process, post(_))
.WillOnce(Invoke(validatePost));
future =
- http::post(process.self(), "post", headers, "This is the payload.");
+ http::post(http.process->self(), "post", headers, "This is the payload.");
AWAIT_READY(future);
ASSERT_EQ(http::statuses[200], future.get().status);
-
- terminate(process);
- wait(process);
}
+
TEST(HTTP, QueryEncodeDecode)
{
// If we use Type<a, b> directly inside a macro without surrounding
[08/12] mesos git commit: Moved http::path::parse from header to .cpp
file.
Posted by bm...@apache.org.
Moved http::path::parse from header to .cpp file.
Review: https://reviews.apache.org/r/32339
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/87bece8a
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/87bece8a
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/87bece8a
Branch: refs/heads/master
Commit: 87bece8acdac674dbacc39ecf930bb72daedc5a5
Parents: f9961e3
Author: Benjamin Mahler <be...@gmail.com>
Authored: Tue Mar 17 12:49:21 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 37 ++-------------------
3rdparty/libprocess/src/http.cpp | 40 +++++++++++++++++++++++
2 files changed, 42 insertions(+), 35 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/87bece8a/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index ca1bedc..1c7b752 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -431,42 +431,9 @@ namespace path {
// books: "books"
// isbn: "0304827484"
// chapters: "chapters"
-inline Try<hashmap<std::string, std::string> > parse(
+Try<hashmap<std::string, std::string> > parse(
const std::string& pattern,
- const std::string& path)
-{
- // Split the pattern by '/' into keys.
- std::vector<std::string> keys = strings::tokenize(pattern, "/");
-
- // Split the path by '/' into segments.
- std::vector<std::string> segments = strings::tokenize(path, "/");
-
- hashmap<std::string, std::string> result;
-
- while (!segments.empty()) {
- if (keys.empty()) {
- return Error(
- "Not expecting suffix '" + strings::join("/", segments) + "'");
- }
-
- std::string key = keys.front();
-
- if (strings::startsWith(key, "{") &&
- strings::endsWith(key, "}")) {
- key = strings::remove(key, "{", strings::PREFIX);
- key = strings::remove(key, "}", strings::SUFFIX);
- } else if (key != segments.front()) {
- return Error("Expecting '" + key + "' not '" + segments.front() + "'");
- }
-
- result[key] = segments.front();
-
- keys.erase(keys.begin());
- segments.erase(segments.begin());
- }
-
- return result;
-}
+ const std::string& path);
} // namespace path {
http://git-wip-us.apache.org/repos/asf/mesos/blob/87bece8a/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index f56c88e..1df8824 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -307,6 +307,46 @@ Future<Nothing> Pipe::Writer::readerClosed()
}
+namespace path {
+
+Try<hashmap<string, string> > parse(const string& pattern, const string& path)
+{
+ // Split the pattern by '/' into keys.
+ vector<string> keys = strings::tokenize(pattern, "/");
+
+ // Split the path by '/' into segments.
+ vector<string> segments = strings::tokenize(path, "/");
+
+ hashmap<string, string> result;
+
+ while (!segments.empty()) {
+ if (keys.empty()) {
+ return Error(
+ "Not expecting suffix '" + strings::join("/", segments) + "'");
+ }
+
+ string key = keys.front();
+
+ if (strings::startsWith(key, "{") &&
+ strings::endsWith(key, "}")) {
+ key = strings::remove(key, "{", strings::PREFIX);
+ key = strings::remove(key, "}", strings::SUFFIX);
+ } else if (key != segments.front()) {
+ return Error("Expecting '" + key + "' not '" + segments.front() + "'");
+ }
+
+ result[key] = segments.front();
+
+ keys.erase(keys.begin());
+ segments.erase(segments.begin());
+ }
+
+ return result;
+}
+
+} // namespace path {
+
+
string encode(const string& s)
{
ostringstream out;
[02/12] mesos git commit: Updated the http-parser upgrade TODO.
Posted by bm...@apache.org.
Updated the http-parser upgrade TODO.
Review: https://reviews.apache.org/r/32342
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/2622b015
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/2622b015
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/2622b015
Branch: refs/heads/master
Commit: 2622b0153ec9e5895e8c5fe0e5a0c53e5863cd72
Parents: 39426df
Author: Benjamin Mahler <be...@gmail.com>
Authored: Fri Mar 20 11:58:27 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/src/decoder.hpp | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/2622b015/3rdparty/libprocess/src/decoder.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/decoder.hpp b/3rdparty/libprocess/src/decoder.hpp
index 45f3d7f..25b0228 100644
--- a/3rdparty/libprocess/src/decoder.hpp
+++ b/3rdparty/libprocess/src/decoder.hpp
@@ -15,7 +15,9 @@
#include <stout/try.hpp>
-// TODO(bmahler): Upgrade our http_parser to the latest version.
+// TODO(bmahler): Switch to joyent/http-parser now that it is no
+// longer being hosted under ry/http-parser.
+
namespace process {
// TODO(benh): Make DataDecoder abstract and make RequestDecoder a
@@ -50,6 +52,7 @@ public:
size_t parsed = http_parser_execute(&parser, &settings, data, length);
if (parsed != length) {
+ // TODO(bmahler): joyent/http-parser exposes error reasons.
failure = true;
}
@@ -296,6 +299,7 @@ public:
size_t parsed = http_parser_execute(&parser, &settings, data, length);
if (parsed != length) {
+ // TODO(bmahler): joyent/http-parser exposes error reasons.
failure = true;
}
[06/12] mesos git commit: Moved http::URL output operator from header
to .cpp file.
Posted by bm...@apache.org.
Moved http::URL output operator from header to .cpp file.
Review: https://reviews.apache.org/r/32340
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/7d37e4a8
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/7d37e4a8
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/7d37e4a8
Branch: refs/heads/master
Commit: 7d37e4a8809e54d64ef300cede756fc0f8eff79a
Parents: 87bece8
Author: Benjamin Mahler <be...@gmail.com>
Authored: Tue Mar 17 13:00:13 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 28 +++-----------------
3rdparty/libprocess/src/http.cpp | 31 ++++++++++++++++++++++-
2 files changed, 33 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/7d37e4a8/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index 1c7b752..332f939 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -3,6 +3,7 @@
#include <stdint.h>
+#include <iosfwd>
#include <queue>
#include <sstream>
#include <string>
@@ -515,32 +516,9 @@ struct URL
};
-inline std::ostream& operator << (
+std::ostream& operator << (
std::ostream& stream,
- const URL& url)
-{
- stream << url.scheme << "://";
-
- if (url.domain.isSome()) {
- stream << url.domain.get();
- } else if (url.ip.isSome()) {
- stream << url.ip.get();
- }
-
- stream << ":" << url.port;
-
- stream << "/" << strings::remove(url.path, "/", strings::PREFIX);
-
- if (!url.query.empty()) {
- stream << "?" << query::encode(url.query);
- }
-
- if (url.fragment.isSome()) {
- stream << "#" << url.fragment.get();
- }
-
- return stream;
-}
+ const URL& url);
// Asynchronously sends an HTTP GET request to the specified URL and
http://git-wip-us.apache.org/repos/asf/mesos/blob/7d37e4a8/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index 1df8824..a7eeee9 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -8,7 +8,7 @@
#include <cstring>
#include <deque>
#include <iomanip>
-#include <iostream>
+#include <ostream>
#include <map>
#include <queue>
#include <string>
@@ -36,6 +36,7 @@
using std::deque;
using std::istringstream;
using std::map;
+using std::ostream;
using std::ostringstream;
using std::queue;
using std::string;
@@ -485,6 +486,34 @@ std::string encode(const hashmap<std::string, std::string>& query)
} // namespace query {
+ostream& operator << (
+ ostream& stream,
+ const URL& url)
+{
+ stream << url.scheme << "://";
+
+ if (url.domain.isSome()) {
+ stream << url.domain.get();
+ } else if (url.ip.isSome()) {
+ stream << url.ip.get();
+ }
+
+ stream << ":" << url.port;
+
+ stream << "/" << strings::remove(url.path, "/", strings::PREFIX);
+
+ if (!url.query.empty()) {
+ stream << "?" << query::encode(url.query);
+ }
+
+ if (url.fragment.isSome()) {
+ stream << "#" << url.fragment.get();
+ }
+
+ return stream;
+}
+
+
namespace internal {
Future<Response> decode(const string& buffer)
[07/12] mesos git commit: Moved http encode/decode from header to
.cpp file.
Posted by bm...@apache.org.
Moved http encode/decode from header to .cpp file.
Review: https://reviews.apache.org/r/32338
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/f9961e35
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/f9961e35
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/f9961e35
Branch: refs/heads/master
Commit: f9961e353a3ceac964ed099ba5507469d250f2dd
Parents: dab7bdb
Author: Benjamin Mahler <be...@gmail.com>
Authored: Tue Mar 17 12:43:10 2015 -0700
Committer: Benjamin Mahler <be...@gmail.com>
Committed: Tue Mar 24 16:47:18 2015 -0700
----------------------------------------------------------------------
3rdparty/libprocess/include/process/http.hpp | 109 +++-------------------
3rdparty/libprocess/src/http.cpp | 94 +++++++++++++++++++
2 files changed, 105 insertions(+), 98 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/f9961e35/3rdparty/libprocess/include/process/http.hpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp
index a96bc28..ca1bedc 100644
--- a/3rdparty/libprocess/include/process/http.hpp
+++ b/3rdparty/libprocess/include/process/http.hpp
@@ -1,13 +1,8 @@
#ifndef __PROCESS_HTTP_HPP__
#define __PROCESS_HTTP_HPP__
-#include <limits.h>
#include <stdint.h>
-#include <unistd.h>
-#include <cctype>
-#include <cstdlib>
-#include <iomanip>
#include <queue>
#include <sstream>
#include <string>
@@ -18,7 +13,6 @@
#include <process/pid.hpp>
#include <stout/error.hpp>
-#include <stout/foreach.hpp>
#include <stout/hashmap.hpp>
#include <stout/ip.hpp>
#include <stout/json.hpp>
@@ -477,6 +471,17 @@ inline Try<hashmap<std::string, std::string> > parse(
} // namespace path {
+// Returns a percent-encoded string according to RFC 3986.
+// The input string must not already be percent encoded.
+std::string encode(const std::string& s);
+
+
+// Decodes a percent-encoded string according to RFC 3986.
+// The input string must not already be decoded.
+// Returns error on the occurrence of a malformed % escape in s.
+Try<std::string> decode(const std::string& s);
+
+
namespace query {
// Decodes an HTTP query string into a map. For example:
@@ -500,98 +505,6 @@ std::string encode(const hashmap<std::string, std::string>& query);
} // namespace query {
-// Returns a percent-encoded string according to RFC 3986.
-// The input string must not already be percent encoded.
-inline std::string encode(const std::string& s)
-{
- std::ostringstream out;
-
- foreach (unsigned char c, s) {
- switch (c) {
- // Reserved characters.
- case '$':
- case '&':
- case '+':
- case ',':
- case '/':
- case ':':
- case ';':
- case '=':
- case '?':
- case '@':
- // Unsafe characters.
- case ' ':
- case '"':
- case '<':
- case '>':
- case '#':
- case '%':
- case '{':
- case '}':
- case '|':
- case '\\':
- case '^':
- case '~':
- case '[':
- case ']':
- case '`':
- // NOTE: The cast to unsigned int is needed.
- out << '%' << std::setfill('0') << std::setw(2) << std::hex
- << std::uppercase << (unsigned int) c;
- break;
- default:
- // ASCII control characters and non-ASCII characters.
- // NOTE: The cast to unsigned int is needed.
- if (c < 0x20 || c > 0x7F) {
- out << '%' << std::setfill('0') << std::setw(2) << std::hex
- << std::uppercase << (unsigned int) c;
- } else {
- out << c;
- }
- break;
- }
- }
-
- return out.str();
-}
-
-
-// Decodes a percent-encoded string according to RFC 3986.
-// The input string must not already be decoded.
-// Returns error on the occurrence of a malformed % escape in s.
-inline Try<std::string> decode(const std::string& s)
-{
- std::ostringstream out;
-
- for (size_t i = 0; i < s.length(); ++i) {
- if (s[i] != '%') {
- out << (s[i] == '+' ? ' ' : s[i]);
- continue;
- }
-
- // We now expect two more characters: "% HEXDIG HEXDIG"
- if (i + 2 >= s.length() || !isxdigit(s[i+1]) || !isxdigit(s[i+2])) {
- return Error(
- "Malformed % escape in '" + s + "': '" + s.substr(i, 3) + "'");
- }
-
- // Convert from HEXDIG HEXDIG to char value.
- std::istringstream in(s.substr(i + 1, 2));
- unsigned long l;
- in >> std::hex >> l;
- if (l > UCHAR_MAX) {
- ABORT("Unexpected conversion from hex string: " + s.substr(i + 1, 2) +
- " to unsigned long: " + stringify(l));
- }
- out << static_cast<unsigned char>(l);
-
- i += 2;
- }
-
- return out.str();
-}
-
-
// Represents a Uniform Resource Locator:
// scheme://domain|ip:port/path?query#fragment
struct URL
http://git-wip-us.apache.org/repos/asf/mesos/blob/f9961e35/3rdparty/libprocess/src/http.cpp
----------------------------------------------------------------------
diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp
index 3d2b541..f56c88e 100644
--- a/3rdparty/libprocess/src/http.cpp
+++ b/3rdparty/libprocess/src/http.cpp
@@ -1,14 +1,18 @@
#include <arpa/inet.h>
#include <stdint.h>
+#include <stdlib.h>
#include <algorithm>
+#include <cctype>
#include <cstring>
#include <deque>
+#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <string>
+#include <sstream>
#include <vector>
#include <process/future.hpp>
@@ -30,7 +34,9 @@
#include "decoder.hpp"
using std::deque;
+using std::istringstream;
using std::map;
+using std::ostringstream;
using std::queue;
using std::string;
using std::vector;
@@ -301,6 +307,93 @@ Future<Nothing> Pipe::Writer::readerClosed()
}
+string encode(const string& s)
+{
+ ostringstream out;
+
+ foreach (unsigned char c, s) {
+ switch (c) {
+ // Reserved characters.
+ case '$':
+ case '&':
+ case '+':
+ case ',':
+ case '/':
+ case ':':
+ case ';':
+ case '=':
+ case '?':
+ case '@':
+ // Unsafe characters.
+ case ' ':
+ case '"':
+ case '<':
+ case '>':
+ case '#':
+ case '%':
+ case '{':
+ case '}':
+ case '|':
+ case '\\':
+ case '^':
+ case '~':
+ case '[':
+ case ']':
+ case '`':
+ // NOTE: The cast to unsigned int is needed.
+ out << '%' << std::setfill('0') << std::setw(2) << std::hex
+ << std::uppercase << (unsigned int) c;
+ break;
+ default:
+ // ASCII control characters and non-ASCII characters.
+ // NOTE: The cast to unsigned int is needed.
+ if (c < 0x20 || c > 0x7F) {
+ out << '%' << std::setfill('0') << std::setw(2) << std::hex
+ << std::uppercase << (unsigned int) c;
+ } else {
+ out << c;
+ }
+ break;
+ }
+ }
+
+ return out.str();
+}
+
+
+Try<string> decode(const string& s)
+{
+ ostringstream out;
+
+ for (size_t i = 0; i < s.length(); ++i) {
+ if (s[i] != '%') {
+ out << (s[i] == '+' ? ' ' : s[i]);
+ continue;
+ }
+
+ // We now expect two more characters: "% HEXDIG HEXDIG"
+ if (i + 2 >= s.length() || !isxdigit(s[i+1]) || !isxdigit(s[i+2])) {
+ return Error(
+ "Malformed % escape in '" + s + "': '" + s.substr(i, 3) + "'");
+ }
+
+ // Convert from HEXDIG HEXDIG to char value.
+ istringstream in(s.substr(i + 1, 2));
+ unsigned long l;
+ in >> std::hex >> l;
+ if (l > UCHAR_MAX) {
+ ABORT("Unexpected conversion from hex string: " + s.substr(i + 1, 2) +
+ " to unsigned long: " + stringify(l));
+ }
+ out << static_cast<unsigned char>(l);
+
+ i += 2;
+ }
+
+ return out.str();
+}
+
+
namespace query {
Try<hashmap<std::string, std::string>> decode(const std::string& query)
@@ -351,6 +444,7 @@ std::string encode(const hashmap<std::string, std::string>& query)
} // namespace query {
+
namespace internal {
Future<Response> decode(const string& buffer)