summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2019-02-08 21:13:13 +0000
committerDan Goodliffe <dan@randomdan.homeip.net>2019-02-08 21:13:13 +0000
commit328f8930e80068bf0b04411f5ca2b1e4702f8515 (patch)
tree8d11a436b61fcc036cfccbd10d117ef6e7bacb5c
parentUpdate boost::function to std::function (diff)
downloadicespider-328f8930e80068bf0b04411f5ca2b1e4702f8515.tar.bz2
icespider-328f8930e80068bf0b04411f5ca2b1e4702f8515.tar.xz
icespider-328f8930e80068bf0b04411f5ca2b1e4702f8515.zip
Properly generic parameter extraction
-rw-r--r--icespider/core/ihttpRequest.cpp48
-rw-r--r--icespider/core/ihttpRequest.h47
2 files changed, 48 insertions, 47 deletions
diff --git a/icespider/core/ihttpRequest.cpp b/icespider/core/ihttpRequest.cpp
index aaa0c26..b8d866a 100644
--- a/icespider/core/ihttpRequest.cpp
+++ b/icespider/core/ihttpRequest.cpp
@@ -103,8 +103,8 @@ namespace IceSpider {
}
}
- const std::string &
- IHttpRequest::getURLParam(unsigned int idx) const
+ OptionalString
+ IHttpRequest::getURLParam(const unsigned int & idx) const
{
auto & url = getRequestPath();
if (idx >= url.size()) {
@@ -170,45 +170,9 @@ namespace IceSpider {
s.second->Serialize(mp);
}
- std::optional<std::string>
- operator!(const std::optional<std::string_view> & sv)
- {
- // TODO: Fix this mess (only required if operation requires std::string)
- if (sv) return { std::string(*sv) };
- return {};
- }
-
-#define getParams(T) \
- template<> T IHttpRequest::getURLParam<T>(unsigned int idx) const { \
- return wrapLexicalCast<T>(getURLParam(idx)); } \
- template<> std::optional<T> IHttpRequest::getQueryStringParam<T>(const std::string_view & key) const { \
- return optionalLexicalCast<T>(getQueryStringParam(key)); } \
- template<> std::optional<T> IHttpRequest::getCookieParam<T>(const std::string_view & key) const { \
- return optionalLexicalCast<T>(getCookieParam(key)); } \
- template<> std::optional<T> IHttpRequest::getHeaderParam<T>(const std::string_view & key) const { \
- return optionalLexicalCast<T>(getHeaderParam(key)); }
- template<> std::string_view IHttpRequest::getURLParam<std::string_view>(unsigned int idx) const {
- return getURLParam(idx); }
- template<> OptionalString IHttpRequest::getQueryStringParam<std::string_view>(const std::string_view & key) const { \
- return getQueryStringParam(key); }
- template<> OptionalString IHttpRequest::getCookieParam<std::string_view>(const std::string_view & key) const { \
- return getCookieParam(key); }
- template<> OptionalString IHttpRequest::getHeaderParam<std::string_view>(const std::string_view & key) const { \
- return getHeaderParam(key); }
- template<> std::string IHttpRequest::getURLParam<std::string>(unsigned int idx) const {
- return getURLParam(idx); }
- template<> std::optional<std::string> IHttpRequest::getQueryStringParam<std::string>(const std::string_view & key) const { \
- return !getQueryStringParam(key); }
- template<> std::optional<std::string> IHttpRequest::getCookieParam<std::string>(const std::string_view & key) const { \
- return !getCookieParam(key); }
- template<> std::optional<std::string> IHttpRequest::getHeaderParam<std::string>(const std::string_view & key) const { \
- return !getHeaderParam(key); }
-
- getParams(bool);
- getParams(Ice::Short);
- getParams(Ice::Int);
- getParams(Ice::Long);
- getParams(Ice::Float);
- getParams(Ice::Double);
+ static_assert(std::is_convertible<OptionalString::value_type, std::string_view>::value);
+ static_assert(!std::is_convertible<OptionalString::value_type, std::string>::value);
+ static_assert(std::is_constructible<OptionalString::value_type, std::string>::value);
}
+
diff --git a/icespider/core/ihttpRequest.h b/icespider/core/ihttpRequest.h
index 5471209..fb56efb 100644
--- a/icespider/core/ihttpRequest.h
+++ b/icespider/core/ihttpRequest.h
@@ -9,6 +9,7 @@
#include <slicer/slicer.h>
#include <Ice/Optional.h>
#include <boost/lexical_cast.hpp>
+#include "exceptions.h"
namespace IceSpider {
class Core;
@@ -27,7 +28,7 @@ namespace IceSpider {
virtual PathElements & getRequestPath() = 0;
virtual HttpMethod getRequestMethod() const = 0;
- const std::string & getURLParam(unsigned int) const;
+ OptionalString getURLParam(const unsigned int &) const;
virtual OptionalString getQueryStringParam(const std::string_view &) const = 0;
virtual OptionalString getHeaderParam(const std::string_view &) const = 0;
virtual OptionalString getCookieParam(const std::string_view &) const = 0;
@@ -41,8 +42,35 @@ namespace IceSpider {
virtual std::ostream & dump(std::ostream & s) const = 0;
+ template<typename T, typename K>
+ inline
+ std::optional<T> getFrom(const K & key, OptionalString (IHttpRequest::*src)(const K &) const) const
+ {
+ if (auto v = (this->*src)(key)) {
+ if constexpr (std::is_convertible<std::string_view, T>::value) {
+ return *v;
+ }
+ else if constexpr (std::is_constructible<std::string_view, T>::value) {
+ return T(*v);
+ }
+ else {
+ try {
+ return boost::lexical_cast<T>(*v);
+ }
+ catch (const boost::bad_lexical_cast & e) {
+ throw Http400_BadRequest();
+ }
+ }
+ }
+ else {
+ return std::nullopt;
+ }
+ }
template<typename T>
- T getURLParam(unsigned int) const;
+ T getURLParam(unsigned int n) const
+ {
+ return *getFrom<T, unsigned int>(n, &IHttpRequest::getURLParam);
+ }
template<typename T>
std::optional<T> getBody() const
{
@@ -79,11 +107,20 @@ namespace IceSpider {
}
}
template<typename T>
- std::optional<T> getQueryStringParam(const std::string_view & key) const;
+ std::optional<T> getQueryStringParam(const std::string_view & key) const
+ {
+ return getFrom<T, std::string_view>(key, &IHttpRequest::getQueryStringParam);
+ }
template<typename T>
- std::optional<T> getHeaderParam(const std::string_view & key) const;
+ std::optional<T> getHeaderParam(const std::string_view & key) const
+ {
+ return getFrom<T, std::string_view>(key, &IHttpRequest::getHeaderParam);
+ }
template<typename T>
- std::optional<T> getCookieParam(const std::string_view & key) const;
+ std::optional<T> getCookieParam(const std::string_view & key) const
+ {
+ return getFrom<T, std::string_view>(key, &IHttpRequest::getCookieParam);
+ }
virtual void response(short, const std::string_view &) const = 0;
template<typename T>
void response(const IRouteHandler * route, const T & t) const