Repository: mesos Updated Branches: refs/heads/master 942fe33d1 -> c869b0647
Exposed the http::internal::request function. Review: https://reviews.apache.org/r/41789/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/c869b064 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/c869b064 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/c869b064 Branch: refs/heads/master Commit: c869b0647d56b22fdd940a015df7015069732169 Parents: 942fe33 Author: Yongqiao Wang <[email protected]> Authored: Tue Feb 9 19:13:39 2016 -0800 Committer: Adam B <[email protected]> Committed: Tue Feb 9 19:13:39 2016 -0800 ---------------------------------------------------------------------- 3rdparty/libprocess/include/process/http.hpp | 35 ++++++- 3rdparty/libprocess/src/http.cpp | 118 +++++++++++++++------- 3rdparty/libprocess/src/tests/http_tests.cpp | 30 ++++++ 3 files changed, 144 insertions(+), 39 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/c869b064/3rdparty/libprocess/include/process/http.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/include/process/http.hpp b/3rdparty/libprocess/include/process/http.hpp index bcba304..8f4eabc 100644 --- a/3rdparty/libprocess/include/process/http.hpp +++ b/3rdparty/libprocess/include/process/http.hpp @@ -783,8 +783,39 @@ private: Future<Connection> connect(const URL& url); -// TODO(bmahler): Consolidate these functions into a single -// http::request function that takes a 'Request' object. +// Create a http Request from the specified parameters. +Request createRequest( + const UPID& upid, + const std::string& method, + bool enableSSL = false, + const Option<std::string>& path = None(), + const Option<Headers>& headers = None(), + const Option<std::string>& body = None(), + const Option<std::string>& contentType = None()); + + +Request createRequest( + const URL& url, + const std::string& method, + const Option<Headers>& headers = None(), + const Option<std::string>& body = None(), + const Option<std::string>& contentType = None()); + +/** + * Asynchronously sends an HTTP request to the process and + * returns the HTTP response once the entire response is received. + * + * @param streamedResponse Being true indicates the HTTP response will + * be 'PIPE' type, and caller must read the response body from the + * Pipe::Reader, otherwise, the HTTP response will be 'BODY' type. + */ +Future<Response> request( + const Request& request, + bool streamedResponse = false); + + +// TODO(Yongqiao Wang): Refactor other functions +// (such as post/get/requestDelete) to use the 'request' function. // TODO(bmahler): Support discarding the future responses; // discarding should disconnect from the server. http://git-wip-us.apache.org/repos/asf/mesos/blob/c869b064/3rdparty/libprocess/src/http.cpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/src/http.cpp b/3rdparty/libprocess/src/http.cpp index a19cd12..3ca0cfd 100644 --- a/3rdparty/libprocess/src/http.cpp +++ b/3rdparty/libprocess/src/http.cpp @@ -1266,7 +1266,53 @@ Future<Connection> connect(const URL& url) } -namespace internal { +Request createRequest( + const URL& url, + const string& method, + const Option<Headers>& headers, + const Option<string>& body, + const Option<string>& contentType) +{ + Request request; + request.method = method; + request.url = url; + request.keepAlive = false; + + if (headers.isSome()) { + request.headers = headers.get(); + } + + if (body.isSome()) { + request.body = body.get(); + } + + if (contentType.isSome()) { + request.headers["Content-Type"] = contentType.get(); + } + + return request; +} + + +Request createRequest( + const UPID& upid, + const string& method, + bool enableSSL, + const Option<string>& path, + const Option<Headers>& headers, + const Option<string>& body, + const Option<string>& contentType) +{ + string scheme = enableSSL ? "https" : "http"; + URL url(scheme, net::IP(upid.address.ip), upid.address.port, upid.id); + + if (path.isSome()) { + url.path = strings::join("/", url.path, path.get()); + } + + return createRequest(url, method, headers, body, contentType); +} + Future<Response> request(const Request& request, bool streamedResponse) { @@ -1292,23 +1338,21 @@ Future<Response> request(const Request& request, bool streamedResponse) }); } -} // namespace internal { - Future<Response> get( const URL& url, const Option<Headers>& headers) { - Request request; - request.method = "GET"; - request.url = url; - request.keepAlive = false; + Request _request; + _request.method = "GET"; + _request.url = url; + _request.keepAlive = false; if (headers.isSome()) { - request.headers = headers.get(); + _request.headers = headers.get(); } - return internal::request(request, false); + return request(_request, false); } @@ -1350,24 +1394,24 @@ Future<Response> post( return Failure("Attempted to do a POST with a Content-Type but no body"); } - Request request; - request.method = "POST"; - request.url = url; - request.keepAlive = false; + Request _request; + _request.method = "POST"; + _request.url = url; + _request.keepAlive = false; if (headers.isSome()) { - request.headers = headers.get(); + _request.headers = headers.get(); } if (body.isSome()) { - request.body = body.get(); + _request.body = body.get(); } if (contentType.isSome()) { - request.headers["Content-Type"] = contentType.get(); + _request.headers["Content-Type"] = contentType.get(); } - return internal::request(request, false); + return request(_request, false); } @@ -1393,16 +1437,16 @@ Future<Response> requestDelete( const URL& url, const Option<Headers>& headers) { - Request request; - request.method = "DELETE"; - request.url = url; - request.keepAlive = false; + Request _request; + _request.method = "DELETE"; + _request.url = url; + _request.keepAlive = false; if (headers.isSome()) { - request.headers = headers.get(); + _request.headers = headers.get(); } - return internal::request(request, false); + return request(_request, false); } @@ -1430,16 +1474,16 @@ Future<Response> get( const URL& url, const Option<Headers>& headers) { - Request request; - request.method = "GET"; - request.url = url; - request.keepAlive = false; + Request _request; + _request.method = "GET"; + _request.url = url; + _request.keepAlive = false; if (headers.isSome()) { - request.headers = headers.get(); + _request.headers = headers.get(); } - return internal::request(request, true); + return request(_request, true); } @@ -1481,24 +1525,24 @@ Future<Response> post( return Failure("Attempted to do a POST with a Content-Type but no body"); } - Request request; - request.method = "POST"; - request.url = url; - request.keepAlive = false; + Request _request; + _request.method = "POST"; + _request.url = url; + _request.keepAlive = false; if (body.isSome()) { - request.body = body.get(); + _request.body = body.get(); } if (headers.isSome()) { - request.headers = headers.get(); + _request.headers = headers.get(); } if (contentType.isSome()) { - request.headers["Content-Type"] = contentType.get(); + _request.headers["Content-Type"] = contentType.get(); } - return internal::request(request, true); + return request(_request, true); } http://git-wip-us.apache.org/repos/asf/mesos/blob/c869b064/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 dfd93d9..410551c 100644 --- a/3rdparty/libprocess/src/tests/http_tests.cpp +++ b/3rdparty/libprocess/src/tests/http_tests.cpp @@ -76,6 +76,7 @@ public: MOCK_METHOD1(body, Future<http::Response>(const http::Request&)); MOCK_METHOD1(pipe, Future<http::Response>(const http::Request&)); + MOCK_METHOD1(request, Future<http::Response>(const http::Request&)); MOCK_METHOD1(get, Future<http::Response>(const http::Request&)); MOCK_METHOD1(post, Future<http::Response>(const http::Request&)); MOCK_METHOD1(requestDelete, Future<http::Response>(const http::Request&)); @@ -91,6 +92,7 @@ protected: { route("/body", None(), &HttpProcess::body); route("/pipe", None(), &HttpProcess::pipe); + route("/request", None(), &HttpProcess::request); route("/get", None(), &HttpProcess::get); route("/post", None(), &HttpProcess::post); route("/delete", None(), &HttpProcess::requestDelete); @@ -730,6 +732,34 @@ TEST(HTTPTest, Delete) } +http::Response validateDeleteHttpRequest(const http::Request& request) +{ + EXPECT_EQ("DELETE", request.method); + EXPECT_THAT(request.url.path, EndsWith("request")); + EXPECT_TRUE(request.body.empty()); + EXPECT_TRUE(request.url.query.empty()); + + return http::OK(); +} + + +TEST(HTTPTest, Request) +{ + Http http; + + EXPECT_CALL(*http.process, request(_)) + .WillOnce(Invoke(validateDeleteHttpRequest)); + + Future<http::Response> future = + http::request(http::createRequest( + http.process->self(), "DELETE", false, "request")); + + AWAIT_READY(future); + ASSERT_EQ(http::Status::OK, future->code); + ASSERT_EQ(http::Status::string(http::Status::OK), future->status); +} + + TEST(HTTPConnectionTest, Serial) { Http http;
