Mercurial > hg > nginx
comparison src/http/ngx_http_parse.c @ 4925:32030fa8cb14
Request body: chunked parsing moved to ngx_http_parse.c from proxy.
No functional changes.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Wed, 21 Nov 2012 00:59:16 +0000 |
parents | 5d86ab8f2340 |
children | 1c9d8b6523c0 |
comparison
equal
deleted
inserted
replaced
4924:caca5603bded | 4925:32030fa8cb14 |
---|---|
1816 | 1816 |
1817 } else { | 1817 } else { |
1818 args->len = 0; | 1818 args->len = 0; |
1819 } | 1819 } |
1820 } | 1820 } |
1821 | |
1822 | |
1823 ngx_int_t | |
1824 ngx_http_parse_chunked(ngx_http_request_t *r, ngx_buf_t *b, | |
1825 ngx_http_chunked_t *ctx) | |
1826 { | |
1827 u_char *pos, ch, c; | |
1828 ngx_int_t rc; | |
1829 enum { | |
1830 sw_chunk_start = 0, | |
1831 sw_chunk_size, | |
1832 sw_chunk_extension, | |
1833 sw_chunk_extension_almost_done, | |
1834 sw_chunk_data, | |
1835 sw_after_data, | |
1836 sw_after_data_almost_done, | |
1837 sw_last_chunk_extension, | |
1838 sw_last_chunk_extension_almost_done, | |
1839 sw_trailer, | |
1840 sw_trailer_almost_done, | |
1841 sw_trailer_header, | |
1842 sw_trailer_header_almost_done | |
1843 } state; | |
1844 | |
1845 state = ctx->state; | |
1846 | |
1847 if (state == sw_chunk_data && ctx->size == 0) { | |
1848 state = sw_after_data; | |
1849 } | |
1850 | |
1851 rc = NGX_AGAIN; | |
1852 | |
1853 for (pos = b->pos; pos < b->last; pos++) { | |
1854 | |
1855 ch = *pos; | |
1856 | |
1857 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
1858 "http chunked byte: %02Xd s:%d", ch, state); | |
1859 | |
1860 switch (state) { | |
1861 | |
1862 case sw_chunk_start: | |
1863 if (ch >= '0' && ch <= '9') { | |
1864 state = sw_chunk_size; | |
1865 ctx->size = ch - '0'; | |
1866 break; | |
1867 } | |
1868 | |
1869 c = (u_char) (ch | 0x20); | |
1870 | |
1871 if (c >= 'a' && c <= 'f') { | |
1872 state = sw_chunk_size; | |
1873 ctx->size = c - 'a' + 10; | |
1874 break; | |
1875 } | |
1876 | |
1877 goto invalid; | |
1878 | |
1879 case sw_chunk_size: | |
1880 if (ch >= '0' && ch <= '9') { | |
1881 ctx->size = ctx->size * 16 + (ch - '0'); | |
1882 break; | |
1883 } | |
1884 | |
1885 c = (u_char) (ch | 0x20); | |
1886 | |
1887 if (c >= 'a' && c <= 'f') { | |
1888 ctx->size = ctx->size * 16 + (c - 'a' + 10); | |
1889 break; | |
1890 } | |
1891 | |
1892 if (ctx->size == 0) { | |
1893 | |
1894 switch (ch) { | |
1895 case CR: | |
1896 state = sw_last_chunk_extension_almost_done; | |
1897 break; | |
1898 case LF: | |
1899 state = sw_trailer; | |
1900 break; | |
1901 case ';': | |
1902 case ' ': | |
1903 case '\t': | |
1904 state = sw_last_chunk_extension; | |
1905 break; | |
1906 default: | |
1907 goto invalid; | |
1908 } | |
1909 | |
1910 break; | |
1911 } | |
1912 | |
1913 switch (ch) { | |
1914 case CR: | |
1915 state = sw_chunk_extension_almost_done; | |
1916 break; | |
1917 case LF: | |
1918 state = sw_chunk_data; | |
1919 break; | |
1920 case ';': | |
1921 case ' ': | |
1922 case '\t': | |
1923 state = sw_chunk_extension; | |
1924 break; | |
1925 default: | |
1926 goto invalid; | |
1927 } | |
1928 | |
1929 break; | |
1930 | |
1931 case sw_chunk_extension: | |
1932 switch (ch) { | |
1933 case CR: | |
1934 state = sw_chunk_extension_almost_done; | |
1935 break; | |
1936 case LF: | |
1937 state = sw_chunk_data; | |
1938 } | |
1939 break; | |
1940 | |
1941 case sw_chunk_extension_almost_done: | |
1942 if (ch == LF) { | |
1943 state = sw_chunk_data; | |
1944 break; | |
1945 } | |
1946 goto invalid; | |
1947 | |
1948 case sw_chunk_data: | |
1949 rc = NGX_OK; | |
1950 goto data; | |
1951 | |
1952 case sw_after_data: | |
1953 switch (ch) { | |
1954 case CR: | |
1955 state = sw_after_data_almost_done; | |
1956 break; | |
1957 case LF: | |
1958 state = sw_chunk_start; | |
1959 } | |
1960 break; | |
1961 | |
1962 case sw_after_data_almost_done: | |
1963 if (ch == LF) { | |
1964 state = sw_chunk_start; | |
1965 break; | |
1966 } | |
1967 goto invalid; | |
1968 | |
1969 case sw_last_chunk_extension: | |
1970 switch (ch) { | |
1971 case CR: | |
1972 state = sw_last_chunk_extension_almost_done; | |
1973 break; | |
1974 case LF: | |
1975 state = sw_trailer; | |
1976 } | |
1977 break; | |
1978 | |
1979 case sw_last_chunk_extension_almost_done: | |
1980 if (ch == LF) { | |
1981 state = sw_trailer; | |
1982 break; | |
1983 } | |
1984 goto invalid; | |
1985 | |
1986 case sw_trailer: | |
1987 switch (ch) { | |
1988 case CR: | |
1989 state = sw_trailer_almost_done; | |
1990 break; | |
1991 case LF: | |
1992 goto done; | |
1993 default: | |
1994 state = sw_trailer_header; | |
1995 } | |
1996 break; | |
1997 | |
1998 case sw_trailer_almost_done: | |
1999 if (ch == LF) { | |
2000 goto done; | |
2001 } | |
2002 goto invalid; | |
2003 | |
2004 case sw_trailer_header: | |
2005 switch (ch) { | |
2006 case CR: | |
2007 state = sw_trailer_header_almost_done; | |
2008 break; | |
2009 case LF: | |
2010 state = sw_trailer; | |
2011 } | |
2012 break; | |
2013 | |
2014 case sw_trailer_header_almost_done: | |
2015 if (ch == LF) { | |
2016 state = sw_trailer; | |
2017 break; | |
2018 } | |
2019 goto invalid; | |
2020 | |
2021 } | |
2022 } | |
2023 | |
2024 data: | |
2025 | |
2026 ctx->state = state; | |
2027 b->pos = pos; | |
2028 | |
2029 switch (state) { | |
2030 | |
2031 case sw_chunk_start: | |
2032 ctx->length = 3 /* "0" LF LF */; | |
2033 break; | |
2034 case sw_chunk_size: | |
2035 ctx->length = 2 /* LF LF */ | |
2036 + (ctx->size ? ctx->size + 4 /* LF "0" LF LF */ : 0); | |
2037 break; | |
2038 case sw_chunk_extension: | |
2039 case sw_chunk_extension_almost_done: | |
2040 ctx->length = 1 /* LF */ + ctx->size + 4 /* LF "0" LF LF */; | |
2041 break; | |
2042 case sw_chunk_data: | |
2043 ctx->length = ctx->size + 4 /* LF "0" LF LF */; | |
2044 break; | |
2045 case sw_after_data: | |
2046 case sw_after_data_almost_done: | |
2047 ctx->length = 4 /* LF "0" LF LF */; | |
2048 break; | |
2049 case sw_last_chunk_extension: | |
2050 case sw_last_chunk_extension_almost_done: | |
2051 ctx->length = 2 /* LF LF */; | |
2052 break; | |
2053 case sw_trailer: | |
2054 case sw_trailer_almost_done: | |
2055 ctx->length = 1 /* LF */; | |
2056 break; | |
2057 case sw_trailer_header: | |
2058 case sw_trailer_header_almost_done: | |
2059 ctx->length = 2 /* LF LF */; | |
2060 break; | |
2061 | |
2062 } | |
2063 | |
2064 return rc; | |
2065 | |
2066 done: | |
2067 | |
2068 return NGX_DONE; | |
2069 | |
2070 invalid: | |
2071 | |
2072 return NGX_ERROR; | |
2073 } |