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/
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
;
57 unsigned int fastpath
=0;
59 void nginx_write(const char *format
, ...) {
61 va_start(args
, format
);
62 vfprintf(nginx_conf_file
, format
, args
);
66 void fastcgi_write(const char *format
, ...) {
68 va_start(args
, format
);
69 vfprintf(fastcgi_conf_file
, format
, args
);
74 void mimetypes_write(const char *format
, ...) {
76 va_start(args
, format
);
77 vfprintf(mimetypes_file
, format
, 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
);
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
);
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",
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
);
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
);
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
);
209 nginx_write("# NGinX generated config file\n");
210 // syslog(LOG_INFO,"NGinX","started writing config file %s\n", nginxconf);
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
);
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");
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
;
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
);
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
;
293 nginx_write("\t}\n");
295 // Process to close and write config file
297 if ((buf
= nvram_safe_get("nginx_custom")) == NULL
) buf
= nginxcustom
;
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" );
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"));
316 syslog(LOG_INFO
,"NGinX - php.ini file built succesfully\n");
321 // Start the NGINX module according environment directives.
322 void start_nginx(void)
325 if(!nvram_match("nginx_enable", "1")){
326 syslog(LOG_INFO
,"NGinX - daemon not enabled cancelled generation of config file\n");
330 syslog(LOG_INFO
,"NGinX - fastpath forced generation of config file\n");
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"))) {
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");
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"));
369 xstart(nginxbin
, "-c", nginxconf
);
372 // Start NGinx using fastpath method no checks
373 void start_nginxfp(void)
379 // Stopping NGINX and remove traces of the process.
380 void stop_nginx(void)
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
)) {
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"))) {
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"))) {
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"))) {
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)