Commit 52e9c1aca08d09df3562d22ad4eb692293168f11
1 parent
91ecca1a
Exists in
master
and in
28 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 | +} |