Complete.
This commit is contained in:
@@ -58,17 +58,131 @@ Now we are in a position to do some negotiating. At the beginning of your handle
|
||||
|
||||
local
|
||||
l_media_variants: MEDIA_TYPE_VARIANT_RESULTS
|
||||
l_is_head: BOOLEAN
|
||||
h: HTTP_HEADER
|
||||
l_msg: STRING
|
||||
do
|
||||
l_is_head := False -- or `True' if this is for a HEAD handler
|
||||
l_media_variants:= conneg.media_type_preference (mime_types_supported, a_req.http_accept)
|
||||
if not l_media_variants.is_acceptable then
|
||||
send_unacceptable_media_type (a_res)
|
||||
send_unacceptable_media_type (a_res, l_is_head)
|
||||
elseif not conneg.charset_preference (charsets_supported, a_req.http_accept_charset).is_acceptable then
|
||||
send_unacceptable_charset (a_res)
|
||||
send_unacceptable_charset (a_res, l_is_head)
|
||||
elseif not conneg.encoding_preference (encodings_supported, a_req.http_accept_encoding).is_acceptable then
|
||||
send_unacceptable_encoding (a_res)
|
||||
send_unacceptable_encoding (a_res, l_is_head)
|
||||
elseif not conneg.language_preference (languages_supported, a_req.http_accept_language).is_acceptable then
|
||||
send_unacceptable_encoding (a_res)
|
||||
else
|
||||
-- We have agreed a representation, let's go and serve it to the client
|
||||
`
|
||||
|
||||
Now for those `send_unnacceptable_...` routines. They are fairly simple:
|
||||
|
||||
send_unacceptable_media_type (a_res: WSF_RESPONSE; a_is_head: BOOLEAN) is
|
||||
-- Send error result as text/plain that the media type is unnacceptable.
|
||||
require
|
||||
a_res_not_void: a_res /= Void
|
||||
status_not_set: not a_res.status_is_set
|
||||
header_not_committed: not a_res.header_committed
|
||||
local
|
||||
l_error_text: STRING
|
||||
do
|
||||
l_error_text := "The requested media type(s) is/are not supported by this server."
|
||||
send_unacceptable (a_res, a_is_head, l_error_text)
|
||||
end
|
||||
|
||||
send_unacceptable_charset (a_res: WSF_RESPONSE; a_is_head: BOOLEAN) is
|
||||
-- Send error result as text/plain that the character set is unnacceptable.
|
||||
require
|
||||
a_res_not_void: a_res /= Void
|
||||
status_not_set: not a_res.status_is_set
|
||||
header_not_committed: not a_res.header_committed
|
||||
local
|
||||
l_error_text: STRING
|
||||
do
|
||||
l_error_text := "The requested character set(s) is/are not supported by this server. Only UTF-8 is supported."
|
||||
send_unacceptable (a_res, a_is_head, l_error_text)
|
||||
end
|
||||
|
||||
send_unacceptable_encoding (a_res: WSF_RESPONSE; a_is_head: BOOLEAN) is
|
||||
-- Send error result as text/plain that the encoding is unnacceptable.
|
||||
require
|
||||
a_res_not_void: a_res /= Void
|
||||
status_not_set: not a_res.status_is_set
|
||||
header_not_committed: not a_res.header_committed
|
||||
local
|
||||
l_error_text: STRING
|
||||
do
|
||||
l_error_text := "The requested encoding(s) is/are not supported by this server. Only identity is supported."
|
||||
send_unacceptable (a_res, a_is_head, l_error_text)
|
||||
end
|
||||
|
||||
send_unacceptable_language (a_res: WSF_RESPONSE; a_is_head: BOOLEAN) is
|
||||
-- Send error result as text/plain that the language unnacceptable.
|
||||
require
|
||||
a_res_not_void: a_res /= Void
|
||||
status_not_set: not a_res.status_is_set
|
||||
header_not_committed: not a_res.header_committed
|
||||
local
|
||||
l_error_text: STRING
|
||||
do
|
||||
l_error_text := "The requested language(s) is/are not supported by this server. Only en (English) is supported."
|
||||
send_unacceptable (a_res, a_is_head, l_error_text)
|
||||
end
|
||||
|
||||
send_unacceptable (a_res: WSF_RESPONSE; a_is_head: BOOLEAN; a_error_text: STRING) is
|
||||
-- Send a_error_text as text/plain that a header is unnacceptable.
|
||||
require
|
||||
a_res_not_void: a_res /= Void
|
||||
status_not_set: not a_res.status_is_set
|
||||
header_not_committed: not a_res.header_committed
|
||||
a_error_text_not_void: a_error_text /= Void
|
||||
local
|
||||
h: HTTP_HEADER
|
||||
do
|
||||
create h.make
|
||||
set_content_type (h, Void)
|
||||
h.put_content_length (a_error_text.count)
|
||||
h.put_current_date
|
||||
a_res.set_status_code ({HTTP_STATUS_CODE}.not_acceptable)
|
||||
a_res.put_header_text (h.string)
|
||||
if not a_is_head then
|
||||
a_res.put_string (a_error_text)
|
||||
end
|
||||
end
|
||||
|
||||
We'll see that `set_content_type` routine in a bit. But for now, we just have to generate the response. Let's go back to that `else ...` bit:
|
||||
|
||||
else
|
||||
-- We have agreed a representation, let's go and serve it to the client
|
||||
create h.make
|
||||
set_content_type (h, a_media_variants)
|
||||
if a_media_variants.media_type ~ {HTTP_MIME_TYPES}.application_xml then
|
||||
l_msg := "<?xml version='1.0' encoding='UTF-8' ?><my-tag>etc."
|
||||
else
|
||||
l_msg := json.value (<some-value>).representation
|
||||
end
|
||||
h.put_content_length (l_msg.count)
|
||||
h.put_current_date
|
||||
a_res.set_status_code ({HTTP_STATUS_CODE}.ok)
|
||||
a_res.put_header_text (h.string)
|
||||
if not a_is_head then
|
||||
a_res.put_string (l_msg)
|
||||
end
|
||||
|
||||
There's that `set_content_type` again. Finally, we will take a look at it:
|
||||
|
||||
set_content_type (a_h: HTTP_HEADER; a_media_variants: MEDIA_TYPE_VARIANT_RESULTS) is
|
||||
-- Set the content=type header in `a_h' according to `a_media_variants'.
|
||||
require
|
||||
a_h_not_void: a_h /= Void
|
||||
do
|
||||
if a_media_variants = Void or else not a_media_variants.is_acceptable then
|
||||
a_h.put_content_type ({HTTP_MIME_TYPES}.text_plain)
|
||||
else
|
||||
a_h.put_content_type (a_media_variants.media_type)
|
||||
end
|
||||
a_h.put_header_key_value ({HTTP_HEADER_NAMES}.header_vary, {HTTP_HEADER_NAMES}.header_accept)
|
||||
end
|
||||
|
||||
Firstly, if we haven't agreed a media-type, then we send our (negative) response as `plain/text`. Otherwise we will send the response in the agreed media-type. But in each case we add a `Vary:Accept` header. This tells proxy caches that they have to check the media-type before returning a cached result, as there may be a different representation available. Since we do not vary our representation by language, charset or encoding, we don't add `Vary:Accept-Language,Accept-Charset,Accept-Encoding`. But if we were to negotiate different representations on those dimensions also, we would need to list the appropriate headers in the `Vary` header.
|
||||
Reference in New Issue
Block a user