- Added proxy function 06/7006/5
authorMauro Sardara <[email protected]>
Mon, 5 Jun 2017 16:43:52 +0000 (18:43 +0200)
committerMauro Sardara <[email protected]>
Mon, 5 Jun 2017 18:32:17 +0000 (20:32 +0200)
- Changed interface between library and application
- Support for different build type

Change-Id: I34ae75057490eb887d353e53c6d013f88bead04f
Signed-off-by: Mauro Sardara <[email protected]>
17 files changed:
CMakeLists.txt
cmake/Modules/FindCURL.cmake [new file with mode: 0644]
cmake/Modules/FindLibhicnet.cmake [new file with mode: 0644]
cmake/Modules/FindLibicnet.cmake
config.h.in [new file with mode: 0644]
dockerfile.ubuntu.xenial [new file with mode: 0644]
http-client/http_client.cc [new file with mode: 0644]
http-client/http_client.h [new file with mode: 0644]
http-server/common.h
http-server/http_server.cc
http-server/http_server.h
http-server/icn_request.cc
http-server/icn_request.h
http-server/icn_response.cc
http-server/icn_response.h
main.cc
scripts/build-package.sh

index 7d24384..f909c9c 100644 (file)
 
 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 (file)
index 0000000..239b0e5
--- /dev/null
@@ -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 <[email protected]>
+#
+# 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 (file)
index 0000000..0d4f5fb
--- /dev/null
@@ -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)
index 3c9c4f5..bfb81ef 100644 (file)
@@ -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 (file)
index 0000000..d10e62e
--- /dev/null
@@ -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 (file)
index 0000000..42f141c
--- /dev/null
@@ -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 (file)
index 0000000..221e7bb
--- /dev/null
@@ -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 (file)
index 0000000..19d3c41
--- /dev/null
@@ -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
index e69706e..580f8a4 100644 (file)
 #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;
 
index ebc8503..6bdf18f 100644 (file)
@@ -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());
index fbc841c..704863d 100644 (file)
@@ -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_;
index 07d95a2..1709e91 100644 (file)
 
 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
index c5aa10e..ec9ee19 100644 (file)
@@ -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_;
 
 };
 
index 6fe8b1e..241eda5 100644 (file)
 
 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);
 
index e9af0d4..13a7562 100644 (file)
@@ -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 13e4ee7..ab661d7 100644 (file)
--- 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;
index e459c96..f13b894 100644 (file)
@@ -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() {