@@ -93,22 +93,20 @@ static int sapi_thttpd_ub_write(const char *str, uint str_length TSRMLS_DC)
93
93
return sent ;
94
94
}
95
95
96
- #define ADD_VEC (str ,l ) vec[n].iov_base=str;len += (vec[n].iov_len=l); n++
97
- #define ADD_VEC_S (str ) ADD_VEC((str), sizeof(str)-1)
98
- #define COMBINE_HEADERS 30
96
+ #define COMBINE_HEADERS 64
97
+
98
+ #if defined(IOV_MAX )
99
+ # if IOV_MAX - 64 <= 0
100
+ # define SERIALIZE_HEADERS
101
+ # endif
102
+ #endif
99
103
100
104
static int do_writev (struct iovec * vec , int nvec , int len TSRMLS_DC )
101
105
{
102
106
int n ;
103
107
104
- /*
105
- * XXX: partial writevs are not handled
106
- * This can only cause problems, if the user tries to send
107
- * huge headers, so I consider this a void issue right now.
108
- * The maximum size depends on SO_SNDBUF and is usually
109
- * at least 16KB from my experience.
110
- */
111
-
108
+ assert (nvec <= IOV_MAX );
109
+
112
110
if (TG (sbuf ).c == 0 ) {
113
111
n = writev (TG (hc )-> conn_fd , vec , nvec );
114
112
@@ -151,6 +149,18 @@ static int do_writev(struct iovec *vec, int nvec, int len TSRMLS_DC)
151
149
return 0 ;
152
150
}
153
151
152
+ #ifdef SERIALIZE_HEADERS
153
+ # define ADD_VEC (str ,l ) smart_str_appendl(&vec_str, (str), (l))
154
+ # define VEC_BASE () smart_str vec_str = {0}
155
+ # define VEC_FREE () smart_str_free(&vec_str)
156
+ #else
157
+ # define ADD_VEC (str ,l ) vec[n].iov_base=str;len += (vec[n].iov_len=l); n++
158
+ # define VEC_BASE () struct iovec vec[COMBINE_HEADERS]
159
+ # define VEC_FREE () do {} while (0)
160
+ #endif
161
+
162
+ #define ADD_VEC_S (str ) ADD_VEC((str), sizeof(str)-1)
163
+
154
164
#define CL_TOKEN "Content-length: "
155
165
#define CN_TOKEN "Connection: "
156
166
#define KA_DO "Connection: keep-alive\r\n"
@@ -160,8 +170,7 @@ static int do_writev(struct iovec *vec, int nvec, int len TSRMLS_DC)
160
170
static int sapi_thttpd_send_headers (sapi_headers_struct * sapi_headers TSRMLS_DC )
161
171
{
162
172
char buf [1024 ], * p ;
163
- struct iovec vec [COMBINE_HEADERS ];
164
-
173
+ VEC_BASE ();
165
174
int n = 0 ;
166
175
zend_llist_position pos ;
167
176
sapi_header_struct * h ;
@@ -197,10 +206,12 @@ static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
197
206
}
198
207
199
208
ADD_VEC (h -> header , h -> header_len );
209
+ #ifndef SERIALIZE_HEADERS
200
210
if (n >= COMBINE_HEADERS - 1 ) {
201
211
len = do_writev (vec , n , len TSRMLS_CC );
202
212
n = 0 ;
203
213
}
214
+ #endif
204
215
ADD_VEC ("\r\n" , 2 );
205
216
206
217
h = zend_llist_get_next_ex (& sapi_headers -> headers , & pos );
@@ -214,8 +225,14 @@ static int sapi_thttpd_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
214
225
}
215
226
216
227
ADD_VEC ("\r\n" , 2 );
217
-
228
+
229
+ #ifdef SERIALIZE_HEADERS
230
+ sapi_thttpd_ub_write (vec_str .c , vec_str .len TSRMLS_CC );
231
+ #else
218
232
do_writev (vec , n , len TSRMLS_CC );
233
+ #endif
234
+
235
+ VEC_FREE ();
219
236
220
237
return SAPI_HEADER_SENT_SUCCESSFULLY ;
221
238
}
0 commit comments