Mercurial > hg > nginx-vendor-0-6
comparison src/http/ngx_http_core_module.c @ 384:09b703ae3ba5 NGINX_0_6_36
nginx 0.6.36
*) Change: now the "Invalid argument" error returned by
setsockopt(TCP_NODELAY) on Solaris, is ignored.
*) Change: now POSTs without "Content-Length" header line are allowed.
*) Feature: the "try_files" directive.
*) Feature: the --with-pcre option in the configure.
*) Feature: the "if_modified_since" directive.
*) Feature: the "$cookie_..." variables.
*) Feature: the "$arg_..." variables.
*) Bugfix: compatibility with Tru64 UNIX.
Thanks to Dustin Marquess.
*) Bugfix: a "ssl_engine" directive did not use a SSL-accelerator for
asymmetric ciphers.
Thanks to Marcin Gozdalik.
*) Bugfix: in a redirect rewrite directive original arguments were
concatenated with new arguments by a "?" rather than an "&";
the bug had appeared in 0.1.18.
Thanks to Maxim Dounin.
*) Bugfix: nginx could not be built on AIX.
*) Bugfix: a double response might be returned if the epoll or rtsig
methods are used and a redirect was returned to a request with
body.
Thanks to Eden Li.
*) Bugfix: a segmentation fault might occur in worker process if
"resolver" directive was used in SMTP proxy.
*) Bugfix: fastcgi_store stored files not always.
*) Bugfix: nginx did not process a FastCGI server response, if the
server send too many messages to stderr before response.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Thu, 02 Apr 2009 00:00:00 +0400 |
parents | e9979466be2f |
children | 1878e9c00f22 |
comparison
equal
deleted
inserted
replaced
383:3d40b0260a84 | 384:09b703ae3ba5 |
---|---|
59 void *conf); | 59 void *conf); |
60 static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); | 60 static char *ngx_http_core_root(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); |
61 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, | 61 static char *ngx_http_core_limit_except(ngx_conf_t *cf, ngx_command_t *cmd, |
62 void *conf); | 62 void *conf); |
63 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, | 63 static char *ngx_http_core_error_page(ngx_conf_t *cf, ngx_command_t *cmd, |
64 void *conf); | |
65 static char *ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, | |
64 void *conf); | 66 void *conf); |
65 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, | 67 static char *ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, |
66 void *conf); | 68 void *conf); |
67 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, | 69 static char *ngx_http_core_error_log(ngx_conf_t *cf, ngx_command_t *cmd, |
68 void *conf); | 70 void *conf); |
112 { ngx_string("any"), NGX_HTTP_SATISFY_ANY }, | 114 { ngx_string("any"), NGX_HTTP_SATISFY_ANY }, |
113 { ngx_null_string, 0 } | 115 { ngx_null_string, 0 } |
114 }; | 116 }; |
115 | 117 |
116 | 118 |
119 static ngx_conf_enum_t ngx_http_core_if_modified_since[] = { | |
120 { ngx_string("off"), NGX_HTTP_IMS_OFF }, | |
121 { ngx_string("exact"), NGX_HTTP_IMS_EXACT }, | |
122 { ngx_string("before"), NGX_HTTP_IMS_BEFORE }, | |
123 { ngx_null_string, 0 } | |
124 }; | |
125 | |
126 | |
117 #if (NGX_HTTP_GZIP) | 127 #if (NGX_HTTP_GZIP) |
118 | 128 |
119 static ngx_conf_enum_t ngx_http_gzip_http_version[] = { | 129 static ngx_conf_enum_t ngx_http_gzip_http_version[] = { |
120 { ngx_string("1.0"), NGX_HTTP_VERSION_10 }, | 130 { ngx_string("1.0"), NGX_HTTP_VERSION_10 }, |
121 { ngx_string("1.1"), NGX_HTTP_VERSION_11 }, | 131 { ngx_string("1.1"), NGX_HTTP_VERSION_11 }, |
505 ngx_conf_set_flag_slot, | 515 ngx_conf_set_flag_slot, |
506 NGX_HTTP_LOC_CONF_OFFSET, | 516 NGX_HTTP_LOC_CONF_OFFSET, |
507 offsetof(ngx_http_core_loc_conf_t, server_tokens), | 517 offsetof(ngx_http_core_loc_conf_t, server_tokens), |
508 NULL }, | 518 NULL }, |
509 | 519 |
520 { ngx_string("if_modified_since"), | |
521 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1, | |
522 ngx_conf_set_enum_slot, | |
523 NGX_HTTP_LOC_CONF_OFFSET, | |
524 offsetof(ngx_http_core_loc_conf_t, if_modified_since), | |
525 &ngx_http_core_if_modified_since }, | |
526 | |
510 { ngx_string("error_page"), | 527 { ngx_string("error_page"), |
511 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF | 528 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF |
512 |NGX_CONF_2MORE, | 529 |NGX_CONF_2MORE, |
513 ngx_http_core_error_page, | 530 ngx_http_core_error_page, |
531 NGX_HTTP_LOC_CONF_OFFSET, | |
532 0, | |
533 NULL }, | |
534 | |
535 { ngx_string("try_files"), | |
536 NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_2MORE, | |
537 ngx_http_core_try_files, | |
514 NGX_HTTP_LOC_CONF_OFFSET, | 538 NGX_HTTP_LOC_CONF_OFFSET, |
515 0, | 539 0, |
516 NULL }, | 540 NULL }, |
517 | 541 |
518 { ngx_string("post_action"), | 542 { ngx_string("post_action"), |
995 return NGX_AGAIN; | 1019 return NGX_AGAIN; |
996 } | 1020 } |
997 | 1021 |
998 | 1022 |
999 ngx_int_t | 1023 ngx_int_t |
1024 ngx_http_core_try_files_phase(ngx_http_request_t *r, | |
1025 ngx_http_phase_handler_t *ph) | |
1026 { | |
1027 size_t len, root, alias, reserve, allocated; | |
1028 u_char *p, *name; | |
1029 ngx_str_t path, args; | |
1030 ngx_uint_t test_dir; | |
1031 ngx_http_try_file_t *tf; | |
1032 ngx_open_file_info_t of; | |
1033 ngx_http_script_code_pt code; | |
1034 ngx_http_script_engine_t e; | |
1035 ngx_http_core_loc_conf_t *clcf; | |
1036 ngx_http_script_len_code_pt lcode; | |
1037 | |
1038 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1039 "try files phase: %ui", r->phase_handler); | |
1040 | |
1041 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
1042 | |
1043 if (clcf->try_files == NULL) { | |
1044 r->phase_handler++; | |
1045 return NGX_AGAIN; | |
1046 } | |
1047 | |
1048 allocated = 0; | |
1049 root = 0; | |
1050 name = NULL; | |
1051 /* suppress MSVC warning */ | |
1052 path.data = NULL; | |
1053 | |
1054 tf = clcf->try_files; | |
1055 | |
1056 alias = clcf->alias ? clcf->name.len : 0; | |
1057 | |
1058 for ( ;; ) { | |
1059 | |
1060 if (tf->lengths) { | |
1061 ngx_memzero(&e, sizeof(ngx_http_script_engine_t)); | |
1062 | |
1063 e.ip = tf->lengths->elts; | |
1064 e.request = r; | |
1065 | |
1066 /* 1 is for terminating '\0' as in static names */ | |
1067 len = 1; | |
1068 | |
1069 while (*(uintptr_t *) e.ip) { | |
1070 lcode = *(ngx_http_script_len_code_pt *) e.ip; | |
1071 len += lcode(&e); | |
1072 } | |
1073 | |
1074 } else { | |
1075 len = tf->name.len; | |
1076 } | |
1077 | |
1078 /* 16 bytes are preallocation */ | |
1079 reserve = ngx_abs((ssize_t) (len - r->uri.len)) + alias + 16; | |
1080 | |
1081 if (reserve > allocated) { | |
1082 | |
1083 /* we just need to allocate path and to copy a root */ | |
1084 | |
1085 if (ngx_http_map_uri_to_path(r, &path, &root, reserve) == NULL) { | |
1086 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1087 return NGX_OK; | |
1088 } | |
1089 | |
1090 name = path.data + root; | |
1091 allocated = path.len - root - (r->uri.len - alias); | |
1092 } | |
1093 | |
1094 if (tf->values == NULL) { | |
1095 | |
1096 /* tf->name.len includes the terminating '\0' */ | |
1097 | |
1098 ngx_memcpy(name, tf->name.data, tf->name.len); | |
1099 | |
1100 path.len = (name + tf->name.len - 1) - path.data; | |
1101 | |
1102 } else { | |
1103 e.ip = tf->values->elts; | |
1104 e.pos = name; | |
1105 e.flushed = 1; | |
1106 | |
1107 while (*(uintptr_t *) e.ip) { | |
1108 code = *(ngx_http_script_code_pt *) e.ip; | |
1109 code((ngx_http_script_engine_t *) &e); | |
1110 } | |
1111 | |
1112 path.len = e.pos - path.data; | |
1113 | |
1114 *e.pos = '\0'; | |
1115 | |
1116 if (alias && ngx_strncmp(name, clcf->name.data, alias) == 0) { | |
1117 ngx_memcpy(name, name + alias, len - alias); | |
1118 path.len -= alias; | |
1119 } | |
1120 } | |
1121 | |
1122 test_dir = tf->test_dir; | |
1123 | |
1124 tf++; | |
1125 | |
1126 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1127 "try to use file: \"%s\" \"%s\"", name, path.data); | |
1128 | |
1129 if (tf->lengths == NULL && tf->name.len == 0) { | |
1130 | |
1131 path.len -= root; | |
1132 path.data += root; | |
1133 | |
1134 if (path.data[0] == '@') { | |
1135 (void) ngx_http_named_location(r, &path); | |
1136 | |
1137 } else { | |
1138 ngx_http_split_args(r, &path, &args); | |
1139 | |
1140 (void) ngx_http_internal_redirect(r, &path, &args); | |
1141 } | |
1142 | |
1143 return NGX_OK; | |
1144 } | |
1145 | |
1146 ngx_memzero(&of, sizeof(ngx_open_file_info_t)); | |
1147 | |
1148 of.valid = clcf->open_file_cache_valid; | |
1149 of.min_uses = clcf->open_file_cache_min_uses; | |
1150 of.errors = clcf->open_file_cache_errors; | |
1151 of.events = clcf->open_file_cache_events; | |
1152 | |
1153 if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool) | |
1154 != NGX_OK) | |
1155 { | |
1156 if (of.err != NGX_ENOENT && of.err != NGX_ENOTDIR) { | |
1157 ngx_log_error(NGX_LOG_CRIT, r->connection->log, of.err, | |
1158 ngx_open_file_n " \"%s\" failed", path.data); | |
1159 } | |
1160 | |
1161 continue; | |
1162 } | |
1163 | |
1164 if (of.is_dir && !test_dir) { | |
1165 continue; | |
1166 } | |
1167 | |
1168 path.len -= root; | |
1169 path.data += root; | |
1170 | |
1171 if (!alias) { | |
1172 r->uri = path; | |
1173 | |
1174 } else { | |
1175 r->uri.len = alias + path.len; | |
1176 r->uri.data = ngx_palloc(r->pool, r->uri.len); | |
1177 if (r->uri.data == NULL) { | |
1178 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1179 return NGX_OK; | |
1180 } | |
1181 | |
1182 p = ngx_copy(r->uri.data, clcf->name.data, alias); | |
1183 ngx_memcpy(p, name, path.len); | |
1184 } | |
1185 | |
1186 if (ngx_http_set_exten(r) != NGX_OK) { | |
1187 ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
1188 return NGX_OK; | |
1189 } | |
1190 | |
1191 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1192 "try file uri: \"%V\"", &r->uri); | |
1193 | |
1194 r->phase_handler++; | |
1195 return NGX_AGAIN; | |
1196 } | |
1197 | |
1198 /* not reached */ | |
1199 } | |
1200 | |
1201 | |
1202 ngx_int_t | |
1000 ngx_http_core_content_phase(ngx_http_request_t *r, | 1203 ngx_http_core_content_phase(ngx_http_request_t *r, |
1001 ngx_http_phase_handler_t *ph) | 1204 ngx_http_phase_handler_t *ph) |
1002 { | 1205 { |
1003 size_t root; | 1206 size_t root; |
1004 ngx_int_t rc; | 1207 ngx_int_t rc; |
2670 * lcf->post_action = { 0, NULL }; | 2873 * lcf->post_action = { 0, NULL }; |
2671 * lcf->types = NULL; | 2874 * lcf->types = NULL; |
2672 * lcf->default_type = { 0, NULL }; | 2875 * lcf->default_type = { 0, NULL }; |
2673 * lcf->err_log = NULL; | 2876 * lcf->err_log = NULL; |
2674 * lcf->error_pages = NULL; | 2877 * lcf->error_pages = NULL; |
2878 * lcf->try_files = NULL; | |
2675 * lcf->client_body_path = NULL; | 2879 * lcf->client_body_path = NULL; |
2676 * lcf->regex = NULL; | 2880 * lcf->regex = NULL; |
2677 * lcf->exact_match = 0; | 2881 * lcf->exact_match = 0; |
2678 * lcf->auto_redirect = 0; | 2882 * lcf->auto_redirect = 0; |
2679 * lcf->alias = 0; | 2883 * lcf->alias = 0; |
2682 | 2886 |
2683 lcf->client_max_body_size = NGX_CONF_UNSET; | 2887 lcf->client_max_body_size = NGX_CONF_UNSET; |
2684 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; | 2888 lcf->client_body_buffer_size = NGX_CONF_UNSET_SIZE; |
2685 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC; | 2889 lcf->client_body_timeout = NGX_CONF_UNSET_MSEC; |
2686 lcf->satisfy = NGX_CONF_UNSET_UINT; | 2890 lcf->satisfy = NGX_CONF_UNSET_UINT; |
2891 lcf->if_modified_since = NGX_CONF_UNSET_UINT; | |
2687 lcf->internal = NGX_CONF_UNSET; | 2892 lcf->internal = NGX_CONF_UNSET; |
2688 lcf->client_body_in_file_only = NGX_CONF_UNSET; | 2893 lcf->client_body_in_file_only = NGX_CONF_UNSET; |
2689 lcf->sendfile = NGX_CONF_UNSET; | 2894 lcf->sendfile = NGX_CONF_UNSET; |
2690 lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE; | 2895 lcf->sendfile_max_chunk = NGX_CONF_UNSET_SIZE; |
2691 lcf->tcp_nopush = NGX_CONF_UNSET; | 2896 lcf->tcp_nopush = NGX_CONF_UNSET; |
2868 ngx_conf_merge_msec_value(conf->client_body_timeout, | 3073 ngx_conf_merge_msec_value(conf->client_body_timeout, |
2869 prev->client_body_timeout, 60000); | 3074 prev->client_body_timeout, 60000); |
2870 | 3075 |
2871 ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, | 3076 ngx_conf_merge_uint_value(conf->satisfy, prev->satisfy, |
2872 NGX_HTTP_SATISFY_ALL); | 3077 NGX_HTTP_SATISFY_ALL); |
3078 ngx_conf_merge_uint_value(conf->if_modified_since, prev->if_modified_since, | |
3079 NGX_HTTP_IMS_EXACT); | |
2873 ngx_conf_merge_value(conf->internal, prev->internal, 0); | 3080 ngx_conf_merge_value(conf->internal, prev->internal, 0); |
2874 ngx_conf_merge_value(conf->client_body_in_file_only, | 3081 ngx_conf_merge_value(conf->client_body_in_file_only, |
2875 prev->client_body_in_file_only, 0); | 3082 prev->client_body_in_file_only, 0); |
2876 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); | 3083 ngx_conf_merge_value(conf->sendfile, prev->sendfile, 0); |
2877 ngx_conf_merge_size_value(conf->sendfile_max_chunk, | 3084 ngx_conf_merge_size_value(conf->sendfile_max_chunk, |
3586 return NGX_CONF_OK; | 3793 return NGX_CONF_OK; |
3587 } | 3794 } |
3588 | 3795 |
3589 | 3796 |
3590 static char * | 3797 static char * |
3798 ngx_http_core_try_files(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | |
3799 { | |
3800 ngx_http_core_loc_conf_t *clcf = conf; | |
3801 | |
3802 ngx_str_t *value; | |
3803 ngx_uint_t i, n; | |
3804 ngx_http_try_file_t *tf; | |
3805 ngx_http_script_compile_t sc; | |
3806 ngx_http_core_main_conf_t *cmcf; | |
3807 | |
3808 if (clcf->try_files) { | |
3809 return "is duplicate"; | |
3810 } | |
3811 | |
3812 cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module); | |
3813 | |
3814 cmcf->try_files = 1; | |
3815 | |
3816 tf = ngx_pcalloc(cf->pool, cf->args->nelts * sizeof(ngx_http_try_file_t)); | |
3817 if (tf == NULL) { | |
3818 return NGX_CONF_ERROR; | |
3819 } | |
3820 | |
3821 clcf->try_files = tf; | |
3822 | |
3823 value = cf->args->elts; | |
3824 | |
3825 for (i = 0; i < cf->args->nelts - 1; i++) { | |
3826 | |
3827 tf[i].name = value[i + 1]; | |
3828 | |
3829 if (tf[i].name.data[tf[i].name.len - 1] == '/') { | |
3830 tf[i].test_dir = 1; | |
3831 tf[i].name.len--; | |
3832 tf[i].name.data[tf[i].name.len] = '\0'; | |
3833 } | |
3834 | |
3835 n = ngx_http_script_variables_count(&tf[i].name); | |
3836 | |
3837 if (n) { | |
3838 ngx_memzero(&sc, sizeof(ngx_http_script_compile_t)); | |
3839 | |
3840 sc.cf = cf; | |
3841 sc.source = &tf[i].name; | |
3842 sc.lengths = &tf[i].lengths; | |
3843 sc.values = &tf[i].values; | |
3844 sc.variables = n; | |
3845 sc.complete_lengths = 1; | |
3846 sc.complete_values = 1; | |
3847 | |
3848 if (ngx_http_script_compile(&sc) != NGX_OK) { | |
3849 return NGX_CONF_ERROR; | |
3850 } | |
3851 | |
3852 } else { | |
3853 /* add trailing '\0' to length */ | |
3854 tf[i].name.len++; | |
3855 } | |
3856 } | |
3857 | |
3858 return NGX_CONF_OK; | |
3859 } | |
3860 | |
3861 | |
3862 static char * | |
3591 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 3863 ngx_http_core_open_file_cache(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
3592 { | 3864 { |
3593 ngx_http_core_loc_conf_t *lcf = conf; | 3865 ngx_http_core_loc_conf_t *lcf = conf; |
3594 | 3866 |
3595 time_t inactive; | 3867 time_t inactive; |