diff options
| author | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-09-17 01:14:15 +0100 | 
|---|---|---|
| committer | Dan Goodliffe <dan@randomdan.homeip.net> | 2016-09-17 01:14:15 +0100 | 
| commit | 8c88dc924cfb6119a48cdff3b3e2613131ddf974 (patch) | |
| tree | 42792f2f594b9d9b5c65941cb8d4d2a044d3f3ed | |
| parent | Refactor routes into a flat list so we can correctly detect matching routes, ... (diff) | |
| download | icespider-8c88dc924cfb6119a48cdff3b3e2613131ddf974.tar.bz2 icespider-8c88dc924cfb6119a48cdff3b3e2613131ddf974.tar.xz icespider-8c88dc924cfb6119a48cdff3b3e2613131ddf974.zip | |
Proper exceptions for handling 404 and 405
| -rw-r--r-- | icespider/common/http.ice | 5 | ||||
| -rw-r--r-- | icespider/core/core.cpp | 27 | ||||
| -rw-r--r-- | icespider/core/core.h | 15 | ||||
| -rw-r--r-- | icespider/unittests/testApp.cpp | 22 | 
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(); | 
