aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-11-27 23:08:12 +0000
committerlloyd <[email protected]>2013-11-27 23:08:12 +0000
commit9917c4c7fa1c7db677d12b3e305e5e2938ef1726 (patch)
tree2673701314ef30154e794ad26de131e8cdbb914a
parentf583ef72eaa57bc52b5a0bc75bbde4a0a4e25c8b (diff)
Add a simple HTTP 1.0 GET using asio (for CRLs and OCSP)
-rw-r--r--doc/relnotes/1_11_6.rst3
-rw-r--r--src/build-data/cc/gcc.txt2
-rw-r--r--src/libstate/info.txt4
-rw-r--r--src/utils/http_get/http_get.cpp95
-rw-r--r--src/utils/http_get/http_get.h34
-rw-r--r--src/utils/http_get/info.txt3
6 files changed, 139 insertions, 2 deletions
diff --git a/doc/relnotes/1_11_6.rst b/doc/relnotes/1_11_6.rst
index a776411fd..84d081d5c 100644
--- a/doc/relnotes/1_11_6.rst
+++ b/doc/relnotes/1_11_6.rst
@@ -1,5 +1,6 @@
Version 1.11.6, Not Yet Released
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- * Add HKDF from :rfc:`5869`
+ * Botan now requires Boost, specifically the filesystem and asio libraries.
+ * Add HKDF from :rfc:`5869`
diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt
index 3a12c64ed..ed425ca84 100644
--- a/src/build-data/cc/gcc.txt
+++ b/src/build-data/cc/gcc.txt
@@ -9,7 +9,7 @@ add_lib_dir_option -L
add_lib_option -l
lang_flags "-D_REENTRANT -std=c++11"
-warning_flags "-Werror -Wno-error=old-style-cast -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast -Wzero-as-null-pointer-constant"
+warning_flags "-Werror -Wno-error=old-style-cast -Wno-error=zero-as-null-pointer-constant -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast -Wzero-as-null-pointer-constant"
lib_opt_flags "-O3"
check_opt_flags "-O2"
diff --git a/src/libstate/info.txt b/src/libstate/info.txt
index 49a6d38ee..7e2bac6ee 100644
--- a/src/libstate/info.txt
+++ b/src/libstate/info.txt
@@ -19,3 +19,7 @@ pubkey
rng
stream
</requires>
+
+<libs>
+all -> boost_system,boost_filesystem
+</libs>
diff --git a/src/utils/http_get/http_get.cpp b/src/utils/http_get/http_get.cpp
new file mode 100644
index 000000000..a6069c861
--- /dev/null
+++ b/src/utils/http_get/http_get.cpp
@@ -0,0 +1,95 @@
+/*
+* HTTP GET function
+* (C) 2013 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/http_get.h>
+#include <botan/parsing.h>
+#include <boost/asio.hpp>
+
+namespace Botan {
+
+http_response sync_http_get(const std::string& url, std::chrono::milliseconds timeout)
+ {
+ using namespace boost::asio::ip;
+
+ const auto protocol_host_sep = url.find("://");
+ const auto host_loc_sep = url.find('/', protocol_host_sep + 3);
+
+ if(protocol_host_sep == std::string::npos || host_loc_sep == std::string::npos)
+ throw std::runtime_error("Invalid URL " + url);
+
+ const std::string protocol = url.substr(0, protocol_host_sep);
+ const std::string hostname = url.substr(protocol_host_sep+3, host_loc_sep-protocol_host_sep-3);
+ const std::string loc = url.substr(host_loc_sep, std::string::npos);
+
+ if(protocol != "http")
+ throw std::runtime_error("Unsupported protocol " + protocol);
+
+ tcp::iostream sock;
+
+ if(timeout.count())
+ sock.expires_from_now(boost::posix_time::milliseconds(timeout.count()));
+
+ sock.connect(hostname, protocol);
+ if(!sock)
+ throw std::runtime_error("Connection to " + hostname + " / " + protocol + " failed");
+
+ sock << "GET " << loc << " HTTP/1.0\r\n";
+ sock << "Host: " << hostname << "\r\n";
+ sock << "Accept: */*\r\n";
+ sock << "Cache-Control: no-cache\r\n";
+ sock << "Connection: close\r\n\r\n";
+ sock.flush();
+
+ std::string line1;
+ std::getline(sock, line1);
+ if(!sock)
+ throw std::runtime_error("No response");
+
+ std::stringstream response_stream(line1);
+ std::string http_version;
+ unsigned int status_code;
+ std::string status_message;
+
+ response_stream >> http_version >> status_code;
+
+ std::getline(response_stream, status_message);
+
+ if(!response_stream || http_version.substr(0,5) != "HTTP/")
+ throw std::runtime_error("Not an HTTP response");
+
+ std::map<std::string, std::string> headers;
+ std::string header_line;
+ while (std::getline(sock, header_line) && header_line != "\r")
+ {
+ auto sep = header_line.find(": ");
+ if(sep == std::string::npos || sep > header_line.size() - 2)
+ throw std::runtime_error("Invalid HTTP header " + header_line);
+ const std::string key = header_line.substr(0, sep);
+ const std::string val = header_line.substr(sep + 2, std::string::npos);
+ headers[key] = val;
+ }
+
+ if(status_code == 301 && headers.count("Location"))
+ return sync_http_get(headers["Location"], timeout);
+
+ std::vector<byte> body;
+ std::vector<byte> buf(4096);
+ while(sock.good())
+ {
+ sock.read(reinterpret_cast<char*>(&buf[0]), buf.size());
+ body.insert(body.end(), &buf[0], &buf[sock.gcount()]);
+ }
+
+ return http_response { status_code, body, headers };
+ }
+
+std::future<http_response> async_http_get(const std::string& url)
+ {
+ return std::async(std::launch::async, sync_http_get, url, std::chrono::seconds(3));
+ }
+
+}
diff --git a/src/utils/http_get/http_get.h b/src/utils/http_get/http_get.h
new file mode 100644
index 000000000..68ee2f85c
--- /dev/null
+++ b/src/utils/http_get/http_get.h
@@ -0,0 +1,34 @@
+/*
+* HTTP GET function
+* (C) 2013 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/types.h>
+#include <future>
+#include <vector>
+#include <map>
+#include <chrono>
+#include <string>
+
+#ifndef BOTAN_UTILS_URLGET_H__
+#define BOTAN_UTILS_URLGET_H__
+
+namespace Botan {
+
+struct http_response
+ {
+ unsigned int status_code;
+ std::vector<byte> body;
+ std::map<std::string, std::string> headers;
+ };
+
+BOTAN_DLL http_response sync_http_get(const std::string& url,
+ std::chrono::milliseconds timeout);
+
+BOTAN_DLL std::future<http_response> BOTAN_DLL async_http_get(const std::string& url);
+
+}
+
+#endif
diff --git a/src/utils/http_get/info.txt b/src/utils/http_get/info.txt
new file mode 100644
index 000000000..ab36a6b95
--- /dev/null
+++ b/src/utils/http_get/info.txt
@@ -0,0 +1,3 @@
+define HTTP_GET
+
+load_on auto