add support for OPTIONS http method

This commit is contained in:
Tomasz Sowa 2022-08-11 08:04:40 +02:00
parent f651df6e1f
commit ceb5336ca1
7 changed files with 41 additions and 10 deletions

View File

@ -1305,6 +1305,9 @@ void App::CheckRequestMethod()
else else
if( pt::to_lower(cur.request->env_request_method[0]) == 'd' ) if( pt::to_lower(cur.request->env_request_method[0]) == 'd' )
cur.request->method = Request::delete_; cur.request->method = Request::delete_;
else
if( pt::to_lower(cur.request->env_request_method[0]) == 'o' )
cur.request->method = Request::options;
} }
} }

View File

@ -53,6 +53,7 @@ public:
static constexpr const wchar_t * accept = L"Accept"; static constexpr const wchar_t * accept = L"Accept";
static constexpr const wchar_t * accept_language = L"Accept-Language"; static constexpr const wchar_t * accept_language = L"Accept-Language";
static constexpr const wchar_t * authorization = L"Authorization"; static constexpr const wchar_t * authorization = L"Authorization";
static constexpr const wchar_t * allow = L"Allow";
/* /*
* headers' names lower case * headers' names lower case
@ -92,6 +93,7 @@ public:
static const int status_200_ok = 200; static const int status_200_ok = 200;
static const int status_204_no_content = 204;
static const int status_300_multiple_choices = 300; static const int status_300_multiple_choices = 300;
static const int status_301_moved_permanently = 301; static const int status_301_moved_permanently = 301;
static const int status_302_found = 302; static const int status_302_found = 302;
@ -106,6 +108,7 @@ public:
static constexpr const wchar_t * str_status_200 = L"OK"; static constexpr const wchar_t * str_status_200 = L"OK";
static constexpr const wchar_t * str_status_204 = L"No Content";
static constexpr const wchar_t * str_status_300 = L"Multiple Choices"; static constexpr const wchar_t * str_status_300 = L"Multiple Choices";
static constexpr const wchar_t * str_status_301 = L"Moved Permanently"; static constexpr const wchar_t * str_status_301 = L"Moved Permanently";
static constexpr const wchar_t * str_status_302 = L"Found"; static constexpr const wchar_t * str_status_302 = L"Found";
@ -134,6 +137,7 @@ protected:
static constexpr StatusIntStringMapHelper status_int_string_map[] = { static constexpr StatusIntStringMapHelper status_int_string_map[] = {
{status_200_ok, str_status_200}, {status_200_ok, str_status_200},
{status_204_no_content, str_status_204},
{status_300_multiple_choices, str_status_300}, {status_300_multiple_choices, str_status_300},
{status_301_moved_permanently, str_status_301}, {status_301_moved_permanently, str_status_301},
{status_302_found, str_status_302}, {status_302_found, str_status_302},

View File

@ -828,8 +828,8 @@ void Request::ModifyStatusForRedirect()
// may rename to something like PrepareAndSendAnswer()?
void Request::SendAnswer() void Request::PrepareAndSendAnswer()
{ {
output_8bit.clear(); output_8bit.clear();
compressed_output.clear(); compressed_output.clear();
@ -845,9 +845,7 @@ void Request::SendAnswer()
} }
} }
// may use CanSendContent() method? if( !redirect_to.empty() || !x_sendfile.empty() || method == Request::options )
// what about method HEAD?
if( !redirect_to.empty() || !x_sendfile.empty() )
{ {
Send8bitOutput(output_8bit); // send empty content Send8bitOutput(output_8bit); // send empty content
return; return;
@ -1787,7 +1785,7 @@ void Request::SendHeaders()
{ {
if( i->second->is_wstr() ) if( i->second->is_wstr() )
{ {
pt::wide_to_utf8(i->first, aheader_name); pt::wide_to_utf8(i->first, aheader_name);
pt::wide_to_utf8(*i->second->get_wstr(), aheader_value); pt::wide_to_utf8(*i->second->get_wstr(), aheader_value);
FCGX_PutS(aheader_name.c_str(), fcgi_request.out); FCGX_PutS(aheader_name.c_str(), fcgi_request.out);
@ -1905,7 +1903,7 @@ bool Request::CanSendContent()
return false; return false;
} }
if( method == Request::head ) if( method == Request::head || method == Request::options )
{ {
return false; return false;
} }
@ -1933,7 +1931,7 @@ void Request::LogRequestTime()
void Request::FinishRequest() void Request::FinishRequest()
{ {
modify_status_code_if_needed(); // will be removed modify_status_code_if_needed(); // will be removed
SendAnswer(); PrepareAndSendAnswer();
RequestEnds(); RequestEnds();
LogRequestTime(); LogRequestTime();

View File

@ -160,7 +160,7 @@ public:
the HTTP method the HTTP method
!! IMPROVE ME add the rest methods here !! IMPROVE ME add the rest methods here
*/ */
enum Method { get, post, head, delete_, unknown_method } method; enum Method { get, post, head, delete_, options, unknown_method } method;
/* /*
@ -549,7 +549,7 @@ private:
void http_status_error_title(EzcEnv & env); void http_status_error_title(EzcEnv & env);
void http_status_error_description(EzcEnv & env); void http_status_error_description(EzcEnv & env);
void SendAnswer(); void PrepareAndSendAnswer();
void PrepareRawAnswer(); void PrepareRawAnswer();
void PrepareJsonAnswer(); void PrepareJsonAnswer();
void PrepareXmlAnswer(); void PrepareXmlAnswer();

View File

@ -160,6 +160,13 @@ void FunctionBase::MakeDelete()
} }
void FunctionBase::MakeOptions()
{
cur->request->http_status = Header::status_204_no_content;
cur->request->out_headers.add(Header::allow, L"OPTIONS, GET, HEAD, POST, DELETE");
}
void FunctionBase::Clear() void FunctionBase::Clear()
{ {
// do nothing by default // do nothing by default
@ -183,6 +190,10 @@ void FunctionBase::ContinueMakeDelete()
// do nothing by default // do nothing by default
} }
void FunctionBase::ContinueMakeOptions()
{
// do nothing by default
}
} // namespace Winix } // namespace Winix

View File

@ -113,6 +113,7 @@ public:
virtual void MakePost(); virtual void MakePost();
virtual void MakeGet(); virtual void MakeGet();
virtual void MakeDelete(); virtual void MakeDelete();
virtual void MakeOptions();
virtual void Clear(); virtual void Clear();
/* /*
@ -122,6 +123,7 @@ public:
virtual void ContinueMakePost(); virtual void ContinueMakePost();
virtual void ContinueMakeGet(); virtual void ContinueMakeGet();
virtual void ContinueMakeDelete(); virtual void ContinueMakeDelete();
virtual void ContinueMakeOptions();
//void SetConfig(Config * pconfig); //void SetConfig(Config * pconfig);

View File

@ -505,6 +505,12 @@ void Functions::MakeFunction()
cur->request->function->MakeDelete(); cur->request->function->MakeDelete();
} }
else else
if( cur->request->method == Request::options )
{
if( cur->request->redirect_to.empty() )
cur->request->function->MakeOptions();
}
else
{ {
log << log1 << "Functions: unknown request method (skipping)" << logend; log << log1 << "Functions: unknown request method (skipping)" << logend;
} }
@ -557,6 +563,13 @@ void Functions::ContinueMakeFunction()
cur->request->function->ContinueMakeDelete(); cur->request->function->ContinueMakeDelete();
} }
else else
if( cur->request->method == Request::options )
{
log << log4 << "Functions: continuing method options for request " << cur->request
<< " for function " << cur->request->function->fun.url << logend;
cur->request->function->ContinueMakeOptions();
}
else
{ {
log << log1 << "Functions: cannot continue a request, unknown request method (skipping)" << logend; log << log1 << "Functions: cannot continue a request, unknown request method (skipping)" << logend;
} }