Commit 493c8fe0 authored by Mathieu Stefani's avatar Mathieu Stefani

The server now returns an HTTP Bad Request when parsing fails and returns a...

The server now returns an HTTP Bad Request when parsing fails and returns a 500 when an exception is thrown
parent c7169630
...@@ -106,8 +106,8 @@ namespace Private { ...@@ -106,8 +106,8 @@ namespace Private {
} }
void void
Parser::Step::raise(const char* msg) { Parser::Step::raise(const char* msg, Code code /* = Code::Bad_Request */) {
throw ParsingError(msg); throw HttpError(code, msg);
} }
Parser::State Parser::State
...@@ -143,10 +143,13 @@ namespace Private { ...@@ -143,10 +143,13 @@ namespace Private {
else if (tryMatch("DELETE")) { else if (tryMatch("DELETE")) {
request->method = Method::Delete; request->method = Method::Delete;
} }
else {
raise("Unknown HTTP request method");
}
auto n = cursor.next(); auto n = cursor.next();
if (n == Cursor::Eof) return State::Again; if (n == Cursor::Eof) return State::Again;
else if (n != ' ') raise("Malformed HTTP Request"); else if (n != ' ') raise("Malformed HTTP request after Method, expected SP");
if (!cursor.advance(2)) return State::Again; if (!cursor.advance(2)) return State::Again;
...@@ -376,9 +379,19 @@ const char* codeString(Code code) ...@@ -376,9 +379,19 @@ const char* codeString(Code code)
#undef CODE #undef CODE
} }
unreachable(); return "";
} }
HttpError::HttpError(Code code, std::string reason)
: code_(static_cast<int>(code))
, reason_(std::move(reason))
{ }
HttpError::HttpError(int code, std::string reason)
: code_(code)
, reason_(std::move(reason))
{ }
Message::Message() Message::Message()
: version(Version::Http11) : version(Version::Http11)
{ } { }
...@@ -448,8 +461,13 @@ Handler::onInput(const char* buffer, size_t len, Tcp::Peer& peer) { ...@@ -448,8 +461,13 @@ Handler::onInput(const char* buffer, size_t len, Tcp::Peer& peer) {
onRequest(parser.request, peer); onRequest(parser.request, peer);
parser.reset(); parser.reset();
} }
} catch (const Private::ParsingError &err) { } catch (const HttpError &err) {
cerr << "Error when parsing HTTP request: " << err.what() << endl; Response response(err.code(), err.reason());
response.writeTo(peer);
}
catch (const std::exception& e) {
Response response(Code::Internal_Server_Error, e.what());
response.writeTo(peer);
} }
} }
} }
......
...@@ -90,6 +90,22 @@ enum class Version { ...@@ -90,6 +90,22 @@ enum class Version {
const char* methodString(Method method); const char* methodString(Method method);
const char* codeString(Code code); const char* codeString(Code code);
struct HttpError : public std::exception {
HttpError(Code code, std::string reason);
HttpError(int code, std::string reason);
~HttpError() noexcept { }
const char* what() const noexcept { return reason_.c_str(); }
int code() const { return code_; }
std::string reason() const { return reason_; }
private:
int code_;
std::string reason_;
};
// 4. HTTP Message // 4. HTTP Message
class Message { class Message {
public: public:
...@@ -124,10 +140,6 @@ private: ...@@ -124,10 +140,6 @@ private:
namespace Private { namespace Private {
struct ParsingError : public std::runtime_error {
ParsingError(const char* msg) : std::runtime_error(msg) { }
};
struct Parser { struct Parser {
struct Buffer { struct Buffer {
...@@ -204,7 +216,7 @@ namespace Private { ...@@ -204,7 +216,7 @@ namespace Private {
virtual State apply(Cursor& cursor) = 0; virtual State apply(Cursor& cursor) = 0;
void raise(const char* msg); void raise(const char* msg, Code code = Code::Bad_Request);
Request *request; Request *request;
}; };
...@@ -336,7 +348,6 @@ public: ...@@ -336,7 +348,6 @@ public:
private: private:
Private::Parser& getParser(Tcp::Peer& peer); Private::Parser& getParser(Tcp::Peer& peer);
}; };
class Endpoint { class Endpoint {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment