Commit 52e9c1aca08d09df3562d22ad4eb692293168f11
1 parent
91ecca1a
Exists in
master
and in
23 other branches
Documenting Varnish usage
(ActionItem1608)
Showing
2 changed files
with
253 additions
and
0 deletions
Show diff stats
| @@ -0,0 +1,67 @@ | @@ -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 |
| @@ -0,0 +1,186 @@ | @@ -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 | +} |