aboutsummaryrefslogtreecommitdiffstats
path: root/HttpServer/app/src/main/cpp/httpServerWrap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'HttpServer/app/src/main/cpp/httpServerWrap.cpp')
-rw-r--r--HttpServer/app/src/main/cpp/httpServerWrap.cpp236
1 files changed, 236 insertions, 0 deletions
diff --git a/HttpServer/app/src/main/cpp/httpServerWrap.cpp b/HttpServer/app/src/main/cpp/httpServerWrap.cpp
new file mode 100644
index 00000000..d554fe58
--- /dev/null
+++ b/HttpServer/app/src/main/cpp/httpServerWrap.cpp
@@ -0,0 +1,236 @@
+/*
+ * Copyright (c) 2018 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 <jni.h>
+#include <string>
+#include <stdlib.h>
+#include <http-server/http_server.h>
+#include <http-client/http_client_icn.h>
+#include <http-client/http_client_tcp.h>
+#include <boost/filesystem.hpp>
+#include <fstream>
+#include <iostream>
+#include <android/log.h>
+
+
+static bool _isRunning = false;
+icn_httpserver::HttpServer *server;
+
+void default_resource_send(const icn_httpserver::HttpServer &server,
+ std::shared_ptr<icn_httpserver::Response> response,
+ std::shared_ptr<std::ifstream> ifs,
+ std::shared_ptr<std::vector<char>> buffer,
+ std::size_t bytes_to_read) {
+ std::streamsize read_length;
+
+ if ((read_length = ifs->read(&(*buffer)[0], buffer->size()).gcount()) > 0) {
+ response->write(&(*buffer)[0], read_length);
+
+ if (bytes_to_read <= static_cast<std::streamsize>(buffer->size())) {
+ return;
+ }
+
+ std::size_t to_read = bytes_to_read - read_length;
+ server.send(response,
+ [&server, response, ifs, buffer, to_read](const boost::system::error_code &ec) {
+ if (!ec) {
+ default_resource_send(server, response, ifs, buffer, to_read);
+ } else {
+ __android_log_print(ANDROID_LOG_ERROR, "HttpServer",
+ "Connection interrupted");
+ }
+ });
+ }
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_icn_httpserver_com_supportlibrary_HttpServer_start(JNIEnv *env, jobject instance,
+ jstring rootFolderString,
+ jstring tcpListenPortString,
+ jstring webServerPrefixString,
+ jstring proxyAddressString,
+ jstring iCNproxyAddressString) {
+ std::string root_folder = "";
+ int port = 8080;
+ std::string webserver_prefix = "";
+ std::string proxy_address = "";
+ std::string icn_proxy_address = "";
+ if (rootFolderString) {
+ const char *rootFolderChar = env->GetStringUTFChars(rootFolderString, JNI_FALSE);
+ root_folder.append(rootFolderChar);
+ env->ReleaseStringUTFChars(rootFolderString, rootFolderChar);
+ }
+
+ if (tcpListenPortString) {
+ const char *tcpListenPortChar = env->GetStringUTFChars(tcpListenPortString, JNI_FALSE);
+ port = atoi(tcpListenPortChar);
+ env->ReleaseStringUTFChars(tcpListenPortString, tcpListenPortChar);
+ }
+ if (webServerPrefixString) {
+ const char *webServerPrefixChar = env->GetStringUTFChars(webServerPrefixString, JNI_FALSE);
+ webserver_prefix.append(webServerPrefixChar);
+ env->ReleaseStringUTFChars(webServerPrefixString, webServerPrefixChar);
+ }
+ if (proxyAddressString) {
+ const char *proxyAddressChar = env->GetStringUTFChars(proxyAddressString, JNI_FALSE);
+ proxy_address.append(proxyAddressChar);
+ env->ReleaseStringUTFChars(proxyAddressString, proxyAddressChar);
+ }
+
+ if (iCNproxyAddressString) {
+ const char *iCNproxyAddressChar = env->GetStringUTFChars(iCNproxyAddressString, JNI_FALSE);
+ icn_proxy_address.append(iCNproxyAddressChar);
+ env->ReleaseStringUTFChars(iCNproxyAddressString, iCNproxyAddressChar);
+ }
+ boost::asio::io_service io_service;
+ server = new icn_httpserver::HttpServer(port, webserver_prefix, 50, 50, 300,
+ io_service);
+ _isRunning = true;
+ server->resource["^/info$"]["GET"] = [](std::shared_ptr<icn_httpserver::Response> response,
+ std::shared_ptr<icn_httpserver::Request> request) {
+ std::stringstream content_stream;
+ content_stream << "<h1>This webserver is able to reply to HTTP over TCP/ICN</h1>";
+ content_stream << request->getMethod() << " " << request->getPath() << " HTTP/"
+ << request->getHttp_version() << "<br>";
+ for (auto &header: request->getHeader()) {
+ content_stream << header.first << ": " << header.second << "<br>";
+ }
+
+ content_stream.seekp(0, std::ios::end);
+
+ *response << "HTTP/1.1 200 OK\r\nContent-Length: " << content_stream.tellp() << "\r\n\r\n"
+ << content_stream.rdbuf();
+ };
+
+
+ server->default_resource["GET"] = [&root_folder, &proxy_address, &icn_proxy_address](
+ std::shared_ptr<icn_httpserver::Response> response,
+ std::shared_ptr<icn_httpserver::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(3000));
+ }
+
+ icn_httpserver::SocketRequest *socket_request = dynamic_cast<icn_httpserver::SocketRequest *>(request.get());
+
+ if (boost::filesystem::exists(path)) {
+ path = boost::filesystem::canonical(path);
+
+ if (std::distance(web_root_path.begin(), web_root_path.end()) <=
+ std::distance(path.begin(), path.end()) &&
+ std::equal(web_root_path.begin(), web_root_path.end(), path.begin())) {
+ if (boost::filesystem::is_directory(path)) {
+ path /= "index.html";
+ } // default path
+
+ if (boost::filesystem::exists(path) && boost::filesystem::is_regular_file(path)) {
+ auto ifs = std::make_shared<std::ifstream>();
+ ifs->open(path.string(), std::ifstream::in | std::ios::binary);
+ if (*ifs) {
+ std::streamsize buffer_size = 15 * 1024 * 1024;
+ auto buffer = std::make_shared<std::vector<char> >(buffer_size);
+
+ ifs->seekg(0, std::ios::end);
+ auto length = ifs->tellg();
+ ifs->seekg(0, std::ios::beg);
+
+ response->setResponseLength(length);
+ *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));
+ }
+ default_resource_send(*server, response, ifs, buffer, length);
+
+ return;
+
+ }
+ }
+ }
+ }
+
+ std::string proxy = "";
+ HTTPClient *client = nullptr;
+
+ if (proxy_address.empty() && !icn_proxy_address.empty()) {
+ proxy = icn_proxy_address;
+ client = new HTTPClientIcn(20);
+ } else if (!proxy_address.empty() && icn_proxy_address.empty()) {
+ proxy = proxy_address;
+ client = new HTTPClientTcp;
+ } else if (!proxy_address.empty() && !icn_proxy_address.empty()) {
+ if (socket_request) {
+ proxy = icn_proxy_address;
+ client = new HTTPClientIcn(20);
+ } else {
+ proxy = proxy_address;
+ client = new HTTPClientTcp;
+ }
+ }
+
+ if (!proxy.empty()) {
+ std::stringstream ss;
+ if (strncmp("http://", proxy.c_str(), 7) != 0) {
+ if (strncmp("https://", proxy.c_str(), 8) != 0) {
+ ss << "https://";
+ } else {
+ ss << "http://";
+ }
+ }
+ ss << proxy;
+ ss << request->getPath();
+ std::cout << ss.str() << std::endl;
+ client->download(ss.str(), *response);
+
+ delete client;
+ if (response->size() == 0) {
+ *response << "HTTP/1.1 504 Gateway Timeout\r\n\r\n";
+ }
+
+ return;
+ }
+
+ std::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;
+ };
+
+ __android_log_print(ANDROID_LOG_INFO, "HttpServer", "HttpServer Starting");
+ server->start();
+
+}
+
+extern "C"
+JNIEXPORT void JNICALL
+Java_icn_httpserver_com_supportlibrary_HttpServer_stop(JNIEnv *env, jobject instance) {
+ server->stop();
+ _isRunning = false;
+ __android_log_print(ANDROID_LOG_INFO, "HttpServer", "HttpServer Stopped");
+
+}
+
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_icn_httpserver_com_supportlibrary_HttpServer_isRunning(JNIEnv *env, jobject instance) {
+ __android_log_print(ANDROID_LOG_INFO, "HttpServer", "Is Running? %s", _isRunning ? "true" : "false");
+ return _isRunning;
+
+} \ No newline at end of file