aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Sardara <msardara+fdio@cisco.com>2018-02-16 17:53:36 +0100
committerMauro Sardara <msardara+fdio@cisco.com>2018-02-16 18:18:16 +0100
commita81921f0fd4296f8def24665174062782b3480be (patch)
treed645459d7fb1fa1b76159cc548af71cce85dd343
parent0475d783825a6f649853da581df5d812cf5f3bae (diff)
Added reverse proxy (TCP --> ICN) functionality
Change-Id: I2305aa11aea4a37d3d63c6399c49389f78dfd91c Signed-off-by: Mauro Sardara <msardara+fdio@cisco.com>
-rw-r--r--CMakeLists.txt101
-rw-r--r--cmake/Modules/FindLibhicnet.cmake39
-rw-r--r--config.h.in3
-rw-r--r--dockerfile.ubuntu.xenial4
-rw-r--r--http-client/http_client.h24
-rw-r--r--http-client/http_client_icn.cc41
-rw-r--r--http-client/http_client_icn.h34
-rw-r--r--http-client/http_client_tcp.cc99
-rw-r--r--http-client/http_client_tcp.h35
-rw-r--r--http-server/common.h16
-rw-r--r--http-server/configuration.h5
-rw-r--r--http-server/content.h5
-rw-r--r--http-server/http_server.cc56
-rw-r--r--http-server/http_server.h12
-rw-r--r--http-server/icn_request.h9
-rw-r--r--http-server/icn_response.cc10
-rw-r--r--http-server/icn_response.h11
-rw-r--r--http-server/request.h7
-rw-r--r--http-server/response.cc1
-rw-r--r--http-server/response.h13
-rw-r--r--http-server/socket_request.h5
-rw-r--r--http-server/socket_response.h5
-rw-r--r--main.cc98
-rw-r--r--scripts/build-package.sh8
24 files changed, 414 insertions, 227 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8b51e1b3..674f0386 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -23,66 +23,93 @@ endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
option(ICNET "Link against Libicnet." ON)
-option(HICNET "Link against Libhicnet." OFF)
-if (HICNET)
- find_package(Libhicnet REQUIRED)
- set(TRANSPORT_LIBRARY HICNET)
- set(ICNET OFF)
- set(PREFIX "hicn-")
-else()
- find_package(Libicnet REQUIRED)
- set(TRANSPORT_LIBRARY ICNET)
- set(PREFIX "")
-endif()
+find_package(Libicnet REQUIRED)
+set(TRANSPORT_LIBRARY ICNET)
+set(PREFIX "")
configure_file("${PROJECT_SOURCE_DIR}/config.h.in"
"${CMAKE_BINARY_DIR}/config.h")
-include_directories(${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIRS} http-server http-client)
-
-find_package(Threads REQUIRED)
-
-find_package(CURL REQUIRED)
-include_directories(${CURL_INCLUDE_DIRS})
+include_directories(${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIRS})
+
+if(ANDROID_API)
+ find_package(Threads REQUIRED)
+ set(CURL_INCLUDE_DIRS "$ENV{DISTILLERY_ROOT_DIR}/external/libcurl_android/jni/libcurl/include")
+ set(CURL_LIBRARIES "$ENV{DISTILLERY_ROOT_DIR}/usr/lib/libcurl.a" "$ENV{DISTILLERY_ROOT_DIR}/usr/lib/libcurl-library.a")
+ find_package(Boost 1.53.0 COMPONENTS regex system filesystem REQUIRED)
+ include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${CMAKE_BINARY_DIR} ${CURL_INCLUDE_DIRS} ${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIR} http-server http-client)
+ include_directories(${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.9/include)
+ include_directories(${ANDROID_NDK}/sources/cxx-stl/gnu-libstdc++/4.9/libs/armeabi/include)
+ set(ANDROID_LIBRARIES "${ANDROID_NDK}/platforms/android-24/arch-arm/usr/lib/libz.a" "${ANDROID_NDK}/platforms/android-24/arch-arm/usr/lib/liblog.so" "$ENV{NDK}/sources/cxx-stl/gnu-libstdc++/4.9/libs/$ENV{ABI}/libgnustl_shared.so")
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} ${ANDROID_C_FLAGS} -Wall")
+else()
+ find_package(Threads REQUIRED)
-find_package(Boost 1.53.0 COMPONENTS regex system filesystem REQUIRED)
-include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${CMAKE_BINARY_DIR} ${CURL_INCLUDE_DIRS} ${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIR})
+ find_package(CURL REQUIRED)
+ include_directories(${CURL_INCLUDE_DIRS})
-set(SOURCE_FILES
- main.cc
+ find_package(Boost 1.53.0 COMPONENTS regex system filesystem REQUIRED)
+ include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${CMAKE_BINARY_DIR} ${CURL_INCLUDE_DIRS} ${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIR} http-server http-client)
+endif()
+set(LIB_SOURCE_FILES
http-server/http_server.cc
- http-server/http_server.h
http-server/response.cc
- http-server/response.h
- http-server/common.h
http-server/socket_response.cc
- http-server/socket_response.h
http-server/icn_response.cc
- http-server/icn_response.h
http-server/content.cc
- http-server/content.h
http-server/request.cc
- http-server/request.h
http-server/icn_request.cc
- http-server/icn_request.h
http-server/socket_request.cc
- http-server/socket_request.h
http-server/configuration.cc
+ http-client/http_client_tcp.cc
+ http-client/http_client_icn.cc)
+
+set(LIB_SERVER_HEADER_FILES
+ http-server/http_server.h
+ http-server/response.h
+ http-server/common.h
+ http-server/socket_response.h
+ http-server/content.h
+ http-server/request.h
+ http-server/icn_request.h
+ http-server/socket_request.h
http-server/configuration.h
- http-client/http_client.cc
- http-client/http_client.h
- ${CMAKE_BINARY_DIR}/config.h)
+ ${CMAKE_BINARY_DIR}/config.h
+ http-server/icn_response.h)
+
+set(LIB_CLIENT_HEADER_FILES
+ http-client/http_client_tcp.h
+ http-client/http_client_icn.h
+ http-client/http_client.h)
+
+set(APP_SOURCE_FILES
+ main.cc)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_CXX_FLAGS}")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS} -fpermissive")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS} -fpermissive")
set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_CXX_FLAGS} -fpermissive")
-add_executable(${PREFIX}http-server ${SOURCE_FILES})
-target_link_libraries(${PREFIX}http-server ${LIB${TRANSPORT_LIBRARY}_LIBRARY} ${CURL_LIBRARY} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+add_library(${PREFIX}httpserver ${LIB_SOURCE_FILES})
+
+if(ANDROID_API)
+ target_link_libraries(${PREFIX}httpserver ${LIB${TRANSPORT_LIBRARY}_LIBRARY} ${CURL_LIBRARY} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${ANDROID_LIBRARIES} )
+ target_compile_definitions(${PREFIX}httpserver PRIVATE ${TRANSPORT_LIBRARY}=1)
+else()
+
+ target_link_libraries(${PREFIX}httpserver ${LIB${TRANSPORT_LIBRARY}_LIBRARY} ${CURL_LIBRARY} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+
+ add_executable(${PREFIX}http-server ${APP_SOURCE_FILES})
+ target_link_libraries(${PREFIX}http-server ${PREFIX}httpserver)
+ install(TARGETS ${PREFIX}http-server DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
+endif()
+
+install(TARGETS ${PREFIX}httpserver DESTINATION ${CMAKE_INSTALL_PREFIX}/lib)
+
+install(FILES ${LIB_SERVER_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/http-server)
+install(FILES ${LIB_CLIENT_HEADER_FILES} DESTINATION ${CMAKE_INSTALL_PREFIX}/include/http-client)
-install(TARGETS ${PREFIX}http-server DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
# Generate DEB / RPM packages
@@ -104,7 +131,7 @@ set(CPACK_PACKAGE_CONTACT ${CONTACT})
# Get the version
execute_process(COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/version
OUTPUT_VARIABLE PACKAGE_VERSION)
-string(STRIP ${PACKAGE_VERSION} PACKAGE_VERSION)
+string(STRIP "${PACKAGE_VERSION}" PACKAGE_VERSION)
string(TOLOWER ${TRANSPORT_LIBRARY} TRANSPORT_DEPENDENCY)
diff --git a/cmake/Modules/FindLibhicnet.cmake b/cmake/Modules/FindLibhicnet.cmake
deleted file mode 100644
index 0d4f5fbc..00000000
--- a/cmake/Modules/FindLibhicnet.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-########################################
-#
-# Find the Libhicnet libraries and includes
-# This module sets:
-# LIBHICNET_FOUND: True if Libconsumer-producer was found
-# LIBHICNETR_LIBRARY: The Libconsumer-producer library
-# LIBHICNET_LIBRARIES: The Libconsumer-producer library and dependencies
-# LIBHICNET_INCLUDE_DIR: The Libconsumer-producer include dir
-#
-
-set(LIBHICNET_SEARCH_PATH_LIST
- ${LIBHICNET_HOME}
- $ENV{LIBHICNETHOME}
- $ENV{CCNX_HOME}
- $ENV{PARC_HOME}
- $ENV{FOUNDATION_HOME}
- /usr/local/parc
- /usr/local/ccnx
- /usr/local/ccn
- /usr/local
- /opt
- /usr
- )
-
-find_path(LIBHICNET_INCLUDE_DIR hicnet/hicnet_core_common.h
- HINTS ${LIBHICNET_SEARCH_PATH_LIST}
- PATH_SUFFIXES include
- DOC "Find the libhicnet includes")
-
-find_library(LIBHICNET_LIBRARY NAMES hicnet
- HINTS ${LIBHICNET_SEARCH_PATH_LIST}
- PATH_SUFFIXES lib
- DOC "Find the libhicnet libraries")
-
-set(LIBHICNET_LIBRARIES ${LIBHICNET_LIBRARY})
-set(LIBHICNET_INCLUDE_DIRS ${LIBHICNET_INCLUDE_DIR})
-
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(Libhicnet DEFAULT_MSG LIBHICNET_LIBRARY LIBHICNET_INCLUDE_DIR)
diff --git a/config.h.in b/config.h.in
index d10e62ee..ac3f5f2d 100644
--- a/config.h.in
+++ b/config.h.in
@@ -15,5 +15,4 @@
#pragma once
-#cmakedefine ICNET
-#cmakedefine HICNET
+#cmakedefine ICNET \ No newline at end of file
diff --git a/dockerfile.ubuntu.xenial b/dockerfile.ubuntu.xenial
index 42f141c5..362eff41 100644
--- a/dockerfile.ubuntu.xenial
+++ b/dockerfile.ubuntu.xenial
@@ -11,12 +11,12 @@ RUN \
sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
apt-get update && \
apt-get -y upgrade && \
- apt-get install -y git build-essential curl software-properties-common apt-transport-https nano && \
+ apt-get install -y git build-essential curl software-properties-common apt-transport-https git-core && \
echo "deb [trusted=yes] http://nexus.fd.io/content/repositories/fd.io.master.ubuntu.xenial.main ./" | tee /etc/apt/sources.list.d/99fd.io.master.list && \
sh -c "echo 'deb http://archive.getdeb.net/ubuntu xenial-getdeb apps' >> /etc/apt/sources.list.d/getdeb.list" && \
echo "deb [trusted=yes] https://engci-maven-master.cisco.com/artifactory/icn-debian xenial main" | tee /etc/apt/sources.list.d/artifactory.icndebian.list && \
apt-get update && \
- apt-get install -y git-core build-essential \
+ apt-get install -y git-core build-essential nano \
libhicnet-dev libhicn-dev libcurl4-openssl-dev \
libboost-system-dev libboost-regex-dev libboost-filesystem-dev && \
rm -rf /var/lib/apt/lists/*
diff --git a/http-client/http_client.h b/http-client/http_client.h
index 19d3c41e..9bd998bd 100644
--- a/http-client/http_client.h
+++ b/http-client/http_client.h
@@ -13,23 +13,19 @@
* limitations under the License.
*/
-#ifndef HTTP_CLIENT_H_
-#define HTTP_CLIENT_H_
+#pragma once
+
+#include "config.h"
#include <string>
+# include <icnet/icnet_http_facade.h>
+
class HTTPClient {
public:
- HTTPClient();
- ~HTTPClient();
- /**
- * Download a file using HTTP GET and store in in a std::string
- * @param url The URL to download
- * @return The download result
- */
- bool download(const std::string& url, std::ostream& out);
- private:
- void* curl_;
-};
+ virtual ~HTTPClient() = default;
-#endif // HTTP_CLIENT_H_ \ No newline at end of file
+ virtual void setTcp() = 0;
+
+ virtual bool download(const std::string &url, std::ostream &out) = 0;
+};
diff --git a/http-client/http_client_icn.cc b/http-client/http_client_icn.cc
new file mode 100644
index 00000000..88294f80
--- /dev/null
+++ b/http-client/http_client_icn.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2017 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 "http_client_icn.h"
+#include "response.h"
+
+#include <curl/curl.h>
+
+using namespace std;
+
+HTTPClientIcn::HTTPClientIcn(uint32_t timeout) {
+ std::chrono::seconds _timeout(timeout);
+ connection_.setTimeout(_timeout);
+}
+
+void HTTPClientIcn::setTcp() {
+
+}
+
+HTTPClientIcn::~HTTPClientIcn() {
+
+}
+
+bool HTTPClientIcn::download(const std::string& url, std::ostream& out) {
+ connection_.get(url);
+ libl4::http::HTTPResponse r = connection_.response();
+ out.write(reinterpret_cast<const char*>(r.data()), r.size());
+ return true;
+}
diff --git a/http-client/http_client_icn.h b/http-client/http_client_icn.h
new file mode 100644
index 00000000..67cc499c
--- /dev/null
+++ b/http-client/http_client_icn.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2017 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 "http_client.h"
+
+#include <string>
+
+class HTTPClientIcn : public HTTPClient {
+ public:
+ HTTPClientIcn(uint32_t timeout);
+
+ void setTcp();
+
+ ~HTTPClientIcn();
+
+ bool download(const std::string &url, std::ostream &out);
+ private:
+ libl4::http::HTTPClientConnection connection_;
+
+};
diff --git a/http-client/http_client_tcp.cc b/http-client/http_client_tcp.cc
new file mode 100644
index 00000000..ec83cd66
--- /dev/null
+++ b/http-client/http_client_tcp.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2017 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 "http_client_tcp.h"
+#include "response.h"
+
+#include <curl/curl.h>
+#include <sstream>
+#include <iostream>
+#include <string.h>
+#include <stdio.h>
+
+using namespace std;
+
+struct UserData {
+ void * out;
+ void * curl;
+ bool tcp;
+ bool first_time;
+};
+
+typedef struct UserData UserData;
+
+size_t write_data(void *ptr, size_t size, size_t nmemb, void *user_data) {
+
+ UserData *data = (UserData *) user_data;
+
+ if(data->tcp && data->first_time) {
+ double cl;
+
+ int res = curl_easy_getinfo(data->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &cl);
+
+ if(res >= 0){
+ *(ostream *)data->out << "HTTP/1.0 200 OK\r\nContent-Length: " << std::size_t(cl) << "\r\n\r\n";
+ }
+
+ data->first_time = false;
+ }
+
+ ((icn_httpserver::Response*) data->out)->write((const char*)ptr, size * nmemb);
+// ((icn_httpserver::Response*) data->out)->send();
+ return size * nmemb;
+}
+
+HTTPClientTcp::HTTPClientTcp() {
+ tcp_ = false;
+ first_time = true;
+ curl_ = curl_easy_init();
+}
+
+void HTTPClientTcp::setTcp() {
+ tcp_ = true;
+}
+
+HTTPClientTcp::~HTTPClientTcp() {
+ curl_easy_cleanup(curl_);
+}
+
+bool HTTPClientTcp::download(const std::string& url, std::ostream& out) {
+ curl_easy_setopt(curl_, CURLOPT_URL, url.c_str());
+
+ /* example.com is redirected, so we tell libcurl to follow redirection */
+ curl_easy_setopt(curl_, CURLOPT_FOLLOWLOCATION, 1L);
+ curl_easy_setopt(curl_, CURLOPT_NOSIGNAL, 1);
+ curl_easy_setopt(curl_, CURLOPT_ACCEPT_ENCODING, "deflate");
+
+ curl_easy_setopt(curl_, CURLOPT_WRITEFUNCTION, write_data);
+ UserData data;
+ data.out = &out;
+ data.curl = curl_;
+ data.tcp = tcp_;
+ data.first_time = first_time;
+
+ curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &data);
+
+ /* Perform the request, res will get the return code */
+ CURLcode res = curl_easy_perform(curl_);
+
+ /* Check for errors */
+ if (res != CURLE_OK) {
+ fprintf(stderr, "curl_easy_perform() failed: %s\n",
+ curl_easy_strerror(res));
+ return false;
+ }
+
+ return true;
+}
diff --git a/http-client/http_client_tcp.h b/http-client/http_client_tcp.h
new file mode 100644
index 00000000..b8324717
--- /dev/null
+++ b/http-client/http_client_tcp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2017 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 "http_client.h"
+
+#include <string>
+
+class HTTPClientTcp : public HTTPClient {
+ public:
+ HTTPClientTcp();
+
+ void setTcp();
+
+ ~HTTPClientTcp();
+
+ bool download(const std::string& url, std::ostream& out);
+ private:
+ bool first_time;
+ bool tcp_;
+ void* curl_;
+};
diff --git a/http-server/common.h b/http-server/common.h
index 580f8a41..3d88fc42 100644
--- a/http-server/common.h
+++ b/http-server/common.h
@@ -13,20 +13,12 @@
* limitations under the License.
*/
-#ifndef ICN_WEB_SERVER_COMMON_H_
-#define ICN_WEB_SERVER_COMMON_H_
+#pragma once
#include "config.h"
-#if defined(HICNET)
- #include <hicnet/hicnet_http_facade.h>
- #include <hicnet/hicnet_utils_hash.h>
-#elif defined(ICNET)
- #include <icnet/icnet_http_facade.h>
- #include <icnet/icnet_utils_hash.h>
-#else
- #error "No ICN tranport library to which link against."
-#endif
+#include <icnet/icnet_http_facade.h>
+#include <icnet/icnet_utils_hash.h>
#include <boost/asio.hpp>
#include <boost/regex.hpp>
@@ -45,5 +37,3 @@
typedef boost::asio::ip::tcp::socket socket_type;
typedef std::function<void(const boost::system::error_code &)> SendCallback;
-
-#endif // ICN_WEB_SERVER_COMMON_H_
diff --git a/http-server/configuration.h b/http-server/configuration.h
index 65d3170a..8939fb75 100644
--- a/http-server/configuration.h
+++ b/http-server/configuration.h
@@ -13,8 +13,7 @@
* limitations under the License.
*/
-#ifndef ICN_WEB_SERVER_CONFIGURATION_H_
-#define ICN_WEB_SERVER_CONFIGURATION_H_
+#pragma once
#include "common.h"
@@ -48,5 +47,3 @@ class Configuration {
};
} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_CONFIGURATION_H_
diff --git a/http-server/content.h b/http-server/content.h
index a81ad643..4e2fe74f 100644
--- a/http-server/content.h
+++ b/http-server/content.h
@@ -15,8 +15,7 @@
#include "common.h"
-#ifndef ICN_WEB_SERVER_CONTENT_H_
-#define ICN_WEB_SERVER_CONTENT_H_
+#pragma once
namespace icn_httpserver {
@@ -34,5 +33,3 @@ class Content
};
} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_CONTENT_H_
diff --git a/http-server/http_server.cc b/http-server/http_server.cc
index 478d072e..a0ec905f 100644
--- a/http-server/http_server.cc
+++ b/http-server/http_server.cc
@@ -23,11 +23,13 @@
*/
#include "http_server.h"
-
namespace icn_httpserver {
HttpServer::HttpServer(unsigned short port,
- std::string icn_name, size_t num_threads, long timeout_request, long timeout_send_or_receive)
+ std::string icn_name,
+ size_t num_threads,
+ long timeout_request,
+ long timeout_send_or_receive)
: config_(port, num_threads),
icn_name_(icn_name),
internal_io_service_(std::make_shared<boost::asio::io_service>()),
@@ -53,7 +55,8 @@ HttpServer::HttpServer(unsigned short port,
void HttpServer::onIcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher> &publisher,
const uint8_t *buffer,
- std::size_t size) {
+ std::size_t size,
+ int request_id) {
std::shared_ptr<Request> request = std::make_shared<IcnRequest>(publisher);
request->getContent().rdbuf()->sputn((char*)buffer, size);
@@ -61,29 +64,21 @@ void HttpServer::onIcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>
return;
}
- int request_id = libl4::utils::Hash::hash32(buffer, size);
-
- std::cout << "Request ID" << request_id << std::endl;
+ std::map<int, std::shared_ptr<libl4::http::HTTPServerPublisher>>& icn_publishers = icn_acceptor_->getPublishers();
std::unique_lock<std::mutex> lock(thread_list_mtx_);
- if (icn_publishers_.size() < config_.getNum_threads()) {
- if (icn_publishers_.find(request_id) == icn_publishers_.end()) {
+ if (icn_publishers.size() < config_.getNum_threads()) {
std::cout << "Received request for: " << request->getPath() << std::endl;
- icn_publishers_[request_id] = publisher;
- icn_publishers_[request_id]->attachPublisher();
- if (request->getPath().substr(request->getPath().find_last_of(".") + 1) == "mpd") {
- icn_publishers_[request_id]->setTimeout(1);
- } else {
- icn_publishers_[request_id]->setTimeout(5);
- }
+
+ publisher->attachPublisher();
std::cout << "Starting new thread" << std::endl;
io_service_.dispatch([this, request, request_id]() {
+ std::map<int, std::shared_ptr<libl4::http::HTTPServerPublisher>>& icn_publishers = icn_acceptor_->getPublishers();
find_resource(nullptr, request);
- icn_publishers_[request_id]->serveClients();
+ icn_publishers[request_id]->serveClients();
std::unique_lock<std::mutex> lock(thread_list_mtx_);
- icn_publishers_.erase(request_id);
+ icn_publishers.erase(request_id);
});
- }
}
}
@@ -92,7 +87,8 @@ void HttpServer::setIcnAcceptor() {
this,
std::placeholders::_1,
std::placeholders::_2,
- std::placeholders::_3));
+ std::placeholders::_3,
+ std::placeholders::_4));
icn_acceptor_->listen(true);
}
@@ -117,6 +113,7 @@ void HttpServer::spawnThreads() {
accept();
+
//If num_threads>1, start m_io_service.run() in (num_threads-1) threads for thread-pooling
socket_threads_.clear();
for (size_t c = 1; c < config_.getNum_threads(); c++) {
@@ -124,6 +121,7 @@ void HttpServer::spawnThreads() {
io_service_.run();
});
}
+
}
void HttpServer::start() {
@@ -148,13 +146,13 @@ void HttpServer::start() {
}
spawnThreads();
+
setIcnAcceptor();
// Wait for the rest of the threads, if any, to finish as well
for (auto &t: socket_threads_) {
t.join();
}
-
// for (auto &t : icn_threads) {
// t.second.get();
// }
@@ -162,17 +160,14 @@ void HttpServer::start() {
void HttpServer::stop() {
acceptor_.close();
- icn_acceptor_.reset();
+
io_service_.stop();
- for (auto &p: icn_publishers_) {
- p.second->stop();
- }
+ std::map<int, std::shared_ptr<libl4::http::HTTPServerPublisher>>& icn_publishers = icn_acceptor_->getPublishers();
- for (auto p : icn_publishers_) {
- p.second.reset();
+ for (auto &p : icn_publishers) {
+ p.second->stop();
}
-
}
void HttpServer::accept() {
@@ -251,7 +246,7 @@ void HttpServer::read_request_and_content(std::shared_ptr<socket_type> socket) {
}
unsigned long long content_length;
try {
- content_length = stoull(it->second);
+ content_length = atol(it->second.c_str());
} catch (const std::exception &) {
return;
}
@@ -385,7 +380,7 @@ void HttpServer::write_response(std::shared_ptr<socket_type> socket,
float http_version;
try {
- http_version = stof(request->getHttp_version());
+ http_version = atof(request->getHttp_version().c_str());
} catch (const std::exception &) {
return;
}
@@ -403,12 +398,15 @@ void HttpServer::write_response(std::shared_ptr<socket_type> socket,
});
});
+
try {
resource_function(response, request);
} catch (const std::exception &) {
return;
}
+
}
} // end namespace icn_httpserver
+
diff --git a/http-server/http_server.h b/http-server/http_server.h
index 704863d5..630f26b6 100644
--- a/http-server/http_server.h
+++ b/http-server/http_server.h
@@ -22,8 +22,7 @@
* SOFTWARE.
*/
-#ifndef ICN_WEB_SERVER_WEB_SERVER_H_
-#define ICN_WEB_SERVER_WEB_SERVER_H_
+#pragma once
#include "common.h"
#include "icn_request.h"
@@ -49,6 +48,7 @@ namespace icn_httpserver {
class HttpServer {
public:
+
explicit HttpServer(unsigned short port,
std::string icn_name,
size_t num_threads,
@@ -71,10 +71,11 @@ class HttpServer {
void send(std::shared_ptr<Response> response, SendCallback callback = nullptr) const;
std::unordered_map<std::string, std::unordered_map<std::string, ResourceCallback> > resource;
+
std::unordered_map<std::string, ResourceCallback> default_resource;
+ void onIcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher, const uint8_t* buffer, std::size_t size, int request_id);
private:
- void onIcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher, const uint8_t* buffer, std::size_t size);
void spawnThreads();
@@ -100,11 +101,8 @@ class HttpServer {
boost::asio::io_service &io_service_;
boost::asio::ip::tcp::acceptor acceptor_;
std::vector<std::thread> socket_threads_;
-
- // ICN parameters
std::string icn_name_;
std::shared_ptr<libl4::http::HTTPServerAcceptor> icn_acceptor_;
- std::unordered_map<int, std::shared_ptr<libl4::http::HTTPServerPublisher>> icn_publishers_;
std::mutex thread_list_mtx_;
long timeout_request_;
@@ -113,5 +111,3 @@ class HttpServer {
};
} // end namespace icn_httpserver
-
-#endif //ICN_WEB_SERVER_WEB_SERVER_H_
diff --git a/http-server/icn_request.h b/http-server/icn_request.h
index ec9ee198..d18a6e64 100644
--- a/http-server/icn_request.h
+++ b/http-server/icn_request.h
@@ -13,8 +13,7 @@
* limitations under the License.
*/
-#ifndef ICN_WEB_SERVER_ICNREQUEST_H_
-#define ICN_WEB_SERVER_ICNREQUEST_H_
+#pragma once
#include "common.h"
#include "request.h"
@@ -32,6 +31,8 @@ class IcnRequest
std::string method,
std::string http_version);
+ ~IcnRequest() = default;
+
const std::string &getName() const;
void setName(const std::string &name);
@@ -51,6 +52,4 @@ class IcnRequest
};
-} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_ICNREQUEST_H_
+} // end namespace icn_httpserver \ No newline at end of file
diff --git a/http-server/icn_response.cc b/http-server/icn_response.cc
index 9741556b..630ee001 100644
--- a/http-server/icn_response.cc
+++ b/http-server/icn_response.cc
@@ -25,14 +25,13 @@ IcnResponse::IcnResponse(std::shared_ptr<libl4::http::HTTPServerPublisher> publi
}
void IcnResponse::send(const SendCallback &callback) {
+
std::size_t buffer_size = this->streambuf_.size();
this->streambuf_.commit(this->streambuf_.size());
- std::cout << "Rrsponse Id " << response_id_ << std::endl;
-
this->publisher_->publishContent(boost::asio::buffer_cast<const uint8_t *>(this->streambuf_.data()),
buffer_size,
- this->response_lifetime_,
+ std::chrono::milliseconds(100000),
this->response_id_,
this->is_last_);
@@ -43,4 +42,9 @@ void IcnResponse::send(const SendCallback &callback) {
}
}
+void IcnResponse::setResponseLifetime(const std::chrono::milliseconds &response_lifetime) {
+ this->publisher_->setTimeout(response_lifetime, true);
+ Response::setResponseLifetime(response_lifetime);
+}
+
} // end namespace icn_httpserver
diff --git a/http-server/icn_response.h b/http-server/icn_response.h
index 13a75629..7019590b 100644
--- a/http-server/icn_response.h
+++ b/http-server/icn_response.h
@@ -13,10 +13,9 @@
* limitations under the License.
*/
-#include "response.h"
+#pragma once
-#ifndef ICN_WEB_SERVER_ICNRESPONSE_H_
-#define ICN_WEB_SERVER_ICNRESPONSE_H_
+#include "response.h"
namespace icn_httpserver {
@@ -30,7 +29,9 @@ class IcnResponse
std::string ndn_path,
int response_id);
- void send(const SendCallback &callback = nullptr);
+ void send(const SendCallback &callback = nullptr) override;
+
+ void setResponseLifetime(const std::chrono::milliseconds &response_lifetime) override;
private:
std::string ndn_name_;
@@ -40,5 +41,3 @@ class IcnResponse
};
} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_ICNRESPONSE_H_
diff --git a/http-server/request.h b/http-server/request.h
index 6ffff296..3f61a46b 100644
--- a/http-server/request.h
+++ b/http-server/request.h
@@ -13,8 +13,7 @@
* limitations under the License.
*/
-#ifndef ICN_WEB_SERVER_REQUEST_H_
-#define ICN_WEB_SERVER_REQUEST_H_
+#pragma once
#include "common.h"
#include "content.h"
@@ -46,6 +45,8 @@ class Request {
virtual void read_remote_endpoint_data(socket_type &socket) {
};
+ virtual ~Request() = default;
+
const std::string &getMethod() const;
void setMethod(const std::string &method);
@@ -79,5 +80,3 @@ class Request {
};
} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_REQUEST_H_
diff --git a/http-server/response.cc b/http-server/response.cc
index 21a93dd8..c4560ba9 100644
--- a/http-server/response.cc
+++ b/http-server/response.cc
@@ -45,6 +45,7 @@ void Response::setIsLast(bool is_last) {
const std::chrono::milliseconds &Response::getResponseLifetime() const {
return response_lifetime_;
}
+
void Response::setResponseLifetime(const std::chrono::milliseconds &response_lifetime) {
Response::response_lifetime_ = response_lifetime;
}
diff --git a/http-server/response.h b/http-server/response.h
index cc8df9c6..51837556 100644
--- a/http-server/response.h
+++ b/http-server/response.h
@@ -13,8 +13,7 @@
* limitations under the License.
*/
-#ifndef ICN_WEB_SERVER_RESPONSE_H_
-#define ICN_WEB_SERVER_RESPONSE_H_
+#pragma once
#include "common.h"
@@ -25,8 +24,7 @@ class Response
public:
Response();
- virtual
- ~Response();
+ virtual ~Response();
size_t size();
@@ -41,8 +39,7 @@ class Response
const std::chrono::milliseconds &getResponseLifetime() const;
- void setResponseLifetime(const std::chrono::milliseconds &response_lifetime);
-
+ virtual void setResponseLifetime(const std::chrono::milliseconds &response_lifetime);
protected:
boost::asio::streambuf streambuf_;
@@ -51,6 +48,4 @@ class Response
std::chrono::milliseconds response_lifetime_;
};
-} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_RESPONSE_H_
+} // end namespace icn_httpserver \ No newline at end of file
diff --git a/http-server/socket_request.h b/http-server/socket_request.h
index cc77ef73..657226a3 100644
--- a/http-server/socket_request.h
+++ b/http-server/socket_request.h
@@ -22,8 +22,7 @@
* SOFTWARE.
*/
-#ifndef ICN_WEB_SERVER_SOCKETREQUEST_H_
-#define ICN_WEB_SERVER_SOCKETREQUEST_H_
+#pragma once
#include "request.h"
@@ -40,5 +39,3 @@ class SocketRequest
};
} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_SOCKETREQUEST_H_
diff --git a/http-server/socket_response.h b/http-server/socket_response.h
index 722e8196..e1a72142 100644
--- a/http-server/socket_response.h
+++ b/http-server/socket_response.h
@@ -22,8 +22,7 @@
* SOFTWARE.
*/
-#ifndef ICN_WEB_SERVER_SOCKETRESPONSE_H_
-#define ICN_WEB_SERVER_SOCKETRESPONSE_H_
+#pragma once
#include "response.h"
@@ -48,5 +47,3 @@ class SocketResponse
};
} // end namespace icn_httpserver
-
-#endif // ICN_WEB_SERVER_SOCKETRESPONSE_H_
diff --git a/main.cc b/main.cc
index e3b6e078..0a1c07a6 100644
--- a/main.cc
+++ b/main.cc
@@ -27,7 +27,8 @@
#include <boost/filesystem.hpp>
#include "http-server/http_server.h"
-#include "http-client/http_client.h"
+#include "http_client_tcp.h"
+#include "http_client_icn.h"
typedef icn_httpserver::HttpServer HttpServer;
typedef icn_httpserver::Response Response;
@@ -67,7 +68,7 @@ void afterSignal(HttpServer *webServer, const boost::system::error_code &errorCo
}
void usage(const char *programName) {
- cerr << programName << " [-p PATH_TO_ROOT_FOOT_FOLDER] [-o TCP_LISTEN_PORT] [-l WEBSERVER_PREFIX] [-x PROXY_ADDRESS]\n"
+ cerr << programName << " [-p PATH_TO_ROOT_FOOT_FOLDER] [-o TCP_LISTEN_PORT] [-l WEBSERVER_PREFIX] [-x TCP_PROXY_ADDRESS] [-z ICN_PROXY_PREFIX]\n"
<< "Web server able to publish content and generate http responses over TCP/ICN\n" << endl;
exit(1);
@@ -78,12 +79,12 @@ int main(int argc, char **argv) {
string root_folder = "/var/www/html";
string webserver_prefix = "http://webserver";
- string proxy_address = "";
+ string tcp_proxy_address;
+ string icn_proxy_prefix;
int port = 8080;
int opt = 0;
- while ((opt = getopt(argc, argv, "p:l:o:hx:")) != -1) {
-
+ while ((opt = getopt(argc, argv, "p:l:o:hx:z:")) != -1) {
switch (opt) {
case 'p':
root_folder = optarg;
@@ -92,11 +93,14 @@ int main(int argc, char **argv) {
webserver_prefix = optarg;
break;
case 'x':
- proxy_address = optarg;
+ tcp_proxy_address = optarg;
break;
case 'o':
port = atoi(optarg);
break;
+ case 'z':
+ icn_proxy_prefix = optarg;
+ break;
case 'h':
default:
usage(argv[0]);
@@ -120,6 +124,12 @@ int main(int argc, char **argv) {
std::cout << "Using web root folder: [" << root_folder << "]" << std::endl;
std::cout << "Using locator: [" << webserver_prefix << "]" << std::endl;
+ if (!tcp_proxy_address.empty()) {
+ std::cout << "Using TCP proxy: [" << tcp_proxy_address << "]" << std::endl;
+ }
+ if (!icn_proxy_prefix.empty()) {
+ std::cout << "Using ICN proxy: [" << icn_proxy_prefix << "]" << std::endl;
+ }
boost::asio::io_service io_service;
HttpServer server(port, webserver_prefix, 50, 5, 300, io_service);
@@ -147,16 +157,27 @@ int main(int argc, char **argv) {
// Will respond with content in the web/-directory, and its subdirectories.
// Default file: index.html
// Can for instance be used to retrieve an HTML 5 client that uses REST-resources on this server
- server.default_resource["GET"] = [&server, &root_folder, &proxy_address](shared_ptr<Response> response, shared_ptr<Request> request) {
+ server.default_resource["GET"] = [&server, &root_folder, &tcp_proxy_address, &icn_proxy_prefix]
+ (shared_ptr<Response> response, shared_ptr<Request> request) {
const auto web_root_path = boost::filesystem::canonical(root_folder);
boost::filesystem::path path = web_root_path;
path /= request->getPath();
- if (path.extension().string() == ".mpd") {
- response->setResponseLifetime(std::chrono::milliseconds(1000));
+ auto socket_request = dynamic_cast<icn_httpserver::SocketRequest *>(request.get());
+
+ std::chrono::milliseconds response_lifetime;
+
+ if (path.extension().string() == ".mpd" || path.stem() == "latest") {
+ std::cout << "Setting lifetime to 1 second" << std::endl;
+ response_lifetime = std::chrono::milliseconds(1000);
+ } else {
+ std::cout << "Setting lifetime to 5 second" << std::endl;
+ response_lifetime = std::chrono::milliseconds(5000);
}
+ response->setResponseLifetime(response_lifetime);
+
if (boost::filesystem::exists(path)) {
path = boost::filesystem::canonical(path);
@@ -175,7 +196,7 @@ int main(int argc, char **argv) {
ifs->open(path.string(), ifstream::in | ios::binary);
if (*ifs) {
- //read and send 1 MB at a time
+ //read and send 15 MB at a time
streamsize buffer_size = 15 * 1024 * 1024;
auto buffer = make_shared<vector<char> >(buffer_size);
@@ -184,17 +205,7 @@ int main(int argc, char **argv) {
ifs->seekg(0, ios::beg);
response->setResponseLength(length);
-
- icn_httpserver::SocketRequest
- *socket_request = dynamic_cast<icn_httpserver::SocketRequest *>(request.get());
-
- if (socket_request) {
- *response << "HTTP/1.0 200 OK\r\nContent-Length: " << length << "\r\n\r\n";
- }
-
- if (path.extension().string() == ".mpd") {
- response->setResponseLifetime(std::chrono::milliseconds(1000));
- }
+ *response << "HTTP/1.0 200 OK\r\nContent-Length: " << length << "\r\n\r\n";
default_resource_send(server, response, ifs, buffer, length);
@@ -205,31 +216,54 @@ int main(int argc, char **argv) {
}
}
- if (!proxy_address.empty()) {
+ string proxy;
+ HTTPClient* client = nullptr;
+
+ if (tcp_proxy_address.empty() && !icn_proxy_prefix.empty()) {
+ proxy = icn_proxy_prefix;
+ client = new HTTPClientIcn(20);
+ } else if (!tcp_proxy_address.empty() && icn_proxy_prefix.empty()) {
+ proxy = tcp_proxy_address;
+ client = new HTTPClientTcp;
+ } else if (!tcp_proxy_address.empty() && !icn_proxy_prefix.empty()) {
+ if (socket_request) {
+ proxy = icn_proxy_prefix;
+ client = new HTTPClientIcn(20);
+ } else {
+ proxy = tcp_proxy_address;
+ client = new HTTPClientTcp;
+ }
+ }
+ if (!proxy.empty()) {
// Fetch content from remote origin
std::stringstream ss;
- if (strncmp("http://", proxy_address.c_str(), 7) || strncmp("https://", proxy_address.c_str(), 8)) {
- ss << "http://";
+
+ if (strncmp("http://", proxy.c_str(), 7) != 0) {
+ if (strncmp("https://", proxy.c_str(), 8) != 0) {
+ ss << "https://";
+ } else {
+ ss << "http://";
+ }
}
- ss << proxy_address;
+ ss << proxy;
ss << request->getPath();
- std::cout << ss.str() << std::endl;
+ std::cout << "Forwarding request to " << ss.str() << std::endl;
- HTTPClient client;
+ client->download(ss.str(), *response);
- client.download(ss.str(), *response);
+ delete client;
-// std::cout << "+++++++++++++++++++++++++++++++++++" << reply.size() << std::endl;
-
-// *response << reply;
+ if (response->size() == 0) {
+ *response << "HTTP/1.1 504 Gateway Timeout\r\n\r\n";
+ }
return;
}
- string content = "Could not open path " + request->getPath();
+ string content = "Could not open path " + request->getPath() + "\n";
*response << "HTTP/1.1 404 Not found\r\nContent-Length: " << content.length() << "\r\n\r\n" << content;
diff --git a/scripts/build-package.sh b/scripts/build-package.sh
index f13b894a..1d58760a 100644
--- a/scripts/build-package.sh
+++ b/scripts/build-package.sh
@@ -33,15 +33,7 @@ baseurl=http://mirror.ghettoforge.org/distributions/gf/el/7/plus/x86_64/
enabled=1
gpgcheck=0
EOF
- sudo cat << EOF > jsoncpp.repo
-[jsoncp-repo]
-name=Repo for jsoncpp
-baseurl=http://dl.fedoraproject.org/pub/epel/7/x86_64/
-enabled=1
-gpgcheck=0
-EOF
sudo mv cmake.repo /etc/yum.repos.d/cmake.repo
- sudo mv jsoncpp.repo /etc/yum.repos.d/jsoncpp.repo
fi
}