inets httpd incorrectly returns 501 Not Implemented for 'PUT' and 'DELETE' methods

Hunter Morris huntermorris@REDACTED
Mon Jul 6 14:01:45 CEST 2009


Hello,

httpd_request:validate/3 does not allow applications to use the 'PUT'
and 'DELETE' methods which are common in many server applications.
The patch included inline would allow the two additional methods:

---
 lib/inets/src/http_server/httpd_request.erl |    6 +++++-
 lib/inets/src/http_server/mod_cgi.erl       |    2 ++
 lib/inets/src/http_server/mod_esi.erl       |   24 ++++++++++++++++++++++++
 3 files changed, 31 insertions(+), 1 deletions(-)

diff --git a/lib/inets/src/http_server/httpd_request.erl
b/lib/inets/src/http_server/httpd_request.erl
index ad2cc4b..5a2f0d4 100644
--- a/lib/inets/src/http_server/httpd_request.erl
+++ b/lib/inets/src/http_server/httpd_request.erl
@@ -71,7 +71,7 @@ body_data(Headers, Body) ->
 %%-------------------------------------------------------------------------
 %% validate(Method, Uri, Version) -> ok | {error, {bad_request, Reason} |
 %%			     {error, {not_supported, {Method, Uri, Version}}
-%%      Method = "HEAD" | "GET" | "POST" | "TRACE"
+%%      Method = "HEAD" | "GET" | "POST" | "TRACE" | "PUT" | "DELETE"
 %%      Uri = uri()
 %%      Version = "HTTP/N.M"
 %% Description: Checks that HTTP-request-line is valid.
@@ -86,6 +86,10 @@ validate("GET", Uri, "HTTP/1." ++ _N) ->
     validate_uri(Uri);
 validate("POST", Uri, "HTTP/1." ++ _N) ->
     validate_uri(Uri);
+validate("PUT", Uri, "HTTP/1." ++ _N) ->
+    validate_uri(Uri);
+validate("DELETE", Uri, "HTTP/1." ++ _N) ->
+    validate_uri(Uri);
 validate("TRACE", Uri, "HTTP/1." ++ N) when hd(N) >= $1 ->
     validate_uri(Uri);
 validate(Method, Uri, Version) ->
diff --git a/lib/inets/src/http_server/mod_cgi.erl
b/lib/inets/src/http_server/mod_cgi.erl
index ab12a3b..a0206bd 100644
--- a/lib/inets/src/http_server/mod_cgi.erl
+++ b/lib/inets/src/http_server/mod_cgi.erl
@@ -335,6 +335,8 @@ script_elements(#mod{method = "GET"}, {PathInfo,
QueryString}) ->
     [{query_string, QueryString}, {path_info, PathInfo}];
 script_elements(#mod{method = "POST", entity_body = Body}, _) ->
     [{entity_body, Body}];
+script_elements(#mod{method = "PUT", entity_body = Body}, _) ->
+    [{entity_body, Body}];
 script_elements(_, _) ->
     [].

diff --git a/lib/inets/src/http_server/mod_esi.erl
b/lib/inets/src/http_server/mod_esi.erl
index dd6f62a..ec9de66 100644
--- a/lib/inets/src/http_server/mod_esi.erl
+++ b/lib/inets/src/http_server/mod_esi.erl
@@ -249,6 +249,18 @@ erl(#mod{method = Method} = ModData, ESIBody, Modules)
 	    {proceed, [{status,{400, none, BadRequest}} | ModData#mod.data]}
     end;

+erl(#mod{request_uri = ReqUri, method = "PUT",
+         http_version = Version, data = Data}, _ESIBody, _Modules) ->
+    {proceed,[{status,{501,{"PUT", ReqUri, Version},
+		       ?NICE("Erl mechanism doesn't support method PUT")}}|
+	      Data]};
+
+erl(#mod{request_uri = ReqUri, method = "DELETE",
+         http_version = Version, data = Data}, _ESIBody, _Modules) ->
+    {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+		       ?NICE("Erl mechanism doesn't support method DELETE")}}|
+	      Data]};
+
 erl(#mod{method = "POST", entity_body = Body} = ModData, ESIBody, Modules) ->
     case httpd_util:split(ESIBody,":|%3A|/",2) of
 	{ok,[ModuleName, Function]} ->
@@ -450,6 +462,18 @@ eval(#mod{request_uri = ReqUri, method = "POST",
 		       ?NICE("Eval mechanism doesn't support method POST")}}|
 	      Data]};

+eval(#mod{request_uri = ReqUri, method = "PUT",
+	  http_version = Version, data = Data}, _ESIBody, _Modules) ->
+    {proceed,[{status,{501,{"PUT", ReqUri, Version},
+		       ?NICE("Eval mechanism doesn't support method PUT")}}|
+	      Data]};
+
+eval(#mod{request_uri = ReqUri, method = "DELETE",
+	  http_version = Version, data = Data}, _ESIBody, _Modules) ->
+    {proceed,[{status,{501,{"DELETE", ReqUri, Version},
+		       ?NICE("Eval mechanism doesn't support method DELETE")}}|
+	      Data]};
+
 eval(#mod{method = Method} = ModData, ESIBody, Modules)
   when Method == "GET"; Method == "HEAD" ->
     case is_authorized(ESIBody, Modules) of
--


More information about the erlang-bugs mailing list