Move crow to its own repo
diff --git a/crow/include/crow/http_request.h b/crow/include/crow/http_request.h
new file mode 100644
index 0000000..354f997
--- /dev/null
+++ b/crow/include/crow/http_request.h
@@ -0,0 +1,62 @@
+#pragma once
+
+#include <boost/asio.hpp>
+
+#include "crow/ci_map.h"
+#include "crow/common.h"
+#include "crow/query_string.h"
+
+namespace crow {
+template <typename T>
+inline const std::string& get_header_value(const T& headers,
+                                           const std::string& key) {
+  if (headers.count(key)) {
+    return headers.find(key)->second;
+  }
+  static std::string empty;
+  return empty;
+}
+
+struct DetachHelper;
+
+struct request {
+  HTTPMethod method;
+  std::string raw_url;
+  std::string url;
+  query_string url_params;
+  ci_map headers;
+  std::string body;
+
+  void* middleware_context{};
+  boost::asio::io_service* io_service{};
+
+  request() : method(HTTPMethod::Get) {}
+
+  request(HTTPMethod method, std::string raw_url, std::string url,
+          query_string url_params, ci_map headers, std::string body)
+      : method(method),
+        raw_url(std::move(raw_url)),
+        url(std::move(url)),
+        url_params(std::move(url_params)),
+        headers(std::move(headers)),
+        body(std::move(body)) {}
+
+  void add_header(std::string key, std::string value) {
+    headers.emplace(std::move(key), std::move(value));
+  }
+
+  const std::string& get_header_value(const std::string& key) const {
+    return crow::get_header_value(headers, key);
+  }
+
+  template <typename CompletionHandler>
+  void post(CompletionHandler handler) {
+    io_service->post(handler);
+  }
+
+  template <typename CompletionHandler>
+  void dispatch(CompletionHandler handler) {
+    io_service->dispatch(handler);
+  }
+};
+}