a bit better way to treah handlers
This commit is contained in:
parent
f0d205dee7
commit
3fe6d25448
16 changed files with 291 additions and 95 deletions
|
@ -3,6 +3,8 @@
|
|||
|
||||
#include "request.h"
|
||||
|
||||
#include "response/response.h"
|
||||
|
||||
constexpr static const char* GET("GET");
|
||||
|
||||
constexpr static const char* REQUEST_METHOD("REQUEST_METHOD");
|
||||
|
@ -16,9 +18,18 @@ constexpr static const char* SERVER_NAME("SERVER_NAME");
|
|||
//
|
||||
// constexpr static const char* SCRIPT_NAME("SCRIPT_NAME");
|
||||
|
||||
constexpr std::array<
|
||||
std::pair<std::string_view, Request::Method>,
|
||||
static_cast<uint8_t>(Request::Method::unknown)
|
||||
> methods = {{
|
||||
{"GET", Request::Method::get},
|
||||
{"POST", Request::Method::post}
|
||||
}};
|
||||
|
||||
Request::Request ():
|
||||
state(State::initial),
|
||||
raw()
|
||||
raw(),
|
||||
response(nullptr)
|
||||
{}
|
||||
|
||||
Request::~Request() {
|
||||
|
@ -36,12 +47,17 @@ void Request::terminate() {
|
|||
}
|
||||
}
|
||||
|
||||
bool Request::isGet() const {
|
||||
if (state != State::accepted)
|
||||
throw std::runtime_error("An attempt to read request type on a wrong request state");
|
||||
Request::Method Request::method() const {
|
||||
if (state == State::initial)
|
||||
throw std::runtime_error("An attempt to read request method on not accepted request");
|
||||
|
||||
std::string_view method(FCGX_GetParam(REQUEST_METHOD, raw.envp));
|
||||
return method == GET;
|
||||
for (const auto& pair : methods) {
|
||||
if (pair.first == method)
|
||||
return pair.second;
|
||||
}
|
||||
|
||||
return Request::Method::unknown;
|
||||
}
|
||||
|
||||
bool Request::wait(int socketDescriptor) {
|
||||
|
@ -59,20 +75,61 @@ bool Request::wait(int socketDescriptor) {
|
|||
return result;
|
||||
}
|
||||
|
||||
OStream Request::getOutputStream() {
|
||||
if (state != State::accepted)
|
||||
throw std::runtime_error("An attempt to request output stream on a wrong request state");
|
||||
|
||||
OStream Request::getOutputStream(const Response* response) {
|
||||
validateResponse(response);
|
||||
return OStream(raw.out);
|
||||
}
|
||||
|
||||
OStream Request::getErrorStream() {
|
||||
if (state != State::accepted)
|
||||
throw std::runtime_error("An attempt to request error stream on a wrong request state");
|
||||
|
||||
OStream Request::getErrorStream(const Response* response) {
|
||||
validateResponse(response);
|
||||
return OStream(raw.err);
|
||||
}
|
||||
|
||||
void Request::responseIsComplete(const Response* response) {
|
||||
switch (state) {
|
||||
case State::initial:
|
||||
throw std::runtime_error("An attempt to mark the request as complete, but it wasn't even accepted yet");
|
||||
break;
|
||||
case State::accepted:
|
||||
throw std::runtime_error("An attempt to mark the request as complete, but it wasn't responded");
|
||||
break;
|
||||
case State::responding:
|
||||
if (Request::response != response)
|
||||
throw std::runtime_error("An attempt to mark the request as complete by the different response who actually started responding");
|
||||
|
||||
Request::response = nullptr;
|
||||
state = State::responded;
|
||||
break;
|
||||
case State::responded:
|
||||
throw std::runtime_error("An attempt to mark the request as a complete for the second time");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Request::validateResponse(const Response* response) {
|
||||
switch (state) {
|
||||
case State::initial:
|
||||
throw std::runtime_error("An attempt to request stream while the request wasn't even accepted yet");
|
||||
break;
|
||||
case State::accepted:
|
||||
Request::response = response;
|
||||
state = State::responding;
|
||||
break;
|
||||
case State::responding:
|
||||
if (Request::response != response)
|
||||
throw std::runtime_error("Error handling a request: first time one response started replying, then another continued");
|
||||
|
||||
break;
|
||||
case State::responded:
|
||||
throw std::runtime_error("An attempt to request stream on a request that was already done responding");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Request::State Request::currentState() const {
|
||||
return state;
|
||||
}
|
||||
|
||||
std::string Request::getPath(const std::string& serverName) const {
|
||||
if (state != State::accepted)
|
||||
throw std::runtime_error("An attempt to request path on a wrong request state");
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <string_view>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#include <fcgiapp.h>
|
||||
|
||||
|
@ -13,14 +15,22 @@
|
|||
|
||||
#include "stream/ostream.h"
|
||||
|
||||
class Response;
|
||||
class Request {
|
||||
public:
|
||||
enum class State {
|
||||
initial,
|
||||
accepted,
|
||||
responding,
|
||||
responded
|
||||
};
|
||||
|
||||
enum class Method {
|
||||
get,
|
||||
post,
|
||||
unknown
|
||||
};
|
||||
|
||||
Request();
|
||||
~Request();
|
||||
Request(const Request& other) = delete;
|
||||
|
@ -30,17 +40,24 @@ public:
|
|||
|
||||
bool wait(int socketDescriptor);
|
||||
void terminate();
|
||||
bool isGet() const;
|
||||
|
||||
OStream getOutputStream();
|
||||
OStream getErrorStream();
|
||||
Method method() const;
|
||||
State currentState() const;
|
||||
|
||||
OStream getOutputStream(const Response* response);
|
||||
OStream getErrorStream(const Response* response);
|
||||
void responseIsComplete(const Response* response);
|
||||
|
||||
std::string getPath(const std::string& serverName) const;
|
||||
std::string getServerName() const;
|
||||
void printEnvironment(std::ostream& out);
|
||||
void printEnvironment(nlohmann::json& out);
|
||||
|
||||
private:
|
||||
void validateResponse(const Response* response);
|
||||
|
||||
private:
|
||||
State state;
|
||||
FCGX_Request raw;
|
||||
const Response* response;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue