1 /* ====================================================================
2  *    Licensed to the Apache Software Foundation (ASF) under one
3  *    or more contributor license agreements.  See the NOTICE file
4  *    distributed with this work for additional information
5  *    regarding copyright ownership.  The ASF licenses this file
6  *    to you under the Apache License, Version 2.0 (the
7  *    "License"); you may not use this file except in compliance
8  *    with the License.  You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  *    Unless required by applicable law or agreed to in writing,
13  *    software distributed under the License is distributed on an
14  *    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15  *    KIND, either express or implied.  See the License for the
16  *    specific language governing permissions and limitations
17  *    under the License.
18  * ====================================================================
19  */
20 
21 #include <apr_pools.h>
22 
23 #include "serf.h"
24 #include "serf_bucket_util.h"
25 #include "serf_private.h"
26 
serf_bucket_create(const serf_bucket_type_t * type,serf_bucket_alloc_t * allocator,void * data)27 serf_bucket_t *serf_bucket_create(
28     const serf_bucket_type_t *type,
29     serf_bucket_alloc_t *allocator,
30     void *data)
31 {
32     serf_bucket_t *bkt = serf_bucket_mem_alloc(allocator, sizeof(*bkt));
33 
34     bkt->type = type;
35     bkt->data = data;
36     bkt->allocator = allocator;
37 
38     return bkt;
39 }
40 
41 
serf_default_read_iovec(serf_bucket_t * bucket,apr_size_t requested,int vecs_size,struct iovec * vecs,int * vecs_used)42 apr_status_t serf_default_read_iovec(
43     serf_bucket_t *bucket,
44     apr_size_t requested,
45     int vecs_size,
46     struct iovec *vecs,
47     int *vecs_used)
48 {
49     const char *data;
50     apr_size_t len;
51 
52     /* Read some data from the bucket.
53      *
54      * Because we're an internal 'helper' to the bucket, we can't call the
55      * normal serf_bucket_read() call because the debug allocator tracker will
56      * end up marking the bucket as read *twice* - once for us and once for
57      * our caller - which is reading the same bucket.  This leads to premature
58      * abort()s if we ever see EAGAIN.  Instead, we'll go directly to the
59      * vtable and bypass the debug tracker.
60      */
61     apr_status_t status = bucket->type->read(bucket, requested, &data, &len);
62 
63     /* assert that vecs_size >= 1 ? */
64 
65     /* Return that data as a single iovec. */
66     if (len) {
67         vecs[0].iov_base = (void *)data; /* loses the 'const' */
68         vecs[0].iov_len = len;
69         *vecs_used = 1;
70     }
71     else {
72         *vecs_used = 0;
73     }
74 
75     return status;
76 }
77 
78 
serf_default_read_for_sendfile(serf_bucket_t * bucket,apr_size_t requested,apr_hdtr_t * hdtr,apr_file_t ** file,apr_off_t * offset,apr_size_t * len)79 apr_status_t serf_default_read_for_sendfile(
80     serf_bucket_t *bucket,
81     apr_size_t requested,
82     apr_hdtr_t *hdtr,
83     apr_file_t **file,
84     apr_off_t *offset,
85     apr_size_t *len)
86 {
87     /* Read a bunch of stuff into the headers.
88      *
89      * See serf_default_read_iovec as to why we call into the vtable
90      * directly.
91      */
92     apr_status_t status = bucket->type->read_iovec(bucket, requested,
93                                                    hdtr->numheaders,
94                                                    hdtr->headers,
95                                                    &hdtr->numheaders);
96 
97     /* There isn't a file, and there are no trailers. */
98     *file = NULL;
99     hdtr->numtrailers = 0;
100 
101     return status;
102 }
103 
104 
serf_default_read_bucket(serf_bucket_t * bucket,const serf_bucket_type_t * type)105 serf_bucket_t *serf_default_read_bucket(
106     serf_bucket_t *bucket,
107     const serf_bucket_type_t *type)
108 {
109     return NULL;
110 }
111 
112 
serf_default_destroy(serf_bucket_t * bucket)113 void serf_default_destroy(serf_bucket_t *bucket)
114 {
115 #ifdef SERF_DEBUG_BUCKET_USE
116     serf_debug__bucket_destroy(bucket);
117 #endif
118 
119     serf_bucket_mem_free(bucket->allocator, bucket);
120 }
121 
122 
serf_default_destroy_and_data(serf_bucket_t * bucket)123 void serf_default_destroy_and_data(serf_bucket_t *bucket)
124 {
125     serf_bucket_mem_free(bucket->allocator, bucket->data);
126     serf_default_destroy(bucket);
127 }
128 
129 
130 /* ==================================================================== */
131 
132 
serf_bstrmemdup(serf_bucket_alloc_t * allocator,const char * str,apr_size_t size)133 char *serf_bstrmemdup(serf_bucket_alloc_t *allocator,
134                       const char *str,
135                       apr_size_t size)
136 {
137     char *newstr = serf_bucket_mem_alloc(allocator, size + 1);
138     memcpy(newstr, str, size);
139     newstr[size] = '\0';
140     return newstr;
141 }
142 
143 
serf_bmemdup(serf_bucket_alloc_t * allocator,const void * mem,apr_size_t size)144 void *serf_bmemdup(serf_bucket_alloc_t *allocator,
145                    const void *mem,
146                    apr_size_t size)
147 {
148     void *newmem = serf_bucket_mem_alloc(allocator, size);
149     memcpy(newmem, mem, size);
150     return newmem;
151 }
152 
153 
serf_bstrdup(serf_bucket_alloc_t * allocator,const char * str)154 char *serf_bstrdup(serf_bucket_alloc_t *allocator,
155                    const char *str)
156 {
157     apr_size_t size = strlen(str) + 1;
158     char *newstr = serf_bucket_mem_alloc(allocator, size);
159     memcpy(newstr, str, size);
160     return newstr;
161 }
162 
serf_bstrcatv(serf_bucket_alloc_t * allocator,struct iovec * vec,int vecs,apr_size_t * bytes_written)163 char *serf_bstrcatv(serf_bucket_alloc_t *allocator, struct iovec *vec,
164                     int vecs, apr_size_t *bytes_written)
165 {
166     int i;
167     apr_size_t new_len = 0;
168     char *c, *newstr;
169 
170     for (i = 0; i < vecs; i++) {
171         new_len += vec[i].iov_len;
172     }
173 
174     /* It's up to the caller to free this memory later. */
175     newstr = serf_bucket_mem_alloc(allocator, new_len);
176 
177     c = newstr;
178     for (i = 0; i < vecs; i++) {
179         memcpy(c, vec[i].iov_base, vec[i].iov_len);
180         c += vec[i].iov_len;
181     }
182 
183     if (bytes_written) {
184         *bytes_written = c - newstr;
185     }
186 
187     return newstr;
188 }
189 
190 /* ==================================================================== */
191 
192 
find_crlf(const char ** data,apr_size_t * len,int * found)193 static void find_crlf(const char **data, apr_size_t *len, int *found)
194 {
195     const char *start = *data;
196     const char *end = start + *len;
197 
198     while (start < end) {
199         const char *cr = memchr(start, '\r', *len);
200 
201         if (cr == NULL) {
202             break;
203         }
204         ++cr;
205 
206         if (cr < end && cr[0] == '\n') {
207             *len -= cr + 1 - start;
208             *data = cr + 1;
209             *found = SERF_NEWLINE_CRLF;
210             return;
211         }
212         if (cr == end) {
213             *len = 0;
214             *data = end;
215             *found = SERF_NEWLINE_CRLF_SPLIT;
216             return;
217         }
218 
219         /* It was a bare CR without an LF. Just move past it. */
220         *len -= cr - start;
221         start = cr;
222     }
223 
224     *data = start + *len;
225     *len -= *data - start;
226     *found = SERF_NEWLINE_NONE;
227 }
228 
229 
serf_util_readline(const char ** data,apr_size_t * len,int acceptable,int * found)230 void serf_util_readline(
231     const char **data,
232     apr_size_t *len,
233     int acceptable,
234     int *found)
235 {
236     const char *start;
237     const char *cr;
238     const char *lf;
239     int want_cr;
240     int want_crlf;
241     int want_lf;
242 
243     /* If _only_ CRLF is acceptable, then the scanning needs a loop to
244      * skip false hits on CR characters. Use a separate function.
245      */
246     if (acceptable == SERF_NEWLINE_CRLF) {
247         find_crlf(data, len, found);
248         return;
249     }
250 
251     start = *data;
252     cr = lf = NULL;
253     want_cr = acceptable & SERF_NEWLINE_CR;
254     want_crlf = acceptable & SERF_NEWLINE_CRLF;
255     want_lf = acceptable & SERF_NEWLINE_LF;
256 
257     if (want_cr || want_crlf) {
258         cr = memchr(start, '\r', *len);
259     }
260     if (want_lf) {
261         lf = memchr(start, '\n', *len);
262     }
263 
264     if (cr != NULL) {
265         if (lf != NULL) {
266             if (cr + 1 == lf)
267                 *found = want_crlf ? SERF_NEWLINE_CRLF : SERF_NEWLINE_CR;
268             else if (want_cr && cr < lf)
269                 *found = SERF_NEWLINE_CR;
270             else
271                 *found = SERF_NEWLINE_LF;
272         }
273         else if (cr == start + *len - 1) {
274             /* the CR occurred in the last byte of the buffer. this could be
275              * a CRLF split across the data boundary.
276              * ### FIX THIS LOGIC? does caller need to detect?
277              */
278             *found = want_crlf ? SERF_NEWLINE_CRLF_SPLIT : SERF_NEWLINE_CR;
279         }
280         else if (want_cr)
281             *found = SERF_NEWLINE_CR;
282         else /* want_crlf */
283             *found = SERF_NEWLINE_NONE;
284     }
285     else if (lf != NULL)
286         *found = SERF_NEWLINE_LF;
287     else
288         *found = SERF_NEWLINE_NONE;
289 
290     switch (*found) {
291       case SERF_NEWLINE_LF:
292         *data = lf + 1;
293         break;
294       case SERF_NEWLINE_CR:
295       case SERF_NEWLINE_CRLF:
296       case SERF_NEWLINE_CRLF_SPLIT:
297         *data = cr + 1 + (*found == SERF_NEWLINE_CRLF);
298         break;
299       case SERF_NEWLINE_NONE:
300         *data += *len;
301         break;
302       default:
303         /* Not reachable */
304         return;
305     }
306 
307     *len -= *data - start;
308 }
309 
310 
311 /* ==================================================================== */
312 
313 
serf_databuf_init(serf_databuf_t * databuf)314 void serf_databuf_init(serf_databuf_t *databuf)
315 {
316     /* nothing is sitting in the buffer */
317     databuf->remaining = 0;
318 
319     /* avoid thinking we have hit EOF */
320     databuf->status = APR_SUCCESS;
321 }
322 
323 /* Ensure the buffer is prepared for reading. Will return APR_SUCCESS,
324  * APR_EOF, or some failure code. *len is only set for EOF. */
common_databuf_prep(serf_databuf_t * databuf,apr_size_t * len)325 static apr_status_t common_databuf_prep(serf_databuf_t *databuf,
326                                         apr_size_t *len)
327 {
328     apr_size_t readlen;
329     apr_status_t status;
330 
331     /* if there is data in the buffer, then we're happy. */
332     if (databuf->remaining > 0)
333         return APR_SUCCESS;
334 
335     /* if we already hit EOF, then keep returning that. */
336     if (APR_STATUS_IS_EOF(databuf->status)) {
337         /* *data = NULL;   ?? */
338         *len = 0;
339         return APR_EOF;
340     }
341 
342     /* refill the buffer */
343     status = (*databuf->read)(databuf->read_baton, sizeof(databuf->buf),
344                               databuf->buf, &readlen);
345     if (SERF_BUCKET_READ_ERROR(status)) {
346         return status;
347     }
348 
349     databuf->current = databuf->buf;
350     databuf->remaining = readlen;
351     databuf->status = status;
352 
353     return APR_SUCCESS;
354 }
355 
356 
serf_databuf_read(serf_databuf_t * databuf,apr_size_t requested,const char ** data,apr_size_t * len)357 apr_status_t serf_databuf_read(
358     serf_databuf_t *databuf,
359     apr_size_t requested,
360     const char **data,
361     apr_size_t *len)
362 {
363     apr_status_t status = common_databuf_prep(databuf, len);
364     if (status)
365         return status;
366 
367     /* peg the requested amount to what we have remaining */
368     if (requested == SERF_READ_ALL_AVAIL || requested > databuf->remaining)
369         requested = databuf->remaining;
370 
371     /* return the values */
372     *data = databuf->current;
373     *len = requested;
374 
375     /* adjust our internal state to note we've consumed some data */
376     databuf->current += requested;
377     databuf->remaining -= requested;
378 
379     /* If we read everything, then we need to return whatever the data
380      * read returned to us. This is going to be APR_EOF or APR_EGAIN.
381      * If we have NOT read everything, then return APR_SUCCESS to indicate
382      * that we're ready to return some more if asked.
383      */
384     return databuf->remaining ? APR_SUCCESS : databuf->status;
385 }
386 
387 
serf_databuf_readline(serf_databuf_t * databuf,int acceptable,int * found,const char ** data,apr_size_t * len)388 apr_status_t serf_databuf_readline(
389     serf_databuf_t *databuf,
390     int acceptable,
391     int *found,
392     const char **data,
393     apr_size_t *len)
394 {
395     apr_status_t status = common_databuf_prep(databuf, len);
396     if (status)
397         return status;
398 
399     /* the returned line will start at the current position. */
400     *data = databuf->current;
401 
402     /* read a line from the buffer, and adjust the various pointers. */
403     serf_util_readline(&databuf->current, &databuf->remaining, acceptable,
404                        found);
405 
406     /* the length matches the amount consumed by the readline */
407     *len = databuf->current - *data;
408 
409     /* see serf_databuf_read's return condition */
410     return databuf->remaining ? APR_SUCCESS : databuf->status;
411 }
412 
413 
serf_databuf_peek(serf_databuf_t * databuf,const char ** data,apr_size_t * len)414 apr_status_t serf_databuf_peek(
415     serf_databuf_t *databuf,
416     const char **data,
417     apr_size_t *len)
418 {
419     apr_status_t status = common_databuf_prep(databuf, len);
420     if (status)
421         return status;
422 
423     /* return everything we have */
424     *data = databuf->current;
425     *len = databuf->remaining;
426 
427     /* If the last read returned EOF, then the peek should return the same.
428      * The other possibility in databuf->status is APR_EAGAIN, which we
429      * should never return. Thus, just return APR_SUCCESS for non-EOF cases.
430      */
431     if (APR_STATUS_IS_EOF(databuf->status))
432         return APR_EOF;
433     return APR_SUCCESS;
434 }
435 
436 
437 /* ==================================================================== */
438 
439 
serf_linebuf_init(serf_linebuf_t * linebuf)440 void serf_linebuf_init(serf_linebuf_t *linebuf)
441 {
442     linebuf->state = SERF_LINEBUF_EMPTY;
443     linebuf->used = 0;
444 }
445 
446 
serf_linebuf_fetch(serf_linebuf_t * linebuf,serf_bucket_t * bucket,int acceptable)447 apr_status_t serf_linebuf_fetch(
448     serf_linebuf_t *linebuf,
449     serf_bucket_t *bucket,
450     int acceptable)
451 {
452     /* If we had a complete line, then assume the caller has used it, so
453      * we can now reset the state.
454      */
455     if (linebuf->state == SERF_LINEBUF_READY) {
456         linebuf->state = SERF_LINEBUF_EMPTY;
457 
458         /* Reset the line_used, too, so we don't have to test the state
459          * before using this value.
460          */
461         linebuf->used = 0;
462     }
463 
464     while (1) {
465         apr_status_t status;
466         const char *data;
467         apr_size_t len;
468 
469         if (linebuf->state == SERF_LINEBUF_CRLF_SPLIT) {
470             /* On the previous read, we received just a CR. The LF might
471              * be present, but the bucket couldn't see it. We need to
472              * examine a single character to determine how to handle the
473              * split CRLF.
474              */
475 
476             status = serf_bucket_peek(bucket, &data, &len);
477             if (SERF_BUCKET_READ_ERROR(status))
478                 return status;
479 
480             if (len > 0) {
481                 if (*data == '\n') {
482                     /* We saw the second part of CRLF. We don't need to
483                      * save that character, so do an actual read to suck
484                      * up that character.
485                      */
486                     /* ### check status */
487                     (void) serf_bucket_read(bucket, 1, &data, &len);
488                 }
489                 /* else:
490                  *   We saw the first character of the next line. Thus,
491                  *   the current line is terminated by the CR. Just
492                  *   ignore whatever we peeked at. The next reader will
493                  *   see it and handle it as appropriate.
494                  */
495 
496                 /* Whatever was read, the line is now ready for use. */
497                 linebuf->state = SERF_LINEBUF_READY;
498             } else {
499                 /* no data available, try again later. */
500                 return APR_EAGAIN;
501             }
502         }
503         else {
504             int found;
505 
506             status = serf_bucket_readline(bucket, acceptable, &found,
507                                           &data, &len);
508             if (SERF_BUCKET_READ_ERROR(status)) {
509                 return status;
510             }
511             /* Some bucket types (socket) might need an extra read to find
512                out EOF state, so they'll return no data in that read. This
513                means we're done reading, return what we got. */
514             if (APR_STATUS_IS_EOF(status) && len == 0) {
515 	        return status;
516             }
517             if (linebuf->used + len > sizeof(linebuf->line)) {
518                 /* ### need a "line too long" error */
519                 return APR_EGENERAL;
520             }
521 
522             /* Note: our logic doesn't change for SERF_LINEBUF_PARTIAL. That
523              * only affects how we fill the buffer. It is a communication to
524              * our caller on whether the line is ready or not.
525              */
526 
527             /* If we didn't see a newline, then we should mark the line
528              * buffer as partially complete.
529              */
530             if (found == SERF_NEWLINE_NONE) {
531                 linebuf->state = SERF_LINEBUF_PARTIAL;
532             }
533             else if (found == SERF_NEWLINE_CRLF_SPLIT) {
534                 linebuf->state = SERF_LINEBUF_CRLF_SPLIT;
535 
536                 /* Toss the partial CR. We won't ever need it. */
537                 --len;
538             }
539             else {
540                 /* We got a newline (of some form). We don't need it
541                  * in the line buffer, so back up the length. Then
542                  * mark the line as ready.
543                  */
544                 len -= 1 + (found == SERF_NEWLINE_CRLF);
545 
546                 linebuf->state = SERF_LINEBUF_READY;
547             }
548 
549             /* ### it would be nice to avoid this copy if at all possible,
550                ### and just return the a data/len pair to the caller. we're
551                ### keeping it simple for now. */
552             memcpy(&linebuf->line[linebuf->used], data, len);
553             linebuf->used += len;
554         }
555 
556         /* If we saw anything besides "success. please read again", then
557          * we should return that status. If the line was completed, then
558          * we should also return.
559          */
560         if (status || linebuf->state == SERF_LINEBUF_READY)
561             return status;
562 
563         /* We got APR_SUCCESS and the line buffer is not complete. Let's
564          * loop to read some more data.
565          */
566     }
567     /* NOTREACHED */
568 }
569 
570 /* Logging functions.
571    Use with one of the [COMP]_VERBOSE defines so that the compiler knows to
572    optimize this code out when no logging is needed. */
log_time()573 static void log_time()
574 {
575     apr_time_exp_t tm;
576 
577     apr_time_exp_lt(&tm, apr_time_now());
578     fprintf(stderr, "[%d-%02d-%02dT%02d:%02d:%02d.%06d%+03d] ",
579             1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
580             tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec,
581             tm.tm_gmtoff/3600);
582 }
583 
serf__log(int verbose_flag,const char * filename,const char * fmt,...)584 void serf__log(int verbose_flag, const char *filename, const char *fmt, ...)
585 {
586     va_list argp;
587 
588     if (verbose_flag) {
589         log_time();
590 
591         if (filename)
592             fprintf(stderr, "%s: ", filename);
593 
594         va_start(argp, fmt);
595         vfprintf(stderr, fmt, argp);
596         va_end(argp);
597     }
598 }
599 
serf__log_nopref(int verbose_flag,const char * fmt,...)600 void serf__log_nopref(int verbose_flag, const char *fmt, ...)
601 {
602     va_list argp;
603 
604     if (verbose_flag) {
605         va_start(argp, fmt);
606         vfprintf(stderr, fmt, argp);
607         va_end(argp);
608     }
609 }
610 
serf__log_skt(int verbose_flag,const char * filename,apr_socket_t * skt,const char * fmt,...)611 void serf__log_skt(int verbose_flag, const char *filename, apr_socket_t *skt,
612                    const char *fmt, ...)
613 {
614     va_list argp;
615 
616     if (verbose_flag) {
617         apr_sockaddr_t *sa;
618         log_time();
619 
620         if (skt) {
621             /* Log local and remote ip address:port */
622             fprintf(stderr, "[l:");
623             if (apr_socket_addr_get(&sa, APR_LOCAL, skt) == APR_SUCCESS) {
624                 char buf[32];
625                 apr_sockaddr_ip_getbuf(buf, 32, sa);
626                 fprintf(stderr, "%s:%d", buf, sa->port);
627             }
628             fprintf(stderr, " r:");
629             if (apr_socket_addr_get(&sa, APR_REMOTE, skt) == APR_SUCCESS) {
630                 char buf[32];
631                 apr_sockaddr_ip_getbuf(buf, 32, sa);
632                 fprintf(stderr, "%s:%d", buf, sa->port);
633             }
634             fprintf(stderr, "] ");
635         }
636 
637         if (filename)
638             fprintf(stderr, "%s: ", filename);
639 
640         va_start(argp, fmt);
641         vfprintf(stderr, fmt, argp);
642         va_end(argp);
643     }
644 }
645 
646