From 6feaf5757f0a87a459ce1f241f356011ba097d2d Mon Sep 17 00:00:00 2001 From: jvelilla Date: Wed, 30 Nov 2011 07:15:17 -0300 Subject: [PATCH] Update conneg library and test cases --- .../src/{variants.e => conneg_server_side.e} | 108 +++++++++++++++++- .../CONNEG/src/language_variant_results.e | 46 ++++++++ .../CONNEG/src/media_type_variant_results.e | 47 ++++++++ library/protocol/CONNEG/src/variant_results.e | 58 ++++++++++ .../CONNEG/test/conneg_server_side_test.e | 61 ++++++++++ library/protocol/CONNEG/test/test.rc | 1 + 6 files changed, 315 insertions(+), 6 deletions(-) rename library/protocol/CONNEG/src/{variants.e => conneg_server_side.e} (54%) create mode 100644 library/protocol/CONNEG/src/language_variant_results.e create mode 100644 library/protocol/CONNEG/src/media_type_variant_results.e create mode 100644 library/protocol/CONNEG/src/variant_results.e create mode 100644 library/protocol/CONNEG/test/conneg_server_side_test.e create mode 100644 library/protocol/CONNEG/test/test.rc diff --git a/library/protocol/CONNEG/src/variants.e b/library/protocol/CONNEG/src/conneg_server_side.e similarity index 54% rename from library/protocol/CONNEG/src/variants.e rename to library/protocol/CONNEG/src/conneg_server_side.e index 3379edc9..0e34108c 100644 --- a/library/protocol/CONNEG/src/variants.e +++ b/library/protocol/CONNEG/src/conneg_server_side.e @@ -1,5 +1,5 @@ note - description: "Summary description for {VARIANTS}. Utility class to support Server Side Content Negotiation " + description: "Summary description for {CONNEG_SERVER_SIDE}. Utility class to support Server Side Content Negotiation " author: "" date: "$Date$" revision: "$Revision$" @@ -13,21 +13,97 @@ note In order to improve the server's guess, the user agent MAY include request header fields (Accept, Accept-Language, Accept-Encoding, etc.) which describe its preferences for such a response. ]" class - VARIANTS + CONNEG_SERVER_SIDE inherit SHARED_CONNEG REFACTORING_HELPER +create + make + +feature -- Initialization + make ( a_mime: STRING; a_language : STRING; a_charset :STRING; an_encoding: STRING) + do + set_mime_default (a_mime) + set_language_default (a_language) + set_charset_default (a_charset) + set_encoding_defautl (an_encoding) + end +feature -- Server Side Defaults Formats + mime_default : STRING + + set_mime_default ( a_mime: STRING) + -- set the mime_default with `a_mime' + do + mime_default := a_mime + ensure + set_mime_default: a_mime ~ mime_default + end + + + language_default : STRING + + set_language_default (a_language : STRING) + -- set the language_default with `a_language' + do + language_default := a_language + ensure + set_language : a_language ~ language_default + end + + + charset_default : STRING + + set_charset_default (a_charset : STRING) + -- set the charset_default with `a_charset' + do + charset_default := a_charset + ensure + set_charset : a_charset ~ charset_default + end + + + encoding_default : STRING + + set_encoding_defautl (an_encoding : STRING) + do + encoding_default := an_encoding + ensure + set_encoding : an_encoding ~ encoding_default + end + + + feature -- Media Type Negotiation - media_type_preference ( mime_types_supported : LIST[STRING]; header : STRING) : STRING + media_type_preference ( mime_types_supported : LIST[STRING]; header : STRING) : MEDIA_TYPE_VARIANT_RESULTS -- mime_types_supported represent media types supported by the server. -- header represent the Accept header, ie, the client preferences. -- Return which media type to use for representaion in a response, if the server support -- one media type, or empty in other case. -- Reference : http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 + local + mime_match: STRING do - Result := mime.best_match (mime_types_supported, header) + create Result + if header.is_empty then + -- the request has no Accept header, ie the header is empty, in this case we use the default format + Result.set_acceptable (TRUE) + Result.set_media_type (mime_default) + else + -- select the best match, server support, client preferences + mime_match := mime.best_match (mime_types_supported, header) + if mime_match.is_empty then + -- The server does not support any of the media types prefered by the client + Result.set_acceptable (False) + Result.set_supported_variants (mime_types_supported) + else + -- Set the best match + Result.set_media_type(mime_match) + Result.set_acceptable (True) + Result.set_variant_header + end + end end @@ -58,14 +134,34 @@ feature -- Compression Negotiation feature -- Language Negotiation - language_preference (server_language_supported : LIST[STRING]; header: STRING) : STRING + language_preference (server_language_supported : LIST[STRING]; header: STRING) : LANGUAGE_VARIANT_RESULTS -- server_language_supported represent a list of languages supported by the server. -- header represent the Accept-Language header, ie, the client preferences. -- Return which Language to use in a response, if the server support -- one Language, or empty in other case. -- Reference: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 + local + language_match: STRING do - Result := language.best_match (server_language_supported, header) + create Result + if header.is_empty then + -- the request has no Accept header, ie the header is empty, in this case we use the default format + Result.set_acceptable (TRUE) + Result.set_language_type (mime_default) + else + -- select the best match, server support, client preferences + language_match := language.best_match (server_language_supported, header) + if language_match.is_empty then + -- The server does not support any of the media types prefered by the client + Result.set_acceptable (False) + Result.set_supported_variants (server_language_supported) + else + -- Set the best match + Result.set_language_type(language_match) + Result.set_acceptable (True) + Result.set_variant_header + end + end end note diff --git a/library/protocol/CONNEG/src/language_variant_results.e b/library/protocol/CONNEG/src/language_variant_results.e new file mode 100644 index 00000000..096f4293 --- /dev/null +++ b/library/protocol/CONNEG/src/language_variant_results.e @@ -0,0 +1,46 @@ +note + description: "Summary description for {LANGUAGE_VARIANT_RESULTS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + LANGUAGE_VARIANT_RESULTS + +feature + language_type : detachable STRING + set_language_type ( a_language_type: STRING) + do + language_type := a_language_type + ensure + set_language_type : a_language_type ~ language_type + end + + variant_header : detachable STRING + set_variant_header + do + variant_header := "Accept-Language" + end + + supported_variants : detachable LIST[STRING] + set_supported_variants (a_supported : LIST[STRING]) + do + supported_variants := a_supported + ensure + set_supported_variants : supported_variants = a_supported + end + + is_acceptable : BOOLEAN + + set_acceptable ( acceptable : BOOLEAN) + do + is_acceptable := acceptable + ensure + is_acceptable = acceptable + end + + +note + copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/library/protocol/CONNEG/src/media_type_variant_results.e b/library/protocol/CONNEG/src/media_type_variant_results.e new file mode 100644 index 00000000..8e4a6234 --- /dev/null +++ b/library/protocol/CONNEG/src/media_type_variant_results.e @@ -0,0 +1,47 @@ +note + description: "Summary description for {MEDIA_TYPE_VARIANT_RESULTS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + MEDIA_TYPE_VARIANT_RESULTS + +feature + + media_type : detachable STRING + set_media_type ( a_media_type: STRING) + do + media_type := a_media_type + ensure + set_media_type : a_media_type ~ media_type + end + + variant_header : detachable STRING + set_variant_header + do + variant_header := "Accept" + end + + supported_variants : detachable LIST[STRING] + set_supported_variants (a_supported : LIST[STRING]) + do + supported_variants := a_supported + ensure + set_supported_variants : supported_variants = a_supported + end + + is_acceptable : BOOLEAN + + set_acceptable ( acceptable : BOOLEAN) + do + is_acceptable := acceptable + ensure + is_acceptable = acceptable + end + + +note + copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/library/protocol/CONNEG/src/variant_results.e b/library/protocol/CONNEG/src/variant_results.e new file mode 100644 index 00000000..65272762 --- /dev/null +++ b/library/protocol/CONNEG/src/variant_results.e @@ -0,0 +1,58 @@ +note + description: "Summary description for {VARIANT_RESULTS}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + VARIANT_RESULTS + +feature -- Mime, Language, Charset and Encoding Results + + mime_result : detachable STRING + + set_mime_result ( a_mime: STRING) + -- set the mime_result with `a_mime' + do + mime_result := a_mime + ensure + set_mime_result: a_mime ~ mime_result + end + + + language_result : detachable STRING + + set_language_result (a_language : STRING) + -- set the language_result with `a_language' + do + language_result := a_language + ensure + set_language : a_language ~ language_result + end + + + charset_result : detachable STRING + + set_charset_result (a_charset : STRING) + -- set the charset_result with `a_charset' + do + charset_result := a_charset + ensure + set_charset : a_charset ~ charset_result + end + + + encoding_result : detachable STRING + + set_encoding_defautl (an_encoding : STRING) + do + encoding_result := an_encoding + ensure + set_encoding : an_encoding ~ encoding_result + end + + +note + copyright: "2011-2011, Javier Velilla, Jocelyn Fiat and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" +end diff --git a/library/protocol/CONNEG/test/conneg_server_side_test.e b/library/protocol/CONNEG/test/conneg_server_side_test.e new file mode 100644 index 00000000..a36084a0 --- /dev/null +++ b/library/protocol/CONNEG/test/conneg_server_side_test.e @@ -0,0 +1,61 @@ +note + description: "Summary description for {CONNEG_SERVER_SIDE_TEST}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + CONNEG_SERVER_SIDE_TEST +inherit + EQA_TEST_SET + redefine + on_prepare + end + +feature {NONE} -- Events + + on_prepare + -- Called after all initializations in `default_create'. + do + create conneg.make ("application/json", "es", "UTF8", "") + -- set default values + end + +feature -- Test routines + test_media_type_negotiation + local + media_variants : MEDIA_TYPE_VARIANT_RESULTS + mime_types_supported : LIST [STRING] + l_types : STRING + do + -- Scenario 1, the server side does not support client preferences + l_types := "application/json,application/xbel+xml,application/xml" + mime_types_supported := l_types.split(',') + media_variants := conneg.media_type_preference (mime_types_supported, "text/html") + assert ("Expected Not Acceptable", not media_variants.is_acceptable) + assert ("Same Value at 1",mime_types_supported.at (1).is_equal (media_variants.supported_variants.at (1))) + assert ("Same count",mime_types_supported.count = media_variants.supported_variants.count) + assert ("Variant header is void",media_variants.variant_header = Void) + assert ("Media type is void",media_variants.media_type = Void) + + -- Scenario 2, the client doesnt send values in the header, Accpet: + media_variants := conneg.media_type_preference (mime_types_supported, "") + assert ("Expected Acceptable", media_variants.is_acceptable) + assert ("Variants is dettached",media_variants.supported_variants = Void) + assert ("Mime is defaul", conneg.mime_default.is_equal (media_variants.media_type)) + assert ("Variant header", media_variants.variant_header = Void) + + --Scenario 3, the server select the best match, and set the vary header + media_variants := conneg.media_type_preference (mime_types_supported, "text/*,application/json;q=0.5") + assert ("Expected Acceptable", media_variants.is_acceptable) + assert ("Variants is dettached",media_variants.supported_variants = Void) + assert ("Variant Header", media_variants.variant_header.is_equal ("Accept")) + assert ("Media Type is application/json", media_variants.media_type.is_equal ("application/json")) + + end + + + +feature -- Implementation + conneg : CONNEG_SERVER_SIDE +end diff --git a/library/protocol/CONNEG/test/test.rc b/library/protocol/CONNEG/test/test.rc new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/library/protocol/CONNEG/test/test.rc @@ -0,0 +1 @@ +