/ngx_http_ajp_module.c

http://github.com/yaoweibin/nginx_ajp_module · C · 1071 lines · 814 code · 239 blank · 18 comment · 106 complexity · a59c599decfdad1779aafa08c0d92b39 MD5 · raw file

  1. #include <ngx_config.h>
  2. #include <ngx_core.h>
  3. #include <ngx_http.h>
  4. #include <ngx_http_ajp.h>
  5. #include <ngx_http_ajp_module.h>
  6. #include <ngx_http_ajp_handler.h>
  7. static char *ngx_http_ajp_pass(ngx_conf_t *cf, ngx_command_t *cmd,
  8. void *conf);
  9. static char *ngx_http_ajp_store(ngx_conf_t *cf, ngx_command_t *cmd,
  10. void *conf);
  11. #if (NGX_HTTP_CACHE)
  12. static char *ngx_http_ajp_cache(ngx_conf_t *cf, ngx_command_t *cmd,
  13. void *conf);
  14. static char *ngx_http_ajp_cache_key(ngx_conf_t *cf, ngx_command_t *cmd,
  15. void *conf);
  16. #endif
  17. static char *ngx_http_ajp_lowat_check(ngx_conf_t *cf, void *post,
  18. void *data);
  19. static char *ngx_http_ajp_upstream_max_fails_unsupported(ngx_conf_t *cf,
  20. ngx_command_t *cmd, void *conf);
  21. static char *ngx_http_ajp_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
  22. ngx_command_t *cmd, void *conf);
  23. static void *ngx_http_ajp_create_loc_conf(ngx_conf_t *cf);
  24. static char *ngx_http_ajp_merge_loc_conf(ngx_conf_t *cf,
  25. void *parent, void *child);
  26. static ngx_int_t ngx_http_ajp_module_init_process(ngx_cycle_t *cycle);
  27. static ngx_conf_post_t ngx_http_ajp_lowat_post = { ngx_http_ajp_lowat_check };
  28. static ngx_conf_bitmask_t ngx_http_ajp_next_upstream_masks[] = {
  29. { ngx_string("error"), NGX_HTTP_UPSTREAM_FT_ERROR },
  30. { ngx_string("timeout"), NGX_HTTP_UPSTREAM_FT_TIMEOUT },
  31. { ngx_string("invalid_header"), NGX_HTTP_UPSTREAM_FT_INVALID_HEADER },
  32. { ngx_string("http_500"), NGX_HTTP_UPSTREAM_FT_HTTP_500 },
  33. { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
  34. { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
  35. { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
  36. { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
  37. { ngx_null_string, 0 }
  38. };
  39. static ngx_path_init_t ngx_http_ajp_temp_path = {
  40. ngx_string(NGX_HTTP_AJP_TEMP_PATH), { 1, 2, 0 }
  41. };
  42. static ngx_str_t ngx_http_ajp_hide_headers[] = {
  43. ngx_string("Status"),
  44. ngx_string("X-Accel-Expires"),
  45. ngx_string("X-Accel-Redirect"),
  46. ngx_string("X-Accel-Limit-Rate"),
  47. ngx_string("X-Accel-Buffering"),
  48. ngx_string("X-Accel-Charset"),
  49. ngx_null_string
  50. };
  51. #if (NGX_HTTP_CACHE)
  52. static ngx_str_t ngx_http_ajp_hide_cache_headers[] = {
  53. ngx_string("Status"),
  54. ngx_string("X-Accel-Expires"),
  55. ngx_string("X-Accel-Redirect"),
  56. ngx_string("X-Accel-Limit-Rate"),
  57. ngx_string("X-Accel-Buffering"),
  58. ngx_string("X-Accel-Charset"),
  59. ngx_string("Set-Cookie"),
  60. ngx_string("P3P"),
  61. ngx_null_string
  62. };
  63. #endif
  64. static ngx_command_t ngx_http_ajp_commands[] = {
  65. { ngx_string("ajp_pass"),
  66. NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE12,
  67. ngx_http_ajp_pass,
  68. NGX_HTTP_LOC_CONF_OFFSET,
  69. 0,
  70. NULL },
  71. { ngx_string("ajp_secret"),
  72. NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF|NGX_CONF_TAKE1,
  73. ngx_conf_set_str_slot,
  74. NGX_HTTP_LOC_CONF_OFFSET,
  75. offsetof(ngx_http_ajp_loc_conf_t, secret),
  76. NULL },
  77. { ngx_string("ajp_header_packet_buffer_size"),
  78. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  79. ngx_conf_set_size_slot,
  80. NGX_HTTP_LOC_CONF_OFFSET,
  81. offsetof(ngx_http_ajp_loc_conf_t, ajp_header_packet_buffer_size_conf),
  82. NULL },
  83. { ngx_string("ajp_max_data_packet_size"),
  84. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  85. ngx_conf_set_str_slot,
  86. NGX_HTTP_LOC_CONF_OFFSET,
  87. offsetof(ngx_http_ajp_loc_conf_t, max_ajp_data_packet_size_conf),
  88. NULL },
  89. { ngx_string("ajp_store"),
  90. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  91. ngx_http_ajp_store,
  92. NGX_HTTP_LOC_CONF_OFFSET,
  93. 0,
  94. NULL },
  95. { ngx_string("ajp_store_access"),
  96. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
  97. ngx_conf_set_access_slot,
  98. NGX_HTTP_LOC_CONF_OFFSET,
  99. offsetof(ngx_http_ajp_loc_conf_t, upstream.store_access),
  100. NULL },
  101. { ngx_string("ajp_ignore_client_abort"),
  102. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  103. ngx_conf_set_flag_slot,
  104. NGX_HTTP_LOC_CONF_OFFSET,
  105. offsetof(ngx_http_ajp_loc_conf_t, upstream.ignore_client_abort),
  106. NULL },
  107. { ngx_string("ajp_connect_timeout"),
  108. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  109. ngx_conf_set_msec_slot,
  110. NGX_HTTP_LOC_CONF_OFFSET,
  111. offsetof(ngx_http_ajp_loc_conf_t, upstream.connect_timeout),
  112. NULL },
  113. { ngx_string("ajp_send_timeout"),
  114. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  115. ngx_conf_set_msec_slot,
  116. NGX_HTTP_LOC_CONF_OFFSET,
  117. offsetof(ngx_http_ajp_loc_conf_t, upstream.send_timeout),
  118. NULL },
  119. { ngx_string("ajp_send_lowat"),
  120. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  121. ngx_conf_set_size_slot,
  122. NGX_HTTP_LOC_CONF_OFFSET,
  123. offsetof(ngx_http_ajp_loc_conf_t, upstream.send_lowat),
  124. &ngx_http_ajp_lowat_post },
  125. { ngx_string("ajp_buffer_size"),
  126. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  127. ngx_conf_set_size_slot,
  128. NGX_HTTP_LOC_CONF_OFFSET,
  129. offsetof(ngx_http_ajp_loc_conf_t, upstream.buffer_size),
  130. NULL },
  131. { ngx_string("ajp_pass_request_headers"),
  132. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  133. ngx_conf_set_flag_slot,
  134. NGX_HTTP_LOC_CONF_OFFSET,
  135. offsetof(ngx_http_ajp_loc_conf_t, upstream.pass_request_headers),
  136. NULL },
  137. { ngx_string("ajp_pass_request_body"),
  138. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  139. ngx_conf_set_flag_slot,
  140. NGX_HTTP_LOC_CONF_OFFSET,
  141. offsetof(ngx_http_ajp_loc_conf_t, upstream.pass_request_body),
  142. NULL },
  143. { ngx_string("ajp_intercept_errors"),
  144. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  145. ngx_conf_set_flag_slot,
  146. NGX_HTTP_LOC_CONF_OFFSET,
  147. offsetof(ngx_http_ajp_loc_conf_t, upstream.intercept_errors),
  148. NULL },
  149. { ngx_string("ajp_read_timeout"),
  150. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  151. ngx_conf_set_msec_slot,
  152. NGX_HTTP_LOC_CONF_OFFSET,
  153. offsetof(ngx_http_ajp_loc_conf_t, upstream.read_timeout),
  154. NULL },
  155. { ngx_string("ajp_buffers"),
  156. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
  157. ngx_conf_set_bufs_slot,
  158. NGX_HTTP_LOC_CONF_OFFSET,
  159. offsetof(ngx_http_ajp_loc_conf_t, upstream.bufs),
  160. NULL },
  161. { ngx_string("ajp_busy_buffers_size"),
  162. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  163. ngx_conf_set_size_slot,
  164. NGX_HTTP_LOC_CONF_OFFSET,
  165. offsetof(ngx_http_ajp_loc_conf_t, upstream.busy_buffers_size_conf),
  166. NULL },
  167. #if (NGX_HTTP_CACHE)
  168. { ngx_string("ajp_cache"),
  169. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  170. ngx_http_ajp_cache,
  171. NGX_HTTP_LOC_CONF_OFFSET,
  172. 0,
  173. NULL },
  174. { ngx_string("ajp_cache_key"),
  175. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  176. ngx_http_ajp_cache_key,
  177. NGX_HTTP_LOC_CONF_OFFSET,
  178. 0,
  179. NULL },
  180. { ngx_string("ajp_cache_path"),
  181. NGX_HTTP_MAIN_CONF|NGX_CONF_2MORE,
  182. ngx_http_file_cache_set_slot,
  183. 0,
  184. 0,
  185. &ngx_http_ajp_module },
  186. { ngx_string("ajp_cache_valid"),
  187. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  188. ngx_http_file_cache_valid_set_slot,
  189. NGX_HTTP_LOC_CONF_OFFSET,
  190. offsetof(ngx_http_ajp_loc_conf_t, upstream.cache_valid),
  191. NULL },
  192. { ngx_string("ajp_cache_min_uses"),
  193. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  194. ngx_conf_set_num_slot,
  195. NGX_HTTP_LOC_CONF_OFFSET,
  196. offsetof(ngx_http_ajp_loc_conf_t, upstream.cache_min_uses),
  197. NULL },
  198. { ngx_string("ajp_cache_use_stale"),
  199. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  200. ngx_conf_set_bitmask_slot,
  201. NGX_HTTP_LOC_CONF_OFFSET,
  202. offsetof(ngx_http_ajp_loc_conf_t, upstream.cache_use_stale),
  203. &ngx_http_ajp_next_upstream_masks },
  204. { ngx_string("ajp_cache_methods"),
  205. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  206. ngx_conf_set_bitmask_slot,
  207. NGX_HTTP_LOC_CONF_OFFSET,
  208. offsetof(ngx_http_ajp_loc_conf_t, upstream.cache_methods),
  209. &ngx_http_upstream_cache_method_mask },
  210. { ngx_string("ajp_cache_lock"),
  211. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  212. ngx_conf_set_flag_slot,
  213. NGX_HTTP_LOC_CONF_OFFSET,
  214. offsetof(ngx_http_ajp_loc_conf_t, upstream.cache_lock),
  215. NULL },
  216. { ngx_string("ajp_cache_lock_timeout"),
  217. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  218. ngx_conf_set_msec_slot,
  219. NGX_HTTP_LOC_CONF_OFFSET,
  220. offsetof(ngx_http_ajp_loc_conf_t, upstream.cache_lock_timeout),
  221. NULL },
  222. #endif
  223. { ngx_string("ajp_temp_path"),
  224. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1234,
  225. ngx_conf_set_path_slot,
  226. NGX_HTTP_LOC_CONF_OFFSET,
  227. offsetof(ngx_http_ajp_loc_conf_t, upstream.temp_path),
  228. NULL },
  229. { ngx_string("ajp_max_temp_file_size"),
  230. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  231. ngx_conf_set_size_slot,
  232. NGX_HTTP_LOC_CONF_OFFSET,
  233. offsetof(ngx_http_ajp_loc_conf_t, upstream.max_temp_file_size_conf),
  234. NULL },
  235. { ngx_string("ajp_temp_file_write_size"),
  236. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  237. ngx_conf_set_size_slot,
  238. NGX_HTTP_LOC_CONF_OFFSET,
  239. offsetof(ngx_http_ajp_loc_conf_t, upstream.temp_file_write_size_conf),
  240. NULL },
  241. { ngx_string("ajp_next_upstream"),
  242. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  243. ngx_conf_set_bitmask_slot,
  244. NGX_HTTP_LOC_CONF_OFFSET,
  245. offsetof(ngx_http_ajp_loc_conf_t, upstream.next_upstream),
  246. &ngx_http_ajp_next_upstream_masks },
  247. { ngx_string("ajp_upstream_max_fails"),
  248. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  249. ngx_http_ajp_upstream_max_fails_unsupported,
  250. 0,
  251. 0,
  252. NULL },
  253. { ngx_string("ajp_upstream_fail_timeout"),
  254. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
  255. ngx_http_ajp_upstream_fail_timeout_unsupported,
  256. 0,
  257. 0,
  258. NULL },
  259. { ngx_string("ajp_pass_header"),
  260. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  261. ngx_conf_set_str_array_slot,
  262. NGX_HTTP_LOC_CONF_OFFSET,
  263. offsetof(ngx_http_ajp_loc_conf_t, upstream.pass_headers),
  264. NULL },
  265. { ngx_string("ajp_hide_header"),
  266. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  267. ngx_conf_set_str_array_slot,
  268. NGX_HTTP_LOC_CONF_OFFSET,
  269. offsetof(ngx_http_ajp_loc_conf_t, upstream.hide_headers),
  270. NULL },
  271. { ngx_string("ajp_ignore_headers"),
  272. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_1MORE,
  273. ngx_conf_set_bitmask_slot,
  274. NGX_HTTP_LOC_CONF_OFFSET,
  275. offsetof(ngx_http_ajp_loc_conf_t, upstream.ignore_headers),
  276. &ngx_http_upstream_ignore_headers_masks },
  277. { ngx_string("ajp_keep_conn"),
  278. NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
  279. ngx_conf_set_flag_slot,
  280. NGX_HTTP_LOC_CONF_OFFSET,
  281. offsetof(ngx_http_ajp_loc_conf_t, keep_conn),
  282. NULL },
  283. ngx_null_command
  284. };
  285. static ngx_http_module_t ngx_http_ajp_module_ctx = {
  286. NULL, /* preconfiguration */
  287. NULL, /* postconfiguration */
  288. NULL, /* create main configuration */
  289. NULL, /* init main configuration */
  290. NULL, /* create server configuration */
  291. NULL, /* merge server configuration */
  292. ngx_http_ajp_create_loc_conf, /* create location configuration */
  293. ngx_http_ajp_merge_loc_conf /* merge location configuration */
  294. };
  295. ngx_module_t ngx_http_ajp_module = {
  296. NGX_MODULE_V1,
  297. &ngx_http_ajp_module_ctx, /* module context */
  298. ngx_http_ajp_commands, /* module directives */
  299. NGX_HTTP_MODULE, /* module type */
  300. NULL, /* init master */
  301. NULL, /* init module */
  302. ngx_http_ajp_module_init_process, /* init process */
  303. NULL, /* init thread */
  304. NULL, /* exit thread */
  305. NULL, /* exit process */
  306. NULL, /* exit master */
  307. NGX_MODULE_V1_PADDING
  308. };
  309. static char *
  310. ngx_http_ajp_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  311. {
  312. ngx_http_ajp_loc_conf_t *alcf = conf;
  313. size_t add;
  314. u_short port;
  315. ngx_url_t u;
  316. ngx_str_t *value, *url;
  317. ngx_uint_t n;
  318. ngx_http_core_loc_conf_t *clcf;
  319. ngx_http_script_compile_t sc;
  320. if (alcf->upstream.upstream || alcf->ajp_lengths) {
  321. return "is duplicate";
  322. }
  323. clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
  324. clcf->handler = ngx_http_ajp_handler;
  325. if (clcf->name.data[clcf->name.len - 1] == '/') {
  326. clcf->auto_redirect = 1;
  327. }
  328. value = cf->args->elts;
  329. url = &value[1];
  330. n = ngx_http_script_variables_count(url);
  331. if (n) {
  332. ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
  333. sc.cf = cf;
  334. sc.source = url;
  335. sc.lengths = &alcf->ajp_lengths;
  336. sc.values = &alcf->ajp_values;
  337. sc.variables = n;
  338. sc.complete_lengths = 1;
  339. sc.complete_values = 1;
  340. if (ngx_http_script_compile(&sc) != NGX_OK) {
  341. return NGX_CONF_ERROR;
  342. }
  343. if( cf->args->nelts>2 ) {
  344. alcf->secret = value[2];
  345. }
  346. return NGX_CONF_OK;
  347. }
  348. add = port = 0;
  349. if (ngx_strncasecmp(url->data, (u_char *) "ajp://", 6) == 0) {
  350. add = 6;
  351. port = 8009;
  352. }
  353. ngx_memzero(&u, sizeof(ngx_url_t));
  354. u.url.len = url->len - add;
  355. u.url.data = url->data + add;
  356. u.default_port = port;
  357. u.uri_part = 1;
  358. u.no_resolve = 1;
  359. alcf->upstream.upstream = ngx_http_upstream_add(cf, &u, 0);
  360. if (alcf->upstream.upstream == NULL) {
  361. return NGX_CONF_ERROR;
  362. }
  363. if( cf->args->nelts>2 ) {
  364. alcf->secret = value[2];
  365. }
  366. return NGX_CONF_OK;
  367. }
  368. static char *
  369. ngx_http_ajp_store(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  370. {
  371. ngx_str_t *value;
  372. ngx_http_ajp_loc_conf_t *alcf = conf;
  373. ngx_http_script_compile_t sc;
  374. if ((alcf->upstream.store != NGX_CONF_UNSET) ||
  375. alcf->upstream.store_lengths)
  376. {
  377. return "is duplicate";
  378. }
  379. value = cf->args->elts;
  380. if (ngx_strcmp(value[1].data, "off") == 0) {
  381. alcf->upstream.store = 0;
  382. return NGX_CONF_OK;
  383. }
  384. #if (NGX_HTTP_CACHE)
  385. #if (nginx_version >= 1007009)
  386. if (alcf->upstream.cache > 0)
  387. #else
  388. if (alcf->upstream.cache != NGX_CONF_UNSET_PTR
  389. && alcf->upstream.cache != NULL)
  390. #endif
  391. {
  392. return "is incompatible with \"ajp_cache\"";
  393. }
  394. #endif
  395. if (ngx_strcmp(value[1].data, "on") == 0) {
  396. alcf->upstream.store = 1;
  397. return NGX_CONF_OK;
  398. }
  399. /* include the terminating '\0' into script */
  400. value[1].len++;
  401. ngx_memzero(&sc, sizeof(ngx_http_script_compile_t));
  402. sc.cf = cf;
  403. sc.source = &value[1];
  404. sc.lengths = &alcf->upstream.store_lengths;
  405. sc.values = &alcf->upstream.store_values;
  406. sc.variables = ngx_http_script_variables_count(&value[1]);
  407. sc.complete_lengths = 1;
  408. sc.complete_values = 1;
  409. if (ngx_http_script_compile(&sc) != NGX_OK) {
  410. return NGX_CONF_ERROR;
  411. }
  412. return NGX_CONF_OK;
  413. }
  414. static char *
  415. ngx_http_ajp_lowat_check(ngx_conf_t *cf, void *post, void *data)
  416. {
  417. #if (NGX_FREEBSD)
  418. ssize_t *np = data;
  419. if ((u_long) *np >= ngx_freebsd_net_inet_tcp_sendspace) {
  420. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  421. "\"ajp_send_lowat\" must be less than %d "
  422. "(sysctl net.inet.tcp.sendspace)",
  423. ngx_freebsd_net_inet_tcp_sendspace);
  424. return NGX_CONF_ERROR;
  425. }
  426. #elif !(NGX_HAVE_SO_SNDLOWAT)
  427. ssize_t *np = data;
  428. ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  429. "\"ajp_send_lowat\" is not supported, ignored");
  430. *np = 0;
  431. #endif
  432. return NGX_CONF_OK;
  433. }
  434. #if (NGX_HTTP_CACHE)
  435. static char *
  436. ngx_http_ajp_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  437. {
  438. ngx_http_ajp_loc_conf_t *alcf = conf;
  439. ngx_str_t *value;
  440. #if (nginx_version >= 1007009)
  441. ngx_http_complex_value_t cv;
  442. ngx_http_compile_complex_value_t ccv;
  443. #endif
  444. value = cf->args->elts;
  445. #if (nginx_version >= 1007009)
  446. if (alcf->upstream.cache != NGX_CONF_UNSET) {
  447. #else
  448. if (alcf->upstream.cache != NGX_CONF_UNSET_PTR) {
  449. #endif
  450. return "is duplicate";
  451. }
  452. if (ngx_strcmp(value[1].data, "off") == 0) {
  453. #if (nginx_version >= 1007009)
  454. alcf->upstream.cache = 0;
  455. #else
  456. alcf->upstream.cache = NULL;
  457. #endif
  458. return NGX_CONF_OK;
  459. }
  460. if (alcf->upstream.store > 0 || alcf->upstream.store_lengths) {
  461. return "is incompatible with \"ajp_store\"";
  462. }
  463. #if (nginx_version >= 1007009)
  464. alcf->upstream.cache = 1;
  465. ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
  466. ccv.cf = cf;
  467. ccv.value = &value[1];
  468. ccv.complex_value = &cv;
  469. if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  470. return NGX_CONF_ERROR;
  471. }
  472. if (cv.lengths != NULL) {
  473. alcf->upstream.cache_value = ngx_palloc(cf->pool,
  474. sizeof(ngx_http_complex_value_t));
  475. if (alcf->upstream.cache_value == NULL) {
  476. return NGX_CONF_ERROR;
  477. }
  478. *alcf->upstream.cache_value = cv;
  479. return NGX_CONF_OK;
  480. }
  481. alcf->upstream.cache_zone = ngx_shared_memory_add(cf, &value[1], 0,
  482. &ngx_http_ajp_module);
  483. if (alcf->upstream.cache_zone == NULL) {
  484. return NGX_CONF_ERROR;
  485. }
  486. #else
  487. alcf->upstream.cache = ngx_shared_memory_add(cf, &value[1], 0,
  488. &ngx_http_ajp_module);
  489. if (alcf->upstream.cache == NULL) {
  490. return NGX_CONF_ERROR;
  491. }
  492. #endif
  493. return NGX_CONF_OK;
  494. }
  495. static char *
  496. ngx_http_ajp_cache_key(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
  497. {
  498. ngx_http_ajp_loc_conf_t *alcf = conf;
  499. ngx_str_t *value;
  500. ngx_http_compile_complex_value_t ccv;
  501. value = cf->args->elts;
  502. if (alcf->cache_key.value.len) {
  503. return "is duplicate";
  504. }
  505. ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
  506. ccv.cf = cf;
  507. ccv.value = &value[1];
  508. ccv.complex_value = &alcf->cache_key;
  509. if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
  510. return NGX_CONF_ERROR;
  511. }
  512. return NGX_CONF_OK;
  513. }
  514. #endif
  515. static char *
  516. ngx_http_ajp_upstream_max_fails_unsupported(ngx_conf_t *cf,
  517. ngx_command_t *cmd, void *conf)
  518. {
  519. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  520. "\"ajp_upstream_max_fails\" is not supported, "
  521. "use the \"max_fails\" parameter of the \"server\" directive ",
  522. "inside the \"upstream\" block");
  523. return NGX_CONF_ERROR;
  524. }
  525. static char *
  526. ngx_http_ajp_upstream_fail_timeout_unsupported(ngx_conf_t *cf,
  527. ngx_command_t *cmd, void *conf)
  528. {
  529. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  530. "\"ajp_upstream_fail_timeout\" is not supported, "
  531. "use the \"fail_timeout\" parameter of the \"server\" directive ",
  532. "inside the \"upstream\" block");
  533. return NGX_CONF_ERROR;
  534. }
  535. static void *
  536. ngx_http_ajp_create_loc_conf(ngx_conf_t *cf)
  537. {
  538. ngx_http_ajp_loc_conf_t *conf;
  539. conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_ajp_loc_conf_t));
  540. if (conf == NULL) {
  541. return NULL;
  542. }
  543. /*
  544. * set by ngx_pcalloc():
  545. *
  546. * conf->upstream.bufs.num = 0;
  547. * conf->upstream.ignore_headers = 0;
  548. * conf->upstream.next_upstream = 0;
  549. * conf->upstream.cache_use_stale = 0;
  550. * conf->upstream.cache_methods = 0;
  551. * conf->upstream.temp_path = NULL;
  552. * conf->upstream.hide_headers_hash = { NULL, 0 };
  553. * conf->upstream.uri = { 0, NULL };
  554. * conf->upstream.location = NULL;
  555. * conf->upstream.store_lengths = NULL;
  556. * conf->upstream.store_values = NULL;
  557. *
  558. */
  559. conf->ajp_header_packet_buffer_size_conf = NGX_CONF_UNSET_SIZE;
  560. conf->max_ajp_data_packet_size_conf = NGX_CONF_UNSET_SIZE;
  561. conf->upstream.store = NGX_CONF_UNSET;
  562. conf->upstream.store_access = NGX_CONF_UNSET_UINT;
  563. conf->upstream.buffering = NGX_CONF_UNSET;
  564. conf->upstream.ignore_client_abort = NGX_CONF_UNSET;
  565. conf->upstream.connect_timeout = NGX_CONF_UNSET_MSEC;
  566. conf->upstream.send_timeout = NGX_CONF_UNSET_MSEC;
  567. conf->upstream.read_timeout = NGX_CONF_UNSET_MSEC;
  568. conf->upstream.send_lowat = NGX_CONF_UNSET_SIZE;
  569. conf->upstream.buffer_size = NGX_CONF_UNSET_SIZE;
  570. conf->upstream.busy_buffers_size_conf = NGX_CONF_UNSET_SIZE;
  571. conf->upstream.max_temp_file_size_conf = NGX_CONF_UNSET_SIZE;
  572. conf->upstream.temp_file_write_size_conf = NGX_CONF_UNSET_SIZE;
  573. conf->upstream.pass_request_headers = NGX_CONF_UNSET;
  574. conf->upstream.pass_request_body = NGX_CONF_UNSET;
  575. #if (NGX_HTTP_CACHE)
  576. #if (nginx_version >= 1007009)
  577. conf->upstream.cache = NGX_CONF_UNSET;
  578. #else
  579. conf->upstream.cache = NGX_CONF_UNSET_PTR;
  580. #endif
  581. conf->upstream.cache_min_uses = NGX_CONF_UNSET_UINT;
  582. conf->upstream.cache_valid = NGX_CONF_UNSET_PTR;
  583. conf->upstream.cache_lock = NGX_CONF_UNSET;
  584. conf->upstream.cache_lock_timeout = NGX_CONF_UNSET_MSEC;
  585. #endif
  586. conf->upstream.hide_headers = NGX_CONF_UNSET_PTR;
  587. conf->upstream.pass_headers = NGX_CONF_UNSET_PTR;
  588. conf->upstream.intercept_errors = NGX_CONF_UNSET;
  589. /* "ajp_cyclic_temp_file" is disabled */
  590. conf->upstream.cyclic_temp_file = 0;
  591. conf->keep_conn = NGX_CONF_UNSET;
  592. ngx_str_set(&conf->upstream.module, "ajp");
  593. return conf;
  594. }
  595. static char *
  596. ngx_http_ajp_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
  597. {
  598. ngx_http_ajp_loc_conf_t *prev = parent;
  599. ngx_http_ajp_loc_conf_t *conf = child;
  600. size_t size;
  601. ngx_str_t *h;
  602. ngx_hash_init_t hash;
  603. if (conf->secret.data == NULL){
  604. conf->secret = prev->secret;
  605. }
  606. #if (NGX_HTTP_CACHE) && (nginx_version >= 1007009)
  607. if (conf->upstream.store > 0) {
  608. conf->upstream.cache = 0;
  609. }
  610. if (conf->upstream.cache > 0) {
  611. conf->upstream.store = 0;
  612. }
  613. #endif
  614. if (conf->upstream.store != 0) {
  615. ngx_conf_merge_value(conf->upstream.store,
  616. prev->upstream.store, 0);
  617. if (conf->upstream.store_lengths == NULL) {
  618. conf->upstream.store_lengths = prev->upstream.store_lengths;
  619. conf->upstream.store_values = prev->upstream.store_values;
  620. }
  621. }
  622. ngx_conf_merge_size_value(conf->ajp_header_packet_buffer_size_conf,
  623. prev->ajp_header_packet_buffer_size_conf,
  624. (size_t) AJP_MSG_BUFFER_SZ);
  625. ngx_conf_merge_size_value(conf->max_ajp_data_packet_size_conf,
  626. prev->max_ajp_data_packet_size_conf,
  627. (size_t) AJP_MSG_BUFFER_SZ);
  628. ngx_conf_merge_uint_value(conf->upstream.store_access,
  629. prev->upstream.store_access, 0600);
  630. ngx_conf_merge_value(conf->upstream.buffering,
  631. prev->upstream.buffering, 1);
  632. ngx_conf_merge_value(conf->upstream.ignore_client_abort,
  633. prev->upstream.ignore_client_abort, 0);
  634. ngx_conf_merge_msec_value(conf->upstream.connect_timeout,
  635. prev->upstream.connect_timeout, 60000);
  636. ngx_conf_merge_msec_value(conf->upstream.send_timeout,
  637. prev->upstream.send_timeout, 60000);
  638. ngx_conf_merge_msec_value(conf->upstream.read_timeout,
  639. prev->upstream.read_timeout, 60000);
  640. ngx_conf_merge_size_value(conf->upstream.send_lowat,
  641. prev->upstream.send_lowat, 0);
  642. ngx_conf_merge_size_value(conf->upstream.buffer_size,
  643. prev->upstream.buffer_size,
  644. (size_t) ngx_pagesize);
  645. ngx_conf_merge_bufs_value(conf->upstream.bufs, prev->upstream.bufs,
  646. 8, ngx_pagesize);
  647. if (conf->upstream.bufs.num < 2) {
  648. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  649. "there must be at least 2 \"ajp_buffers\"");
  650. return NGX_CONF_ERROR;
  651. }
  652. if (conf->ajp_header_packet_buffer_size_conf > AJP_MAX_BUFFER_SZ) {
  653. conf->ajp_header_packet_buffer_size_conf = AJP_MAX_BUFFER_SZ;
  654. }
  655. if(conf->max_ajp_data_packet_size_conf < AJP_MSG_BUFFER_SZ) {
  656. conf->max_ajp_data_packet_size_conf = AJP_MSG_BUFFER_SZ;
  657. } else if(conf->max_ajp_data_packet_size_conf > AJP_MAX_BUFFER_SZ ) {
  658. conf->max_ajp_data_packet_size_conf = AJP_MAX_BUFFER_SZ;
  659. }
  660. size = conf->upstream.buffer_size;
  661. if (size < conf->upstream.bufs.size) {
  662. size = conf->upstream.bufs.size;
  663. }
  664. ngx_conf_merge_size_value(conf->upstream.busy_buffers_size_conf,
  665. prev->upstream.busy_buffers_size_conf,
  666. NGX_CONF_UNSET_SIZE);
  667. if (conf->upstream.busy_buffers_size_conf == NGX_CONF_UNSET_SIZE) {
  668. conf->upstream.busy_buffers_size = 2 * size;
  669. } else {
  670. conf->upstream.busy_buffers_size =
  671. conf->upstream.busy_buffers_size_conf;
  672. }
  673. if (conf->upstream.busy_buffers_size < size) {
  674. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  675. "\"ajp_busy_buffers_size\" must be equal or bigger than "
  676. "maximum of the value of \"ajp_buffer_size\" and "
  677. "one of the \"ajp_buffers\"");
  678. return NGX_CONF_ERROR;
  679. }
  680. if (conf->upstream.busy_buffers_size
  681. > (conf->upstream.bufs.num - 1) * conf->upstream.bufs.size)
  682. {
  683. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  684. "\"ajp_busy_buffers_size\" must be less than "
  685. "the size of all \"ajp_buffers\" minus one buffer");
  686. return NGX_CONF_ERROR;
  687. }
  688. ngx_conf_merge_size_value(conf->upstream.temp_file_write_size_conf,
  689. prev->upstream.temp_file_write_size_conf,
  690. NGX_CONF_UNSET_SIZE);
  691. if (conf->upstream.temp_file_write_size_conf == NGX_CONF_UNSET_SIZE) {
  692. conf->upstream.temp_file_write_size = 2 * size;
  693. } else {
  694. conf->upstream.temp_file_write_size =
  695. conf->upstream.temp_file_write_size_conf;
  696. }
  697. if (conf->upstream.temp_file_write_size < size) {
  698. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  699. "\"ajp_temp_file_write_size\" must be equal or bigger than "
  700. "maximum of the value of \"ajp_buffer_size\" and "
  701. "one of the \"ajp_buffers\"");
  702. return NGX_CONF_ERROR;
  703. }
  704. ngx_conf_merge_size_value(conf->upstream.max_temp_file_size_conf,
  705. prev->upstream.max_temp_file_size_conf,
  706. NGX_CONF_UNSET_SIZE);
  707. if (conf->upstream.max_temp_file_size_conf == NGX_CONF_UNSET_SIZE) {
  708. conf->upstream.max_temp_file_size = 1024 * 1024 * 1024;
  709. } else {
  710. conf->upstream.max_temp_file_size =
  711. conf->upstream.max_temp_file_size_conf;
  712. }
  713. if (conf->upstream.max_temp_file_size != 0
  714. && conf->upstream.max_temp_file_size < size)
  715. {
  716. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  717. "\"ajp_max_temp_file_size\" must be equal to zero to disable "
  718. "the temporary files usage or must be equal or bigger than "
  719. "maximum of the value of \"ajp_buffer_size\" and "
  720. "one of the \"ajp_buffers\"");
  721. return NGX_CONF_ERROR;
  722. }
  723. ngx_conf_merge_bitmask_value(conf->upstream.ignore_headers,
  724. prev->upstream.ignore_headers,
  725. NGX_CONF_BITMASK_SET);
  726. ngx_conf_merge_bitmask_value(conf->upstream.next_upstream,
  727. prev->upstream.next_upstream,
  728. (NGX_CONF_BITMASK_SET
  729. |NGX_HTTP_UPSTREAM_FT_ERROR
  730. |NGX_HTTP_UPSTREAM_FT_TIMEOUT));
  731. if (conf->upstream.next_upstream & NGX_HTTP_UPSTREAM_FT_OFF) {
  732. conf->upstream.next_upstream = NGX_CONF_BITMASK_SET
  733. |NGX_HTTP_UPSTREAM_FT_OFF;
  734. }
  735. if (ngx_conf_merge_path_value(cf, &conf->upstream.temp_path,
  736. prev->upstream.temp_path,
  737. &ngx_http_ajp_temp_path)
  738. != NGX_OK)
  739. {
  740. return NGX_CONF_ERROR;
  741. }
  742. #if (NGX_HTTP_CACHE)
  743. #if (nginx_version >= 1007009)
  744. if (conf->upstream.cache == NGX_CONF_UNSET) {
  745. ngx_conf_merge_value(conf->upstream.cache,
  746. prev->upstream.cache, 0);
  747. conf->upstream.cache_zone = prev->upstream.cache_zone;
  748. conf->upstream.cache_value = prev->upstream.cache_value;
  749. }
  750. if (conf->upstream.cache_zone && conf->upstream.cache_zone->data == NULL) {
  751. ngx_shm_zone_t *shm_zone;
  752. shm_zone = conf->upstream.cache_zone;
  753. #else
  754. ngx_conf_merge_ptr_value(conf->upstream.cache,
  755. prev->upstream.cache, NULL);
  756. if (conf->upstream.cache && conf->upstream.cache->data == NULL) {
  757. ngx_shm_zone_t *shm_zone;
  758. shm_zone = conf->upstream.cache;
  759. #endif
  760. ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
  761. "\"ajp_cache\" zone \"%V\" is unknown, "
  762. "Maybe you haven't set the ajp_cache_path",
  763. &shm_zone->shm.name);
  764. return NGX_CONF_ERROR;
  765. }
  766. ngx_conf_merge_uint_value(conf->upstream.cache_min_uses,
  767. prev->upstream.cache_min_uses, 1);
  768. ngx_conf_merge_bitmask_value(conf->upstream.cache_use_stale,
  769. prev->upstream.cache_use_stale,
  770. (NGX_CONF_BITMASK_SET
  771. |NGX_HTTP_UPSTREAM_FT_OFF));
  772. if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_OFF) {
  773. conf->upstream.cache_use_stale = NGX_CONF_BITMASK_SET
  774. |NGX_HTTP_UPSTREAM_FT_OFF;
  775. }
  776. if (conf->upstream.cache_use_stale & NGX_HTTP_UPSTREAM_FT_ERROR) {
  777. conf->upstream.cache_use_stale |= NGX_HTTP_UPSTREAM_FT_NOLIVE;
  778. }
  779. if (conf->upstream.cache_methods == 0) {
  780. conf->upstream.cache_methods = prev->upstream.cache_methods;
  781. }
  782. conf->upstream.cache_methods |= NGX_HTTP_GET|NGX_HTTP_HEAD;
  783. ngx_conf_merge_ptr_value(conf->upstream.cache_valid,
  784. prev->upstream.cache_valid, NULL);
  785. if (conf->cache_key.value.data == NULL) {
  786. conf->cache_key = prev->cache_key;
  787. }
  788. if (conf->upstream.cache && conf->cache_key.value.data == NULL) {
  789. ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
  790. "no \"fastcgi_cache_key\" for \"fastcgi_cache\"");
  791. }
  792. ngx_conf_merge_value(conf->upstream.cache_lock,
  793. prev->upstream.cache_lock, 0);
  794. ngx_conf_merge_msec_value(conf->upstream.cache_lock_timeout,
  795. prev->upstream.cache_lock_timeout, 5000);
  796. #endif
  797. ngx_conf_merge_value(conf->upstream.pass_request_headers,
  798. prev->upstream.pass_request_headers, 1);
  799. ngx_conf_merge_value(conf->upstream.pass_request_body,
  800. prev->upstream.pass_request_body, 1);
  801. ngx_conf_merge_value(conf->upstream.intercept_errors,
  802. prev->upstream.intercept_errors, 0);
  803. ngx_conf_merge_value(conf->keep_conn, prev->keep_conn, 0);
  804. hash.max_size = 512;
  805. hash.bucket_size = ngx_align(64, ngx_cacheline_size);
  806. hash.name = "ajp_hide_headers_hash";
  807. #if (NGX_HTTP_CACHE)
  808. h = conf->upstream.cache ? ngx_http_ajp_hide_cache_headers:
  809. ngx_http_ajp_hide_headers;
  810. #else
  811. h = ngx_http_ajp_hide_headers;
  812. #endif
  813. if (ngx_http_upstream_hide_headers_hash(cf, &conf->upstream,
  814. &prev->upstream, h, &hash)
  815. != NGX_OK)
  816. {
  817. return NGX_CONF_ERROR;
  818. }
  819. if (conf->upstream.upstream == NULL) {
  820. conf->upstream.upstream = prev->upstream.upstream;
  821. }
  822. if (conf->ajp_lengths == NULL) {
  823. conf->ajp_lengths = prev->ajp_lengths;
  824. conf->ajp_values = prev->ajp_values;
  825. }
  826. return NGX_CONF_OK;
  827. }
  828. static ngx_int_t ngx_http_ajp_module_init_process(ngx_cycle_t *cycle)
  829. {
  830. ajp_header_init();
  831. return NGX_OK;
  832. }