comparison src/http/modules/ngx_http_fastcgi_module.c @ 500:ed3d382670c7 NGINX_0_7_62

nginx 0.7.62 *) Security: a segmentation fault might occur in worker process while specially crafted request handling. Thanks to Chris Ries. *) Feature: the $upstream_cache_status variable. *) Bugfix: an expired cached response might stick in the "UPDATING" state. *) Bugfix: a segmentation fault might occur in worker process, if error_log was set to info or debug level. Thanks to Sergey Bochenkov. *) Bugfix: in handling FastCGI headers split in records. *) Bugfix: XSLT filter may fail with message "not well formed XML document" for valid XML document. Thanks to Kuramoto Eiji. *) Bugfix: now in MacOSX, Cygwin, and nginx/Windows locations given by a regular expression are always tested in case insensitive mode. *) Bugfix: now nginx/Windows ignores trailing dots in URI. Thanks to Hugo Leisink. *) Bugfix: name of file specified in --conf-path was not honored during installation; the bug had appeared in 0.6.6. Thanks to Maxim Dounin. *) Bugfix: a 500 error code was returned for invalid login/password while HTTP Basic authentication on Windows.
author Igor Sysoev <http://sysoev.ru>
date Mon, 14 Sep 2009 00:00:00 +0400
parents 116d5de7cbb6
children 89dc5654117c
comparison
equal deleted inserted replaced
499:f2c782e5161f 500:ed3d382670c7
1070 1070
1071 1071
1072 static ngx_int_t 1072 static ngx_int_t
1073 ngx_http_fastcgi_process_header(ngx_http_request_t *r) 1073 ngx_http_fastcgi_process_header(ngx_http_request_t *r)
1074 { 1074 {
1075 u_char *p, *start, *last, *part_start; 1075 u_char *p, *msg, *start, *last,
1076 *part_start, *part_end;
1076 size_t size; 1077 size_t size;
1077 ngx_str_t *status_line, line, *pattern; 1078 ngx_str_t *status_line, *pattern;
1078 ngx_int_t rc, status; 1079 ngx_int_t rc, status;
1079 ngx_buf_t buf; 1080 ngx_buf_t buf;
1080 ngx_uint_t i; 1081 ngx_uint_t i;
1081 ngx_table_elt_t *h; 1082 ngx_table_elt_t *h;
1082 ngx_http_upstream_t *u; 1083 ngx_http_upstream_t *u;
1156 /* f->state == ngx_http_fastcgi_st_data */ 1157 /* f->state == ngx_http_fastcgi_st_data */
1157 1158
1158 if (f->type == NGX_HTTP_FASTCGI_STDERR) { 1159 if (f->type == NGX_HTTP_FASTCGI_STDERR) {
1159 1160
1160 if (f->length) { 1161 if (f->length) {
1161 line.data = u->buffer.pos; 1162 msg = u->buffer.pos;
1162 1163
1163 if (u->buffer.pos + f->length <= u->buffer.last) { 1164 if (u->buffer.pos + f->length <= u->buffer.last) {
1164 line.len = f->length;
1165 u->buffer.pos += f->length; 1165 u->buffer.pos += f->length;
1166 f->length = 0; 1166 f->length = 0;
1167 f->state = ngx_http_fastcgi_st_padding; 1167 f->state = ngx_http_fastcgi_st_padding;
1168 1168
1169 } else { 1169 } else {
1170 line.len = u->buffer.last - u->buffer.pos;
1171 f->length -= u->buffer.last - u->buffer.pos; 1170 f->length -= u->buffer.last - u->buffer.pos;
1172 u->buffer.pos = u->buffer.last; 1171 u->buffer.pos = u->buffer.last;
1173 } 1172 }
1174 1173
1175 while (line.data[line.len - 1] == LF 1174 for (p = u->buffer.pos - 1; msg < p; p--) {
1176 || line.data[line.len - 1] == CR 1175 if (*p != LF && *p != CR && *p != '.' && *p != ' ') {
1177 || line.data[line.len - 1] == '.' 1176 break;
1178 || line.data[line.len - 1] == ' ') 1177 }
1179 {
1180 line.len--;
1181 } 1178 }
1182 1179
1180 p++;
1181
1183 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, 1182 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
1184 "FastCGI sent in stderr: \"%V\"", &line); 1183 "FastCGI sent in stderr: \"%*s\"", p - msg, msg);
1185 1184
1186 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module); 1185 flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
1187 1186
1188 if (flcf->catch_stderr) { 1187 if (flcf->catch_stderr) {
1189 pattern = flcf->catch_stderr->elts; 1188 pattern = flcf->catch_stderr->elts;
1190 1189
1191 line.data[line.len - 1] = '\0';
1192
1193 for (i = 0; i < flcf->catch_stderr->nelts; i++) { 1190 for (i = 0; i < flcf->catch_stderr->nelts; i++) {
1194 if (ngx_strstr(line.data, pattern[i].data)) { 1191 if (ngx_strnstr(msg, (char *) pattern[i].data,
1192 p - msg)
1193 != NULL)
1194 {
1195 return NGX_HTTP_UPSTREAM_INVALID_HEADER; 1195 return NGX_HTTP_UPSTREAM_INVALID_HEADER;
1196 } 1196 }
1197 } 1197 }
1198 } 1198 }
1199 1199
1242 } 1242 }
1243 1243
1244 for ( ;; ) { 1244 for ( ;; ) {
1245 1245
1246 part_start = u->buffer.pos; 1246 part_start = u->buffer.pos;
1247 part_end = u->buffer.last;
1247 1248
1248 rc = ngx_http_parse_header_line(r, &u->buffer, 1); 1249 rc = ngx_http_parse_header_line(r, &u->buffer, 1);
1249 1250
1250 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, 1251 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
1251 "http fastcgi parser: %d", rc); 1252 "http fastcgi parser: %d", rc);
1442 } 1443 }
1443 1444
1444 part = ngx_array_push(f->split_parts); 1445 part = ngx_array_push(f->split_parts);
1445 1446
1446 part->start = part_start; 1447 part->start = part_start;
1447 part->end = u->buffer.last; 1448 part->end = part_end;
1449
1450 if (u->buffer.pos < u->buffer.last) {
1451 continue;
1452 }
1448 1453
1449 return NGX_AGAIN; 1454 return NGX_AGAIN;
1450 } 1455 }
1451 } 1456 }
1452 1457
1453 1458
1454 static ngx_int_t 1459 static ngx_int_t
1455 ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf) 1460 ngx_http_fastcgi_input_filter(ngx_event_pipe_t *p, ngx_buf_t *buf)
1456 { 1461 {
1462 u_char *m, *msg;
1457 ngx_int_t rc; 1463 ngx_int_t rc;
1458 ngx_buf_t *b, **prev; 1464 ngx_buf_t *b, **prev;
1459 ngx_str_t line;
1460 ngx_chain_t *cl; 1465 ngx_chain_t *cl;
1461 ngx_http_request_t *r; 1466 ngx_http_request_t *r;
1462 ngx_http_fastcgi_ctx_t *f; 1467 ngx_http_fastcgi_ctx_t *f;
1463 1468
1464 if (buf->pos == buf->last) { 1469 if (buf->pos == buf->last) {
1538 1543
1539 if (f->pos == f->last) { 1544 if (f->pos == f->last) {
1540 break; 1545 break;
1541 } 1546 }
1542 1547
1543 line.data = f->pos; 1548 msg = f->pos;
1544 1549
1545 if (f->pos + f->length <= f->last) { 1550 if (f->pos + f->length <= f->last) {
1546 line.len = f->length;
1547 f->pos += f->length; 1551 f->pos += f->length;
1548 f->length = 0; 1552 f->length = 0;
1549 f->state = ngx_http_fastcgi_st_padding; 1553 f->state = ngx_http_fastcgi_st_padding;
1550 1554
1551 } else { 1555 } else {
1552 line.len = f->last - f->pos;
1553 f->length -= f->last - f->pos; 1556 f->length -= f->last - f->pos;
1554 f->pos = f->last; 1557 f->pos = f->last;
1555 } 1558 }
1556 1559
1557 while (line.data[line.len - 1] == LF 1560 for (m = f->pos - 1; msg < m; m--) {
1558 || line.data[line.len - 1] == CR 1561 if (*m != LF && *m != CR && *m != '.' && *m != ' ') {
1559 || line.data[line.len - 1] == '.' 1562 break;
1560 || line.data[line.len - 1] == ' ') 1563 }
1561 {
1562 line.len--;
1563 } 1564 }
1564 1565
1565 ngx_log_error(NGX_LOG_ERR, p->log, 0, 1566 ngx_log_error(NGX_LOG_ERR, p->log, 0,
1566 "FastCGI sent in stderr: \"%V\"", &line); 1567 "FastCGI sent in stderr: \"%*s\"",
1568 m + 1 - msg, msg);
1567 1569
1568 if (f->pos == f->last) { 1570 if (f->pos == f->last) {
1569 break; 1571 break;
1570 } 1572 }
1571 1573