@@ -35,6 +35,57 @@ std::string Server::GetVar(const char* var) {
3535 return Z_STRVAL_P (data);
3636}
3737
38+ // Return the method from the query param _method (_GET["_method"])
39+ std::string Server::GetMethodFromQuery () {
40+ zval *get_array;
41+ get_array = zend_hash_str_find (&EG (symbol_table), " _GET" , sizeof (" _GET" ) - 1 );
42+ if (!get_array || Z_TYPE_P (get_array) != IS_ARRAY) {
43+ return " " ;
44+ }
45+
46+ zval* query_method = zend_hash_str_find (Z_ARRVAL_P (get_array), " _method" , sizeof (" _method" ) - 1 );
47+ if (!query_method) {
48+ return " " ;
49+ }
50+ if (Z_TYPE_P (query_method) != IS_STRING) {
51+ return " " ;
52+ }
53+ std::string query_method_str = Z_STRVAL_P (query_method);
54+ return ToUppercase (query_method_str);
55+ }
56+
57+ // For frameworks like Symfony, Laravel, method override is supported using X-HTTP-METHOD-OVERRIDE or _method query param
58+ // https://github.com/symfony/symfony/blob/b8eaa4be31f2159918e79e5694bc9ff241e0d692/src/Symfony/Component/HttpFoundation/Request.php#L1169-L1215
59+ std::string Server::GetMethod () {
60+ std::string method = ToUppercase (this ->GetVar (" REQUEST_METHOD" ));
61+
62+ // if symfony http foundation is not used, return the method as is, otherwise we need to check the method override
63+ if (!AIKIDO_GLOBAL (uses_symfony_http_foundation)) {
64+ return method;
65+ }
66+
67+ // only for POST requests, we need to check the method override
68+ if (method != " POST" ) {
69+ return method;
70+ }
71+
72+ // X-HTTP-METHOD-OVERRIDE
73+ std::string x_http_method_override = ToUppercase (this ->GetVar (" HTTP_X_HTTP_METHOD_OVERRIDE" ));
74+ if (x_http_method_override != " " ) {
75+ method = x_http_method_override;
76+ }
77+
78+ // in case of X-HTTP-METHOD-OVERRIDE is not set, we check the query param _method
79+ if (x_http_method_override == " " ) {
80+ std::string query_method = this ->GetMethodFromQuery ();
81+ if (query_method != " " ) {
82+ method = query_method;
83+ }
84+ }
85+
86+ return method;
87+ }
88+
3889std::string Server::GetRoute () {
3990 std::string route = this ->GetVar (" REQUEST_URI" );
4091 size_t pos = route.find (" ?" );
0 commit comments