diff --git a/src/valum-negociate.vala b/src/valum-negociate.vala new file mode 100644 index 000000000..cb5c15b9a --- /dev/null +++ b/src/valum-negociate.vala @@ -0,0 +1,74 @@ +/* + * This file is part of Valum. + * + * Valum is free software: you can redistribute it and/or modify it under the + * terms of the GNU Lesser General Public License as published by the Free + * Software Foundation, either version 3 of the License, or (at your option) any + * later version. + * + * Valum is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more + * details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with Valum. If not, see . + */ + +using Soup; + +namespace Valum { + + /** + * Negociate a HTTP header against a given expectation. + * + * The header is extracted as a quality list and a lookup is performed to + * see if the expected value is accepted by the user agent. + * + * @since 0.3 + * + * @param header_name header to negociate + * @param expectation expected value in the quality list + */ + public MatcherCallback negociate (string header_name, string expectation) { + return (req) => { + var header = req.headers.get_list (header_name); + return header != null && header_parse_quality_list (header, null).find_custom (expectation, strcmp) != null; + }; + } + + /** + * @since 0.3 + */ + public MatcherCallback accept (string content_type) { + return negociate ("Accept", content_type); + } + + /** + * @since 0.3 + */ + public MatcherCallback accept_charset (string charset) { + return negociate ("Accept-Charset", charset); + } + + /** + * @since 0.3 + */ + public MatcherCallback accept_encoding (string encoding) { + return negociate ("Accept-Encoding", encoding); + } + + /** + * @since 0.3 + */ + public MatcherCallback accept_language (string language) { + return negociate ("Accept-Language", language); + } + + /** + * @since 0.3 + */ + public MatcherCallback accept_ranges (string ranges) { + return negociate ("Accept-Ranges", ranges); + } +} diff --git a/tests/negociate-test.vala b/tests/negociate-test.vala new file mode 100644 index 000000000..bfe5b2f0f --- /dev/null +++ b/tests/negociate-test.vala @@ -0,0 +1,17 @@ +using Valum; +using VSGI.Test; + +/** + * @since 0.3 + */ +public void test_negociate () { + var req = new Request (new Connection (), "GET", new Soup.URI ("http://localhost/")); + + req.headers.append ("Accept", "text/html; q=0.9, text/xml; q=0"); + + assert (negociate ("Accept", "text/html") (req, null)); + assert (!negociate ("Accept", "text/xml") (req, null)); + assert (!negociate ("Accept-Encoding", "utf-8") (req, null)); +} + + diff --git a/tests/tests.vala b/tests/tests.vala index 8994420ab..94e0d8030 100644 --- a/tests/tests.vala +++ b/tests/tests.vala @@ -24,6 +24,8 @@ public int main (string[] args) { Test.init (ref args); Test.bug_base ("https://github.com/valum-framework/valum/issues/%s"); + Test.add_func ("/negociate", test_negociate); + Test.add_func ("/router", test_router); Test.add_func ("/router/handle", test_router_handle); Test.add_func ("/router/custom_method", test_router_custom_method);