aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMauro Sardara <msardara+fdio@cisco.com>2017-06-05 18:43:52 +0200
committerMauro Sardara <msardara+fdio@cisco.com>2017-06-05 20:32:17 +0200
commit4da1b7955fb3190c0e0646cfde99436aa140d271 (patch)
treebb9518b7aaf0c0493de03da83753d6a50f0aa9bf
parente8a980e1bc33adacb763066dc263f447656cb351 (diff)
- Added proxy function
- Changed interface between library and application - Support for different build type Change-Id: I34ae75057490eb887d353e53c6d013f88bead04f Signed-off-by: Mauro Sardara <msardara+fdio@cisco.com>
-rw-r--r--CMakeLists.txt48
-rw-r--r--cmake/Modules/FindCURL.cmake69
-rw-r--r--cmake/Modules/FindLibhicnet.cmake39
-rw-r--r--cmake/Modules/FindLibicnet.cmake2
-rw-r--r--config.h.in19
-rw-r--r--dockerfile.ubuntu.xenial31
-rw-r--r--http-client/http_client.cc59
-rw-r--r--http-client/http_client.h35
-rw-r--r--http-server/common.h15
-rw-r--r--http-server/http_server.cc144
-rw-r--r--http-server/http_server.h16
-rw-r--r--http-server/icn_request.cc16
-rw-r--r--http-server/icn_request.h10
-rw-r--r--http-server/icn_response.cc15
-rw-r--r--http-server/icn_response.h4
-rw-r--r--main.cc41
-rw-r--r--scripts/build-package.sh5
17 files changed, 404 insertions, 164 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7d243842..f909c9c1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -13,17 +13,39 @@
cmake_minimum_required(VERSION 3.2)
project(http-server)
+set(CMAKE_CXX_STANDARD 11)
+
+if (NOT CMAKE_BUILD_TYPE)
+ message(STATUS "No build type selected, default to Release")
+ set(CMAKE_BUILD_TYPE "Release")
+endif()
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O3")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
-find_package(Libicnet REQUIRED)
-include_directories(${LIBICNET_INCLUDE_DIRS})
+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)
+else()
+ find_package(Libicnet REQUIRED)
+ set (TRANSPORT_LIBRARY ICNET)
+endif()
+
+configure_file("${PROJECT_SOURCE_DIR}/config.h.in"
+ "${CMAKE_BINARY_DIR}/config.h")
+
+include_directories(${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIRS})
find_package(Threads REQUIRED)
+find_package(CURL REQUIRED)
+include_directories(${CURL_INCLUDE_DIRS})
+
find_package(Boost 1.53.0 COMPONENTS regex system filesystem REQUIRED)
-include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${LIBICNET_INCLUDE_DIR})
+include_directories(SYSTEM ${Boost_INCLUDE_DIR} ${CMAKE_BINARY_DIR} ${CURL_INCLUDE_DIRS} ${LIB${TRANSPORT_LIBRARY}_INCLUDE_DIR})
set(SOURCE_FILES
main.cc
@@ -45,10 +67,18 @@ set(SOURCE_FILES
http-server/socket_request.cc
http-server/socket_request.h
http-server/configuration.cc
- http-server/configuration.h)
+ http-server/configuration.h
+ http-client/http_client.cc
+ http-client/http_client.h
+ ${CMAKE_BINARY_DIR}/config.h)
+
+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(http-server ${SOURCE_FILES})
-target_link_libraries(http-server ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT} ${LIBICNET_LIBRARY})
+target_link_libraries(http-server ${LIB${TRANSPORT_LIBRARY}_LIBRARY} ${CURL_LIBRARY} ${Boost_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
install(TARGETS http-server DESTINATION ${CMAKE_INSTALL_PREFIX}/bin)
@@ -74,19 +104,21 @@ execute_process(COMMAND bash ${CMAKE_SOURCE_DIR}/scripts/version
OUTPUT_VARIABLE PACKAGE_VERSION)
string(STRIP ${PACKAGE_VERSION} PACKAGE_VERSION)
+string(TOLOWER ${TRANSPORT_LIBRARY} TRANSPORT_DEPENDENCY)
+
if (DEB_PACKAGE)
set(TYPE "DEBIAN")
set(GENERATOR "DEB")
set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_NAME}_${PACKAGE_VERSION}_${ARCHITECTURE}")
set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON)
- set(CPACK_${TYPE}_PACKAGE_DEPENDS "libicnet (>= 1.0)")
+ set(CPACK_${TYPE}_PACKAGE_DEPENDS "lib${TRANSPORT_DEPENDENCY} (>= 0.1)")
elseif (RPM_PACKAGE)
set(TYPE "RPM")
set(GENERATOR "RPM")
set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_NAME}-${PACKAGE_VERSION}.${ARCHITECTURE}")
set(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION "/usr/etc" "/usr/lib/python2.7" "/usr/lib/python2.7/site-packages")
set(CPACK_${TYPE}_PACKAGE_AUTOREQ ON)
- set(CPACK_${TYPE}_PACKAGE_REQUIRES "boost-system >= 1.53, boost-regex >= 1.53, boost-filesystem >= 1.53, libicnet >= 1.0")
+ set(CPACK_${TYPE}_PACKAGE_REQUIRES "boost-system >= 1.53, boost-regex >= 1.53, boost-filesystem >= 1.53, lib${TRANSPORT_DEPENDENCY} >= 1.0")
else ()
return()
endif ()
diff --git a/cmake/Modules/FindCURL.cmake b/cmake/Modules/FindCURL.cmake
new file mode 100644
index 00000000..239b0e50
--- /dev/null
+++ b/cmake/Modules/FindCURL.cmake
@@ -0,0 +1,69 @@
+#.rst:
+# FindCURL
+# --------
+#
+# Find curl
+#
+# Find the native CURL headers and libraries.
+#
+# ::
+#
+# CURL_INCLUDE_DIRS - where to find curl_/curl_.h, etc.
+# CURL_LIBRARIES - List of libraries when using curl.
+# CURL_FOUND - True if curl found.
+# CURL_VERSION_STRING - the version of curl found (since CMake 2.8.8)
+
+#=============================================================================
+# Copyright 2006-2009 Kitware, Inc.
+# Copyright 2012 Rolf Eike Beer <eike@sf-mail.de>
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distribute this file outside of CMake, substitute the full
+# License text for the above reference.)
+
+# Look for the header file.
+find_path(CURL_INCLUDE_DIR NAMES curl/curl.h)
+mark_as_advanced(CURL_INCLUDE_DIR)
+
+# Look for the library (sorted from most current/relevant entry to least).
+find_library(CURL_LIBRARY NAMES
+ curl
+ # Windows MSVC prebuilts:
+ curllib
+ libcurl_imp
+ curllib_static
+ # Windows older "Win32 - MSVC" prebuilts (libcurl.lib, e.g. libcurl-7.15.5-win32-msvc.zip):
+ libcurl
+ )
+mark_as_advanced(CURL_LIBRARY)
+
+if(CURL_INCLUDE_DIR)
+ foreach(_curl_version_header curlver.h curl.h)
+ if(EXISTS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}")
+ file(STRINGS "${CURL_INCLUDE_DIR}/curl/${_curl_version_header}" curl_version_str REGEX "^#define[\t ]+LIBCURL_VERSION[\t ]+\".*\"")
+
+ string(REGEX REPLACE "^#define[\t ]+LIBCURL_VERSION[\t ]+\"([^\"]*)\".*" "\\1" CURL_VERSION_STRING "${curl_version_str}")
+ unset(curl_version_str)
+ break()
+ endif()
+ endforeach()
+endif()
+
+# handle the QUIETLY and REQUIRED arguments and set CURL_FOUND to TRUE if
+# all listed variables are TRUE
+include(FindPackageHandleStandardArgs)
+
+FIND_PACKAGE_HANDLE_STANDARD_ARGS(CURL
+ REQUIRED_VARS CURL_LIBRARY CURL_INCLUDE_DIR
+ VERSION_VAR CURL_VERSION_STRING)
+
+if(CURL_FOUND)
+ set(CURL_LIBRARIES ${CURL_LIBRARY})
+ set(CURL_INCLUDE_DIRS ${CURL_INCLUDE_DIR})
+endif()
diff --git a/cmake/Modules/FindLibhicnet.cmake b/cmake/Modules/FindLibhicnet.cmake
new file mode 100644
index 00000000..0d4f5fbc
--- /dev/null
+++ b/cmake/Modules/FindLibhicnet.cmake
@@ -0,0 +1,39 @@
+########################################
+#
+# 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/cmake/Modules/FindLibicnet.cmake b/cmake/Modules/FindLibicnet.cmake
index 3c9c4f5f..bfb81ef7 100644
--- a/cmake/Modules/FindLibicnet.cmake
+++ b/cmake/Modules/FindLibicnet.cmake
@@ -22,7 +22,7 @@ set(LIBICNET_SEARCH_PATH_LIST
/usr
)
-find_path(LIBICNET_INCLUDE_DIR icnet/icnet_common.h
+find_path(LIBICNET_INCLUDE_DIR icnet/icnet_ccnx_common.h
HINTS ${LIBICNET_SEARCH_PATH_LIST}
PATH_SUFFIXES include
DOC "Find the libicnet includes")
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 00000000..d10e62ee
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,19 @@
+/*
+ * 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
+
+#cmakedefine ICNET
+#cmakedefine HICNET
diff --git a/dockerfile.ubuntu.xenial b/dockerfile.ubuntu.xenial
new file mode 100644
index 00000000..42f141c5
--- /dev/null
+++ b/dockerfile.ubuntu.xenial
@@ -0,0 +1,31 @@
+# Ubuntu Dockerfile
+#
+# https://github.com/dockerfile/ubuntu
+#
+
+# Pull base image.
+FROM ubuntu:xenial
+
+# Building tools and dependencies
+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 && \
+ 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 \
+ libhicnet-dev libhicn-dev libcurl4-openssl-dev \
+ libboost-system-dev libboost-regex-dev libboost-filesystem-dev && \
+ rm -rf /var/lib/apt/lists/*
+
+# Cmake version 3.8
+ENV CMAKE_INSTALL_SCRIPT_URL="https://cmake.org/files/v3.8/cmake-3.8.0-Linux-x86_64.sh"
+ENV CMAKE_INSTALL_SCRIPT="/tmp/install_cmake.sh"
+ENV CMAKE_INSTALL_LOCATION="/usr"
+
+RUN curl ${CMAKE_INSTALL_SCRIPT_URL} > ${CMAKE_INSTALL_SCRIPT}
+RUN mkdir -p ${CMAKE_INSTALL_LOCATION}
+RUN bash ${CMAKE_INSTALL_SCRIPT} --skip-license --prefix=${CMAKE_INSTALL_LOCATION} --exclude-subdir
diff --git a/http-client/http_client.cc b/http-client/http_client.cc
new file mode 100644
index 00000000..221e7bbe
--- /dev/null
+++ b/http-client/http_client.cc
@@ -0,0 +1,59 @@
+/*
+ * 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.h"
+
+#include <curl/curl.h>
+#include <sstream>
+#include <iostream>
+
+using namespace std;
+
+size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream) {
+ ((ostream*) stream)->write((const char*)ptr, size * nmemb);
+ return size * nmemb;
+}
+
+HTTPClient::HTTPClient() {
+ curl_ = curl_easy_init();
+}
+
+HTTPClient::~HTTPClient() {
+ curl_easy_cleanup(curl_);
+}
+
+bool HTTPClient::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);
+ curl_easy_setopt(curl_, CURLOPT_WRITEDATA, &out);
+
+ /* 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;
+} \ No newline at end of file
diff --git a/http-client/http_client.h b/http-client/http_client.h
new file mode 100644
index 00000000..19d3c41e
--- /dev/null
+++ b/http-client/http_client.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.
+ */
+
+#ifndef HTTP_CLIENT_H_
+#define HTTP_CLIENT_H_
+
+#include <string>
+
+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_;
+};
+
+#endif // HTTP_CLIENT_H_ \ No newline at end of file
diff --git a/http-server/common.h b/http-server/common.h
index e69706e6..580f8a41 100644
--- a/http-server/common.h
+++ b/http-server/common.h
@@ -16,6 +16,18 @@
#ifndef ICN_WEB_SERVER_COMMON_H_
#define ICN_WEB_SERVER_COMMON_H_
+#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 <boost/asio.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string/predicate.hpp>
@@ -31,9 +43,6 @@
#include <sstream>
#include <string>
-// ICN extensions
-#include <icnet/icnet_socket_producer.h>
-
typedef boost::asio::ip::tcp::socket socket_type;
typedef std::function<void(const boost::system::error_code &)> SendCallback;
diff --git a/http-server/http_server.cc b/http-server/http_server.cc
index ebc8503b..6bdf18f2 100644
--- a/http-server/http_server.cc
+++ b/http-server/http_server.cc
@@ -33,7 +33,6 @@ HttpServer::HttpServer(unsigned short port,
internal_io_service_(std::make_shared<boost::asio::io_service>()),
io_service_(*internal_io_service_),
acceptor_(io_service_),
- acceptor_producer_(std::make_shared<icnet::ProducerSocket>(icnet::Name(icn_name))),
timeout_request_(timeout_request),
timeout_content_(timeout_send_or_receive) {
}
@@ -48,124 +47,51 @@ HttpServer::HttpServer(unsigned short port,
icn_name_(icn_name),
io_service_(ioService),
acceptor_(io_service_),
- acceptor_producer_(std::make_shared<icnet::ProducerSocket>(icnet::Name(icn_name))),
timeout_request_(timeout_request),
timeout_content_(timeout_send_or_receive) {
}
-void HttpServer::processIncomingInterest(icnet::ProducerSocket &p, const icnet::Interest &interest) {
- icnet::Name complete_name = interest.getName();
+void HttpServer::onIcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher> &publisher,
+ const uint8_t *buffer,
+ std::size_t size) {
+ publisher->setTimeout(5);
+ std::shared_ptr<Request> request = std::make_shared<IcnRequest>(publisher);
+ request->getContent().rdbuf()->sputn((char*)buffer, size);
- if (complete_name.getSegmentCount() <= 2) {
- std::cerr << "Received malformed name " << complete_name << ". Ignoring it." << std::endl;
+ if (!parse_request(request, request->getContent())) {
return;
}
- icnet::Name request_name = complete_name.get(-1).isSegment() ? complete_name.getPrefix(-1) : complete_name;
+ int request_id = libl4::utils::Hash::hash32(buffer, size);
+
+ std::cout << "Request ID" << request_id << std::endl;
std::unique_lock<std::mutex> lock(thread_list_mtx_);
- if (icn_producers_.size() < config_.getNum_threads()) {
- if (icn_producers_.find(request_name) == icn_producers_.end()) {
- std::cout << "Received interest name: " << request_name << std::endl;
- std::shared_ptr<icnet::ProducerSocket> p = makeProducer(request_name);
- icn_producers_[request_name] = p;
+ if (icn_publishers_.size() < config_.getNum_threads()) {
+ if (icn_publishers_.find(request_id) == icn_publishers_.end()) {
+ std::cout << "Received request for: " << request->getPath() << std::endl;
+ icn_publishers_[request_id] = publisher;
std::cout << "Starting new thread" << std::endl;
- std::thread t([this, interest, request_name, p]() {
- processInterest(request_name, p);
+ io_service_.dispatch([this, request, request_id]() {
+ find_resource(nullptr, request);
+ icn_publishers_[request_id]->serveClients();
+ std::unique_lock<std::mutex> lock(thread_list_mtx_);
+ icn_publishers_.erase(request_id);
});
- t.detach();
- } else {
- icn_producers_[request_name]->onInterest(complete_name, interest);
}
}
}
-void HttpServer::signPacket(icnet::ProducerSocket &p, icnet::ContentObject &content_object) {
- // This is not really signing the packet. Signing every packet is cpu expensive.
- icnet::KeyLocator keyLocator;
- content_object.signWithSha256(keyLocator);
-}
-
-void HttpServer::processInterest(icnet::Name request_name, std::shared_ptr<icnet::ProducerSocket> p) {
- // Create timer
- std::shared_ptr<icnet::ccnx::Portal> portal;
- p->getSocketOption(icnet::GeneralTransportOptions::PORTAL, portal);
- boost::asio::io_service &ioService = portal->getIoService();
-
- boost::asio::deadline_timer t(ioService, boost::posix_time::seconds(5));
-
- std::function<void(const boost::system::error_code e)>
- wait_callback = [&ioService](const boost::system::error_code e) {
- if (!e) {
- // Be sure to delete the timer before the io_service, otherwise we'll get some strange behavior!
- ioService.stop();
- }
- };
-
- t.async_wait(wait_callback);
-
- // Get the name of the HTTP method to compute
- std::string method = request_name.get(1).toString();
- std::transform(method.begin(), method.end(), method.begin(), ::toupper);
- std::string path;
-
- // This is done for getting rid of useless name components such as ccnx: or ndn:
- if (request_name.getSegmentCount() > 2) {
- std::string rawPath = request_name.getSubName(2).toString();
- std::size_t pos = rawPath.find("/");
- path = rawPath.substr(pos);
- }
-
- std::function<void(icnet::ProducerSocket &p, const icnet::Interest &interest)>
- interest_enter_callback = [this, &wait_callback, &t](icnet::ProducerSocket &p, const icnet::Interest &interest) {
- t.cancel();
- t.expires_from_now(boost::posix_time::seconds(5));
- t.async_wait(wait_callback);
- };
-
- p->setSocketOption(icnet::ProducerCallbacksOptions::INTEREST_INPUT,
- (icnet::ProducerInterestCallback) interest_enter_callback);
-
- // TODO The parsing of the parameters in theURL is missing!
- if (method == GET) {
- // Build new GET request to submit to the server
-
- std::shared_ptr<Request> request = std::make_shared<IcnRequest>(p, request_name.toString(), path, method, "1.0");
-
- std::static_pointer_cast<IcnRequest>(request)->getHeader()
- .insert(std::make_pair(std::string("Host"), std::string("localhost")));
-
- p->attach();
-
- find_resource(nullptr, request);
- }
-
- p->serveForever();
-
- std::unique_lock<std::mutex> lock(thread_list_mtx_);
- icn_producers_.erase(request_name);
-}
-
-std::shared_ptr<icnet::ProducerSocket> HttpServer::makeProducer(icnet::Name request_name) {
- std::shared_ptr<icnet::ProducerSocket> producer = std::make_shared<icnet::ProducerSocket>(request_name);
- // producer->setContextOption(FAST_SIGNING, true);
- // producer->setContextOption(DATA_TO_SECURE, (api::ProducerDataCallback) bind(&http-server::signPacket, this, _1, _2));
- producer->setSocketOption(icnet::GeneralTransportOptions::DATA_PACKET_SIZE, PACKET_SIZE);
- producer->setSocketOption(icnet::GeneralTransportOptions::OUTPUT_BUFFER_SIZE, SEND_BUFFER_SIZE);
-
- return producer;
-}
-
void HttpServer::setIcnAcceptor() {
- acceptor_producer_->setSocketOption(icnet::ProducerCallbacksOptions::INTEREST_INPUT,
- (icnet::ProducerInterestCallback) bind(&HttpServer::processIncomingInterest,
- this,
- std::placeholders::_1,
- std::placeholders::_2));
- acceptor_producer_->dispatch();
+ icn_acceptor_ = std::make_shared<libl4::http::HTTPServerAcceptor>(icn_name_, std::bind(&HttpServer::onIcnRequest,
+ this,
+ std::placeholders::_1,
+ std::placeholders::_2,
+ std::placeholders::_3));
+ icn_acceptor_->listen(true);
}
-void HttpServer::spawnTcpThreads() {
+void HttpServer::spawnThreads() {
if (io_service_.stopped()) {
io_service_.reset();
}
@@ -216,11 +142,9 @@ void HttpServer::start() {
}
}
- spawnTcpThreads();
+ spawnThreads();
setIcnAcceptor();
-
-
// Wait for the rest of the threads, if any, to finish as well
for (auto &t: socket_threads_) {
t.join();
@@ -233,16 +157,14 @@ void HttpServer::start() {
void HttpServer::stop() {
acceptor_.close();
- acceptor_producer_.reset();
+ icn_acceptor_.reset();
io_service_.stop();
- for (auto p: icn_producers_) {
- std::shared_ptr<icnet::ccnx::Portal> portalPtr;
- p.second->getSocketOption(icnet::GeneralTransportOptions::PORTAL, portalPtr);
- portalPtr->getIoService().stop();
+ for (auto &p: icn_publishers_) {
+ p.second->stop();
}
- for (auto p : icn_producers_) {
+ for (auto p : icn_publishers_) {
p.second.reset();
}
@@ -289,7 +211,7 @@ void HttpServer::read_request_and_content(std::shared_ptr<socket_type> socket) {
std::shared_ptr<Request> request = std::make_shared<SocketRequest>();
request->read_remote_endpoint_data(*socket);
- //Set timeout on the following boost::asio::async-read or write function
+ // Set timeout on the following boost::asio::async-read or write function
std::shared_ptr<boost::asio::deadline_timer> timer;
if (timeout_request_ > 0) {
timer = set_timeout_on_socket(socket, timeout_request_);
@@ -439,7 +361,7 @@ void HttpServer::write_response(std::shared_ptr<socket_type> socket,
if (socket) {
resp = new SocketResponse(socket);
} else {
- resp = new IcnResponse(std::static_pointer_cast<IcnRequest>(request)->getProducer(),
+ resp = new IcnResponse(std::static_pointer_cast<IcnRequest>(request)->getHttpPublisher(),
std::static_pointer_cast<IcnRequest>(request)->getName(),
std::static_pointer_cast<IcnRequest>(request)->getPath(),
std::static_pointer_cast<IcnRequest>(request)->getRequest_id());
diff --git a/http-server/http_server.h b/http-server/http_server.h
index fbc841c7..704863d5 100644
--- a/http-server/http_server.h
+++ b/http-server/http_server.h
@@ -74,13 +74,9 @@ class HttpServer {
std::unordered_map<std::string, ResourceCallback> default_resource;
private:
- void processInterest(icnet::Name request_name, std::shared_ptr<icnet::ProducerSocket> p);
+ void onIcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher, const uint8_t* buffer, std::size_t size);
- void processIncomingInterest(icnet::ProducerSocket &p, const icnet::Interest &interest);
-
- void signPacket(icnet::ProducerSocket &p, icnet::ContentObject &content_object);
-
- void spawnTcpThreads();
+ void spawnThreads();
void setIcnAcceptor();
@@ -96,8 +92,6 @@ class HttpServer {
std::shared_ptr<Request> request,
ResourceCallback &resource_function);
- std::shared_ptr<icnet::ProducerSocket> makeProducer(icnet::Name request_name);
-
Configuration config_;
std::vector<std::pair<std::string, std::vector<std::pair<boost::regex, ResourceCallback> > > > opt_resource_;
@@ -109,10 +103,8 @@ class HttpServer {
// ICN parameters
std::string icn_name_;
- std::shared_ptr<icnet::ProducerSocket> acceptor_producer_;
- std::unordered_map<icnet::Name, std::future<void>> icn_threads_;
- std::unordered_map<icnet::Name, std::shared_ptr<icnet::ProducerSocket>> icn_producers_;
- std::unordered_map<icnet::Name, std::shared_ptr<boost::asio::io_service>> name_io_service_map_;
+ 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_;
diff --git a/http-server/icn_request.cc b/http-server/icn_request.cc
index 07d95a22..1709e917 100644
--- a/http-server/icn_request.cc
+++ b/http-server/icn_request.cc
@@ -17,19 +17,19 @@
namespace icn_httpserver {
-IcnRequest::IcnRequest(std::shared_ptr<icnet::ProducerSocket> producer)
- : producer_(producer) {
+IcnRequest::IcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher)
+ : publisher_(publisher) {
time_t t;
time(&t);
srand((unsigned int) t);
request_id_ = rand();
}
-IcnRequest::IcnRequest(std::shared_ptr<icnet::ProducerSocket> producer,
+IcnRequest::IcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher,
std::string name,
std::string path,
std::string method, std::string http_version)
- : IcnRequest(producer) {
+ : IcnRequest(publisher) {
this->name_ = name;
this->path_ = path;
this->method_ = method;
@@ -52,12 +52,12 @@ void IcnRequest::setRequest_id(int request_id) {
IcnRequest::request_id_ = request_id;
}
-const std::shared_ptr<icnet::ProducerSocket> &IcnRequest::getProducer() const {
- return producer_;
+const std::shared_ptr<libl4::http::HTTPServerPublisher> &IcnRequest::getHttpPublisher() const {
+ return publisher_;
}
-void IcnRequest::setProducer(const std::shared_ptr<icnet::ProducerSocket> &producer) {
- IcnRequest::producer_ = producer;
+void IcnRequest::setProducer(const std::shared_ptr<libl4::http::HTTPServerPublisher> &producer) {
+ IcnRequest::publisher_ = producer;
}
} // end namespace icn_httpserver
diff --git a/http-server/icn_request.h b/http-server/icn_request.h
index c5aa10e4..ec9ee198 100644
--- a/http-server/icn_request.h
+++ b/http-server/icn_request.h
@@ -24,9 +24,9 @@ namespace icn_httpserver {
class IcnRequest
: public Request {
public:
- IcnRequest(std::shared_ptr<icnet::ProducerSocket> producer);
+ IcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher);
- IcnRequest(std::shared_ptr<icnet::ProducerSocket> producer,
+ IcnRequest(std::shared_ptr<libl4::http::HTTPServerPublisher>& publisher,
std::string name,
std::string path,
std::string method,
@@ -40,14 +40,14 @@ class IcnRequest
void setRequest_id(int request_id);
- const std::shared_ptr<icnet::ProducerSocket> &getProducer() const;
+ const std::shared_ptr<libl4::http::HTTPServerPublisher> &getHttpPublisher() const;
- void setProducer(const std::shared_ptr<icnet::ProducerSocket> &producer);
+ void setProducer(const std::shared_ptr<libl4::http::HTTPServerPublisher> &producer);
private:
std::string name_;
int request_id_;
- std::shared_ptr<icnet::ProducerSocket> producer_;
+ std::shared_ptr<libl4::http::HTTPServerPublisher> publisher_;
};
diff --git a/http-server/icn_response.cc b/http-server/icn_response.cc
index 6fe8b1e1..241eda51 100644
--- a/http-server/icn_response.cc
+++ b/http-server/icn_response.cc
@@ -17,22 +17,23 @@
namespace icn_httpserver {
-IcnResponse::IcnResponse(std::shared_ptr<icnet::ProducerSocket> producer,
+IcnResponse::IcnResponse(std::shared_ptr<libl4::http::HTTPServerPublisher> publisher,
std::string ndn_name,
std::string ndn_path,
int response_id)
- : producer_(producer), ndn_name_(ndn_name), ndn_path_(ndn_path), response_id_(response_id) {
+ : publisher_(publisher), ndn_name_(ndn_name), ndn_path_(ndn_path), response_id_(response_id) {
}
void IcnResponse::send(const SendCallback &callback) {
std::size_t buffer_size = this->streambuf_.size();
this->streambuf_.commit(this->streambuf_.size());
- this->producer_->produce(icnet::Name(/*this->ndn_name*/),
- boost::asio::buffer_cast<const uint8_t *>(this->streambuf_.data()),
- buffer_size,
- this->response_id_,
- this->is_last_);
+ 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_id_,
+ this->is_last_);
this->streambuf_.consume(buffer_size);
diff --git a/http-server/icn_response.h b/http-server/icn_response.h
index e9af0d40..13a75629 100644
--- a/http-server/icn_response.h
+++ b/http-server/icn_response.h
@@ -25,7 +25,7 @@ class IcnResponse
public:
- IcnResponse(std::shared_ptr<icnet::ProducerSocket> producer,
+ IcnResponse(std::shared_ptr<libl4::http::HTTPServerPublisher> producer,
std::string ndn_name,
std::string ndn_path,
int response_id);
@@ -36,7 +36,7 @@ class IcnResponse
std::string ndn_name_;
std::string ndn_path_;
int response_id_;
- std::shared_ptr<icnet::ProducerSocket> producer_;
+ std::shared_ptr<libl4::http::HTTPServerPublisher> publisher_;
};
} // end namespace icn_httpserver
diff --git a/main.cc b/main.cc
index 13e4ee73..ab661d77 100644
--- a/main.cc
+++ b/main.cc
@@ -27,6 +27,7 @@
#include <boost/filesystem.hpp>
#include "http-server/http_server.h"
+#include "http-client/http_client.h"
typedef icn_httpserver::HttpServer HttpServer;
typedef icn_httpserver::Response Response;
@@ -66,7 +67,7 @@ void afterSignal(HttpServer *webServer, const boost::system::error_code &errorCo
}
void usage(const char *programName) {
- cerr << programName << " [-p PATH_TO_ROOT_FOOT_FOLDER] [-l WEBSERVER_PREFIX]\n"
+ cerr << programName << " [-p PATH_TO_ROOT_FOOT_FOLDER] [-l WEBSERVER_PREFIX] [-x PROXY_ADDRESS]\n"
<< "Web server able to publish content and generate http responses over TCP/ICN\n" << endl;
exit(1);
@@ -76,11 +77,12 @@ int main(int argc, char **argv) {
// Parse command line arguments
string root_folder = "/var/www/html";
- string webserver_prefix = "ccnx:/webserver";
+ string webserver_prefix = "http://webserver";
+ string proxy_address = "";
int opt = 0;
- while ((opt = getopt(argc, argv, "p:l:h")) != -1) {
+ while ((opt = getopt(argc, argv, "p:l:hx:")) != -1) {
switch (opt) {
case 'p':
@@ -89,7 +91,11 @@ int main(int argc, char **argv) {
case 'l':
webserver_prefix = optarg;
break;
+ case 'x':
+ proxy_address = optarg;
+ break;
case 'h':
+ default:
usage(argv[0]);
break;
}
@@ -138,7 +144,7 @@ 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](shared_ptr<Response> response, shared_ptr<Request> request) {
+ server.default_resource["GET"] = [&server, &root_folder, &proxy_address](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;
@@ -164,7 +170,7 @@ int main(int argc, char **argv) {
if (*ifs) {
//read and send 1 MB at a time
streamsize buffer_size = 15 * 1024 * 1024;
- auto buffer = make_shared < vector < char > > (buffer_size);
+ auto buffer = make_shared<vector<char> >(buffer_size);
ifs->seekg(0, ios::end);
auto length = ifs->tellg();
@@ -182,11 +188,36 @@ int main(int argc, char **argv) {
default_resource_send(server, response, ifs, buffer, length);
return;
+
}
}
}
}
+ if (!proxy_address.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://";
+ }
+
+ ss << proxy_address;
+ ss << request->getPath();
+
+ std::cout << ss.str() << std::endl;
+
+ HTTPClient client;
+
+ client.download(ss.str(), *response);
+
+// std::cout << "+++++++++++++++++++++++++++++++++++" << reply.size() << std::endl;
+
+// *response << reply;
+
+ return;
+ }
+
string content = "Could not open path " + request->getPath();
*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 e459c969..f13b894a 100644
--- a/scripts/build-package.sh
+++ b/scripts/build-package.sh
@@ -8,12 +8,12 @@ apt_get=${APT_PATH:-"/usr/local/bin/apt-get"}
BUILD_TOOLS_UBUNTU="build-essential cmake"
LIBSSL_LIBEVENT_UBUNTU="libevent-dev libssl-dev"
-DEPS_UBUNTU="$LIBSSL_LIBEVENT_UBUNTU longbow-dev libparc-dev libccnx-common-dev libccnx-transport-rta-dev libicnet-dev libboost-system-dev libboost-regex-dev libboost-filesystem-dev"
+DEPS_UBUNTU="$LIBSSL_LIBEVENT_UBUNTU libcurl4-openssl-dev longbow-dev libparc-dev libccnx-common-dev libccnx-transport-rta-dev libicnet-dev libboost-system-dev libboost-regex-dev libboost-filesystem-dev"
BUILD_TOOLS_GROUP_CENTOS="'Development Tools'"
BUILD_TOOLS_SINGLE_CENTOS="cmake"
LIBSSL_LIBEVENT_CENTOS="libevent-devel openssl-devel"
-DEPS_CENTOS="$LIBSSL_LIBEVENT_CENTOS longbow-devel libparc-devel libccnx-common-devel libccnx-transport-rta-devel libicnet-devel boost-devel"
+DEPS_CENTOS="$LIBSSL_LIBEVENT_CENTOS curl-devel longbow-devel libparc-devel libccnx-common-devel libccnx-transport-rta-devel libicnet-devel boost-devel"
# Parameters:
# $1 = Distribution [Trusty / CentOS]
@@ -118,6 +118,7 @@ EOF
echo "Distribution $DISTRIB_CODENAME is not supported"
exit -1
fi
+
}
setup() {