1 /* Copyright 2002-2004 Justin Erenkrantz and Greg Stein
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 #include <apr_pools.h>
19 #include "serf_bucket_util.h"
22 serf_bucket_t *serf_bucket_create(
23 const serf_bucket_type_t *type,
24 serf_bucket_alloc_t *allocator,
27 serf_bucket_t *bkt = serf_bucket_mem_alloc(allocator, sizeof(*bkt));
31 bkt->allocator = allocator;
37 apr_status_t serf_default_read_iovec(
38 serf_bucket_t *bucket,
47 /* Read some data from the bucket.
49 * Because we're an internal 'helper' to the bucket, we can't call the
50 * normal serf_bucket_read() call because the debug allocator tracker will
51 * end up marking the bucket as read *twice* - once for us and once for
52 * our caller - which is reading the same bucket. This leads to premature
53 * abort()s if we ever see EAGAIN. Instead, we'll go directly to the
54 * vtable and bypass the debug tracker.
56 apr_status_t status = bucket->type->read(bucket, requested, &data, &len);
58 /* assert that vecs_size >= 1 ? */
60 /* Return that data as a single iovec. */
62 vecs[0].iov_base = (void *)data; /* loses the 'const' */
63 vecs[0].iov_len = len;
74 apr_status_t serf_default_read_for_sendfile(
75 serf_bucket_t *bucket,
82 /* Read a bunch of stuff into the headers.
84 * See serf_default_read_iovec as to why we call into the vtable
87 apr_status_t status = bucket->type->read_iovec(bucket, requested,
92 /* There isn't a file, and there are no trailers. */
94 hdtr->numtrailers = 0;
100 serf_bucket_t *serf_default_read_bucket(
101 serf_bucket_t *bucket,
102 const serf_bucket_type_t *type)
108 void serf_default_destroy(serf_bucket_t *bucket)
110 #ifdef SERF_DEBUG_BUCKET_USE
111 serf_debug__bucket_destroy(bucket);
114 serf_bucket_mem_free(bucket->allocator, bucket);
118 void serf_default_destroy_and_data(serf_bucket_t *bucket)
120 serf_bucket_mem_free(bucket->allocator, bucket->data);
121 serf_default_destroy(bucket);
125 /* ==================================================================== */
128 char *serf_bstrmemdup(serf_bucket_alloc_t *allocator,
132 char *newstr = serf_bucket_mem_alloc(allocator, size + 1);
133 memcpy(newstr, str, size);
139 void *serf_bmemdup(serf_bucket_alloc_t *allocator,
143 void *newmem = serf_bucket_mem_alloc(allocator, size);
144 memcpy(newmem, mem, size);
149 char *serf_bstrdup(serf_bucket_alloc_t *allocator,
152 apr_size_t size = strlen(str) + 1;
153 char *newstr = serf_bucket_mem_alloc(allocator, size);
154 memcpy(newstr, str, size);
159 /* ==================================================================== */
162 static void find_crlf(const char **data, apr_size_t *len, int *found)
164 const char *start = *data;
165 const char *end = start + *len;
167 while (start < end) {
168 const char *cr = memchr(start, '\r', *len);
175 if (cr < end && cr[0] == '\n') {
176 *len -= cr + 1 - start;
178 *found = SERF_NEWLINE_CRLF;
184 *found = SERF_NEWLINE_CRLF_SPLIT;
188 /* It was a bare CR without an LF. Just move past it. */
193 *data = start + *len;
194 *len -= *data - start;
195 *found = SERF_NEWLINE_NONE;
199 void serf_util_readline(
212 /* If _only_ CRLF is acceptable, then the scanning needs a loop to
213 * skip false hits on CR characters. Use a separate function.
215 if (acceptable == SERF_NEWLINE_CRLF) {
216 find_crlf(data, len, found);
222 want_cr = acceptable & SERF_NEWLINE_CR;
223 want_crlf = acceptable & SERF_NEWLINE_CRLF;
224 want_lf = acceptable & SERF_NEWLINE_LF;
226 if (want_cr || want_crlf) {
227 cr = memchr(start, '\r', *len);
230 lf = memchr(start, '\n', *len);
236 *found = want_crlf ? SERF_NEWLINE_CRLF : SERF_NEWLINE_CR;
237 else if (want_cr && cr < lf)
238 *found = SERF_NEWLINE_CR;
240 *found = SERF_NEWLINE_LF;
242 else if (cr == start + *len - 1) {
243 /* the CR occurred in the last byte of the buffer. this could be
244 * a CRLF split across the data boundary.
245 * ### FIX THIS LOGIC? does caller need to detect?
247 *found = want_crlf ? SERF_NEWLINE_CRLF_SPLIT : SERF_NEWLINE_CR;
250 *found = SERF_NEWLINE_CR;
252 *found = SERF_NEWLINE_NONE;
255 *found = SERF_NEWLINE_LF;
257 *found = SERF_NEWLINE_NONE;
260 case SERF_NEWLINE_LF:
263 case SERF_NEWLINE_CR:
264 case SERF_NEWLINE_CRLF:
265 case SERF_NEWLINE_CRLF_SPLIT:
266 *data = cr + 1 + (*found == SERF_NEWLINE_CRLF);
268 case SERF_NEWLINE_NONE:
276 *len -= *data - start;
280 /* ==================================================================== */
283 void serf_databuf_init(serf_databuf_t *databuf)
285 /* nothing is sitting in the buffer */
286 databuf->remaining = 0;
288 /* avoid thinking we have hit EOF */
289 databuf->status = APR_SUCCESS;
292 /* Ensure the buffer is prepared for reading. Will return APR_SUCCESS,
293 * APR_EOF, or some failure code. *len is only set for EOF. */
294 static apr_status_t common_databuf_prep(serf_databuf_t *databuf,
300 /* if there is data in the buffer, then we're happy. */
301 if (databuf->remaining > 0)
304 /* if we already hit EOF, then keep returning that. */
305 if (APR_STATUS_IS_EOF(databuf->status)) {
306 /* *data = NULL; ?? */
311 /* refill the buffer */
312 status = (*databuf->read)(databuf->read_baton, sizeof(databuf->buf),
313 databuf->buf, &readlen);
314 if (SERF_BUCKET_READ_ERROR(status)) {
318 databuf->current = databuf->buf;
319 databuf->remaining = readlen;
320 databuf->status = status;
326 apr_status_t serf_databuf_read(
327 serf_databuf_t *databuf,
328 apr_size_t requested,
332 apr_status_t status = common_databuf_prep(databuf, len);
336 /* peg the requested amount to what we have remaining */
337 if (requested == SERF_READ_ALL_AVAIL || requested > databuf->remaining)
338 requested = databuf->remaining;
340 /* return the values */
341 *data = databuf->current;
344 /* adjust our internal state to note we've consumed some data */
345 databuf->current += requested;
346 databuf->remaining -= requested;
348 /* If we read everything, then we need to return whatever the data
349 * read returned to us. This is going to be APR_EOF or APR_EGAIN.
350 * If we have NOT read everything, then return APR_SUCCESS to indicate
351 * that we're ready to return some more if asked.
353 return databuf->remaining ? APR_SUCCESS : databuf->status;
357 apr_status_t serf_databuf_readline(
358 serf_databuf_t *databuf,
364 apr_status_t status = common_databuf_prep(databuf, len);
368 /* the returned line will start at the current position. */
369 *data = databuf->current;
371 /* read a line from the buffer, and adjust the various pointers. */
372 serf_util_readline(&databuf->current, &databuf->remaining, acceptable,
375 /* the length matches the amount consumed by the readline */
376 *len = databuf->current - *data;
378 /* see serf_databuf_read's return condition */
379 return databuf->remaining ? APR_SUCCESS : databuf->status;
383 apr_status_t serf_databuf_peek(
384 serf_databuf_t *databuf,
388 apr_status_t status = common_databuf_prep(databuf, len);
392 /* return everything we have */
393 *data = databuf->current;
394 *len = databuf->remaining;
396 /* If the last read returned EOF, then the peek should return the same.
397 * The other possibility in databuf->status is APR_EAGAIN, which we
398 * should never return. Thus, just return APR_SUCCESS for non-EOF cases.
400 if (APR_STATUS_IS_EOF(databuf->status))
406 /* ==================================================================== */
409 void serf_linebuf_init(serf_linebuf_t *linebuf)
411 linebuf->state = SERF_LINEBUF_EMPTY;
416 apr_status_t serf_linebuf_fetch(
417 serf_linebuf_t *linebuf,
418 serf_bucket_t *bucket,
421 /* If we had a complete line, then assume the caller has used it, so
422 * we can now reset the state.
424 if (linebuf->state == SERF_LINEBUF_READY) {
425 linebuf->state = SERF_LINEBUF_EMPTY;
427 /* Reset the line_used, too, so we don't have to test the state
428 * before using this value.
438 if (linebuf->state == SERF_LINEBUF_CRLF_SPLIT) {
439 /* On the previous read, we received just a CR. The LF might
440 * be present, but the bucket couldn't see it. We need to
441 * examine a single character to determine how to handle the
445 status = serf_bucket_peek(bucket, &data, &len);
446 if (SERF_BUCKET_READ_ERROR(status))
451 /* We saw the second part of CRLF. We don't need to
452 * save that character, so do an actual read to suck
455 /* ### check status */
456 (void) serf_bucket_read(bucket, 1, &data, &len);
459 * We saw the first character of the next line. Thus,
460 * the current line is terminated by the CR. Just
461 * ignore whatever we peeked at. The next reader will
462 * see it and handle it as appropriate.
465 /* Whatever was read, the line is now ready for use. */
466 linebuf->state = SERF_LINEBUF_READY;
468 /* no data available, try again later. */
475 status = serf_bucket_readline(bucket, acceptable, &found,
477 if (SERF_BUCKET_READ_ERROR(status)) {
480 /* Some bucket types (socket) might need an extra read to find
481 out EOF state, so they'll return no data in that read. This
482 means we're done reading, return what we got. */
483 if (APR_STATUS_IS_EOF(status) && len == 0) {
486 if (linebuf->used + len > sizeof(linebuf->line)) {
487 /* ### need a "line too long" error */
491 /* Note: our logic doesn't change for SERF_LINEBUF_PARTIAL. That
492 * only affects how we fill the buffer. It is a communication to
493 * our caller on whether the line is ready or not.
496 /* If we didn't see a newline, then we should mark the line
497 * buffer as partially complete.
499 if (found == SERF_NEWLINE_NONE) {
500 linebuf->state = SERF_LINEBUF_PARTIAL;
502 else if (found == SERF_NEWLINE_CRLF_SPLIT) {
503 linebuf->state = SERF_LINEBUF_CRLF_SPLIT;
505 /* Toss the partial CR. We won't ever need it. */
509 /* We got a newline (of some form). We don't need it
510 * in the line buffer, so back up the length. Then
511 * mark the line as ready.
513 len -= 1 + (found == SERF_NEWLINE_CRLF);
515 linebuf->state = SERF_LINEBUF_READY;
518 /* ### it would be nice to avoid this copy if at all possible,
519 ### and just return the a data/len pair to the caller. we're
520 ### keeping it simple for now. */
521 memcpy(&linebuf->line[linebuf->used], data, len);
522 linebuf->used += len;
525 /* If we saw anything besides "success. please read again", then
526 * we should return that status. If the line was completed, then
527 * we should also return.
529 if (status || linebuf->state == SERF_LINEBUF_READY)
532 /* We got APR_SUCCESS and the line buffer is not complete. Let's
533 * loop to read some more data.
539 /* Logging functions.
540 Use with one of the [COMP]_VERBOSE defines so that the compiler knows to
541 optimize this code out when no logging is needed. */
542 static void log_time()
546 apr_time_exp_lt(&tm, apr_time_now());
547 fprintf(stderr, "[%d-%02d-%02dT%02d:%02d:%02d.%06d%+03d] ",
548 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday,
549 tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec,
553 void serf__log(int verbose_flag, const char *filename, const char *fmt, ...)
561 fprintf(stderr, "%s: ", filename);
564 vfprintf(stderr, fmt, argp);
569 void serf__log_nopref(int verbose_flag, const char *fmt, ...)
575 vfprintf(stderr, fmt, argp);
580 void serf__log_skt(int verbose_flag, const char *filename, apr_socket_t *skt,
581 const char *fmt, ...)
590 /* Log local and remote ip address:port */
591 fprintf(stderr, "[l:");
592 if (apr_socket_addr_get(&sa, APR_LOCAL, skt) == APR_SUCCESS) {
594 apr_sockaddr_ip_getbuf(buf, 32, sa);
595 fprintf(stderr, "%s:%d", buf, sa->port);
597 fprintf(stderr, " r:");
598 if (apr_socket_addr_get(&sa, APR_REMOTE, skt) == APR_SUCCESS) {
600 apr_sockaddr_ip_getbuf(buf, 32, sa);
601 fprintf(stderr, "%s:%d", buf, sa->port);
603 fprintf(stderr, "] ");
607 fprintf(stderr, "%s: ", filename);
610 vfprintf(stderr, fmt, argp);