mirror of https://github.com/kiwix/libkiwix.git
Preliminary support for Accept-Language: header
In the absence of the "userlang" query parameter in the URL, the value of the "Accept-Language" header is used. However, it is assumed that "Accept-Language" specifies a single language (rather than a comma separated list of languages possibly weighted with quality values). Example: Accept-Language: fr // should work Accept-Language: fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5 // The requested language will be considered to be // "fr-CH, fr;q=0.9, en;q=0.8, de;q=0.7, *;q=0.5". // The i18n code will fail to find resources for such a language // and will use the default "en" instead.
This commit is contained in:
parent
9987fbd488
commit
927c12574a
|
@ -195,7 +195,15 @@ std::string RequestContext::get_query() const {
|
|||
|
||||
std::string RequestContext::get_user_language() const
|
||||
{
|
||||
return get_optional_param<std::string>("userlang", "en");
|
||||
try {
|
||||
return get_argument("userlang");
|
||||
} catch(const std::out_of_range&) {}
|
||||
|
||||
try {
|
||||
return get_header("Accept-Language");
|
||||
} catch(const std::out_of_range&) {}
|
||||
|
||||
return "en";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -57,7 +57,6 @@ std::string removeEOLWhitespaceMarkers(const std::string& s)
|
|||
return std::regex_replace(s, pattern, "");
|
||||
}
|
||||
|
||||
|
||||
class ZimFileServer
|
||||
{
|
||||
public: // types
|
||||
|
@ -879,6 +878,79 @@ TEST_F(ServerTest, 500)
|
|||
EXPECT_EQ(r->body, expectedBody);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, UserLanguageControl)
|
||||
{
|
||||
struct TestData
|
||||
{
|
||||
const std::string url;
|
||||
const std::string acceptLanguageHeader;
|
||||
const std::string expectedH1;
|
||||
|
||||
operator TestContext() const
|
||||
{
|
||||
return TestContext{
|
||||
{"url", url},
|
||||
{"acceptLanguageHeader", acceptLanguageHeader},
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
const TestData testData[] = {
|
||||
{
|
||||
/*url*/ "/ROOT/zimfile/invalid-article",
|
||||
/*Accept-Language:*/ "",
|
||||
/* expected <h1> */ "Not Found"
|
||||
},
|
||||
{
|
||||
/*url*/ "/ROOT/zimfile/invalid-article?userlang=en",
|
||||
/*Accept-Language:*/ "",
|
||||
/* expected <h1> */ "Not Found"
|
||||
},
|
||||
{
|
||||
/*url*/ "/ROOT/zimfile/invalid-article?userlang=hy",
|
||||
/*Accept-Language:*/ "",
|
||||
/* expected <h1> */ "Սխալ հասցե"
|
||||
},
|
||||
{
|
||||
/*url*/ "/ROOT/zimfile/invalid-article",
|
||||
/*Accept-Language:*/ "*",
|
||||
/* expected <h1> */ "Not Found"
|
||||
},
|
||||
{
|
||||
/*url*/ "/ROOT/zimfile/invalid-article",
|
||||
/*Accept-Language:*/ "hy",
|
||||
/* expected <h1> */ "Սխալ հասցե"
|
||||
},
|
||||
{
|
||||
// userlang query parameter takes precedence over Accept-Language
|
||||
/*url*/ "/ROOT/zimfile/invalid-article?userlang=en",
|
||||
/*Accept-Language:*/ "hy",
|
||||
/* expected <h1> */ "Not Found"
|
||||
},
|
||||
{
|
||||
// The value of the Accept-Language header is not currently parsed.
|
||||
// In case of a comma separated list of languages (optionally weighted
|
||||
// with quality values) the default (en) language is used instead.
|
||||
/*url*/ "/ROOT/zimfile/invalid-article",
|
||||
/*Accept-Language:*/ "hy;q=0.9, en;q=0.2",
|
||||
/* expected <h1> */ "Not Found"
|
||||
},
|
||||
};
|
||||
|
||||
const std::regex h1Regex("<h1>(.+)</h1>");
|
||||
for ( const auto& t : testData ) {
|
||||
std::smatch h1Match;
|
||||
Headers headers;
|
||||
if ( !t.acceptLanguageHeader.empty() ) {
|
||||
headers.insert({"Accept-Language", t.acceptLanguageHeader});
|
||||
}
|
||||
const auto r = zfs1_->GET(t.url.c_str(), headers);
|
||||
std::regex_search(r->body, h1Match, h1Regex);
|
||||
const std::string h1(h1Match[1]);
|
||||
EXPECT_EQ(h1, t.expectedH1) << t;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, RandomPageRedirectsToAnExistingArticle)
|
||||
{
|
||||
auto g = zfs1_->GET("/ROOT/random?content=zimfile");
|
||||
|
|
Loading…
Reference in New Issue