diff --git a/.gitignore b/.gitignore index c4d48214..332345d9 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ tests/temp/ .svn/ *.swp *~ +*# diff --git a/library/server/ewsgi/specification/request/wgi_meta_names.e b/library/server/ewsgi/specification/request/wgi_meta_names.e index 7eeb913e..a4578a6b 100644 --- a/library/server/ewsgi/specification/request/wgi_meta_names.e +++ b/library/server/ewsgi/specification/request/wgi_meta_names.e @@ -52,6 +52,8 @@ feature -- Access http_access_control_request_headers: STRING = "HTTP_ACCESS_CONTROL_REQUEST_HEADERS" + http_if_match: STRING = "HTTP_IF_MATCH" + gateway_interface: STRING = "GATEWAY_INTERFACE" auth_type: STRING = "AUTH_TYPE" diff --git a/library/server/ewsgi/specification/request/wgi_request.e b/library/server/ewsgi/specification/request/wgi_request.e index 86e1e489..9420a766 100644 --- a/library/server/ewsgi/specification/request/wgi_request.e +++ b/library/server/ewsgi/specification/request/wgi_request.e @@ -604,6 +604,11 @@ feature -- HTTP_* deferred end + http_if_match: detachable READABLE_STRING_8 + -- Existence check on resource + deferred + end + feature -- Extra CGI environment variables request_uri: READABLE_STRING_8 diff --git a/library/server/ewsgi/src/implementation/wgi_request_from_table.e b/library/server/ewsgi/src/implementation/wgi_request_from_table.e index 79fb3007..636f5495 100644 --- a/library/server/ewsgi/src/implementation/wgi_request_from_table.e +++ b/library/server/ewsgi/src/implementation/wgi_request_from_table.e @@ -248,6 +248,12 @@ feature -- Access: HTTP_* CGI meta parameters - 1.1 Result := meta_string_variable ({WGI_META_NAMES}.http_access_control_request_headers) end + http_if_match: detachable READABLE_STRING_8 + -- Existence check on resource + do + Result := meta_string_variable ({WGI_META_NAMES}.http_if_match) + end + feature -- Access: Extension to CGI meta parameters - 1.1 request_uri: READABLE_STRING_8 diff --git a/library/server/wsf/router/wsf_routed_skeleton_service.e b/library/server/wsf/router/wsf_routed_skeleton_service.e index 22c44c90..48284652 100644 --- a/library/server/wsf/router/wsf_routed_skeleton_service.e +++ b/library/server/wsf/router/wsf_routed_skeleton_service.e @@ -256,6 +256,7 @@ feature {NONE} -- Implementation h.put_current_date h.put_location (proxy_server (req).string) h.put_content_length (0) + res.put_header_lines (h) res.set_status_code ({HTTP_STATUS_CODE}.use_proxy) ensure response_status_is_set: res.status_is_set diff --git a/library/server/wsf/src/response/wsf_default_router_response.e b/library/server/wsf/src/response/wsf_default_router_response.e index cc933b03..23b7ef99 100644 --- a/library/server/wsf/src/response/wsf_default_router_response.e +++ b/library/server/wsf/src/response/wsf_default_router_response.e @@ -58,8 +58,20 @@ feature {WSF_RESPONSE} -- Output if req.is_request_method ({HTTP_REQUEST_METHODS}.method_trace) then msg := trace_message (req) elseif attached method_not_allowed_message (req) as not_allowed then + --| We give this precedence over 412 Precondition Failed or 404 Not Found, + --| as we assume the existence of a handler for at least one method + --| indicates existence of the resource. This is obviously not the + --| case if the only method allowed is POST, but the handler ought + --| to handle the 404 Not Found and 412 Precondition Failed cases in that case. + --| Ditto for template URI handlers where not all template variable + --| values map to existing resources. msg := not_allowed + elseif attached req.http_if_match as l_match and then l_match.same_string ("*") then + msg := precondition_failed_message (req) else + --| Other response codes are possible, such as 301 Moved permananently, + --| 302 Found and 410 Gone. But these require handlers to implement, + --| so no other code can be given at this point. msg := not_found_message (req) end res.send (msg) @@ -67,7 +79,17 @@ feature {WSF_RESPONSE} -- Output feature {NONE} -- Implementation + precondition_failed_message (req: WSF_REQUEST): WSF_PRECONDITION_FAILED_MESSAGE + -- Automatically generated response for 412 Precondition Failed response + require + req_attached: req /= Void + do + create Result.make (req) + end + method_not_allowed_message (req: WSF_REQUEST): detachable WSF_METHOD_NOT_ALLOWED_RESPONSE + require + req_attached: req /= Void local vis: WSF_ROUTER_AGENT_ITERATOR do diff --git a/library/server/wsf/src/response/wsf_precondition_failed_message.e b/library/server/wsf/src/response/wsf_precondition_failed_message.e new file mode 100644 index 00000000..da0ac71f --- /dev/null +++ b/library/server/wsf/src/response/wsf_precondition_failed_message.e @@ -0,0 +1,130 @@ +note + description: "[ + This class is used to report a 412 Precondition Failed page + ]" + date: "$Date$" + revision: "$Revision$" + +class WSF_PRECONDITION_FAILED_MESSAGE + +inherit + + WSF_RESPONSE_MESSAGE + + SHARED_HTML_ENCODER + +create + + make + +feature {NONE} -- Initialization + + make (req: WSF_REQUEST) + -- Initialize setting `request' from `req'. + do + request := req + create header.make + ensure + req_aliased: request = req + end + +feature -- Header + + header: HTTP_HEADER + -- Response' header + + request: WSF_REQUEST + -- Associated request. + + body: detachable READABLE_STRING_8 + -- Optional body + -- Displayed as extra content + +feature -- Element change + + set_body (b: like body) + -- Set `body' to `b' + do + body := b + end + +feature {WSF_RESPONSE} -- Output + + send_to (res: WSF_RESPONSE) + local + s: STRING + l_text: detachable READABLE_STRING_GENERAL + l_loc: detachable READABLE_STRING_8 + h: like header + do + h := header + res.set_status_code ({HTTP_STATUS_CODE}.precondition_failed) + + if request.is_content_type_accepted ({HTTP_MIME_TYPES}.text_html) then + s := "
" + s.append ("" + html_encoder.encoded_string (request.request_uri) + "