aboutsummaryrefslogtreecommitdiffstats
path: root/libtransport/src/hicn/transport/http
diff options
context:
space:
mode:
Diffstat (limited to 'libtransport/src/hicn/transport/http')
-rwxr-xr-xlibtransport/src/hicn/transport/http/CMakeLists.txt36
-rwxr-xr-xlibtransport/src/hicn/transport/http/callbacks.h46
-rwxr-xr-xlibtransport/src/hicn/transport/http/client_connection.cc194
-rwxr-xr-xlibtransport/src/hicn/transport/http/client_connection.h82
-rwxr-xr-xlibtransport/src/hicn/transport/http/default_values.h32
-rwxr-xr-xlibtransport/src/hicn/transport/http/facade.h22
-rwxr-xr-xlibtransport/src/hicn/transport/http/message.h58
-rwxr-xr-xlibtransport/src/hicn/transport/http/request.cc83
-rwxr-xr-xlibtransport/src/hicn/transport/http/request.h61
-rwxr-xr-xlibtransport/src/hicn/transport/http/response.cc134
-rwxr-xr-xlibtransport/src/hicn/transport/http/response.h58
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_acceptor.cc112
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_acceptor.h62
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_publisher.cc173
-rwxr-xr-xlibtransport/src/hicn/transport/http/server_publisher.h72
15 files changed, 1225 insertions, 0 deletions
diff --git a/libtransport/src/hicn/transport/http/CMakeLists.txt b/libtransport/src/hicn/transport/http/CMakeLists.txt
new file mode 100755
index 000000000..ddcf1fdc3
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/CMakeLists.txt
@@ -0,0 +1,36 @@
+# Copyright (c) 2017-2019 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:
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
+
+list(APPEND SOURCE_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/client_connection.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/request.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/server_publisher.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/server_acceptor.cc
+ ${CMAKE_CURRENT_SOURCE_DIR}/response.cc)
+
+list(APPEND HEADER_FILES
+ ${CMAKE_CURRENT_SOURCE_DIR}/client_connection.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/request.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/server_publisher.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/server_acceptor.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/default_values.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/facade.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/response.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/message.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/callbacks.h
+)
+
+set(SOURCE_FILES ${SOURCE_FILES} PARENT_SCOPE)
+set(HEADER_FILES ${HEADER_FILES} PARENT_SCOPE) \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/callbacks.h b/libtransport/src/hicn/transport/http/callbacks.h
new file mode 100755
index 000000000..5ca5fcbe2
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/callbacks.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/server_publisher.h>
+
+#include <functional>
+#include <memory>
+
+namespace transport {
+
+namespace http {
+
+enum class RC : uint8_t {
+ SUCCESS,
+ CONTENT_PUBLISHED,
+ ERR_UNDEFINED,
+};
+
+using OnHttpRequest =
+ std::function<void(std::shared_ptr<HTTPServerPublisher>&, const uint8_t*,
+ std::size_t, int request_id)>;
+using DeadlineTimerCallback = std::function<void(const std::error_code& e)>;
+using ReceiveCallback = std::function<void(const std::vector<uint8_t>&)>;
+using OnPayloadCallback = std::function<RC(
+ const std::error_code& ec, const core::Name& name,
+ const std::shared_ptr<utils::SharableVector<uint8_t>>& payload)>;
+using ContentSentCallback =
+ std::function<void(const std::error_code&, const core::Name&)>;
+
+} // namespace http
+
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/client_connection.cc b/libtransport/src/hicn/transport/http/client_connection.cc
new file mode 100755
index 000000000..d4207bb81
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/client_connection.cc
@@ -0,0 +1,194 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/http/client_connection.h>
+#include <hicn/transport/utils/hash.h>
+
+#define DEFAULT_BETA 0.99
+#define DEFAULT_GAMMA 0.07
+
+namespace transport {
+
+namespace http {
+
+using namespace transport;
+
+HTTPClientConnection::HTTPClientConnection()
+ : consumer_(TransportProtocolAlgorithms::RAAQM, io_service_),
+ response_(std::make_shared<HTTPResponse>()),
+ timer_(nullptr) {
+ consumer_.setSocketOption(
+ ConsumerCallbacksOptions::CONTENT_OBJECT_TO_VERIFY,
+ (ConsumerContentObjectVerificationCallback)std::bind(
+ &HTTPClientConnection::verifyData, this, std::placeholders::_1,
+ std::placeholders::_2));
+
+ consumer_.setSocketOption(
+ ConsumerCallbacksOptions::CONTENT_RETRIEVED,
+ (ConsumerContentCallback)std::bind(
+ &HTTPClientConnection::processPayload, this, std::placeholders::_1,
+ std::placeholders::_2, std::placeholders::_3));
+
+ consumer_.connect();
+ std::shared_ptr<typename ConsumerSocket::Portal> portal;
+ consumer_.getSocketOption(GeneralTransportOptions::PORTAL, portal);
+ timer_ = std::make_unique<asio::steady_timer>(portal->getIoService());
+}
+
+HTTPClientConnection &HTTPClientConnection::get(
+ const std::string &url, HTTPHeaders headers, HTTPPayload payload,
+ std::shared_ptr<HTTPResponse> response) {
+ return sendRequest(url, HTTPMethod::GET, headers, payload, response);
+}
+
+HTTPClientConnection &HTTPClientConnection::sendRequest(
+ const std::string &url, HTTPMethod method, HTTPHeaders headers,
+ HTTPPayload payload, std::shared_ptr<HTTPResponse> response) {
+ if (!response) {
+ response = response_;
+ }
+
+ auto start = std::chrono::steady_clock::now();
+ HTTPRequest request(method, url, headers, payload);
+ std::string name = sendRequestGetReply(request, response);
+ auto end = std::chrono::steady_clock::now();
+
+ TRANSPORT_LOGI(
+ "%s %s [%s] duration: %llu [usec] %zu [bytes]\n",
+ method_map[method].c_str(), url.c_str(), name.c_str(),
+ (unsigned long long)std::chrono::duration_cast<std::chrono::microseconds>(
+ end - start)
+ .count(),
+ response->size());
+
+ return *this;
+}
+
+std::string HTTPClientConnection::sendRequestGetReply(
+ const HTTPRequest &request, std::shared_ptr<HTTPResponse> &response) {
+ const std::string &request_string = request.getRequestString();
+ const std::string &locator = request.getLocator();
+
+ // Hash it
+
+ uint32_t locator_hash =
+ utils::hash::fnv32_buf(locator.c_str(), locator.size());
+ uint64_t request_hash =
+ utils::hash::fnv64_buf(request_string.c_str(), request_string.size());
+
+ consumer_.setSocketOption(
+ ConsumerCallbacksOptions::INTEREST_OUTPUT,
+ (ConsumerInterestCallback)std::bind(
+ &HTTPClientConnection::processLeavingInterest, this,
+ std::placeholders::_1, std::placeholders::_2, request_string));
+
+ // Send content to producer piggybacking it through first interest (to fix)
+
+ response->clear();
+
+ // Factor hicn name using hash
+
+ std::stringstream stream;
+
+ stream << std::hex << http::default_values::ipv6_first_word << ":";
+
+ for (uint16_t *word = (uint16_t *)&locator_hash;
+ std::size_t(word) < (std::size_t(&locator_hash) + sizeof(locator_hash));
+ word++) {
+ stream << ":" << std::hex << *word;
+ }
+
+ for (uint16_t *word = (uint16_t *)&request_hash;
+ std::size_t(word) < (std::size_t(&request_hash) + sizeof(request_hash));
+ word++) {
+ stream << ":" << std::hex << *word;
+ }
+
+ stream << "|0";
+
+ consumer_.consume(Name(stream.str()), *response);
+
+ consumer_.stop();
+
+ return stream.str();
+}
+
+HTTPResponse &&HTTPClientConnection::response() {
+ // response_->parse();
+ return std::move(*response_);
+}
+
+void HTTPClientConnection::processPayload(ConsumerSocket &c,
+ std::size_t bytes_transferred,
+ const std::error_code &ec) {
+ if (ec) {
+ TRANSPORT_LOGE("Download failed!!");
+ }
+}
+
+bool HTTPClientConnection::verifyData(
+ ConsumerSocket &c, const core::ContentObject &contentObject) {
+ if (contentObject.getPayloadType() == PayloadType::CONTENT_OBJECT) {
+ TRANSPORT_LOGI("VERIFY CONTENT\n");
+ } else if (contentObject.getPayloadType() == PayloadType::MANIFEST) {
+ TRANSPORT_LOGI("VERIFY MANIFEST\n");
+ }
+
+ return true;
+}
+
+void HTTPClientConnection::processLeavingInterest(
+ ConsumerSocket &c, const core::Interest &interest, std::string &payload) {
+ // if (interest.getName().getSuffix() == 0) {
+ Interest &int2 = const_cast<Interest &>(interest);
+ int2.appendPayload((uint8_t *)payload.data(), payload.size());
+ // }
+}
+
+ConsumerSocket &HTTPClientConnection::getConsumer() { return consumer_; }
+
+HTTPClientConnection &HTTPClientConnection::stop() {
+ // This is thread safe and can be called from another thread
+ consumer_.stop();
+
+ return *this;
+}
+
+HTTPClientConnection &HTTPClientConnection::setTimeout(
+ const std::chrono::seconds &timeout) {
+ timer_->cancel();
+ timer_->expires_from_now(timeout);
+ timer_->async_wait([this](std::error_code ec) {
+ if (!ec) {
+ consumer_.stop();
+ }
+ });
+
+ return *this;
+}
+
+HTTPClientConnection &HTTPClientConnection::setCertificate(
+ const std::string &cert_path) {
+ if (consumer_.setSocketOption(GeneralTransportOptions::CERTIFICATE,
+ cert_path) == SOCKET_OPTION_NOT_SET) {
+ throw errors::RuntimeException("Error setting the certificate.");
+ }
+
+ return *this;
+}
+
+} // namespace http
+
+} // namespace transport
diff --git a/libtransport/src/hicn/transport/http/client_connection.h b/libtransport/src/hicn/transport/http/client_connection.h
new file mode 100755
index 000000000..f6e1fa03e
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/client_connection.h
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/default_values.h>
+#include <hicn/transport/http/request.h>
+#include <hicn/transport/http/response.h>
+#include <hicn/transport/interfaces/socket_consumer.h>
+#include <hicn/transport/interfaces/socket_producer.h>
+#include <hicn/transport/utils/uri.h>
+
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+using namespace interface;
+using namespace core;
+
+class HTTPClientConnection {
+ public:
+ HTTPClientConnection();
+
+ HTTPClientConnection &get(const std::string &url, HTTPHeaders headers = {},
+ HTTPPayload payload = {},
+ std::shared_ptr<HTTPResponse> response = nullptr);
+
+ HTTPClientConnection &sendRequest(
+ const std::string &url, HTTPMethod method, HTTPHeaders headers = {},
+ HTTPPayload payload = {},
+ std::shared_ptr<HTTPResponse> response = nullptr);
+
+ HTTPResponse &&response();
+
+ HTTPClientConnection &stop();
+
+ interface::ConsumerSocket &getConsumer();
+
+ HTTPClientConnection &setTimeout(const std::chrono::seconds &timeout);
+
+ HTTPClientConnection &setCertificate(const std::string &cert_path);
+
+ private:
+ void processPayload(interface::ConsumerSocket &c,
+ std::size_t bytes_transferred, const std::error_code &ec);
+
+ std::string sendRequestGetReply(const HTTPRequest &request,
+ std::shared_ptr<HTTPResponse> &response);
+
+ bool verifyData(interface::ConsumerSocket &c,
+ const core::ContentObject &contentObject);
+
+ void processLeavingInterest(interface::ConsumerSocket &c,
+ const core::Interest &interest,
+ std::string &payload);
+
+ asio::io_service io_service_;
+
+ ConsumerSocket consumer_;
+
+ std::shared_ptr<HTTPResponse> response_;
+
+ std::unique_ptr<asio::steady_timer> timer_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/default_values.h b/libtransport/src/hicn/transport/http/default_values.h
new file mode 100755
index 000000000..2d5a6b821
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/default_values.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <cstdint>
+
+namespace transport {
+
+namespace http {
+
+namespace default_values {
+
+const uint16_t ipv6_first_word = 0xb001; // Network byte order
+
+} // namespace default_values
+
+} // namespace http
+
+} // end namespace transport
diff --git a/libtransport/src/hicn/transport/http/facade.h b/libtransport/src/hicn/transport/http/facade.h
new file mode 100755
index 000000000..31c2d1b8d
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/facade.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/transport_http_client_connection.h>
+#include <hicn/transport/http/transport_http_server_acceptor.h>
+#include <hicn/transport/http/transport_http_server_publisher.h>
+
+namespace libl4 = transport; \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/message.h b/libtransport/src/hicn/transport/http/message.h
new file mode 100755
index 000000000..7d4485c90
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/message.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/utils/sharable_vector.h>
+
+#include <map>
+#include <sstream>
+#include <vector>
+
+#define HTTP_VERSION "1.1"
+
+namespace transport {
+
+namespace http {
+
+typedef enum { GET, POST, PUT, PATCH, DELETE } HTTPMethod;
+
+static std::map<HTTPMethod, std::string> method_map = {
+ {GET, "GET"}, {POST, "POST"}, {PUT, "PUT"},
+ {PATCH, "PATCH"}, {DELETE, "DELETE"},
+};
+
+typedef std::map<std::string, std::string> HTTPHeaders;
+typedef std::vector<uint8_t> HTTPPayload;
+
+class HTTPMessage {
+ public:
+ virtual ~HTTPMessage() = default;
+
+ virtual const HTTPHeaders &getHeaders() = 0;
+
+ virtual const HTTPPayload &getPayload() = 0;
+
+ virtual const std::string &getHttpVersion() const = 0;
+
+ protected:
+ HTTPHeaders headers_;
+ HTTPPayload payload_;
+ std::string http_version_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/request.cc b/libtransport/src/hicn/transport/http/request.cc
new file mode 100755
index 000000000..7a63b4f75
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/request.cc
@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/http/request.h>
+#include <hicn/transport/utils/uri.h>
+
+namespace transport {
+
+namespace http {
+
+// std::map<HTTPMethod, std::string> method_map
+
+HTTPRequest::HTTPRequest(HTTPMethod method, const std::string &url,
+ const HTTPHeaders &headers,
+ const HTTPPayload &payload) {
+ utils::Uri uri;
+ uri.parse(url);
+
+ path_ = uri.getPath();
+ query_string_ = uri.getQueryString();
+ protocol_ = uri.getProtocol();
+ locator_ = uri.getLocator();
+ port_ = uri.getPort();
+ http_version_ = HTTP_VERSION;
+
+ headers_ = headers;
+ payload_ = payload;
+
+ std::transform(locator_.begin(), locator_.end(), locator_.begin(), ::tolower);
+
+ std::transform(protocol_.begin(), protocol_.end(), protocol_.begin(),
+ ::tolower);
+
+ std::stringstream stream;
+ stream << method_map[method] << " " << uri.getPath() << " HTTP/"
+ << HTTP_VERSION << "\r\n";
+ for (auto &item : headers) {
+ 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_; }
+
+const std::string &HTTPRequest::getLocator() const { return locator_; }
+
+const std::string &HTTPRequest::getProtocol() const { return protocol_; }
+
+const 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_;
+}
+
+const std::string &HTTPRequest::getHttpVersion() const { return http_version_; }
+
+} // namespace http
+
+} // namespace transport \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/request.h b/libtransport/src/hicn/transport/http/request.h
new file mode 100755
index 000000000..88d67d4ad
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/request.h
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/message.h>
+#include <hicn/transport/utils/sharable_vector.h>
+
+#include <map>
+#include <sstream>
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+class HTTPRequest : public HTTPMessage {
+ public:
+ HTTPRequest(HTTPMethod method, const std::string &url,
+ const HTTPHeaders &headers, const HTTPPayload &payload);
+
+ const std::string &getQueryString() const;
+
+ const std::string &getPath() const;
+
+ const std::string &getProtocol() const;
+
+ const std::string &getLocator() const;
+
+ const std::string &getPort() const;
+
+ const std::string &getRequestString() const;
+
+ const HTTPHeaders &getHeaders() override;
+
+ const HTTPPayload &getPayload() override;
+
+ const std::string &getHttpVersion() const override;
+
+ private:
+ std::string query_string_, path_, protocol_, locator_, port_;
+ std::string request_string_;
+ HTTPHeaders headers_;
+ HTTPPayload payload_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/response.cc b/libtransport/src/hicn/transport/http/response.cc
new file mode 100755
index 000000000..0aa9affe8
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/response.cc
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/errors/errors.h>
+#include <hicn/transport/http/response.h>
+
+#include <algorithm>
+
+#include <cstring>
+
+namespace transport {
+
+namespace http {
+
+HTTPResponse::HTTPResponse() {}
+
+HTTPResponse::HTTPResponse(const HTTPHeaders &headers,
+ const HTTPPayload &payload) {
+ headers_ = headers;
+ payload_ = payload;
+}
+
+const HTTPHeaders &HTTPResponse::getHeaders() {
+ parse();
+ return headers_;
+}
+
+const HTTPPayload &HTTPResponse::getPayload() {
+ parse();
+ return payload_;
+}
+
+bool HTTPResponse::parseHeaders() {
+ const char *crlf2 = "\r\n\r\n";
+ auto it =
+ std::search(this->begin(), this->end(), crlf2, crlf2 + strlen(crlf2));
+
+ if (it != end()) {
+ std::stringstream ss;
+ ss.str(std::string(begin(), it));
+
+ std::string line;
+ getline(ss, line);
+ std::istringstream line_s(line);
+ std::string _http_version;
+ std::string http_version;
+
+ line_s >> _http_version;
+ std::size_t separator;
+ if ((separator = _http_version.find('/')) != std::string::npos) {
+ if (_http_version.substr(0, separator) != "HTTP") {
+ return false;
+ }
+ http_version_ =
+ line.substr(separator + 1, _http_version.length() - separator - 1);
+ } else {
+ return false;
+ }
+
+ std::string status_code, status_string;
+
+ line_s >> status_code_;
+ line_s >> status_string;
+
+ auto _it = std::search(line.begin(), line.end(), status_string.begin(),
+ status_string.end());
+
+ status_string_ = std::string(_it, line.end() - 1);
+
+ std::size_t param_end;
+ std::size_t value_start;
+ while (getline(ss, line)) {
+ if ((param_end = line.find(':')) != std::string::npos) {
+ value_start = param_end + 1;
+ if ((value_start) < line.size()) {
+ if (line[value_start] == ' ') {
+ value_start++;
+ }
+ if (value_start < line.size()) {
+ headers_[line.substr(0, param_end)] =
+ line.substr(value_start, line.size() - value_start - 1);
+ }
+ }
+ } else {
+ return false;
+ }
+ }
+ }
+
+ return true;
+}
+
+void HTTPResponse::parse() {
+ if (!parseHeaders()) {
+ 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<std::vector<uint8_t> *>(this));
+ }
+ }
+}
+
+const std::string &HTTPResponse::getStatusCode() const { return status_code_; }
+
+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
new file mode 100755
index 000000000..e7dec8c40
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/response.h
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/message.h>
+#include <hicn/transport/utils/array.h>
+#include <hicn/transport/utils/sharable_vector.h>
+
+#include <map>
+#include <sstream>
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+class HTTPResponse : public HTTPMessage, public utils::SharableVector<uint8_t> {
+ public:
+ HTTPResponse(const HTTPHeaders &headers, const HTTPPayload &payload);
+
+ HTTPResponse();
+
+ const HTTPHeaders &getHeaders() override;
+
+ const HTTPPayload &getPayload() override;
+
+ const std::string &getStatusCode() const;
+
+ const std::string &getStatusString() const;
+
+ const std::string &getHttpVersion() const override;
+
+ void parse();
+
+ private:
+ bool parseHeaders();
+
+ private:
+ std::string status_code_;
+ std::string status_string_;
+};
+
+} // end namespace http
+
+} // end namespace transport \ No newline at end of file
diff --git a/libtransport/src/hicn/transport/http/server_acceptor.cc b/libtransport/src/hicn/transport/http/server_acceptor.cc
new file mode 100755
index 000000000..717dfb642
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/server_acceptor.cc
@@ -0,0 +1,112 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/http/server_acceptor.h>
+#include <hicn/transport/utils/hash.h>
+#include <hicn/transport/utils/uri.h>
+
+namespace transport {
+
+namespace http {
+
+HTTPServerAcceptor::HTTPServerAcceptor(std::string &&server_locator,
+ OnHttpRequest callback)
+ : HTTPServerAcceptor(server_locator, callback) {}
+
+HTTPServerAcceptor::HTTPServerAcceptor(std::string &server_locator,
+ OnHttpRequest callback)
+ : callback_(callback) {
+ utils::Uri uri;
+
+ uri.parseProtocolAndLocator(server_locator);
+ std::string protocol = uri.getProtocol();
+ std::string locator = uri.getLocator();
+
+ std::transform(locator.begin(), locator.end(), locator.begin(), ::tolower);
+
+ std::transform(protocol.begin(), protocol.end(), protocol.begin(), ::tolower);
+
+ if (protocol != "http") {
+ throw errors::RuntimeException(
+ "Malformed server_locator. The locator format should be in the form "
+ "http://locator");
+ }
+
+ uint32_t locator_hash =
+ utils::hash::fnv32_buf(locator.c_str(), locator.size());
+
+ std::stringstream stream;
+ stream << std::hex << http::default_values::ipv6_first_word << ":0000";
+
+ for (uint16_t *word = (uint16_t *)&locator_hash;
+ std::size_t(word) < (std::size_t(&locator_hash) + sizeof(locator_hash));
+ word++) {
+ stream << ":" << std::hex << *word;
+ }
+
+ stream << "::0";
+
+ std::string network = stream.str();
+
+ core::Prefix acceptor_namespace(network, 64);
+
+ std::string producer_identity = "acceptor_producer";
+ acceptor_producer_ = std::make_shared<ProducerSocket>(
+ io_service_); /*,
+ utils::Identity::generateIdentity(producer_identity));*/
+ acceptor_producer_->registerPrefix(acceptor_namespace);
+}
+
+void HTTPServerAcceptor::listen(bool async) {
+ acceptor_producer_->setSocketOption(
+ ProducerCallbacksOptions::INTEREST_INPUT,
+ (ProducerInterestCallback)bind(
+ &HTTPServerAcceptor::processIncomingInterest, this,
+ std::placeholders::_1, std::placeholders::_2));
+ acceptor_producer_->connect();
+
+ if (!async) {
+ acceptor_producer_->serveForever();
+ }
+}
+
+void HTTPServerAcceptor::processIncomingInterest(ProducerSocket &p,
+ const Interest &interest) {
+ // Temporary solution. With
+ utils::Array<uint8_t> payload = interest.getPayload();
+
+ int request_id = utils::hash::fnv32_buf(payload.data(), payload.length());
+
+ if (publishers_.find(request_id) != publishers_.end()) {
+ if (publishers_[request_id]) {
+ publishers_[request_id]->getProducer().onInterest(interest);
+ return;
+ }
+ }
+
+ publishers_[request_id] =
+ std::make_shared<HTTPServerPublisher>(interest.getName());
+ callback_(publishers_[request_id], (uint8_t *)payload.data(),
+ payload.length(), request_id);
+}
+
+std::map<int, std::shared_ptr<HTTPServerPublisher>>
+ &HTTPServerAcceptor::getPublishers() {
+ return publishers_;
+}
+
+} // namespace http
+
+} // namespace transport
diff --git a/libtransport/src/hicn/transport/http/server_acceptor.h b/libtransport/src/hicn/transport/http/server_acceptor.h
new file mode 100755
index 000000000..549962414
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/server_acceptor.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/callbacks.h>
+#include <hicn/transport/http/default_values.h>
+#include <hicn/transport/http/request.h>
+#include <hicn/transport/http/server_publisher.h>
+#include <hicn/transport/interfaces/socket_consumer.h>
+#include <hicn/transport/interfaces/socket_producer.h>
+
+#include <functional>
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+class HTTPServerAcceptor {
+ friend class HTTPServerPublisher;
+
+ public:
+ HTTPServerAcceptor(std::string &&server_locator, OnHttpRequest callback);
+ HTTPServerAcceptor(std::string &server_locator, OnHttpRequest callback);
+
+ void listen(bool async);
+
+ std::map<int, std::shared_ptr<HTTPServerPublisher>> &getPublishers();
+
+ // void asyncSendResponse();
+
+ // HTTPClientConnection& get(std::string &url, HTTPHeaders headers = {},
+ // HTTPPayload payload = {});
+ //
+ // HTTPResponse&& response();
+
+ private:
+ void processIncomingInterest(ProducerSocket &p, const Interest &interest);
+
+ OnHttpRequest callback_;
+ asio::io_service io_service_;
+ std::shared_ptr<ProducerSocket> acceptor_producer_;
+
+ std::map<int, std::shared_ptr<HTTPServerPublisher>> publishers_;
+};
+
+} // end namespace http
+
+} // end namespace transport
diff --git a/libtransport/src/hicn/transport/http/server_publisher.cc b/libtransport/src/hicn/transport/http/server_publisher.cc
new file mode 100755
index 000000000..012f36091
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/server_publisher.cc
@@ -0,0 +1,173 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <hicn/transport/http/server_publisher.h>
+#include <hicn/transport/utils/literals.h>
+
+namespace transport {
+
+namespace http {
+
+HTTPServerPublisher::HTTPServerPublisher(const core::Name &content_name)
+ : content_name_(content_name, true) {
+ std::string identity = "acceptor_producer";
+ producer_ = std::make_unique<ProducerSocket>(io_service_);
+ // utils::Identity::generateIdentity(identity));
+ core::Prefix publisher_prefix(content_name_, 128);
+ producer_->registerPrefix(publisher_prefix);
+}
+
+HTTPServerPublisher::~HTTPServerPublisher() {
+ if (timer_) {
+ this->timer_->cancel();
+ }
+}
+
+HTTPServerPublisher &HTTPServerPublisher::attachPublisher() {
+ // Create a new publisher
+ producer_->setSocketOption(GeneralTransportOptions::DATA_PACKET_SIZE,
+ 1410_U32);
+ producer_->connect();
+ return *this;
+}
+
+HTTPServerPublisher &HTTPServerPublisher::setTimeout(
+ const std::chrono::milliseconds &timeout, bool timeout_renewal) {
+ std::shared_ptr<typename ProducerSocket::Portal> portal;
+ producer_->getSocketOption(GeneralTransportOptions::PORTAL, portal);
+ timer_ =
+ std::make_unique<asio::steady_timer>(portal->getIoService(), timeout);
+
+ wait_callback_ = [this](const std::error_code &e) {
+ if (!e) {
+ producer_->stop();
+ }
+ };
+
+ if (timeout_renewal) {
+ interest_enter_callback_ = [this, timeout](ProducerSocket &p,
+ const Interest &interest) {
+ this->timer_->cancel();
+ this->timer_->expires_from_now(timeout);
+ this->timer_->async_wait(wait_callback_);
+ };
+
+ producer_->setSocketOption(
+ ProducerCallbacksOptions::CACHE_HIT,
+ (ProducerInterestCallback)interest_enter_callback_);
+ }
+
+ timer_->async_wait(wait_callback_);
+
+ return *this;
+}
+
+void HTTPServerPublisher::publishContent(
+ const uint8_t *buf, size_t buffer_size,
+ std::chrono::milliseconds content_lifetime, bool is_last) {
+ if (producer_) {
+ producer_->setSocketOption(
+ GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME,
+ static_cast<uint32_t>(content_lifetime.count()));
+ producer_->produce(content_name_, buf, buffer_size, is_last);
+ // producer_->setSocketOption(ProducerCallbacksOptions::CACHE_MISS,
+ // [this](ProducerSocket &p, const
+ // core::Interest &interest){
+ // producer_->stop();
+ // });
+ }
+}
+
+template <typename Handler>
+void HTTPServerPublisher::asyncPublishContent(
+ const uint8_t *buf, size_t buffer_size,
+ std::chrono::milliseconds content_lifetime, Handler &&handler,
+ bool is_last) {
+ if (producer_) {
+ producer_->setSocketOption(
+ GeneralTransportOptions::CONTENT_OBJECT_EXPIRY_TIME,
+ static_cast<uint32_t>(content_lifetime.count()));
+ producer_->asyncProduce(content_name_, buf, buffer_size,
+ std::forward<Handler>(handler), is_last);
+ }
+}
+
+void HTTPServerPublisher::serveClients() { producer_->serveForever(); }
+
+void HTTPServerPublisher::stop() {
+ std::shared_ptr<typename ProducerSocket::Portal> portal_ptr;
+ producer_->getSocketOption(GeneralTransportOptions::PORTAL, portal_ptr);
+ portal_ptr->getIoService().stop();
+}
+
+ProducerSocket &HTTPServerPublisher::getProducer() { return *producer_; }
+
+void HTTPServerPublisher::setPublisherName(std::string &name,
+ std::string &mask) {
+ // Name represents the last 64 bits of the ipv6 address.
+ // It is an ipv6 address with the first 64 bits set to 0
+ uint16_t i;
+ std::string s = content_name_.toString();
+ std::shared_ptr<core::Sockaddr> sockaddr = content_name_.getAddress();
+ in6_addr name_ipv6 = ((core::Sockaddr6 *)sockaddr.get())->sin6_addr;
+
+ in6_addr bitmask, new_address, _name;
+
+ if (inet_pton(AF_INET6, mask.c_str(), &bitmask) != 1) {
+ throw errors::RuntimeException("Error during conversion to ipv6 address.");
+ }
+
+ if (inet_pton(AF_INET6, name.c_str(), &_name) != 1) {
+ throw errors::RuntimeException("Error during conversion to ipv6 address.");
+ }
+
+ for (i = 0; i < sizeof(new_address.s6_addr); i++) {
+ new_address.s6_addr[i] = name_ipv6.s6_addr[i] & bitmask.s6_addr[i];
+ }
+
+ for (i = 0; i < sizeof(new_address.s6_addr); i++) {
+ new_address.s6_addr[i] |= _name.s6_addr[i] & ~bitmask.s6_addr[i];
+ }
+
+ // Effectively change the name
+ char str[INET6_ADDRSTRLEN];
+ inet_ntop(AF_INET6, &new_address, str, INET6_ADDRSTRLEN);
+ std::string str2(str);
+
+ core::Name new_name(str2, 0);
+
+ // If the new name differs from the one required by the consumer part, send a
+ // manifest
+ if (!new_name.equals(content_name_, false)) {
+ // Publish manifest pointing to the new name
+
+ auto manifest =
+ std::make_shared<ContentObjectManifest>(content_name_.setSuffix(0));
+
+ content_name_ = core::Name(str2, 0);
+
+ // manifest->setNameList(content_name_);
+ manifest->setLifetime(4000 * 1000);
+ manifest->encode();
+ producer_->produce(*manifest);
+
+ core::Prefix ns(content_name_, 128);
+ producer_->registerPrefix(ns);
+ }
+}
+
+} // namespace http
+
+} // namespace transport
diff --git a/libtransport/src/hicn/transport/http/server_publisher.h b/libtransport/src/hicn/transport/http/server_publisher.h
new file mode 100755
index 000000000..91f7e43e9
--- /dev/null
+++ b/libtransport/src/hicn/transport/http/server_publisher.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2017-2019 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:
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <hicn/transport/http/default_values.h>
+#include <hicn/transport/interfaces/socket_consumer.h>
+#include <hicn/transport/interfaces/socket_producer.h>
+
+#include <functional>
+#include <vector>
+
+namespace transport {
+
+namespace http {
+
+using namespace interface;
+using namespace core;
+
+class HTTPServerPublisher {
+ public:
+ HTTPServerPublisher(const core::Name &content_name);
+
+ ~HTTPServerPublisher();
+
+ void publishContent(const uint8_t *buf, size_t buffer_size,
+ std::chrono::milliseconds content_lifetime, bool is_last);
+
+ template <typename Handler>
+ void asyncPublishContent(const uint8_t *buf, size_t buffer_size,
+ std::chrono::milliseconds content_lifetime,
+ Handler &&handler, bool is_last);
+
+ void serveClients();
+
+ void stop();
+
+ ProducerSocket &getProducer();
+
+ HTTPServerPublisher &setTimeout(const std::chrono::milliseconds &timeout,
+ bool timeout_renewal);
+
+ HTTPServerPublisher &attachPublisher();
+
+ void setPublisherName(std::string &name, std::string &mask);
+
+ private:
+ Name content_name_;
+ std::unique_ptr<asio::steady_timer> timer_;
+ asio::io_service io_service_;
+ std::unique_ptr<ProducerSocket> producer_;
+ ProducerInterestCallback interest_enter_callback_;
+ utils::UserCallback wait_callback_;
+
+ utils::SharableVector<uint8_t> receive_buffer_;
+};
+
+} // end namespace http
+
+} // end namespace transport