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 @@ |
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 @@ |
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 | +} | ... | ... |