Mercurial > hg > nginx-quic
comparison src/http/modules/ngx_http_fastcgi_module.c @ 1276:1494a23b1ed4
fix headers split in FastCGI records
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 09 Jul 2007 06:30:53 +0000 |
parents | 7ffdd1bb86d5 |
children | 13a4ce6e7f1e d59617e7e6a1 |
comparison
equal
deleted
inserted
replaced
1274:7ffdd1bb86d5 | 1276:1494a23b1ed4 |
---|---|
36 ngx_http_fastcgi_st_padding | 36 ngx_http_fastcgi_st_padding |
37 } ngx_http_fastcgi_state_e; | 37 } ngx_http_fastcgi_state_e; |
38 | 38 |
39 | 39 |
40 typedef struct { | 40 typedef struct { |
41 u_char *start; | |
42 u_char *end; | |
43 } ngx_http_fastcgi_split_part_t; | |
44 | |
45 | |
46 typedef struct { | |
41 ngx_http_fastcgi_state_e state; | 47 ngx_http_fastcgi_state_e state; |
42 u_char *pos; | 48 u_char *pos; |
43 u_char *last; | 49 u_char *last; |
44 ngx_uint_t type; | 50 ngx_uint_t type; |
45 size_t length; | 51 size_t length; |
46 size_t padding; | 52 size_t padding; |
47 | 53 |
48 ngx_uint_t fastcgi_stdout; | 54 ngx_uint_t fastcgi_stdout; /* unsigned :1 */ |
55 | |
56 ngx_array_t *split_parts; | |
49 } ngx_http_fastcgi_ctx_t; | 57 } ngx_http_fastcgi_ctx_t; |
50 | 58 |
51 | 59 |
52 #define NGX_HTTP_FASTCGI_RESPONDER 1 | 60 #define NGX_HTTP_FASTCGI_RESPONDER 1 |
53 | 61 |
838 | 846 |
839 | 847 |
840 static ngx_int_t | 848 static ngx_int_t |
841 ngx_http_fastcgi_process_header(ngx_http_request_t *r) | 849 ngx_http_fastcgi_process_header(ngx_http_request_t *r) |
842 { | 850 { |
843 u_char *start, *last; | 851 u_char *p, *start, *last, *part_start; |
852 size_t size; | |
844 ngx_str_t *status_line, line, *pattern; | 853 ngx_str_t *status_line, line, *pattern; |
845 ngx_int_t rc, status; | 854 ngx_int_t rc, status; |
855 ngx_buf_t buf; | |
846 ngx_uint_t i; | 856 ngx_uint_t i; |
847 ngx_table_elt_t *h; | 857 ngx_table_elt_t *h; |
848 ngx_http_upstream_t *u; | 858 ngx_http_upstream_t *u; |
849 ngx_http_fastcgi_ctx_t *f; | 859 ngx_http_fastcgi_ctx_t *f; |
850 ngx_http_upstream_header_t *hh; | 860 ngx_http_upstream_header_t *hh; |
851 ngx_http_fastcgi_loc_conf_t *flcf; | 861 ngx_http_fastcgi_loc_conf_t *flcf; |
862 ngx_http_fastcgi_split_part_t *part; | |
852 ngx_http_upstream_main_conf_t *umcf; | 863 ngx_http_upstream_main_conf_t *umcf; |
853 | 864 |
854 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); | 865 f = ngx_http_get_module_ctx(r, ngx_http_fastcgi_module); |
855 | 866 |
856 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); | 867 umcf = ngx_http_get_module_main_conf(r, ngx_http_upstream_module); |
1015 last = NULL; | 1026 last = NULL; |
1016 } | 1027 } |
1017 | 1028 |
1018 for ( ;; ) { | 1029 for ( ;; ) { |
1019 | 1030 |
1031 part_start = u->buffer.pos; | |
1032 | |
1020 rc = ngx_http_parse_header_line(r, &u->buffer); | 1033 rc = ngx_http_parse_header_line(r, &u->buffer); |
1021 | 1034 |
1022 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 1035 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1023 "http fastcgi parser: %d", rc); | 1036 "http fastcgi parser: %d", rc); |
1024 | 1037 |
1033 h = ngx_list_push(&u->headers_in.headers); | 1046 h = ngx_list_push(&u->headers_in.headers); |
1034 if (h == NULL) { | 1047 if (h == NULL) { |
1035 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 1048 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
1036 } | 1049 } |
1037 | 1050 |
1051 if (f->split_parts && f->split_parts->nelts) { | |
1052 | |
1053 part = f->split_parts->elts; | |
1054 size = u->buffer.pos - part_start; | |
1055 | |
1056 for (i = 0; i < f->split_parts->nelts; i++) { | |
1057 size += part[i].end - part[i].start; | |
1058 } | |
1059 | |
1060 p = ngx_palloc(r->pool, size); | |
1061 if (p == NULL) { | |
1062 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1063 } | |
1064 | |
1065 buf.pos = p; | |
1066 | |
1067 for (i = 0; i < f->split_parts->nelts; i++) { | |
1068 p = ngx_cpymem(p, part[i].start, | |
1069 part[i].end - part[i].start); | |
1070 } | |
1071 | |
1072 p = ngx_cpymem(p, part_start, u->buffer.pos - part_start); | |
1073 | |
1074 buf.last = p; | |
1075 | |
1076 f->split_parts->nelts = 0; | |
1077 | |
1078 rc = ngx_http_parse_header_line(r, &buf); | |
1079 | |
1080 h->key.len = r->header_name_end - r->header_name_start; | |
1081 h->key.data = r->header_name_start; | |
1082 h->key.data[h->key.len] = '\0'; | |
1083 | |
1084 h->value.len = r->header_end - r->header_start; | |
1085 h->value.data = r->header_start; | |
1086 h->value.data[h->value.len] = '\0'; | |
1087 | |
1088 h->lowcase_key = ngx_palloc(r->pool, h->key.len); | |
1089 if (h->lowcase_key == NULL) { | |
1090 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1091 } | |
1092 | |
1093 } else { | |
1094 | |
1095 h->key.len = r->header_name_end - r->header_name_start; | |
1096 h->value.len = r->header_end - r->header_start; | |
1097 | |
1098 h->key.data = ngx_palloc(r->pool, | |
1099 h->key.len + 1 + h->value.len + 1 | |
1100 + h->key.len); | |
1101 if (h->key.data == NULL) { | |
1102 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1103 } | |
1104 | |
1105 h->value.data = h->key.data + h->key.len + 1; | |
1106 h->lowcase_key = h->key.data + h->key.len + 1 | |
1107 + h->value.len + 1; | |
1108 | |
1109 ngx_cpystrn(h->key.data, r->header_name_start, | |
1110 h->key.len + 1); | |
1111 ngx_cpystrn(h->value.data, r->header_start, | |
1112 h->value.len + 1); | |
1113 } | |
1114 | |
1038 h->hash = r->header_hash; | 1115 h->hash = r->header_hash; |
1039 | |
1040 h->key.len = r->header_name_end - r->header_name_start; | |
1041 h->value.len = r->header_end - r->header_start; | |
1042 | |
1043 h->key.data = ngx_palloc(r->pool, | |
1044 h->key.len + 1 + h->value.len + 1 + h->key.len); | |
1045 if (h->key.data == NULL) { | |
1046 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1047 } | |
1048 | |
1049 h->value.data = h->key.data + h->key.len + 1; | |
1050 h->lowcase_key = h->key.data + h->key.len + 1 | |
1051 + h->value.len + 1; | |
1052 | |
1053 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); | |
1054 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); | |
1055 | 1116 |
1056 if (h->key.len == r->lowcase_index) { | 1117 if (h->key.len == r->lowcase_index) { |
1057 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); | 1118 ngx_memcpy(h->lowcase_key, r->lowcase_header, h->key.len); |
1058 | 1119 |
1059 } else { | 1120 } else { |
1121 | 1182 |
1122 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 1183 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
1123 "upstream sent invalid header"); | 1184 "upstream sent invalid header"); |
1124 | 1185 |
1125 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | 1186 return NGX_HTTP_UPSTREAM_INVALID_HEADER; |
1126 | |
1127 } | 1187 } |
1128 | 1188 |
1129 if (last) { | 1189 if (last) { |
1130 u->buffer.last = last; | 1190 u->buffer.last = last; |
1131 } | 1191 } |
1148 return NGX_AGAIN; | 1208 return NGX_AGAIN; |
1149 } | 1209 } |
1150 | 1210 |
1151 /* rc == NGX_AGAIN */ | 1211 /* rc == NGX_AGAIN */ |
1152 | 1212 |
1153 ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0, | 1213 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, |
1154 "upstream split a header line in FastCGI records"); | 1214 "upstream split a header line in FastCGI records"); |
1155 | 1215 |
1156 return NGX_HTTP_UPSTREAM_INVALID_HEADER; | 1216 if (f->split_parts == NULL) { |
1217 f->split_parts = ngx_array_create(r->pool, 1, | |
1218 sizeof(ngx_http_fastcgi_split_part_t)); | |
1219 if (f->split_parts == NULL) { | |
1220 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
1221 } | |
1222 } | |
1223 | |
1224 part = ngx_array_push(f->split_parts); | |
1225 | |
1226 part->start = part_start; | |
1227 part->end = u->buffer.last; | |
1228 | |
1229 return NGX_AGAIN; | |
1157 } | 1230 } |
1158 } | 1231 } |
1159 | 1232 |
1160 | 1233 |
1161 static ngx_int_t | 1234 static ngx_int_t |