comparison src/http/modules/ngx_http_fastcgi_module.c @ 5064:10f5831cf56e stable-1.2

Merge of r5027, r5028, r5029: fastcgi_keep_conn fixes. *) FastCGI: fixed wrong connection close with fastcgi_keep_conn. With fastcgi_keep_conn it was possible that connection was closed after FCGI_STDERR record with zero padding and without any further data read yet. This happended as f->state was set to ngx_http_fastcgi_st_padding and then "break" happened, resulting in p->length being set to f->padding, i.e. 0 (which in turn resulted in connection close). Fix is to make sure we continue the loop after f->state is set. *) FastCGI: unconditional state transitions. Checks for f->padding before state transitions make code hard to follow, remove them and make sure we always do another loop iteration after f->state is set to ngx_http_fastcgi_st_padding. *) FastCGI: proper handling of split fastcgi end request. If fastcgi end request record was split between several network packets, with fastcgi_keep_conn it was possible that connection was saved in incorrect state (e.g. with padding bytes not yet read).
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 11 Feb 2013 16:11:14 +0000
parents 05beaa2d87b3
children
comparison
equal deleted inserted replaced
5063:6b5c3eab095c 5064:10f5831cf56e
1354 1354
1355 return NGX_AGAIN; 1355 return NGX_AGAIN;
1356 } 1356 }
1357 1357
1358 } else { 1358 } else {
1359 if (f->padding) { 1359 f->state = ngx_http_fastcgi_st_padding;
1360 f->state = ngx_http_fastcgi_st_padding;
1361 } else {
1362 f->state = ngx_http_fastcgi_st_version;
1363 }
1364 } 1360 }
1365 1361
1366 continue; 1362 continue;
1367 } 1363 }
1368 1364
1595 } 1591 }
1596 1592
1597 f->length -= u->buffer.pos - start; 1593 f->length -= u->buffer.pos - start;
1598 1594
1599 if (f->length == 0) { 1595 if (f->length == 0) {
1600 if (f->padding) { 1596 f->state = ngx_http_fastcgi_st_padding;
1601 f->state = ngx_http_fastcgi_st_padding;
1602 } else {
1603 f->state = ngx_http_fastcgi_st_version;
1604 }
1605 } 1597 }
1606 1598
1607 if (rc == NGX_HTTP_PARSE_HEADER_DONE) { 1599 if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
1608 return NGX_OK; 1600 return NGX_OK;
1609 } 1601 }
1694 if (rc == NGX_ERROR) { 1686 if (rc == NGX_ERROR) {
1695 return NGX_ERROR; 1687 return NGX_ERROR;
1696 } 1688 }
1697 1689
1698 if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) { 1690 if (f->type == NGX_HTTP_FASTCGI_STDOUT && f->length == 0) {
1699 1691 f->state = ngx_http_fastcgi_st_padding;
1700 if (f->padding) {
1701 f->state = ngx_http_fastcgi_st_padding;
1702 } else {
1703 f->state = ngx_http_fastcgi_st_version;
1704 }
1705 1692
1706 if (!flcf->keep_conn) { 1693 if (!flcf->keep_conn) {
1707 p->upstream_done = 1; 1694 p->upstream_done = 1;
1708 } 1695 }
1709 1696
1713 continue; 1700 continue;
1714 } 1701 }
1715 1702
1716 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) { 1703 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
1717 1704
1718 if (f->padding) {
1719 f->state = ngx_http_fastcgi_st_padding;
1720 } else {
1721 f->state = ngx_http_fastcgi_st_version;
1722 }
1723
1724 p->upstream_done = 1;
1725
1726 if (flcf->keep_conn) {
1727 r->upstream->keepalive = 1;
1728 }
1729
1730 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0, 1705 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, p->log, 0,
1731 "http fastcgi sent end request"); 1706 "http fastcgi sent end request");
1732 1707
1708 if (!flcf->keep_conn) {
1709 p->upstream_done = 1;
1710 break;
1711 }
1712
1713 continue;
1714 }
1715 }
1716
1717
1718 if (f->state == ngx_http_fastcgi_st_padding) {
1719
1720 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
1721
1722 if (f->pos + f->padding < f->last) {
1723 p->upstream_done = 1;
1724 break;
1725 }
1726
1727 if (f->pos + f->padding == f->last) {
1728 p->upstream_done = 1;
1729 r->upstream->keepalive = 1;
1730 break;
1731 }
1732
1733 f->padding -= f->last - f->pos;
1734
1733 break; 1735 break;
1734 } 1736 }
1735 }
1736
1737
1738 if (f->state == ngx_http_fastcgi_st_padding) {
1739 1737
1740 if (f->pos + f->padding < f->last) { 1738 if (f->pos + f->padding < f->last) {
1741 f->state = ngx_http_fastcgi_st_version; 1739 f->state = ngx_http_fastcgi_st_version;
1742 f->pos += f->padding; 1740 f->pos += f->padding;
1743 1741
1786 1784
1787 ngx_log_error(NGX_LOG_ERR, p->log, 0, 1785 ngx_log_error(NGX_LOG_ERR, p->log, 0,
1788 "FastCGI sent in stderr: \"%*s\"", 1786 "FastCGI sent in stderr: \"%*s\"",
1789 m + 1 - msg, msg); 1787 m + 1 - msg, msg);
1790 1788
1791 if (f->pos == f->last) {
1792 break;
1793 }
1794
1795 } else { 1789 } else {
1796 if (f->padding) { 1790 f->state = ngx_http_fastcgi_st_padding;
1797 f->state = ngx_http_fastcgi_st_padding;
1798 } else {
1799 f->state = ngx_http_fastcgi_st_version;
1800 }
1801 } 1791 }
1802 1792
1803 continue; 1793 continue;
1794 }
1795
1796 if (f->type == NGX_HTTP_FASTCGI_END_REQUEST) {
1797
1798 if (f->pos + f->length <= f->last) {
1799 f->state = ngx_http_fastcgi_st_padding;
1800 f->pos += f->length;
1801
1802 continue;
1803 }
1804
1805 f->length -= f->last - f->pos;
1806
1807 break;
1804 } 1808 }
1805 1809
1806 1810
1807 /* f->type == NGX_HTTP_FASTCGI_STDOUT */ 1811 /* f->type == NGX_HTTP_FASTCGI_STDOUT */
1808 1812
1854 /* STUB */ b->num = buf->num; 1858 /* STUB */ b->num = buf->num;
1855 1859
1856 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0, 1860 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, p->log, 0,
1857 "input buf #%d %p", b->num, b->pos); 1861 "input buf #%d %p", b->num, b->pos);
1858 1862
1859 if (f->pos + f->length < f->last) { 1863 if (f->pos + f->length <= f->last) {
1860 1864 f->state = ngx_http_fastcgi_st_padding;
1861 if (f->padding) {
1862 f->state = ngx_http_fastcgi_st_padding;
1863 } else {
1864 f->state = ngx_http_fastcgi_st_version;
1865 }
1866
1867 f->pos += f->length; 1865 f->pos += f->length;
1868 b->last = f->pos; 1866 b->last = f->pos;
1869 1867
1870 continue; 1868 continue;
1871 }
1872
1873 if (f->pos + f->length == f->last) {
1874
1875 if (f->padding) {
1876 f->state = ngx_http_fastcgi_st_padding;
1877 } else {
1878 f->state = ngx_http_fastcgi_st_version;
1879 }
1880
1881 b->last = f->last;
1882
1883 break;
1884 } 1869 }
1885 1870
1886 f->length -= f->last - f->pos; 1871 f->length -= f->last - f->pos;
1887 1872
1888 b->last = f->last; 1873 b->last = f->last;