Mercurial > hg > nginx-vendor-0-7
annotate src/os/unix/ngx_writev_chain.c @ 502:89dc5654117c NGINX_0_7_63
nginx 0.7.63
*) Security: now "/../" are disabled in "Destination" request header
line.
*) Change: minimum supported OpenSSL version is 0.9.7.
*) Change: the "ask" parameter of the "ssl_verify_client" directive was
changed to the "optional" parameter and now it checks a client
certificate if it was offered.
Thanks to Brice Figureau.
*) Feature: now the "-V" switch shows TLS SNI support.
*) Feature: the $ssl_client_verify variable.
Thanks to Brice Figureau.
*) Feature: the "ssl_crl" directive.
Thanks to Brice Figureau.
*) Bugfix: the $ssl_client_cert variable usage corrupted memory; the
bug had appeared in 0.7.7.
Thanks to Sergey Zhuravlev.
*) Feature: now the start cache loader runs in a separate process; this
should improve large caches handling.
*) Feature: now temporary files and permanent storage area may reside
at different file systems.
*) Bugfix: nginx counted incorrectly disk cache size.
*) Change: now directive "gzip_disable msie6" does not disable gzipping
for MSIE 6.0 SV1.
*) Bugfix: nginx always added "Vary: Accept-Encoding" response header
line, if both "gzip_static" and "gzip_vary" were on.
*) Feature: the "proxy" parameter of the "geo" directive.
*) Feature: the ngx_http_geoip_module.
*) Feature: the "limit_rate_after" directive.
Thanks to Ivan Debnar.
*) Feature: the "limit_req_log_level" and "limit_conn_log_level"
directives.
*) Bugfix: now "limit_req" directive conforms to the leaky bucket
algorithm.
Thanks to Maxim Dounin.
*) Bugfix: in ngx_http_limit_req_module.
Thanks to Maxim Dounin.
*) Bugfix: now nginx allows underscores in a request method.
*) Bugfix: "proxy_pass_header" and "fastcgi_pass_header" directives did
not pass to a client the "X-Accel-Redirect", "X-Accel-Limit-Rate",
"X-Accel-Buffering", and "X-Accel-Charset" lines from backend
response header.
Thanks to Maxim Dounin.
*) Bugfix: in handling "Last-Modified" and "Accept-Ranges" backend
response header lines; the bug had appeared in 0.7.44.
Thanks to Maxim Dounin.
*) Feature: the "image_filter_transparency" directive.
*) Feature: the "image_filter" directive supports variables for setting
size.
*) Bugfix: in PNG alpha-channel support in the
ngx_http_image_filter_module.
*) Bugfix: in transparency support in the ngx_http_image_filter_module.
*) Feature: now several "perl_modules" directives may be used.
*) Bugfix: ngx_http_perl_module responses did not work in subrequests.
*) Bugfix: nginx sent '\0' in a "Location" response header line on
MKCOL request.
Thanks to Xie Zhenye.
*) Bugfix: an "error_page" directive did not redirect a 413 error; the
bug had appeared in 0.6.10.
*) Bugfix: in memory allocation error handling.
Thanks to Maxim Dounin and Kirill A. Korinskiy.
author | Igor Sysoev <http://sysoev.ru> |
---|---|
date | Mon, 26 Oct 2009 00:00:00 +0300 |
parents | f7cd062ee035 |
children |
rev | line source |
---|---|
0 | 1 |
2 /* | |
3 * Copyright (C) Igor Sysoev | |
4 */ | |
5 | |
6 | |
7 #include <ngx_config.h> | |
8 #include <ngx_core.h> | |
9 #include <ngx_event.h> | |
10 | |
11 | |
146 | 12 #if (IOV_MAX > 64) |
13 #define NGX_IOVS 64 | |
14 #else | |
15 #define NGX_IOVS IOV_MAX | |
16 #endif | |
0 | 17 |
18 | |
50 | 19 ngx_chain_t * |
20 ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit) | |
0 | 21 { |
22 u_char *prev; | |
10 | 23 ssize_t n, size, sent; |
22 | 24 off_t send, prev_send; |
0 | 25 ngx_uint_t eintr, complete; |
26 ngx_err_t err; | |
27 ngx_array_t vec; | |
28 ngx_chain_t *cl; | |
29 ngx_event_t *wev; | |
30 struct iovec *iov, iovs[NGX_IOVS]; | |
31 | |
32 wev = c->write; | |
33 | |
34 if (!wev->ready) { | |
35 return in; | |
36 } | |
37 | |
18 | 38 #if (NGX_HAVE_KQUEUE) |
0 | 39 |
136 | 40 if ((ngx_event_flags & NGX_USE_KQUEUE_EVENT) && wev->pending_eof) { |
86 | 41 (void) ngx_connection_error(c, wev->kq_errno, |
42 "kevent() reported about an closed connection"); | |
0 | 43 wev->error = 1; |
44 return NGX_CHAIN_ERROR; | |
45 } | |
46 | |
47 #endif | |
48 | |
22 | 49 /* the maximum limit size is the maximum size_t value - the page size */ |
50 | |
324 | 51 if (limit == 0 || limit > (off_t) (NGX_MAX_SIZE_T_VALUE - ngx_pagesize)) { |
26 | 52 limit = NGX_MAX_SIZE_T_VALUE - ngx_pagesize; |
22 | 53 } |
54 | |
0 | 55 send = 0; |
56 complete = 0; | |
57 | |
58 vec.elts = iovs; | |
59 vec.size = sizeof(struct iovec); | |
60 vec.nalloc = NGX_IOVS; | |
61 vec.pool = c->pool; | |
62 | |
63 for ( ;; ) { | |
64 prev = NULL; | |
65 iov = NULL; | |
66 eintr = 0; | |
22 | 67 prev_send = send; |
0 | 68 |
69 vec.nelts = 0; | |
70 | |
71 /* create the iovec and coalesce the neighbouring bufs */ | |
72 | |
73 for (cl = in; cl && vec.nelts < IOV_MAX && send < limit; cl = cl->next) | |
74 { | |
75 if (ngx_buf_special(cl->buf)) { | |
76 continue; | |
77 } | |
78 | |
10 | 79 #if 1 |
80 if (!ngx_buf_in_memory(cl->buf)) { | |
81 ngx_debug_point(); | |
82 } | |
83 #endif | |
84 | |
0 | 85 size = cl->buf->last - cl->buf->pos; |
86 | |
87 if (send + size > limit) { | |
110 | 88 size = (ssize_t) (limit - send); |
0 | 89 } |
90 | |
91 if (prev == cl->buf->pos) { | |
92 iov->iov_len += size; | |
93 | |
94 } else { | |
50 | 95 iov = ngx_array_push(&vec); |
96 if (iov == NULL) { | |
0 | 97 return NGX_CHAIN_ERROR; |
98 } | |
99 | |
100 iov->iov_base = (void *) cl->buf->pos; | |
101 iov->iov_len = size; | |
102 } | |
103 | |
104 prev = cl->buf->pos + size; | |
105 send += size; | |
106 } | |
107 | |
108 n = writev(c->fd, vec.elts, vec.nelts); | |
109 | |
110 if (n == -1) { | |
111 err = ngx_errno; | |
112 | |
113 if (err == NGX_EAGAIN || err == NGX_EINTR) { | |
114 if (err == NGX_EINTR) { | |
115 eintr = 1; | |
116 } | |
117 | |
118 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, | |
119 "writev() not ready"); | |
120 | |
121 } else { | |
122 wev->error = 1; | |
86 | 123 (void) ngx_connection_error(c, err, "writev() failed"); |
0 | 124 return NGX_CHAIN_ERROR; |
125 } | |
126 } | |
127 | |
128 sent = n > 0 ? n : 0; | |
129 | |
10 | 130 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, c->log, 0, "writev: %z", sent); |
0 | 131 |
22 | 132 if (send - prev_send == sent) { |
0 | 133 complete = 1; |
134 } | |
135 | |
136 c->sent += sent; | |
137 | |
10 | 138 for (cl = in; cl; cl = cl->next) { |
139 | |
0 | 140 if (ngx_buf_special(cl->buf)) { |
141 continue; | |
142 } | |
143 | |
144 if (sent == 0) { | |
145 break; | |
146 } | |
147 | |
148 size = cl->buf->last - cl->buf->pos; | |
149 | |
150 if (sent >= size) { | |
151 sent -= size; | |
152 cl->buf->pos = cl->buf->last; | |
153 | |
154 continue; | |
155 } | |
156 | |
157 cl->buf->pos += sent; | |
158 | |
159 break; | |
160 } | |
161 | |
162 if (eintr) { | |
163 continue; | |
164 } | |
165 | |
166 if (!complete) { | |
167 wev->ready = 0; | |
168 return cl; | |
169 } | |
170 | |
171 if (send >= limit || cl == NULL) { | |
172 return cl; | |
173 } | |
174 | |
175 in = cl; | |
176 } | |
177 } |