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
10 * http://www.apache.org/licenses/LICENSE-2.0
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
18 * ====================================================================
21 #include <apr_pools.h>
24 #include "serf_bucket_util.h"
25 #include "serf_private.h"
27 serf_bucket_t *serf_bucket_create(
28 const serf_bucket_type_t *type,
29 serf_bucket_alloc_t *allocator,
32 serf_bucket_t *bkt = serf_bucket_mem_alloc(allocator, sizeof(*bkt));
36 bkt->allocator = allocator;
42 apr_status_t serf_default_read_iovec(
43 serf_bucket_t *bucket,
52 /* Read some data from the bucket.
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.
61 apr_status_t status = bucket->type->read(bucket, requested, &data, &len);
63 /* assert that vecs_size >= 1 ? */
65 /* Return that data as a single iovec. */
67 vecs[0].iov_base = (void *)data; /* loses the 'const' */
68 vecs[0].iov_len = len;
79 apr_status_t serf_default_read_for_sendfile(
80 serf_bucket_t *bucket,
87 /* Read a bunch of stuff into the headers.
89 * See serf_default_read_iovec as to why we call into the vtable
92 apr_status_t status = bucket->type->read_iovec(bucket, requested,
97 /* There isn't a file, and there are no trailers. */
99 hdtr->numtrailers = 0;
105 serf_bucket_t *serf_default_read_bucket(
106 serf_bucket_t *bucket,
107 const serf_bucket_type_t *type)
113 void serf_default_destroy(serf_bucket_t *bucket)
115 #ifdef SERF_DEBUG_BUCKET_USE
116 serf_debug__bucket_destroy(bucket);
119 serf_bucket_mem_free(bucket->allocator, bucket);
123 void serf_default_destroy_and_data(serf_bucket_t *bucket)
125 serf_bucket_mem_free(bucket->allocator, bucket->data);
126 serf_default_destroy(bucket);
130 /* ==================================================================== */
133 char *serf_bstrmemdup(serf_bucket_alloc_t *allocator,
137 char *newstr = serf_bucket_mem_alloc(allocator, size + 1);
138 memcpy(newstr, str, size);
144 void *serf_bmemdup(serf_bucket_alloc_t *allocator,
148 void *newmem = serf_bucket_mem_alloc(allocator, size);
149 memcpy(newmem, mem, size);
154 char *serf_bstrdup(serf_bucket_alloc_t *allocator,
157 apr_size_t size = strlen(str) + 1;
158 char *newstr = serf_bucket_mem_alloc(allocator, size);
159 memcpy(newstr, str, size);
163 char *serf_bstrcatv(serf_bucket_alloc_t *allocator, struct iovec *vec,
164 int vecs, apr_size_t *bytes_written)
167 apr_size_t new_len = 0;
170 for (i = 0; i < vecs; i++) {
171 new_len += vec[i].iov_len;
174 /* It's up to the caller to free this memory later. */
175 newstr = serf_bucket_mem_alloc(allocator, new_len);
178 for (i = 0; i < vecs; i++) {
179 memcpy(c, vec[i].iov_base, vec[i].iov_len);
184 *bytes_written = c - newstr;
190 /* ==================================================================== */
193 static void find_crlf(const char **data, apr_size_t *len, int *found)
195 const char *start = *data;
196 const char *end = start + *len;
198 while (start < end) {
199 const char *cr = memchr(start, '\r', *len);
206 if (cr < end && cr[0] == '\n') {
207 *len -= cr + 1 - start;
209 *found = SERF_NEWLINE_CRLF;
215 *found = SERF_NEWLINE_CRLF_SPLIT;
219 /* It was a bare CR without an LF. Just move past it. */
224 *data = start + *len;
225 *len -= *data - start;
226 *found = SERF_NEWLINE_NONE;
230 void serf_util_readline(
243 /* If _only_ CRLF is acceptable, then the scanning needs a loop to
244 * skip false hits on CR characters. Use a separate function.
246 if (acceptable == SERF_NEWLINE_CRLF) {
247 find_crlf(data, len, found);
253 want_cr = acceptable & SERF_NEWLINE_CR;
254 want_crlf = acceptable & SERF_NEWLINE_CRLF;
255 want_lf = acceptable & SERF_NEWLINE_LF;
257 if (want_cr || want_crlf) {
258 cr = memchr(start, '\r', *len);
261 lf = memchr(start, '\n', *len);
267 *found = want_crlf ? SERF_NEWLINE_CRLF : SERF_NEWLINE_CR;
268 else if (want_cr && cr < lf)
269 *found = SERF_NEWLINE_CR;
271 *found = SERF_NEWLINE_LF;
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?
278 *found = want_crlf ? SERF_NEWLINE_CRLF_SPLIT : SERF_NEWLINE_CR;
281 *found = SERF_NEWLINE_CR;
283 *found = SERF_NEWLINE_NONE;
286 *found = SERF_NEWLINE_LF;
288 *found = SERF_NEWLINE_NONE;
291 case SERF_NEWLINE_LF:
294 case SERF_NEWLINE_CR:
295 case SERF_NEWLINE_CRLF:
296 case SERF_NEWLINE_CRLF_SPLIT:
297 *data = cr + 1 + (*found == SERF_NEWLINE_CRLF);
299 case SERF_NEWLINE_NONE:
307 *len -= *data - start;
311 /* ==================================================================== */
314 void serf_databuf_init(serf_databuf_t *databuf)
316 /* nothing is sitting in the buffer */
317 databuf->remaining = 0;
319 /* avoid thinking we have hit EOF */
320 databuf->status = APR_SUCCESS;
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. */
325 static apr_status_t common_databuf_prep(serf_databuf_t *databuf,
331 /* if there is data in the buffer, then we're happy. */
332 if (databuf->remaining > 0)
335 /* if we already hit EOF, then keep returning that. */
336 if (APR_STATUS_IS_EOF(databuf->status)) {
337 /* *data = NULL; ?? */
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)) {
349 databuf->current = databuf->buf;
350 databuf->remaining = readlen;
351 databuf->status = status;
357 apr_status_t serf_databuf_read(
358 serf_databuf_t *databuf,
359 apr_size_t requested,
363 apr_status_t status = common_databuf_prep(databuf, len);
367 /* peg the requested amount to what we have remaining */
368 if (requested == SERF_READ_ALL_AVAIL || requested > databuf->remaining)
369 requested = databuf->remaining;
371 /* return the values */
372 *data = databuf->current;
375 /* adjust our internal state to note we've consumed some data */
376 databuf->current += requested;
377 databuf->remaining -= requested;
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.
384 return databuf->remaining ? APR_SUCCESS : databuf->status;
388 apr_status_t serf_databuf_readline(
389 serf_databuf_t *databuf,
395 apr_status_t status = common_databuf_prep(databuf, len);
399 /* the returned line will start at the current position. */
400 *data = databuf->current;
402 /* read a line from the buffer, and adjust the various pointers. */
403 serf_util_readline(&databuf->current, &databuf->remaining, acceptable,
406 /* the length matches the amount consumed by the readline */
407 *len = databuf->current - *data;
409 /* see serf_databuf_read's return condition */
410 return databuf->remaining ? APR_SUCCESS : databuf->status;
414 apr_status_t serf_databuf_peek(
415 serf_databuf_t *databuf,
419 apr_status_t status = common_databuf_prep(databuf, len);
423 /* return everything we have */
424 *data = databuf->current;
425 *len = databuf->remaining;
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.
431 if (APR_STATUS_IS_EOF(databuf->status))
437 /* ==================================================================== */
440 void serf_linebuf_init(serf_linebuf_t *linebuf)
442 linebuf->state = SERF_LINEBUF_EMPTY;
447 apr_status_t serf_linebuf_fetch(
448 serf_linebuf_t *linebuf,
449 serf_bucket_t *bucket,
452 /* If we had a complete line, then assume the caller has used it, so
453 * we can now reset the state.
455 if (linebuf->state == SERF_LINEBUF_READY) {
456 linebuf->state = SERF_LINEBUF_EMPTY;
458 /* Reset the line_used, too, so we don't have to test the state
459 * before using this value.
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
476 status = serf_bucket_peek(bucket, &data, &len);
477 if (SERF_BUCKET_READ_ERROR(status))
482 /* We saw the second part of CRLF. We don't need to
483 * save that character, so do an actual read to suck
486 /* ### check status */
487 (void) serf_bucket_read(bucket, 1, &data, &len);
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.
496 /* Whatever was read, the line is now ready for use. */
497 linebuf->state = SERF_LINEBUF_READY;
499 /* no data available, try again later. */
506 status = serf_bucket_readline(bucket, acceptable, &found,
508 if (SERF_BUCKET_READ_ERROR(status)) {
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) {
517 if (linebuf->used + len > sizeof(linebuf->line)) {
518 /* ### need a "line too long" error */
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.
527 /* If we didn't see a newline, then we should mark the line
528 * buffer as partially complete.
530 if (found == SERF_NEWLINE_NONE) {
531 linebuf->state = SERF_LINEBUF_PARTIAL;
533 else if (found == SERF_NEWLINE_CRLF_SPLIT) {
534 linebuf->state = SERF_LINEBUF_CRLF_SPLIT;
536 /* Toss the partial CR. We won't ever need it. */
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.
544 len -= 1 + (found == SERF_NEWLINE_CRLF);
546 linebuf->state = SERF_LINEBUF_READY;
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;
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.
560 if (status || linebuf->state == SERF_LINEBUF_READY)
563 /* We got APR_SUCCESS and the line buffer is not complete. Let's
564 * loop to read some more data.
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. */
573 static void log_time()
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,
584 void serf__log(int verbose_flag, const char *filename, const char *fmt, ...)
592 fprintf(stderr, "%s: ", filename);
595 vfprintf(stderr, fmt, argp);
600 void serf__log_nopref(int verbose_flag, const char *fmt, ...)
606 vfprintf(stderr, fmt, argp);
611 void serf__log_skt(int verbose_flag, const char *filename, apr_socket_t *skt,
612 const char *fmt, ...)
621 /* Log local and remote ip address:port */
622 fprintf(stderr, "[l:");
623 if (apr_socket_addr_get(&sa, APR_LOCAL, skt) == APR_SUCCESS) {
625 apr_sockaddr_ip_getbuf(buf, 32, sa);
626 fprintf(stderr, "%s:%d", buf, sa->port);
628 fprintf(stderr, " r:");
629 if (apr_socket_addr_get(&sa, APR_REMOTE, skt) == APR_SUCCESS) {
631 apr_sockaddr_ip_getbuf(buf, 32, sa);
632 fprintf(stderr, "%s:%d", buf, sa->port);
634 fprintf(stderr, "] ");
638 fprintf(stderr, "%s: ", filename);
641 vfprintf(stderr, fmt, argp);