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 27serf_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 42apr_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 79apr_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 105serf_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 113void 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 123void 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 133char *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 144void *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 154char *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 163char *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 193static 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 230void 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 314void 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. */ 325static 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 357apr_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 388apr_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 414apr_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 440void serf_linebuf_init(serf_linebuf_t *linebuf) 441{ 442 linebuf->state = SERF_LINEBUF_EMPTY; 443 linebuf->used = 0; 444} 445 446 447apr_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. */ 573static 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 584void 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 600void 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 611void 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