diff --git a/winixd/core/app.cpp b/winixd/core/app.cpp index 0294b6e..3ee30fc 100644 --- a/winixd/core/app.cpp +++ b/winixd/core/app.cpp @@ -1305,6 +1305,9 @@ void App::CheckRequestMethod() else if( pt::to_lower(cur.request->env_request_method[0]) == 'd' ) cur.request->method = Request::delete_; + else + if( pt::to_lower(cur.request->env_request_method[0]) == 'o' ) + cur.request->method = Request::options; } } diff --git a/winixd/core/header.h b/winixd/core/header.h index 3b8a3b2..0e60c5b 100644 --- a/winixd/core/header.h +++ b/winixd/core/header.h @@ -53,6 +53,7 @@ public: static constexpr const wchar_t * accept = L"Accept"; static constexpr const wchar_t * accept_language = L"Accept-Language"; static constexpr const wchar_t * authorization = L"Authorization"; + static constexpr const wchar_t * allow = L"Allow"; /* * headers' names lower case @@ -92,6 +93,7 @@ public: 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_301_moved_permanently = 301; 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_204 = L"No Content"; 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_302 = L"Found"; @@ -134,6 +137,7 @@ protected: static constexpr StatusIntStringMapHelper status_int_string_map[] = { {status_200_ok, str_status_200}, + {status_204_no_content, str_status_204}, {status_300_multiple_choices, str_status_300}, {status_301_moved_permanently, str_status_301}, {status_302_found, str_status_302}, diff --git a/winixd/core/request.cpp b/winixd/core/request.cpp index 2c86aca..36f0970 100644 --- a/winixd/core/request.cpp +++ b/winixd/core/request.cpp @@ -828,8 +828,8 @@ void Request::ModifyStatusForRedirect() - -void Request::SendAnswer() +// may rename to something like PrepareAndSendAnswer()? +void Request::PrepareAndSendAnswer() { output_8bit.clear(); compressed_output.clear(); @@ -845,9 +845,7 @@ void Request::SendAnswer() } } - // may use CanSendContent() method? - // what about method HEAD? - if( !redirect_to.empty() || !x_sendfile.empty() ) + if( !redirect_to.empty() || !x_sendfile.empty() || method == Request::options ) { Send8bitOutput(output_8bit); // send empty content return; @@ -1787,7 +1785,7 @@ void Request::SendHeaders() { 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); FCGX_PutS(aheader_name.c_str(), fcgi_request.out); @@ -1905,7 +1903,7 @@ bool Request::CanSendContent() return false; } - if( method == Request::head ) + if( method == Request::head || method == Request::options ) { return false; } @@ -1933,7 +1931,7 @@ void Request::LogRequestTime() void Request::FinishRequest() { modify_status_code_if_needed(); // will be removed - SendAnswer(); + PrepareAndSendAnswer(); RequestEnds(); LogRequestTime(); diff --git a/winixd/core/request.h b/winixd/core/request.h index 0b09d48..9703a74 100644 --- a/winixd/core/request.h +++ b/winixd/core/request.h @@ -160,7 +160,7 @@ public: the HTTP method !! 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_description(EzcEnv & env); - void SendAnswer(); + void PrepareAndSendAnswer(); void PrepareRawAnswer(); void PrepareJsonAnswer(); void PrepareXmlAnswer(); diff --git a/winixd/functions/functionbase.cpp b/winixd/functions/functionbase.cpp index 149a6a4..ea15040 100644 --- a/winixd/functions/functionbase.cpp +++ b/winixd/functions/functionbase.cpp @@ -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() { // do nothing by default @@ -183,6 +190,10 @@ void FunctionBase::ContinueMakeDelete() // do nothing by default } +void FunctionBase::ContinueMakeOptions() +{ + // do nothing by default +} } // namespace Winix diff --git a/winixd/functions/functionbase.h b/winixd/functions/functionbase.h index d257728..1cb5e2e 100644 --- a/winixd/functions/functionbase.h +++ b/winixd/functions/functionbase.h @@ -113,6 +113,7 @@ public: virtual void MakePost(); virtual void MakeGet(); virtual void MakeDelete(); + virtual void MakeOptions(); virtual void Clear(); /* @@ -122,6 +123,7 @@ public: virtual void ContinueMakePost(); virtual void ContinueMakeGet(); virtual void ContinueMakeDelete(); + virtual void ContinueMakeOptions(); //void SetConfig(Config * pconfig); diff --git a/winixd/functions/functions.cpp b/winixd/functions/functions.cpp index 352bb84..01e02a3 100644 --- a/winixd/functions/functions.cpp +++ b/winixd/functions/functions.cpp @@ -505,6 +505,12 @@ void Functions::MakeFunction() cur->request->function->MakeDelete(); } 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; } @@ -557,6 +563,13 @@ void Functions::ContinueMakeFunction() cur->request->function->ContinueMakeDelete(); } 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; }