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 {
}
void
Parser::Step::raise(const char* msg) {
throw ParsingError(msg);
Parser::Step::raise(const char* msg, Code code /* = Code::Bad_Request */) {
throw HttpError(code, msg);
}
Parser::State
......@@ -143,10 +143,13 @@ namespace Private {
else if (tryMatch("DELETE")) {
request->method = Method::Delete;
}
else {
raise("Unknown HTTP request method");
}
auto n = cursor.next();
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;
......@@ -376,9 +379,19 @@ const char* codeString(Code 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()
: version(Version::Http11)
{ }
......@@ -448,8 +461,13 @@ Handler::onInput(const char* buffer, size_t len, Tcp::Peer& peer) {
onRequest(parser.request, peer);
parser.reset();
}
} catch (const Private::ParsingError &err) {
cerr << "Error when parsing HTTP request: " << err.what() << endl;
} catch (const HttpError &err) {
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 {
const char* methodString(Method method);
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
class Message {
public:
......@@ -124,10 +140,6 @@ private:
namespace Private {
struct ParsingError : public std::runtime_error {
ParsingError(const char* msg) : std::runtime_error(msg) { }
};
struct Parser {
struct Buffer {
......@@ -204,7 +216,7 @@ namespace Private {
virtual State apply(Cursor& cursor) = 0;
void raise(const char* msg);
void raise(const char* msg, Code code = Code::Bad_Request);
Request *request;
};
......@@ -336,7 +348,6 @@ public:
private:
Private::Parser& getParser(Tcp::Peer& peer);
};
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