Commit 52e9c1aca08d09df3562d22ad4eb692293168f11

Authored by Antonio Terceiro
1 parent 91ecca1a

Documenting Varnish usage

(ActionItem1608)
INSTALL.varnish 0 → 100644
... ... @@ -0,0 +1,67 @@
  1 += Setting up Varnish for your Noosfero site
  2 +
  3 +Varnish is a HTTP caching server, and using it together with Noosfero is highly
  4 +recommended. See http://www.varnish-cache.org/ for more information on Varnish.
  5 +
  6 +Varnish can be set up to use with Noosfero with the following steps:
  7 +
  8 +1) setup Noosfero with apache according to the INSTALL file.
  9 +
  10 +2) install Varnish
  11 +
  12 + # apt-get install varnish
  13 +
  14 +Noosfero was tested with Varnish 2.x. If you are using a Debian Lenny (and you
  15 +should, unless Debian already released Squeeze by now), make sure you install
  16 +varnish from the lenny-backports suite.
  17 +
  18 +3) Enable varnish logging:
  19 +
  20 +3a) Edit /etc/default/varnishncsa and uncomment the line that contains:
  21 +
  22 +VARNISHNCSA_ENABLED=1
  23 +
  24 +The varnish log will be written to /var/log/varnish/varnishncsa.log in an
  25 +apache-compatible format. You should change your statistics generation software
  26 +(e.g. awstats) to use that instead of apache logs.
  27 +
  28 +3b) Restart Varnish Logging service
  29 +
  30 + # invoke-rc.d varnishncsa start
  31 +
  32 +4) Change Apache to listen on port 8080 instead of 80
  33 +
  34 +4a) Edit /etc/apache2/ports.conf, and:
  35 +
  36 + * change 'Listen 80' to 'Listen 127.0.0.1:8080'
  37 + * change 'NameVirtualHost *:80' to 'NameVirtualHost *:8080'
  38 +
  39 +4b) Edit /etc/apache2/sites-enabled/*, and change '<VirtualHost *:80>' to '<VirtualHost *:8080>'
  40 +
  41 +4c) Restart apache
  42 +
  43 + # invoke-rc.d apache2 restart
  44 +
  45 +5) Change Varnish to listen on port 80
  46 +
  47 +5a) Edit /etc/default/varnish and change '-a :6081' to '-a :80'
  48 +
  49 +5b) Restart Varnish
  50 +
  51 + # invoke-rc.d varnish restart
  52 +
  53 +6) Configure varnish to store separate caches for each language
  54 +
  55 +6a) Add the following line to your /etc/varnish/default.vcl file (assuming
  56 +Noosfero is installed in /var/lib/noosfero):
  57 +
  58 + include "/var/lib/noosfero/etc/noosfero/varnish-accept-language.vcl";
  59 +
  60 +6b) Restart Varnish
  61 +
  62 + # invoke-rc.d varnish restart
  63 +
  64 +Thanks to Cosimo Streppone for varnish-accept-language. See
  65 +http://github.com/cosimo/varnish-accept-language for more information.
  66 +
  67 + -- Antonio Terceiro <terceiro@colivre.coop.br> Sat, 04 Sep 2010 17:29:27 -0300
... ...
etc/noosfero/varnish-accept-language.vcl 0 → 100644
... ... @@ -0,0 +1,186 @@
  1 +C{
  2 +
  3 +/* ------------------------------------------------------------------ */
  4 +/* THIS FILE IS AUTOMATICALLY GENERATED BY ./gen_vcl.pl. DO NOT EDIT. */
  5 +
  6 +/*
  7 + * Accept-language header normalization
  8 + *
  9 + * Cosimo, 21/01/2010
  10 + *
  11 + */
  12 +
  13 +#include <ctype.h> /* isupper */
  14 +#include <stdio.h>
  15 +#include <stdlib.h> /* qsort */
  16 +#include <string.h>
  17 +
  18 +#define DEFAULT_LANGUAGE "en"
  19 +#define SUPPORTED_LANGUAGES ":de:fr:es:ru:pt:hy:en:"
  20 +
  21 +#define vcl_string char
  22 +#define LANG_LIST_SIZE 16
  23 +#define LANG_MAXLEN 16
  24 +#define RETURN_LANG(x) { \
  25 + strncpy(lang, x, LANG_MAXLEN); \
  26 + return; \
  27 +}
  28 +#define RETURN_DEFAULT_LANG RETURN_LANG(DEFAULT_LANGUAGE)
  29 +#define PUSH_LANG(x,y) { \
  30 + /* fprintf(stderr, "Pushing lang [%d] %s %.4f\n", curr_lang, x, y); */ \
  31 + /* We have to copy, otherwise root_lang will be the same every time */ \
  32 + strncpy(pl[curr_lang].lang, x, LANG_MAXLEN); \
  33 + pl[curr_lang].q = y; \
  34 + curr_lang++; \
  35 +}
  36 +
  37 +struct lang_list {
  38 + vcl_string lang[LANG_MAXLEN];
  39 + float q;
  40 +};
  41 +
  42 +/* In-place lowercase of a string */
  43 +static void strtolower(char *s) {
  44 + register char *c;
  45 + for (c=s; *c; c++) {
  46 + if (isupper(*c)) {
  47 + *c = tolower(*c);
  48 + }
  49 + }
  50 + return;
  51 +}
  52 +
  53 +/* Checks if a given language is in the static list of the ones we support */
  54 +int is_supported(vcl_string *lang) {
  55 + vcl_string *supported_languages = SUPPORTED_LANGUAGES;
  56 + vcl_string match_str[LANG_MAXLEN + 3] = ""; /* :, :, \0 = 3 */
  57 + int is_supported = 0;
  58 +
  59 + /* We want to match 'zh-cn' and 'zh-CN' too */
  60 + strtolower(lang);
  61 +
  62 + /* Search ":<lang>:" in supported languages string */
  63 + strncpy(match_str, ":", 1);
  64 + strncat(match_str, lang, LANG_MAXLEN);
  65 + strncat(match_str, ":\0", 2);
  66 +
  67 + if (strstr(supported_languages, match_str)) {
  68 + is_supported = 1;
  69 + }
  70 +
  71 + return is_supported;
  72 +}
  73 +
  74 +/* Used by qsort() below */
  75 +int sort_by_q(const void *x, const void *y) {
  76 + struct lang_list *a = (struct lang_list *)x;
  77 + struct lang_list *b = (struct lang_list *)y;
  78 + if (a->q > b->q) return -1;
  79 + if (a->q < b->q) return 1;
  80 + return 0;
  81 +}
  82 +
  83 +/* Reads Accept-Language, parses it, and finds the first match
  84 + among the supported languages. In case of no match,
  85 + returns the default language.
  86 +*/
  87 +void select_language(const vcl_string *incoming_header, char *lang) {
  88 +
  89 + struct lang_list pl[LANG_LIST_SIZE];
  90 + vcl_string *lang_tok = NULL;
  91 + vcl_string root_lang[3];
  92 + vcl_string *header;
  93 + vcl_string *pos = NULL;
  94 + vcl_string *q_spec = NULL;
  95 + unsigned int curr_lang = 0, i = 0;
  96 + float q;
  97 +
  98 + /* Empty or default string, return default language immediately */
  99 + if (
  100 + !incoming_header
  101 + || (0 == strcmp(incoming_header, "en-US"))
  102 + || (0 == strcmp(incoming_header, "en-GB"))
  103 + || (0 == strcmp(incoming_header, DEFAULT_LANGUAGE))
  104 + || (0 == strcmp(incoming_header, ""))
  105 + )
  106 + RETURN_DEFAULT_LANG;
  107 +
  108 + /* Tokenize Accept-Language */
  109 + header = (vcl_string *) incoming_header;
  110 +
  111 + while ((lang_tok = strtok_r(header, " ,", &pos))) {
  112 +
  113 + q = 1.0;
  114 +
  115 + if ((q_spec = strstr(lang_tok, ";q="))) {
  116 + /* Truncate language name before ';' */
  117 + *q_spec = '\0';
  118 + /* Get q value */
  119 + sscanf(q_spec + 3, "%f", &q);
  120 + }
  121 +
  122 + /* Wildcard language '*' should be last in list */
  123 + if ((*lang_tok) == '*') q = 0.0;
  124 +
  125 + /* Push in the prioritized list */
  126 + PUSH_LANG(lang_tok, q);
  127 +
  128 + /* For cases like 'en-GB', we also want the root language in the final list */
  129 + if ('-' == lang_tok[2]) {
  130 + root_lang[0] = lang_tok[0];
  131 + root_lang[1] = lang_tok[1];
  132 + root_lang[2] = '\0';
  133 + PUSH_LANG(root_lang, q - 0.001);
  134 + }
  135 +
  136 + /* For strtok_r() to proceed from where it left off */
  137 + header = NULL;
  138 +
  139 + /* Break out if stored max no. of languages */
  140 + if (curr_lang >= LANG_MAXLEN) break;
  141 + }
  142 +
  143 + /* Sort by priority */
  144 + qsort(pl, curr_lang, sizeof(struct lang_list), &sort_by_q);
  145 +
  146 + /* Match with supported languages */
  147 + for (i = 0; i < curr_lang; i++) {
  148 + if (is_supported(pl[i].lang))
  149 + RETURN_LANG(pl[i].lang);
  150 + }
  151 +
  152 + RETURN_DEFAULT_LANG;
  153 +}
  154 +
  155 +/* Reads req.http.Accept-Language and writes X-Varnish-Accept-Language */
  156 +void vcl_rewrite_accept_language(const struct sess *sp) {
  157 + vcl_string *in_hdr;
  158 + vcl_string lang[LANG_MAXLEN];
  159 +
  160 + memset(lang, 0, LANG_MAXLEN);
  161 +
  162 + /* Get Accept-Language header from client */
  163 + in_hdr = VRT_GetHdr(sp, HDR_REQ, "\020Accept-Language:");
  164 +
  165 + /* Normalize and filter out by list of supported languages */
  166 + select_language(in_hdr, lang);
  167 +
  168 + /* By default, use a different header name: don't mess with backend logic */
  169 + VRT_SetHdr(sp, HDR_REQ, "\032X-Varnish-Accept-Language:", lang, vrt_magic_string_end);
  170 +
  171 + return;
  172 +}
  173 +
  174 +/* vim: syn=c ts=4 et sts=4 sw=4 tw=0
  175 +*/
  176 +
  177 +/* THIS FILE IS AUTOMATICALLY GENERATED BY ./gen_vcl.pl. DO NOT EDIT. */
  178 +/* ------------------------------------------------------------------ */
  179 +}C
  180 +
  181 +sub vcl_recv {
  182 + C{
  183 + vcl_rewrite_accept_language(sp);
  184 + }C
  185 + return(pass);
  186 +}
... ...