Repository: trafficserver Updated Branches: refs/heads/master f5c07af5d -> b4c340033
Fixed async http fetch to support headers and post body Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/79ae4a1f Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/79ae4a1f Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/79ae4a1f Branch: refs/heads/master Commit: 79ae4a1fc37662ae79167beca0533785be63498a Parents: f5c07af Author: Manjesh Nilange <[email protected]> Authored: Thu Mar 6 12:29:23 2014 -0800 Committer: Manjesh Nilange <[email protected]> Committed: Thu Mar 6 12:29:23 2014 -0800 ---------------------------------------------------------------------- .../examples/async_http_fetch/AsyncHttpFetch.cc | 14 +++++-- lib/atscppapi/src/AsyncHttpFetch.cc | 41 +++++++++++++------- lib/atscppapi/src/Headers.cc | 15 ++++++- .../src/include/atscppapi/AsyncHttpFetch.h | 3 ++ lib/atscppapi/src/include/atscppapi/Headers.h | 3 +- 5 files changed, 56 insertions(+), 20 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/79ae4a1f/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc ---------------------------------------------------------------------- diff --git a/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc b/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc index c0b8079..c296dfe 100644 --- a/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc +++ b/lib/atscppapi/examples/async_http_fetch/AsyncHttpFetch.cc @@ -55,12 +55,17 @@ public: void handleSendRequestHeaders(Transaction &transaction) { Async::execute<AsyncHttpFetch>(this, new AsyncHttpFetch("http://127.0.0.1/"), getMutex()); ++num_fetches_pending_; + AsyncHttpFetch *post_request = new AsyncHttpFetch("http://127.0.0.1/post", "data"); + + Async::execute<AsyncHttpFetch>(this, new AsyncHttpFetch("http://127.0.0.1/post", "data"), + getMutex()); + ++num_fetches_pending_; // we'll add some custom headers for this request AsyncHttpFetch2 *provider2 = new AsyncHttpFetch2("http://127.0.0.1/"); Headers &request_headers = provider2->getRequestHeaders(); - request_headers["Header1"] = "Value1"; - request_headers["Header2"] = "Value2"; + request_headers.set("Header1", "Value1"); + request_headers.set("Header2", "Value2"); Async::execute<AsyncHttpFetch2>(this, provider2, getMutex()); ++num_fetches_pending_; } @@ -93,6 +98,7 @@ private: void handleAnyAsyncComplete(AsyncHttpFetch &async_http_fetch) { // This will be called when our async event is complete. + TS_DEBUG(TAG, "Fetch completed for URL [%s]", async_http_fetch.getRequestUrl().getUrlString().c_str()); const Response &response = async_http_fetch.getResponse(); if (async_http_fetch.getResult() == AsyncHttpFetch::RESULT_SUCCESS) { TS_DEBUG(TAG, "Response version is [%s], status code %d, reason phrase [%s]", @@ -104,7 +110,7 @@ private: const void *body; size_t body_size; async_http_fetch.getResponseBody(body, body_size); - TS_DEBUG(TAG, "Response body is [%.*s]", static_cast<int>(body_size), static_cast<const char*>(body)); + TS_DEBUG(TAG, "Response body is [%.*s]", body_size, body); } else { TS_ERROR(TAG, "Fetch did not complete successfully; Result %d", static_cast<int>(async_http_fetch.getResult())); @@ -137,6 +143,6 @@ public: void TSPluginInit(int argc ATSCPPAPI_UNUSED, const char *argv[] ATSCPPAPI_UNUSED) { TS_DEBUG(TAG, "Loaded async_http_fetch_example plugin"); - new GlobalHookPlugin(); + GlobalPlugin *instance = new GlobalHookPlugin(); } http://git-wip-us.apache.org/repos/asf/trafficserver/blob/79ae4a1f/lib/atscppapi/src/AsyncHttpFetch.cc ---------------------------------------------------------------------- diff --git a/lib/atscppapi/src/AsyncHttpFetch.cc b/lib/atscppapi/src/AsyncHttpFetch.cc index 7f40dd2..1ea8b5f 100644 --- a/lib/atscppapi/src/AsyncHttpFetch.cc +++ b/lib/atscppapi/src/AsyncHttpFetch.cc @@ -26,6 +26,8 @@ #include "logging_internal.h" #include "utils_internal.h" +#include <cstdio> + using namespace atscppapi; using std::string; @@ -35,6 +37,7 @@ using std::string; struct atscppapi::AsyncHttpFetchState : noncopyable { Request request_; Response response_; + string request_body_; AsyncHttpFetch::Result result_; const void *body_; size_t body_size_; @@ -42,9 +45,9 @@ struct atscppapi::AsyncHttpFetchState : noncopyable { TSMLoc hdr_loc_; shared_ptr<AsyncDispatchControllerBase> dispatch_controller_; - AsyncHttpFetchState(const string &url_str, HttpMethod http_method) - : request_(url_str, http_method, HTTP_VERSION_1_0), result_(AsyncHttpFetch::RESULT_FAILURE), body_(NULL), - body_size_(0), hdr_buf_(NULL), hdr_loc_(NULL) { } + AsyncHttpFetchState(const string &url_str, HttpMethod http_method, string request_body) + : request_(url_str, http_method, HTTP_VERSION_1_0), request_body_(request_body), + result_(AsyncHttpFetch::RESULT_FAILURE), body_(NULL), body_size_(0), hdr_buf_(NULL), hdr_loc_(NULL) { } ~AsyncHttpFetchState() { if (hdr_loc_) { @@ -102,9 +105,17 @@ static int handleFetchEvents(TSCont cont, TSEvent event, void *edata) { } -AsyncHttpFetch::AsyncHttpFetch(const std::string &url_str, HttpMethod http_method) { +AsyncHttpFetch::AsyncHttpFetch(const string &url_str, const string &request_body) { + init(url_str, HTTP_METHOD_POST, request_body); +} + +AsyncHttpFetch::AsyncHttpFetch(const string &url_str, HttpMethod http_method) { + init(url_str, http_method, ""); +} + +void AsyncHttpFetch::init(const string &url_str, HttpMethod http_method, const string &request_body) { LOG_DEBUG("Created new AsyncHttpFetch object %p", this); - state_ = new AsyncHttpFetchState(url_str, http_method); + state_ = new AsyncHttpFetchState(url_str, http_method, request_body); } void AsyncHttpFetch::run(shared_ptr<AsyncDispatchControllerBase> sender) { @@ -129,16 +140,20 @@ void AsyncHttpFetch::run(shared_ptr<AsyncDispatchControllerBase> sender) { request_str += ' '; request_str += HTTP_VERSION_STRINGS[state_->request_.getVersion()]; request_str += "\r\n"; - - /* for (Headers::const_iterator iter = state_->request_.getHeaders().begin(), - end = state_->request_.getHeaders().end(); iter != end; ++iter) { - request_str += iter->first; - request_str += ": "; - request_str += Headers::getJoinedValues(iter->second); - request_str += "\r\n"; + Headers &headers = state_->request_.getHeaders(); + if (headers.size()) { + // remove the possibility of keep-alive + headers.erase("Connection"); + headers.erase("Proxy-Connection"); + } + if (!state_->request_body_.empty()) { + char size_buf[128]; + snprintf(size_buf, sizeof(size_buf), "%zu", state_->request_body_.size()); + state_->request_.getHeaders().set("Content-Length", size_buf); } -*/ + request_str += headers.str(); request_str += "\r\n"; + request_str += state_->request_body_; LOG_DEBUG("Issing TSFetchUrl with request\n[%s]", request_str.c_str()); TSFetchUrl(request_str.c_str(), request_str.size(), reinterpret_cast<struct sockaddr const *>(&addr), fetchCont, http://git-wip-us.apache.org/repos/asf/trafficserver/blob/79ae4a1f/lib/atscppapi/src/Headers.cc ---------------------------------------------------------------------- diff --git a/lib/atscppapi/src/Headers.cc b/lib/atscppapi/src/Headers.cc index 871fecc..f65ae1e 100644 --- a/lib/atscppapi/src/Headers.cc +++ b/lib/atscppapi/src/Headers.cc @@ -372,11 +372,24 @@ HeaderField header_field_iterator::operator*() { struct HeadersState: noncopyable { TSMBuffer hdr_buf_; TSMLoc hdr_loc_; - HeadersState() : hdr_buf_(NULL), hdr_loc_(NULL) { } + bool self_created_structures_; + HeadersState() { + hdr_buf_ = TSMBufferCreate(); + hdr_loc_ = TSHttpHdrCreate(hdr_buf_); + self_created_structures_ = true; + } void reset(TSMBuffer bufp, TSMLoc hdr_loc) { + if (self_created_structures_) { + TSHandleMLocRelease(hdr_buf_, TS_NULL_MLOC /* no parent */, hdr_loc_); + TSMBufferDestroy(hdr_buf_); + self_created_structures_ = false; + } hdr_buf_ = bufp; hdr_loc_ = hdr_loc; } + ~HeadersState() { + reset(NULL, NULL); + } }; Headers::Headers() { http://git-wip-us.apache.org/repos/asf/trafficserver/blob/79ae4a1f/lib/atscppapi/src/include/atscppapi/AsyncHttpFetch.h ---------------------------------------------------------------------- diff --git a/lib/atscppapi/src/include/atscppapi/AsyncHttpFetch.h b/lib/atscppapi/src/include/atscppapi/AsyncHttpFetch.h index 5355e41..a98e1a6 100644 --- a/lib/atscppapi/src/include/atscppapi/AsyncHttpFetch.h +++ b/lib/atscppapi/src/include/atscppapi/AsyncHttpFetch.h @@ -47,6 +47,8 @@ class AsyncHttpFetch : public AsyncProvider { public: AsyncHttpFetch(const std::string &url_str, HttpMethod http_method = HTTP_METHOD_GET); + AsyncHttpFetch(const std::string &url_str, const std::string &request_body); + /** * Used to manipulate the headers of the request to be made. * @@ -94,6 +96,7 @@ public: private: AsyncHttpFetchState *state_; + void init(const std::string &url_str, HttpMethod http_method, const std::string &request_body); friend class utils::internal; }; http://git-wip-us.apache.org/repos/asf/trafficserver/blob/79ae4a1f/lib/atscppapi/src/include/atscppapi/Headers.h ---------------------------------------------------------------------- diff --git a/lib/atscppapi/src/include/atscppapi/Headers.h b/lib/atscppapi/src/include/atscppapi/Headers.h index 19d46f8..27c1f0a 100644 --- a/lib/atscppapi/src/include/atscppapi/Headers.h +++ b/lib/atscppapi/src/include/atscppapi/Headers.h @@ -396,8 +396,7 @@ public: class Headers: noncopyable { public: /** - * Constructor for Headers, this shouldn't be used directly unless you're trying to mix the C++ and C apis. - * @warning This should only be used if you're mixing the C++ and C apis, it will be constructed automatically if using only the C++ api. + * Constructor for Headers. This creates a "detached" headers, i.e., not tied to any transaction. */ Headers();
