From 46c924b9d2edd84bc6ecb5367ba52fcff82804fa Mon Sep 17 00:00:00 2001 From: Mauro Sardara Date: Tue, 18 Feb 2020 16:21:07 +0100 Subject: [HICN-528] Add progress bar to higet. Change-Id: I645ef2b8834f4310933793fb1f59e8f37e3d6aef Signed-off-by: Mauro Sardara --- .../src/hicn/transport/http/client_connection.cc | 82 +++++++--------------- .../src/hicn/transport/http/client_connection.h | 26 +++---- libtransport/src/hicn/transport/http/message.h | 20 ++++-- libtransport/src/hicn/transport/http/request.cc | 39 ++++------ libtransport/src/hicn/transport/http/request.h | 26 +++---- libtransport/src/hicn/transport/http/response.cc | 60 +++++++--------- libtransport/src/hicn/transport/http/response.h | 17 ++--- libtransport/src/hicn/transport/utils/membuf.h | 9 ++- 8 files changed, 110 insertions(+), 169 deletions(-) (limited to 'libtransport/src/hicn') diff --git a/libtransport/src/hicn/transport/http/client_connection.cc b/libtransport/src/hicn/transport/http/client_connection.cc index aa9cb0463..bd21bc448 100644 --- a/libtransport/src/hicn/transport/http/client_connection.cc +++ b/libtransport/src/hicn/transport/http/client_connection.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -16,8 +16,6 @@ #include #include -#include - #define DEFAULT_BETA 0.99 #define DEFAULT_GAMMA 0.07 @@ -40,12 +38,6 @@ HTTPClientConnection::HTTPClientConnection() std::placeholders::_2)); consumer_.setSocketOption(ConsumerCallbacksOptions::READ_CALLBACK, this); - consumer_.setSocketOption( - ConsumerCallbacksOptions::VERIFICATION_FAILED, - (ConsumerContentObjectVerificationFailedCallback)std::bind( - &HTTPClientConnection::onSignatureVerificationFailed, this, - std::placeholders::_1, std::placeholders::_2, std::placeholders::_3)); - consumer_.setSocketOption(GeneralTransportOptions::VERIFY_SIGNATURE, false); consumer_.connect(); std::shared_ptr portal; @@ -54,31 +46,30 @@ HTTPClientConnection::HTTPClientConnection() } HTTPClientConnection::RC HTTPClientConnection::get( - const std::string &url, HTTPHeaders headers, HTTPPayload payload, + const std::string &url, HTTPHeaders headers, HTTPPayload &&payload, std::shared_ptr response, ReadBytesCallback *callback, std::string ipv6_first_word) { - return sendRequest(url, HTTPMethod::GET, headers, payload, response, callback, - ipv6_first_word); + return sendRequest(url, HTTPMethod::GET, headers, std::move(payload), + response, callback, ipv6_first_word); } HTTPClientConnection::RC HTTPClientConnection::sendRequest( const std::string &url, HTTPMethod method, HTTPHeaders headers, - HTTPPayload payload, std::shared_ptr response, + HTTPPayload &&payload, std::shared_ptr response, ReadBytesCallback *callback, std::string ipv6_first_word) { current_url_ = url; read_bytes_callback_ = callback; if (!response) { - response = response_; + response_ = std::make_shared(); + } else { + response_ = response; } auto start = std::chrono::steady_clock::now(); - HTTPRequest request(method, url, headers, payload); - response->clear(); + request_.init(method, url, headers, std::move(payload)); success_callback_ = [this, method = std::move(method), url = std::move(url), - start = std::move(start), - response = std::move(response)]( - std::size_t size) -> std::shared_ptr { + start = std::move(start)](std::size_t size) -> void { auto end = std::chrono::steady_clock::now(); TRANSPORT_LOGI( "%s %s [%s] duration: %llu [usec] %zu [bytes]\n", @@ -87,23 +78,15 @@ HTTPClientConnection::RC HTTPClientConnection::sendRequest( std::chrono::duration_cast(end - start) .count(), size); - - return response; }; - sendRequestGetReply(request, response, ipv6_first_word); + sendRequestGetReply(ipv6_first_word); return return_code_; } -void HTTPClientConnection::verifyPacketSignature(bool verify) { - consumer_.setSocketOption(GeneralTransportOptions::VERIFY_SIGNATURE, verify); -} - -void HTTPClientConnection::sendRequestGetReply( - const HTTPRequest &request, std::shared_ptr &response, - std::string &ipv6_first_word) { - const std::string &request_string = request.getRequestString(); - const std::string &locator = request.getLocator(); +void HTTPClientConnection::sendRequestGetReply(std::string &ipv6_first_word) { + const std::string &request_string = request_.getRequestString(); + const std::string &locator = request_.getLocator(); // Hash it @@ -116,7 +99,7 @@ void HTTPClientConnection::sendRequestGetReply( ConsumerCallbacksOptions::INTEREST_OUTPUT, (ConsumerInterestCallback)std::bind( &HTTPClientConnection::processLeavingInterest, this, - std::placeholders::_1, std::placeholders::_2, request_string)); + std::placeholders::_1, std::placeholders::_2)); // Factor hicn name using hash name_.str(""); @@ -142,9 +125,9 @@ void HTTPClientConnection::sendRequestGetReply( consumer_.stop(); } -HTTPResponse HTTPClientConnection::response() { - // response_->parse(); - return std::move(*response_); +std::shared_ptr HTTPClientConnection::response() { + response_->coalescePayloadBuffer(); + return response_; } bool HTTPClientConnection::verifyData( @@ -159,10 +142,14 @@ bool HTTPClientConnection::verifyData( } void HTTPClientConnection::processLeavingInterest( - ConsumerSocket &c, const core::Interest &interest, std::string &payload) { + ConsumerSocket &c, const core::Interest &interest) { if (interest.payloadSize() == 0) { Interest &int2 = const_cast(interest); + auto payload = request_.getRequestString(); + auto payload2 = request_.getPayload(); int2.appendPayload((uint8_t *)payload.data(), payload.size()); + if (payload2) + int2.appendPayload((uint8_t *)payload2->data(), payload2->length()); } } @@ -198,21 +185,11 @@ HTTPClientConnection &HTTPClientConnection::setCertificate( return *this; } -VerificationPolicy HTTPClientConnection::onSignatureVerificationFailed( - ConsumerSocket &consumer, const core::ContentObject &content_object, - std::error_code reason) { - return VerificationPolicy::ACCEPT_PACKET; -} - // Read buffer management void HTTPClientConnection::readBufferAvailable( std::unique_ptr &&buffer) noexcept { if (!read_bytes_callback_) { - if (!read_buffer_) { - read_buffer_ = std::move(buffer); - } else { - read_buffer_->prependChain(std::move(buffer)); - } + response_->appendResponseChunk(std::move(buffer)); } else { read_bytes_callback_->onBytesReceived(std::move(buffer)); } @@ -230,18 +207,9 @@ void HTTPClientConnection::readError(const std::error_code ec) noexcept { } void HTTPClientConnection::readSuccess(std::size_t total_size) noexcept { - auto response = success_callback_(total_size); + success_callback_(total_size); if (read_bytes_callback_) { read_bytes_callback_->onSuccess(total_size); - } else { - response->reserve(total_size); - const utils::MemBuf *head = read_buffer_.get(), *current = head; - do { - response->insert(response->end(), current->data(), current->tail()); - current = current->next(); - } while (current != head); - - read_buffer_.reset(); } return_code_ = HTTPClientConnection::RC::DOWNLOAD_SUCCESS; diff --git a/libtransport/src/hicn/transport/http/client_connection.h b/libtransport/src/hicn/transport/http/client_connection.h index e001653ab..e93a37111 100644 --- a/libtransport/src/hicn/transport/http/client_connection.h +++ b/libtransport/src/hicn/transport/http/client_connection.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,7 +20,6 @@ #include #include #include -#include #include #include @@ -48,18 +47,18 @@ class HTTPClientConnection : public ConsumerSocket::ReadCallback { HTTPClientConnection(); RC get(const std::string &url, HTTPHeaders headers = {}, - HTTPPayload payload = {}, + HTTPPayload &&payload = nullptr, std::shared_ptr response = nullptr, ReadBytesCallback *callback = nullptr, std::string ipv6_first_word = "b001"); RC sendRequest(const std::string &url, HTTPMethod method, - HTTPHeaders headers = {}, HTTPPayload payload = {}, + HTTPHeaders headers = {}, HTTPPayload &&payload = nullptr, std::shared_ptr response = nullptr, ReadBytesCallback *callback = nullptr, std::string ipv6_first_word = "b001"); - HTTPResponse response(); + std::shared_ptr response(); HTTPClientConnection &stop(); @@ -69,23 +68,14 @@ class HTTPClientConnection : public ConsumerSocket::ReadCallback { HTTPClientConnection &setCertificate(const std::string &cert_path); - void verifyPacketSignature(bool verify); - private: - void sendRequestGetReply(const HTTPRequest &request, - std::shared_ptr &response, - std::string &ipv6_first_word); + void sendRequestGetReply(std::string &ipv6_first_word); bool verifyData(interface::ConsumerSocket &c, const core::ContentObject &contentObject); void processLeavingInterest(interface::ConsumerSocket &c, - const core::Interest &interest, - std::string &payload); - - VerificationPolicy onSignatureVerificationFailed( - ConsumerSocket &consumer, const core::ContentObject &content_object, - std::error_code reason); + const core::Interest &interest); // Read callback bool isBufferMovable() noexcept override { return true; } @@ -106,7 +96,7 @@ class HTTPClientConnection : public ConsumerSocket::ReadCallback { // The current hICN name used for downloading std::stringstream name_; // Function to be called when the read is successful - std::function(std::size_t)> success_callback_; + std::function success_callback_; // Return code for current download RC return_code_; @@ -115,6 +105,8 @@ class HTTPClientConnection : public ConsumerSocket::ReadCallback { // any byte internally. ReadBytesCallback *read_bytes_callback_; + HTTPRequest request_; + // Internal read buffer and HTTP response, to be used if the application does // not provide any read_bytes_callback std::unique_ptr read_buffer_; diff --git a/libtransport/src/hicn/transport/http/message.h b/libtransport/src/hicn/transport/http/message.h index 270dd3f0e..b8756224f 100644 --- a/libtransport/src/hicn/transport/http/message.h +++ b/libtransport/src/hicn/transport/http/message.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -19,6 +19,8 @@ #include #endif +#include + #include #include #include @@ -37,17 +39,25 @@ static std::map method_map = { }; typedef std::map HTTPHeaders; -typedef std::vector HTTPPayload; +typedef std::unique_ptr HTTPPayload; class HTTPMessage { public: virtual ~HTTPMessage() = default; - virtual const HTTPHeaders &getHeaders() = 0; + const HTTPHeaders getHeaders() { return headers_; }; + + void coalescePayloadBuffer() { + auto it = headers_.find("Content-Length"); + if (it != headers_.end()) { + auto content_length = std::stoul(it->second); + payload_->gather(content_length); + } + } - virtual const HTTPPayload &getPayload() = 0; + HTTPPayload &&getPayload() { return std::move(payload_); } - virtual const std::string &getHttpVersion() const = 0; + std::string getHttpVersion() const { return http_version_; }; protected: HTTPHeaders headers_; diff --git a/libtransport/src/hicn/transport/http/request.cc b/libtransport/src/hicn/transport/http/request.cc index 7a63b4f75..09f709642 100644 --- a/libtransport/src/hicn/transport/http/request.cc +++ b/libtransport/src/hicn/transport/http/request.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -20,11 +20,15 @@ namespace transport { namespace http { -// std::map method_map +HTTPRequest::HTTPRequest() {} HTTPRequest::HTTPRequest(HTTPMethod method, const std::string &url, - const HTTPHeaders &headers, - const HTTPPayload &payload) { + const HTTPHeaders &headers, HTTPPayload &&payload) { + init(method, url, headers, std::move(payload)); +} + +void HTTPRequest::init(HTTPMethod method, const std::string &url, + const HTTPHeaders &headers, HTTPPayload &&payload) { utils::Uri uri; uri.parse(url); @@ -36,7 +40,7 @@ HTTPRequest::HTTPRequest(HTTPMethod method, const std::string &url, http_version_ = HTTP_VERSION; headers_ = headers; - payload_ = payload; + payload_ = std::move(payload); std::transform(locator_.begin(), locator_.end(), locator_.begin(), ::tolower); @@ -50,33 +54,20 @@ HTTPRequest::HTTPRequest(HTTPMethod method, const std::string &url, stream << item.first << ": " << item.second << "\r\n"; } stream << "\r\n"; - - if (payload.size() > 0) { - stream << payload.data(); - } - request_string_ = stream.str(); } -const std::string &HTTPRequest::getPort() const { return port_; } +std::string HTTPRequest::getPort() const { return port_; } -const std::string &HTTPRequest::getLocator() const { return locator_; } +std::string HTTPRequest::getLocator() const { return locator_; } -const std::string &HTTPRequest::getProtocol() const { return protocol_; } +std::string HTTPRequest::getProtocol() const { return protocol_; } -const std::string &HTTPRequest::getPath() const { return path_; } +std::string HTTPRequest::getPath() const { return path_; } -const std::string &HTTPRequest::getQueryString() const { return query_string_; } - -const HTTPHeaders &HTTPRequest::getHeaders() { return headers_; } - -const HTTPPayload &HTTPRequest::getPayload() { return payload_; } - -const std::string &HTTPRequest::getRequestString() const { - return request_string_; -} +std::string HTTPRequest::getQueryString() const { return query_string_; } -const std::string &HTTPRequest::getHttpVersion() const { return http_version_; } +std::string HTTPRequest::getRequestString() const { return request_string_; } } // namespace http diff --git a/libtransport/src/hicn/transport/http/request.h b/libtransport/src/hicn/transport/http/request.h index 1202144c0..54904d696 100644 --- a/libtransport/src/hicn/transport/http/request.h +++ b/libtransport/src/hicn/transport/http/request.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -27,32 +27,28 @@ namespace http { class HTTPRequest : public HTTPMessage { public: + HTTPRequest(); HTTPRequest(HTTPMethod method, const std::string &url, - const HTTPHeaders &headers, const HTTPPayload &payload); + const HTTPHeaders &headers, HTTPPayload &&payload); - const std::string &getQueryString() const; + void init(HTTPMethod method, const std::string &url, + const HTTPHeaders &headers, HTTPPayload &&payload); - const std::string &getPath() const; + std::string getQueryString() const; - const std::string &getProtocol() const; + std::string getPath() const; - const std::string &getLocator() const; + std::string getProtocol() const; - const std::string &getPort() const; + std::string getLocator() const; - const std::string &getRequestString() const; + std::string getPort() const; - const HTTPHeaders &getHeaders() override; - - const HTTPPayload &getPayload() override; - - const std::string &getHttpVersion() const override; + std::string getRequestString() const; private: std::string query_string_, path_, protocol_, locator_, port_; std::string request_string_; - HTTPHeaders headers_; - HTTPPayload payload_; }; } // end namespace http diff --git a/libtransport/src/hicn/transport/http/response.cc b/libtransport/src/hicn/transport/http/response.cc index db7306cca..a2bc47e6b 100644 --- a/libtransport/src/hicn/transport/http/response.cc +++ b/libtransport/src/hicn/transport/http/response.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -16,7 +16,8 @@ #include #include -#include +#include +#include #include @@ -26,30 +27,32 @@ namespace http { HTTPResponse::HTTPResponse() {} -HTTPResponse::HTTPResponse(const HTTPHeaders &headers, - const HTTPPayload &payload) { - headers_ = headers; - payload_ = payload; +HTTPResponse::HTTPResponse(std::unique_ptr &&response) { + parse(std::move(response)); } -const HTTPHeaders &HTTPResponse::getHeaders() { - parse(); - return headers_; -} - -const HTTPPayload &HTTPResponse::getPayload() { - parse(); - return payload_; +void HTTPResponse::appendResponseChunk( + std::unique_ptr &&response_chunk) { + if (headers_.empty()) { + parse(std::move(response_chunk)); + } else { + payload_->prependChain(std::move(response_chunk)); + } } -bool HTTPResponse::parseHeaders() { +bool HTTPResponse::parseHeaders(std::unique_ptr &&buffer) { const char *crlf2 = "\r\n\r\n"; + const char *begin = (const char *)buffer->data(); + const char *end = begin + buffer->length(); auto it = - std::search(this->begin(), this->end(), crlf2, crlf2 + strlen(crlf2)); + std::experimental::search(begin, end, + std::experimental::make_boyer_moore_searcher( + crlf2, crlf2 + strlen(crlf2))); - if (it != end()) { + if (it != end) { + buffer->trimStart(it + strlen(crlf2) - begin); std::stringstream ss; - ss.str(std::string(begin(), it + 1)); + ss.str(std::string(begin, it)); std::string line; getline(ss, line); @@ -99,24 +102,15 @@ bool HTTPResponse::parseHeaders() { } } + payload_ = std::move(buffer); + return true; } -void HTTPResponse::parse() { - if (!parseHeaders()) { +void HTTPResponse::parse(std::unique_ptr &&response) { + if (!parseHeaders(std::move(response))) { throw errors::RuntimeException("Malformed HTTP response"); } - - if (payload_.empty()) { - const char *crlf2 = "\r\n\r\n"; - auto it = - std::search(this->begin(), this->end(), crlf2, crlf2 + strlen(crlf2)); - - if (it != this->end()) { - erase(begin(), it + strlen(crlf2)); - payload_ = std::move(*dynamic_cast *>(this)); - } - } } const std::string &HTTPResponse::getStatusCode() const { return status_code_; } @@ -125,10 +119,6 @@ const std::string &HTTPResponse::getStatusString() const { return status_string_; } -const std::string &HTTPResponse::getHttpVersion() const { - return http_version_; -} - } // namespace http } // namespace transport \ No newline at end of file diff --git a/libtransport/src/hicn/transport/http/response.h b/libtransport/src/hicn/transport/http/response.h index b261a128a..7ef655059 100644 --- a/libtransport/src/hicn/transport/http/response.h +++ b/libtransport/src/hicn/transport/http/response.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019 Cisco and/or its affiliates. + * Copyright (c) 2017-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -26,26 +26,21 @@ namespace transport { namespace http { -class HTTPResponse : public HTTPMessage, public std::vector { +class HTTPResponse : public HTTPMessage { public: - HTTPResponse(const HTTPHeaders &headers, const HTTPPayload &payload); - HTTPResponse(); - const HTTPHeaders &getHeaders() override; + HTTPResponse(std::unique_ptr &&response); - const HTTPPayload &getPayload() override; + void appendResponseChunk(std::unique_ptr &&response_chunk); const std::string &getStatusCode() const; const std::string &getStatusString() const; - const std::string &getHttpVersion() const override; - - void parse(); + void parse(std::unique_ptr &&response); - private: - bool parseHeaders(); + bool parseHeaders(std::unique_ptr &&buffer); private: std::string status_code_; diff --git a/libtransport/src/hicn/transport/utils/membuf.h b/libtransport/src/hicn/transport/utils/membuf.h index 66e9d7afa..9fc37dd25 100644 --- a/libtransport/src/hicn/transport/utils/membuf.h +++ b/libtransport/src/hicn/transport/utils/membuf.h @@ -526,12 +526,11 @@ class MemBuf { // * // * Returns ByteRange that points to the data MemBuf stores. // */ - // ByteRange coalesceWithHeadroomTailroom( - // std::size_t newHeadroom, - // std::size_t newTailroom) { + // ByteRange coalesceWithHeadroomTailroom(std::size_t newHeadroom, + // std::size_t newTailroom) { // if (isChained()) { - // coalesceAndReallocate( - // newHeadroom, computeChainDataLength(), this, newTailroom); + // coalesceAndReallocate(newHeadroom, computeChainDataLength(), this, + // newTailroom); // } // return ByteRange(data_, length_); // } -- cgit 1.2.3-korg