libusb10: updated to 1.0.9
[tomato.git] / release / src / router / rc / nginx.c
blob93d6440ec639210ae73b5bfef994e9044c609aaa
1 /*
2 * nginx.c
4 * Copyright (C) 2013 NGinX for Tomato RAF
5 * ***** Ofer Chen, roadkill AT tomatoraf DOT com
6 * ***** Vicente Soriano, victek AT tomatoraf DOT com
8 * No part of this program can be used out of Tomato Firmware without owners permission.
9 * This code generates the configurations files for NGINX. You can see these files in /etc/nginx/
12 #include <stdlib.h>
13 #include <rc.h>
14 #include <shutils.h>
15 #include <utils.h>
16 #include <syslog.h>
17 #include <sys/stat.h>
18 #include <stdarg.h>
20 #define nginxbin "nginx" // process name
21 #define nginxname "tomato.local" // server name
22 #define nginxdocrootdir "/www" // document root
23 #define nginxconf "/tmp/etc/nginx/nginx.conf" // config file
24 #define nginxcustom "#" // additional window for custom parameter.
25 #define fastcgiconf "/tmp/etc/nginx/fastcgi.conf" // fastcgi config file
26 #define mimetypes "/tmp/etc/nginx/mime.types" // mime.types config
27 #define nginxdir "/tmp/etc/nginx/" // directory to write config files
28 #define client_body_temp_path "/tmp/var/lib/nginx/client" // temp path needed to execute nginx
29 #define fastcgi_temp_path "/tmp/var/lib/nginx/fastcgi" // temp path needed to execute nginx fastcgi
30 #define uwsgi_temp_path "/tmp/var/lib/nginx/uwsgi" // temp path needed to execute nginx
31 #define scgi_temp_path "/tmp/var/lib/nginx/scgi" // temp path needed to execute nginx
32 #define proxy_temp_path "/tmp/var/lib/nginx/proxy" // temp path needed to execute reverse proxy
33 //#define nginxuser "root" // user. Beta test, root can't be exposed.
34 #define nginx_worker_proc "1" // worker processes. CPU, cores.
35 #define nginx_cpu_affinity "0101" // Can bind the worker process to a CPU, it calls sched_setaffinity().
36 //define nginx_worker_priority "5" // priority ((-20)=High Priority (19)=Lowest Priority) Info: kernel have -5.
37 #define nginx_multi_accept "on" // specifies multiple connections for one core CPU
38 #define nginx_limitrate "50k" // specifies a limit rate of 50Kbps (multiply it by limit_conn_zone) per IP.
39 #define nginx_limitzone "one" // specifies the server zone to apply the restriction (limit_rate+n).
40 #define nginx_globrate "5m" // defines max global speed.
41 #define nginx_master_process "off" // set to "on" in developpment mode only.
42 #define nginx_limitsimconn "10" // defines max number of simulta. Connections in the server zone (limitzone).
43 #define nginxerrorlog "/tmp/var/log/nginx/error.log" // error log
44 #define nginxpid "/tmp/var/run/nginx.pid" // pid
45 #define nginx_worker_rlimit_profile "8192" // worker rlimit profile
46 #define nginx_keepalive_timeout "60" // the server will close connections after this time
47 #define nginx_worker_connections "512" // worker_proc*512/keepalive_timeout*60 = 512 users per minute.
48 #define nginxaccesslog "/tmp/var/log/nginx/access.log" // access log
49 #define nginssendfile "on" // sendfile
50 #define nginxtcp_nopush "on" // tcp_nopush
51 #define nginxserver_names_hash_bucket_size "128" // server names hash bucket size
53 FILE * nginx_conf_file;
54 FILE * fastcgi_conf_file;
55 FILE * mimetypes_file;
56 FILE * phpini_file;
57 unsigned int fastpath=0;
59 void nginx_write(const char *format, ...) {
60 va_list args;
61 va_start(args, format);
62 vfprintf(nginx_conf_file, format, args);
63 va_end(args);
66 void fastcgi_write(const char *format, ...) {
67 va_list args;
68 va_start(args, format);
69 vfprintf(fastcgi_conf_file, format, args);
70 va_end(args);
74 void mimetypes_write(const char *format, ...) {
75 va_list args;
76 va_start(args, format);
77 vfprintf(mimetypes_file, format, args);
78 va_end(args);
81 int build_fastcgi_conf(void) {
82 // Starting a fastcgi configuration file
83 // syslog(LOG_INFO,"FastCGI - config file generation started\n");
85 if(mkdir_if_none(nginxdir));
86 // syslog(LOG_INFO,"FastCGI - directory created %s\n", nginxdir);
87 if((fastcgi_conf_file = fopen(fastcgiconf, "w")) == NULL) {
88 // notice_set("FastCGI","config file %s has been created\n", fastcgiconf);
89 simple_unlock(fastcgiconf);
90 return 0;
93 fastcgi_write("# FastCGI generated config file\n");
94 fastcgi_write("fastcgi_param SCRIPT_FILENAME\t\t$document_root$fastcgi_script_name;\n");
95 fastcgi_write("fastcgi_param QUERY_STRING\t\t$query_string;\n");
96 fastcgi_write("fastcgi_param REQUEST_METHOD\t\t$request_method;\n");
97 fastcgi_write("fastcgi_param CONTENT_TYPE\t\t$content_type;\n");
98 fastcgi_write("fastcgi_param CONTENT_LENGTH\t\t$content_length;\n");
99 fastcgi_write("fastcgi_param SCRIPT_NAME\t\t$fastcgi_script_name;\n");
100 fastcgi_write("fastcgi_param REQUEST_URI\t\t$request_uri;\n");
101 fastcgi_write("fastcgi_param DOCUMENT_URI\t\t$document_uri;\n");
102 fastcgi_write("fastcgi_param DOCUMENT_ROOT\t\t$document_root;\n");
103 fastcgi_write("fastcgi_param SERVER_PROTOCOL\t\t$server_protocol;\n");
104 fastcgi_write("fastcgi_param GATEWAY_INTERFACE\t\tCGI/1.1;\n");
105 fastcgi_write("fastcgi_param SERVER_SOFTWARE\t\tnginx/$nginx_version;\n");
106 fastcgi_write("fastcgi_param REMOTE_ADDR\t\t$remote_addr;\n");
107 fastcgi_write("fastcgi_param REMOTE_PORT\t\t$remote_port;\n");
108 fastcgi_write("fastcgi_param SERVER_ADDR\t\t$server_addr;\n");
109 fastcgi_write("fastcgi_param SERVER_PORT\t\t$server_port;\n");
110 fastcgi_write("fastcgi_param SERVER_NAME\t\t$server_name;\n");
112 fastcgi_write("fastcgi_index index.php;\n");
113 fastcgi_write("fastcgi_param REDIRECT_STATUS 200;\n");
115 fclose(fastcgi_conf_file);
116 // syslog(LOG_INFO,"FastCGI - config file finished succesfully!!\n");
117 fprintf(stderr, "Wrote: %s\n", fastcgiconf);
119 return 0;
122 int build_mime_types(void) {
123 unsigned int i; //integer cast
125 static const char *nginxdmimetypes[] = {
126 "text/html\t\t\t\thtml htm shtml",
127 "text/css\t\t\t\tcss",
128 "text/xml\t\t\t\txml rss",
129 "image/gif\t\t\t\tgif",
130 "image/jpeg\t\t\t\tjpeg jpg",
131 "application/x-javascript\t\t\t\tjs",
132 "text/plain\t\t\t\ttxt",
133 "text/x-component\t\t\t\thtc",
134 "text/mathml\t\t\t\tmml",
135 "image/png\t\t\t\tpng",
136 "image/x-icon\t\t\t\tico",
137 "image/x-jng\t\t\t\tjng",
138 "image/vnd.wap.wbmp\t\t\t\twbmp",
139 "application/java-archive\t\t\t\tjar war ear",
140 "application/mac-binhex40\t\t\t\thqx",
141 "application/pdf\t\t\t\tpdf",
142 "application/x-cocoa\t\t\t\tcco",
143 "application/x-java-archive-diff\t\t\t\tjardiff",
144 "application/x-java-jnlp-file\t\t\t\tjnlp",
145 "application/x-makeself\t\t\t\trun",
146 "application/x-perl\t\t\t\tpl pm",
147 "application/x-pilot\t\t\t\tprc pdb",
148 "application/x-rar-compressed\t\t\t\trar",
149 "application/x-redhat-package-manager\t\t\t\trpm",
150 "application/x-sea\t\t\t\tsea",
151 "application/x-shockwave-flash\t\t\t\tswf",
152 "application/x-stuffit\t\t\t\tsit",
153 "application/x-tcl\t\t\t\ttcl tk",
154 "application/x-x509-ca-cert\t\t\t\tder pem crt",
155 "application/x-xpinstall\t\t\t\txpi",
156 "application/zip\t\t\t\tzip",
157 "application/octet-stream\t\t\t\tdeb",
158 "application/octet-stream\t\t\t\tbin exe dll",
159 "application/octet-stream\t\t\t\tdmg",
160 "application/octet-stream\t\t\t\teot",
161 "application/octet-stream\t\t\t\tiso img",
162 "application/octet-stream\t\t\t\tmsi msp msm",
163 "audio/mpeg\t\t\t\tmp3",
164 "audio/x-realaudio\t\t\t\tra",
165 "video/mpeg\t\t\t\tmpeg mpg",
166 "video/quicktime\t\t\t\tmov",
167 "video/x-flv\t\t\t\tflv",
168 "video/x-msvideo\t\t\t\tavi",
169 "video/x-ms-wmv\t\t\t\twmv",
170 "video/x-ms-asf\t\t\t\tasx asf",
171 "video/x-mng\t\t\t\tmng",
172 NULL };
175 // Starting the mime.types configuration file
176 // syslog(LOG_INFO,"MimeTypes - File generation started\n");
178 if(mkdir_if_none(nginxdir));
179 // syslog(LOG_INFO,"MimeTypes - directory created %s\n", nginxdir);
180 if((mimetypes_file = fopen(mimetypes, "w")) == NULL) {
181 // notice_set("MimeTypes","file %s has been created\n", mimetypes);
182 simple_unlock(mimetypes);
183 return 0;
185 mimetypes_write("# Mime.Types generated file\n");
186 mimetypes_write("types {\n");
187 for(i=0; nginxdmimetypes[i]; i++) { mimetypes_write("\t%s;\n", nginxdmimetypes[i]); }
188 mimetypes_write("}\n");
189 fclose(mimetypes_file);
190 // syslog(LOG_INFO,"MimeTypes - file built succesfully!!\n");
191 fprintf(stderr, "Wrote: %s\n", mimetypes);
192 return 0;
195 int build_nginx_conf(void) {
196 char *buf; //default param buffer
197 unsigned int i; //integer cast
199 // Starting the nginx configuration file
200 syslog(LOG_INFO,"NGinX - started generating nginx config file\n");
202 if(mkdir_if_none(nginxdir));
203 // syslog(LOG_INFO,"NGinX - directory created %s\n", nginxdir);
204 if((nginx_conf_file = fopen(nginxconf, "w")) == NULL) {
205 // notice_set("NGinX","config file %s has been created\n", nginxconf);
206 simple_unlock(nginxconf);
207 return 0;
209 nginx_write("# NGinX generated config file\n");
210 // syslog(LOG_INFO,"NGinX","started writing config file %s\n", nginxconf);
212 //Global process
213 nginx_write("user\t%s;\n", nvram_safe_get("nginx_user"));
214 nginx_write("worker_processes\t%s;\n", nginx_worker_proc);
215 nginx_write("worker_cpu_affinity\t%s;\n", nginx_cpu_affinity);
216 nginx_write("master_process\t%s;\n", nginx_master_process);
217 i = nvram_get_int("nginx_priority");
218 if ((i <= -20) || (i >= 19)) i = 10; // min = Max Performance and max= Min Performance value for worker_priority
219 nginx_write("worker_priority\t%d;\n", i);
220 nginx_write("error_log\t%s;\n", nginxerrorlog);
221 nginx_write("pid\t%s;\n", nginxpid);
222 nginx_write("worker_rlimit_nofile\t%s;\n", nginx_worker_rlimit_profile);
224 //Events
225 nginx_write("events {\n");
226 nginx_write("\tworker_connections\t%s;\n", nginx_worker_connections);
227 // nginx_write("\tmulti_accept\t%s;\n", nginx_multi_accept);
228 nginx_write("\t}\n");
230 //http
231 nginx_write("http {\n");
232 nginx_write("include\t%s;\n", mimetypes);
233 nginx_write("include\t%s;\n", fastcgiconf);
234 nginx_write("default_type\tapplication/octet-stream;\n");
235 nginx_write("log_format main '$remote_addr - $remote_user [$time_local] $status '\n");
236 nginx_write("'\"$request\" $body_bytes_sent \"$http_referer\" '\n");
237 nginx_write("'\"$http_user_agent\" \"$http_x_forwarded_for\"';\n");
238 nginx_write("sendfile\t%s;\n", nginssendfile);
240 //shibby - add custom config to http section
241 nginx_write("client_max_body_size\t%sM;\n", nvram_safe_get("nginx_upload"));
243 if ((buf = nvram_safe_get("nginx_httpcustom")) == NULL) buf = nginxcustom;
244 nginx_write(buf);
245 nginx_write("\n");
247 // nginx_write("keepalive_timeout\t%s;\n", nginx_keepalive_timeout);
248 // nginx_write("tcp_nopush\t%s;\n", nginxtcp_nopush);
249 // nginx_write("server_names_hash_bucket_size\t%s;\n", nginxserver_names_hash_bucket_size);
250 // nginx_write("limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;\n");
252 //Basic Server Parameters.
253 nginx_write("server {\n");
254 i = nvram_get_int("nginx_port");
255 if ((i <= 0) || (i >= 0xFFFF)) i = 85; // 0xFFFF 65535
256 nginx_write("listen\t%d;\n", i);
257 if ((buf = nvram_safe_get("nginx_fqdn")) == NULL) buf = nginxname;
258 nginx_write("server_name\t%s;\n", buf);
259 nginx_write("access_log\t%s\tmain;\n", nginxaccesslog);
260 nginx_write("location\t/\t{\n");
261 if ((buf = nvram_safe_get("nginx_docroot")) == NULL) buf = nginxdocrootdir;
262 nginx_write("root\t%s;\n", buf);
263 nginx_write("index\tindex.html\tindex.htm\tindex.php;\n");
264 // Error pages section
265 nginx_write("error_page 404\t/404.html;\n");
266 nginx_write("error_page 500\t502\t503\t504\t/50x.html;\n");
267 nginx_write("location\t/50x.html\t{\n");
268 if ((buf = nvram_safe_get("nginx_docroot")) == NULL) buf = nginxdocrootdir;
269 nginx_write("root\t%s;\n", buf);
270 nginx_write("}\n");
271 // PHP to FastCGI Server
272 if( nvram_match( "nginx_php", "1" ) ) {
273 nginx_write("location ~ ^(?<script_name>.+?\\.php)(?<path_info>/.*)?$ {\n");
274 nginx_write("try_files \t$script_name = 404;\n");
275 nginx_write("include\t%s;\n", fastcgiconf);
276 nginx_write("fastcgi_param PATH_INFO $path_info;\n");
277 nginx_write("fastcgi_pass\t127.0.0.1:9000;\n");
278 nginx_write("\t}\n");
281 // Server for static files
282 nginx_write("location ~ ^/(images|javascript|js|css|flash|media|static)/ {\n");
283 nginx_write("root\t%s;\n", buf);
284 nginx_write("expires 10d;\n");
285 nginx_write("\t\t\t}\n");
286 nginx_write("\t\t}\n");
288 //shibby - add custom config to server section
289 if ((buf = nvram_safe_get("nginx_servercustom")) == NULL) buf = nginxcustom;
290 nginx_write(buf);
291 nginx_write("\n");
293 nginx_write("\t}\n");
294 nginx_write("}\n");
295 // Process to close and write config file
296 nginx_write("\n");
297 if ((buf = nvram_safe_get("nginx_custom")) == NULL) buf = nginxcustom;
298 nginx_write(buf);
299 fclose(nginx_conf_file);
300 syslog(LOG_INFO,"NGinX - config file built succesfully\n");
301 fprintf(stderr, "Wrote: %s\n", nginxconf);
303 //shibby - create php.ini
304 if( nvram_match( "nginx_php", "1" ) ) {
305 if( !(phpini_file = fopen("/tmp/etc/php.ini", "w")) ) {
306 perror( "/tmp/etc/php.ini" );
307 return;
309 fprintf( phpini_file, "post_max_size = %sM\n", nvram_safe_get("nginx_upload"));
310 fprintf( phpini_file, "upload_max_filesize = %sM\n", nvram_safe_get("nginx_upload"));
311 fprintf( phpini_file, "upload_max_filesize = %sM\n", nvram_safe_get("nginx_upload"));
312 fprintf( phpini_file, "mysql.default_port = 3309\n");
313 fprintf( phpini_file, "mysql.default_socket = /var/run/mysqld.sock\n");
314 fprintf( phpini_file, "%s\n", nvram_safe_get("nginx_phpconf"));
315 fclose(phpini_file);
316 syslog(LOG_INFO,"NGinX - php.ini file built succesfully\n");
318 return 0;
321 // Start the NGINX module according environment directives.
322 void start_nginx(void)
324 if (fastpath != 1) {
325 if(!nvram_match("nginx_enable", "1")){
326 syslog(LOG_INFO,"NGinX - daemon not enabled cancelled generation of config file\n");
327 return;
329 }else{
330 syslog(LOG_INFO,"NGinX - fastpath forced generation of config file\n");
333 if (fastpath != 1) {
334 stop_nginx();
335 }else{
336 stop_nginxfp();
339 if (!f_exists(fastcgiconf)) build_fastcgi_conf();
340 if (!f_exists(mimetypes)) build_mime_types();
341 if ((fastpath != 1) && (!nvram_match("nginx_keepconf", "1"))) {
342 build_nginx_conf();
343 }else{
344 if (!f_exists(nginxconf)) build_nginx_conf();
347 //shibby - create /tmp/var/log/nginx directory before start daemon (if does not exist)
348 xstart("mkdir", "-p", "/tmp/var/log/nginx");
350 if( nvram_match( "nginx_php", "1" ) ) {
351 //shibby - run spawn-fcgi
352 xstart("spawn-fcgi", "-a", "127.0.0.1", "-p", "9000", "-P", "/var/run/php-fastcgi.pid", "-C", "2", "-u", nvram_safe_get("nginx_user"), "-g", nvram_safe_get("nginx_user"), "-f", "php-cgi");
353 } else {
354 killall_tk("php-cgi");
357 if(mkdir_if_none(client_body_temp_path));
358 // syslog(LOG_INFO,"NGinX - directory created %s\n", client_body_temp_path);
359 if(mkdir_if_none(fastcgi_temp_path));
360 // syslog(LOG_INFO,"NGinX - directory created %s\n", fastcgi_temp_path);
361 if(mkdir_if_none(uwsgi_temp_path));
362 // syslog(LOG_INFO,"NGinX - directory created %s\n", uwsgi_temp_path);
363 if(mkdir_if_none(scgi_temp_path));
364 // syslog(LOG_INFO,"NGinX - directory created %s\n", scgi_temp_path);
365 syslog(LOG_INFO,"NGinX - running daemon\n");
366 if( nvram_match( "nginx_override", "1" ) ) {
367 xstart(nginxbin, "-c", nvram_safe_get("nginx_overridefile"));
368 } else {
369 xstart(nginxbin, "-c", nginxconf);
372 // Start NGinx using fastpath method no checks
373 void start_nginxfp(void)
375 fastpath = 1;
376 start_nginx();
377 fastpath = 0;
379 // Stopping NGINX and remove traces of the process.
380 void stop_nginx(void)
382 unsigned int i;
384 i = 0;
385 syslog(LOG_INFO,"NGinX - killing daemon\n");
386 if ((i = pidof (nginxbin)) > 0) {
387 killall_tk(nginxbin);
388 killall_tk("php-cgi"); //shibby
389 if (f_exists(nginxpid)) {
390 unlink(nginxpid);
391 // syslog(LOG_INFO,"NGinX - removed pid file %s\n", nginxpid);
393 if (f_exists(fastcgiconf)) {
394 if ((fastpath != 1) && (!nvram_match("nginx_keepconf", "1"))) {
395 unlink(fastcgiconf);
396 // syslog(LOG_INFO,"NGinX - removed fastcgi config file %s\n", fastcgiconf);
398 // syslog(LOG_INFO,"NGinX - skip removal of fastcgi config file %s due to fastpath method\n", fastcgiconf);
400 if (f_exists(mimetypes)) {
401 if ((fastpath != 1) && (!nvram_match("nginx_keepconf", "1"))) {
402 unlink(mimetypes);
403 // syslog(LOG_INFO,"NGinX - remove mime types file %s\n", mimetypes);
405 // syslog(LOG_INFO,"NGinX - skip removal of mime types config file %s due to fastpath method\n", mimetypes);
407 if (f_exists(nginxconf)) {
408 if ((fastpath != 1) && (!nvram_match("nginx_keepconf", "1"))) {
409 unlink(nginxconf);
410 // syslog(LOG_INFO,"NGinX - removed nginx config file %s\n", nginxconf);
412 // syslog(LOG_INFO,"NGinX - skip removal of nginx config file %s due to fastpath method\n", nginxconf);
416 // Stop NGinx using fastpath method no checks
417 void stop_nginxfp(void)
419 fastpath = 1;
420 stop_nginx();
421 fastpath = 0;