summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Goodliffe <dan@randomdan.homeip.net>2016-09-17 01:14:15 +0100
committerDan Goodliffe <dan@randomdan.homeip.net>2016-09-17 01:14:15 +0100
commit8c88dc924cfb6119a48cdff3b3e2613131ddf974 (patch)
tree42792f2f594b9d9b5c65941cb8d4d2a044d3f3ed
parentRefactor routes into a flat list so we can correctly detect matching routes, ... (diff)
downloadicespider-8c88dc924cfb6119a48cdff3b3e2613131ddf974.tar.bz2
icespider-8c88dc924cfb6119a48cdff3b3e2613131ddf974.tar.xz
icespider-8c88dc924cfb6119a48cdff3b3e2613131ddf974.zip
Proper exceptions for handling 404 and 405
-rw-r--r--icespider/common/http.ice5
-rw-r--r--icespider/core/core.cpp27
-rw-r--r--icespider/core/core.h15
-rw-r--r--icespider/unittests/testApp.cpp22
4 files changed, 52 insertions, 17 deletions
diff --git a/icespider/common/http.ice b/icespider/common/http.ice
index cefb494..abf235f 100644
--- a/icespider/common/http.ice
+++ b/icespider/common/http.ice
@@ -2,6 +2,11 @@
#define ICESPIDER_HTTP_ICE
module IceSpider {
+ exception HttpException {
+ int code;
+ string message;
+ };
+
enum HttpMethod {
GET, HEAD, POST, PUT, DELETE, OPTIONS
};
diff --git a/icespider/core/core.cpp b/icespider/core/core.cpp
index da6a53d..211a4da 100644
--- a/icespider/core/core.cpp
+++ b/icespider/core/core.cpp
@@ -5,6 +5,9 @@
namespace IceSpider {
const boost::filesystem::path Core::defaultConfig("config/ice.properties");
+ DefineHttpEx(Http404_NotFound, 404, "Not found");
+ DefineHttpEx(Http405_MethodNotAllowed, 405, "Method Not Allowed");
+
static
bool
operator/=(const PathElements & pathparts, const IRouteHandler * r)
@@ -49,12 +52,17 @@ namespace IceSpider {
void
Core::process(IHttpRequest * request) const
{
- auto routeHandler = findRoute(request);
- if (routeHandler) {
- routeHandler->execute(request);
+ try {
+ findRoute(request)->execute(request);
+ }
+ catch (const HttpException & he) {
+ request->response(he.code, he.message);
+ }
+ catch (const std::exception & e) {
+ request->response(500, e.what());
}
- else {
- request->response(404, "Not found");
+ catch (...) {
+ request->response(500, "Unknown internal server error");
}
}
@@ -63,8 +71,7 @@ namespace IceSpider {
{
const auto & pathparts = request->getRequestPath();
if (pathparts.size() >= routes.size()) {
- // Not found error
- return NULL;
+ throw Http404_NotFound();
}
const auto & routeSet = routes[pathparts.size()];
bool match = false;
@@ -77,11 +84,9 @@ namespace IceSpider {
}
}
if (!match) {
- // Not found error
- return NULL;
+ throw Http404_NotFound();
}
- // Method not allowed
- return NULL;
+ throw Http405_MethodNotAllowed();
}
Ice::ObjectPrx
diff --git a/icespider/core/core.h b/icespider/core/core.h
index 77d338e..9b011a5 100644
--- a/icespider/core/core.h
+++ b/icespider/core/core.h
@@ -7,7 +7,22 @@
#include <Ice/Communicator.h>
#include <boost/filesystem/path.hpp>
+#define DeclareHttpEx(Name) \
+ class Name : public ::IceSpider::HttpException { \
+ public: \
+ Name(); \
+ static const int code; \
+ static const std::string message; \
+ }
+#define DefineHttpEx(Name, Code, Message) \
+ Name::Name() : ::IceSpider::HttpException(code, message) { } \
+ const int Name::code(Code); \
+ const std::string Name::message(Message);
+
namespace IceSpider {
+ DeclareHttpEx(Http404_NotFound);
+ DeclareHttpEx(Http405_MethodNotAllowed);
+
class DLL_PUBLIC Core {
public:
typedef std::vector<const IRouteHandler *> LengthRoutes;
diff --git a/icespider/unittests/testApp.cpp b/icespider/unittests/testApp.cpp
index 0c44f5e..2a584a4 100644
--- a/icespider/unittests/testApp.cpp
+++ b/icespider/unittests/testApp.cpp
@@ -101,13 +101,13 @@ BOOST_AUTO_TEST_CASE( testFindRoutes )
BOOST_REQUIRE(findRoute(&requestGetIndex));
TestRequest requestPostIndex(this, HttpMethod::POST, "/");
- BOOST_REQUIRE(!findRoute(&requestPostIndex));
+ BOOST_REQUIRE_THROW(findRoute(&requestPostIndex), IceSpider::Http405_MethodNotAllowed);
TestRequest requestPostUpdate(this, HttpMethod::POST, "/something");
BOOST_REQUIRE(findRoute(&requestPostUpdate));
TestRequest requestGetUpdate(this, HttpMethod::GET, "/something");
- BOOST_REQUIRE(!findRoute(&requestGetUpdate));
+ BOOST_REQUIRE_THROW(findRoute(&requestGetUpdate), IceSpider::Http405_MethodNotAllowed);
TestRequest requestGetItem(this, HttpMethod::GET, "/view/something/something");
BOOST_REQUIRE(findRoute(&requestGetItem));
@@ -119,13 +119,13 @@ BOOST_AUTO_TEST_CASE( testFindRoutes )
BOOST_REQUIRE(findRoute(&requestGetItemDefault));
TestRequest requestGetItemLong(this, HttpMethod::GET, "/view/something/something/extra");
- BOOST_REQUIRE(!findRoute(&requestGetItemLong));
+ BOOST_REQUIRE_THROW(findRoute(&requestGetItemLong), IceSpider::Http404_NotFound);
TestRequest requestGetItemShort(this, HttpMethod::GET, "/view/missingSomething");
- BOOST_REQUIRE(!findRoute(&requestGetItemShort));
+ BOOST_REQUIRE_THROW(findRoute(&requestGetItemShort), IceSpider::Http404_NotFound);
TestRequest requestGetNothing(this, HttpMethod::GET, "/badview/something/something");
- BOOST_REQUIRE(!findRoute(&requestGetNothing));
+ BOOST_REQUIRE_THROW(findRoute(&requestGetNothing), IceSpider::Http404_NotFound);
TestRequest requestDeleteThing(this, HttpMethod::DELETE, "/something");
BOOST_REQUIRE(findRoute(&requestDeleteThing));
@@ -388,7 +388,7 @@ BOOST_AUTO_TEST_CASE( testCallIndexComplexAccept )
BOOST_AUTO_TEST_CASE( testCall404 )
{
- TestRequest requestGetIndex(this, HttpMethod::GET, "/404");
+ TestRequest requestGetIndex(this, HttpMethod::GET, "/this/404");
process(&requestGetIndex);
auto h = parseHeaders(requestGetIndex.output);
BOOST_REQUIRE_EQUAL(h["Status"], "404 Not found");
@@ -396,5 +396,15 @@ BOOST_AUTO_TEST_CASE( testCall404 )
BOOST_REQUIRE(requestGetIndex.output.eof());
}
+BOOST_AUTO_TEST_CASE( testCall405 )
+{
+ TestRequest requestGetIndex(this, HttpMethod::GET, "/405");
+ process(&requestGetIndex);
+ auto h = parseHeaders(requestGetIndex.output);
+ BOOST_REQUIRE_EQUAL(h["Status"], "405 Method Not Allowed");
+ requestGetIndex.output.get();
+ BOOST_REQUIRE(requestGetIndex.output.eof());
+}
+
BOOST_AUTO_TEST_SUITE_END();