From 52e9c1aca08d09df3562d22ad4eb692293168f11 Mon Sep 17 00:00:00 2001 From: Antonio Terceiro Date: Sat, 4 Sep 2010 17:35:58 -0300 Subject: [PATCH] Documenting Varnish usage --- INSTALL.varnish | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ etc/noosfero/varnish-accept-language.vcl | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+), 0 deletions(-) create mode 100644 INSTALL.varnish create mode 100644 etc/noosfero/varnish-accept-language.vcl diff --git a/INSTALL.varnish b/INSTALL.varnish new file mode 100644 index 0000000..9285b57 --- /dev/null +++ b/INSTALL.varnish @@ -0,0 +1,67 @@ += Setting up Varnish for your Noosfero site + +Varnish is a HTTP caching server, and using it together with Noosfero is highly +recommended. See http://www.varnish-cache.org/ for more information on Varnish. + +Varnish can be set up to use with Noosfero with the following steps: + +1) setup Noosfero with apache according to the INSTALL file. + +2) install Varnish + + # apt-get install varnish + +Noosfero was tested with Varnish 2.x. If you are using a Debian Lenny (and you +should, unless Debian already released Squeeze by now), make sure you install +varnish from the lenny-backports suite. + +3) Enable varnish logging: + +3a) Edit /etc/default/varnishncsa and uncomment the line that contains: + +VARNISHNCSA_ENABLED=1 + +The varnish log will be written to /var/log/varnish/varnishncsa.log in an +apache-compatible format. You should change your statistics generation software +(e.g. awstats) to use that instead of apache logs. + +3b) Restart Varnish Logging service + + # invoke-rc.d varnishncsa start + +4) Change Apache to listen on port 8080 instead of 80 + +4a) Edit /etc/apache2/ports.conf, and: + + * change 'Listen 80' to 'Listen 127.0.0.1:8080' + * change 'NameVirtualHost *:80' to 'NameVirtualHost *:8080' + +4b) Edit /etc/apache2/sites-enabled/*, and change '' to '' + +4c) Restart apache + + # invoke-rc.d apache2 restart + +5) Change Varnish to listen on port 80 + +5a) Edit /etc/default/varnish and change '-a :6081' to '-a :80' + +5b) Restart Varnish + + # invoke-rc.d varnish restart + +6) Configure varnish to store separate caches for each language + +6a) Add the following line to your /etc/varnish/default.vcl file (assuming +Noosfero is installed in /var/lib/noosfero): + + include "/var/lib/noosfero/etc/noosfero/varnish-accept-language.vcl"; + +6b) Restart Varnish + + # invoke-rc.d varnish restart + +Thanks to Cosimo Streppone for varnish-accept-language. See +http://github.com/cosimo/varnish-accept-language for more information. + + -- Antonio Terceiro Sat, 04 Sep 2010 17:29:27 -0300 diff --git a/etc/noosfero/varnish-accept-language.vcl b/etc/noosfero/varnish-accept-language.vcl new file mode 100644 index 0000000..0c76d81 --- /dev/null +++ b/etc/noosfero/varnish-accept-language.vcl @@ -0,0 +1,186 @@ +C{ + +/* ------------------------------------------------------------------ */ +/* THIS FILE IS AUTOMATICALLY GENERATED BY ./gen_vcl.pl. DO NOT EDIT. */ + +/* + * Accept-language header normalization + * + * Cosimo, 21/01/2010 + * + */ + +#include /* isupper */ +#include +#include /* qsort */ +#include + +#define DEFAULT_LANGUAGE "en" +#define SUPPORTED_LANGUAGES ":de:fr:es:ru:pt:hy:en:" + +#define vcl_string char +#define LANG_LIST_SIZE 16 +#define LANG_MAXLEN 16 +#define RETURN_LANG(x) { \ + strncpy(lang, x, LANG_MAXLEN); \ + return; \ +} +#define RETURN_DEFAULT_LANG RETURN_LANG(DEFAULT_LANGUAGE) +#define PUSH_LANG(x,y) { \ + /* fprintf(stderr, "Pushing lang [%d] %s %.4f\n", curr_lang, x, y); */ \ + /* We have to copy, otherwise root_lang will be the same every time */ \ + strncpy(pl[curr_lang].lang, x, LANG_MAXLEN); \ + pl[curr_lang].q = y; \ + curr_lang++; \ +} + +struct lang_list { + vcl_string lang[LANG_MAXLEN]; + float q; +}; + +/* In-place lowercase of a string */ +static void strtolower(char *s) { + register char *c; + for (c=s; *c; c++) { + if (isupper(*c)) { + *c = tolower(*c); + } + } + return; +} + +/* Checks if a given language is in the static list of the ones we support */ +int is_supported(vcl_string *lang) { + vcl_string *supported_languages = SUPPORTED_LANGUAGES; + vcl_string match_str[LANG_MAXLEN + 3] = ""; /* :, :, \0 = 3 */ + int is_supported = 0; + + /* We want to match 'zh-cn' and 'zh-CN' too */ + strtolower(lang); + + /* Search "::" in supported languages string */ + strncpy(match_str, ":", 1); + strncat(match_str, lang, LANG_MAXLEN); + strncat(match_str, ":\0", 2); + + if (strstr(supported_languages, match_str)) { + is_supported = 1; + } + + return is_supported; +} + +/* Used by qsort() below */ +int sort_by_q(const void *x, const void *y) { + struct lang_list *a = (struct lang_list *)x; + struct lang_list *b = (struct lang_list *)y; + if (a->q > b->q) return -1; + if (a->q < b->q) return 1; + return 0; +} + +/* Reads Accept-Language, parses it, and finds the first match + among the supported languages. In case of no match, + returns the default language. +*/ +void select_language(const vcl_string *incoming_header, char *lang) { + + struct lang_list pl[LANG_LIST_SIZE]; + vcl_string *lang_tok = NULL; + vcl_string root_lang[3]; + vcl_string *header; + vcl_string *pos = NULL; + vcl_string *q_spec = NULL; + unsigned int curr_lang = 0, i = 0; + float q; + + /* Empty or default string, return default language immediately */ + if ( + !incoming_header + || (0 == strcmp(incoming_header, "en-US")) + || (0 == strcmp(incoming_header, "en-GB")) + || (0 == strcmp(incoming_header, DEFAULT_LANGUAGE)) + || (0 == strcmp(incoming_header, "")) + ) + RETURN_DEFAULT_LANG; + + /* Tokenize Accept-Language */ + header = (vcl_string *) incoming_header; + + while ((lang_tok = strtok_r(header, " ,", &pos))) { + + q = 1.0; + + if ((q_spec = strstr(lang_tok, ";q="))) { + /* Truncate language name before ';' */ + *q_spec = '\0'; + /* Get q value */ + sscanf(q_spec + 3, "%f", &q); + } + + /* Wildcard language '*' should be last in list */ + if ((*lang_tok) == '*') q = 0.0; + + /* Push in the prioritized list */ + PUSH_LANG(lang_tok, q); + + /* For cases like 'en-GB', we also want the root language in the final list */ + if ('-' == lang_tok[2]) { + root_lang[0] = lang_tok[0]; + root_lang[1] = lang_tok[1]; + root_lang[2] = '\0'; + PUSH_LANG(root_lang, q - 0.001); + } + + /* For strtok_r() to proceed from where it left off */ + header = NULL; + + /* Break out if stored max no. of languages */ + if (curr_lang >= LANG_MAXLEN) break; + } + + /* Sort by priority */ + qsort(pl, curr_lang, sizeof(struct lang_list), &sort_by_q); + + /* Match with supported languages */ + for (i = 0; i < curr_lang; i++) { + if (is_supported(pl[i].lang)) + RETURN_LANG(pl[i].lang); + } + + RETURN_DEFAULT_LANG; +} + +/* Reads req.http.Accept-Language and writes X-Varnish-Accept-Language */ +void vcl_rewrite_accept_language(const struct sess *sp) { + vcl_string *in_hdr; + vcl_string lang[LANG_MAXLEN]; + + memset(lang, 0, LANG_MAXLEN); + + /* Get Accept-Language header from client */ + in_hdr = VRT_GetHdr(sp, HDR_REQ, "\020Accept-Language:"); + + /* Normalize and filter out by list of supported languages */ + select_language(in_hdr, lang); + + /* By default, use a different header name: don't mess with backend logic */ + VRT_SetHdr(sp, HDR_REQ, "\032X-Varnish-Accept-Language:", lang, vrt_magic_string_end); + + return; +} + +/* vim: syn=c ts=4 et sts=4 sw=4 tw=0 +*/ + +/* THIS FILE IS AUTOMATICALLY GENERATED BY ./gen_vcl.pl. DO NOT EDIT. */ +/* ------------------------------------------------------------------ */ +}C + +sub vcl_recv { + C{ + vcl_rewrite_accept_language(sp); + }C + return(pass); +} -- libgit2 0.21.2