1 /* ====================================================================
2 * The Apache Software License, Version 1.1
3 *
4 * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
5 * reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * 3. The end-user documentation included with the redistribution,
20 * if any, must include the following acknowledgment:
21 * "This product includes software developed by the
22 * Apache Software Foundation (http://www.apache.org/)."
23 * Alternately, this acknowledgment may appear in the software itself,
24 * if and wherever such third-party acknowledgments normally appear.
25 *
26 * 4. The names "Apache" and "Apache Software Foundation" must
27 * not be used to endorse or promote products derived from this
28 * software without prior written permission. For written
29 * permission, please contact apache@apache.org.
30 *
31 * 5. Products derived from this software may not be called "Apache",
32 * nor may "Apache" appear in their name, without prior written
33 * permission of the Apache Software Foundation.
34 *
35 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
36 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
37 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
38 * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
39 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
42 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
43 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
44 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
45 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 * SUCH DAMAGE.
47 * ====================================================================
48 *
49 * This software consists of voluntary contributions made by many
50 * individuals on behalf of the Apache Software Foundation. For more
51 * information on the Apache Software Foundation, please see
52 * <http://www.apache.org/>.
53 *
54 * Portions of this software are based upon public domain software
55 * originally written at the National Center for Supercomputing Applications,
56 * University of Illinois, Urbana-Champaign.
57 */
58
59 #include "httpd.h"
60 #include "http_main.h"
61 #include "http_log.h"
62 #include "buff.h"
63
64 #include <errno.h>
65 #include <stdio.h>
66 #include <stdarg.h>
67 #include <string.h>
68 #include <sys/types.h>
69 #include <sys/uio.h>
70
71 #ifndef DEFAULT_BUFSIZE
72 #define DEFAULT_BUFSIZE (4096)
73 #endif
74 /* This must be enough to represent (DEFAULT_BUFSIZE - 3) in hex,
75 * plus two extra characters.
76 */
77 #ifndef CHUNK_HEADER_SIZE
78 #define CHUNK_HEADER_SIZE (5)
79 #endif
80
81 #define ascii_CRLF "\015\012" /* A CRLF which won't pass the conversion machinery */
82
83 /* bwrite()s of greater than this size can result in a large_write() call,
84 * which can result in a writev(). It's a little more work to set up the
85 * writev() rather than copy bytes into the buffer, so we don't do it for small
86 * writes. This is especially important when chunking (which is a very likely
87 * source of small writes if it's a module using ap_bputc/ap_bputs)...because we
88 * have the expense of actually building two chunks for each writev().
89 */
90 #ifndef LARGE_WRITE_THRESHOLD
91 #define LARGE_WRITE_THRESHOLD 31
92 #endif
93
94
95 /*
96 * Buffered I/O routines.
97 * These are a replacement for the stdio routines.
98 * Advantages:
99 * Known semantics for handling of file-descriptors (on close etc.)
100 * No problems reading and writing simultanously to the same descriptor
101 * No limits on the number of open file handles.
102 * Only uses memory resources; no need to ensure the close routine
103 * is called.
104 * Extra code could be inserted between the buffered and un-buffered routines.
105 * Timeouts could be handled by using select or poll before read or write.
106 * Extra error handling could be introduced; e.g.
107 * keep an address to which we should longjump(), or
108 * keep a stack of routines to call on error.
109 */
110
111 /* Notes:
112 * On reading EOF, EOF will set in the flags and no further Input will
113 * be done.
114 *
115 * On an error except for EAGAIN, ERROR will be set in the flags and no
116 * further I/O will be done
117 */
118
119
120 /* the lowest level reading primitive */
ap_read(BUFF * fb,void * buf,int nbyte)121 static int ap_read(BUFF *fb, void *buf, int nbyte)
122 {
123 int rv;
124
125 if (!ap_hook_call("ap::buff::read", &rv, fb, buf, nbyte))
126 rv = read(fb->fd_in, buf, nbyte);
127
128 return rv;
129 }
130
buff_read(BUFF * fb,void * buf,int nbyte)131 static ap_inline int buff_read(BUFF *fb, void *buf, int nbyte)
132 {
133 int rv;
134
135 rv = ap_read(fb, buf, nbyte);
136 return rv;
137 }
138
139 /* the lowest level writing primitive */
ap_write(BUFF * fb,const void * buf,int nbyte)140 static int ap_write(BUFF *fb, const void *buf, int nbyte)
141 {
142 int rv;
143
144 if (!ap_hook_call("ap::buff::write", &rv, fb, buf, nbyte))
145 rv = write(fb->fd, buf, nbyte);
146 return rv;
147 }
148
buff_write(BUFF * fb,const void * buf,int nbyte)149 static ap_inline int buff_write(BUFF *fb, const void *buf, int nbyte)
150 {
151 int rv;
152
153 if (fb->filter_callback != NULL) {
154 fb->filter_callback(fb, buf, nbyte);
155 }
156
157 rv = ap_write(fb, buf, nbyte);
158 return rv;
159 }
160
doerror(BUFF * fb,int direction)161 static void doerror(BUFF *fb, int direction)
162 {
163 int errsave = errno; /* Save errno to prevent overwriting it below */
164
165 fb->flags |= (direction == B_RD ? B_RDERR : B_WRERR);
166 if (fb->error != NULL)
167 (*fb->error) (fb, direction, fb->error_data);
168
169 errno = errsave;
170 }
171
172 /* Buffering routines */
173 /*
174 * Create a new buffered stream
175 */
ap_bcreate(pool * p,int flags)176 API_EXPORT(BUFF *) ap_bcreate(pool *p, int flags)
177 {
178 BUFF *fb;
179
180 fb = ap_palloc(p, sizeof(BUFF));
181 fb->pool = p;
182 fb->bufsiz = DEFAULT_BUFSIZE;
183 fb->flags = flags & (B_RDWR | B_SOCKET);
184
185 if (flags & B_RD)
186 fb->inbase = ap_palloc(p, fb->bufsiz);
187 else
188 fb->inbase = NULL;
189
190 /* overallocate so that we can put a chunk trailer of CRLF into this
191 * buffer */
192 if (flags & B_WR)
193 fb->outbase = ap_palloc(p, fb->bufsiz + 2);
194 else
195 fb->outbase = NULL;
196
197 fb->inptr = fb->inbase;
198
199 fb->incnt = 0;
200 fb->outcnt = 0;
201 fb->outchunk = -1;
202 fb->error = NULL;
203 fb->bytes_sent = 0L;
204
205 fb->fd = -1;
206 fb->fd_in = -1;
207
208 fb->callback_data = NULL;
209 fb->filter_callback = NULL;
210
211 fb->ctx = ap_ctx_new(p);
212
213 return fb;
214 }
215
216 /*
217 * Push some I/O file descriptors onto the stream
218 */
ap_bpushfd(BUFF * fb,int fd_in,int fd_out)219 API_EXPORT(void) ap_bpushfd(BUFF *fb, int fd_in, int fd_out)
220 {
221 fb->fd = fd_out;
222 fb->fd_in = fd_in;
223 }
224
ap_bsetopt(BUFF * fb,int optname,const void * optval)225 API_EXPORT(int) ap_bsetopt(BUFF *fb, int optname, const void *optval)
226 {
227 if (optname == BO_BYTECT) {
228 fb->bytes_sent = *(const long int *) optval - (long int) fb->outcnt;
229 return 0;
230 }
231 else {
232 errno = EINVAL;
233 return -1;
234 }
235 }
236
ap_bgetopt(BUFF * fb,int optname,void * optval)237 API_EXPORT(int) ap_bgetopt(BUFF *fb, int optname, void *optval)
238 {
239 if (optname == BO_BYTECT) {
240 long int bs = fb->bytes_sent + fb->outcnt;
241 if (bs < 0L)
242 bs = 0L;
243 *(long int *) optval = bs;
244 return 0;
245 }
246 else {
247 errno = EINVAL;
248 return -1;
249 }
250 }
251
252 static int bflush_core(BUFF *fb);
253
254 /*
255 * Start chunked encoding.
256 *
257 * Note that in order for ap_bputc() to be an efficient macro we have to guarantee
258 * that start_chunk() has always been called on the buffer before we leave any
259 * routine in this file. Said another way, if a routine here uses end_chunk()
260 * and writes something on the wire, then it has to call start_chunk() or set
261 * an error condition before returning.
262 */
start_chunk(BUFF * fb)263 static void start_chunk(BUFF *fb)
264 {
265 if (fb->outchunk != -1) {
266 /* already chunking */
267 return;
268 }
269 if ((fb->flags & (B_WRERR | B_EOUT | B_WR)) != B_WR) {
270 /* unbuffered writes */
271 return;
272 }
273
274 /* we need at least the header_len + at least 1 data byte
275 * remember that we've overallocated fb->outbase so that we can always
276 * fit the two byte CRLF trailer
277 */
278 if (fb->bufsiz - fb->outcnt < CHUNK_HEADER_SIZE + 1) {
279 bflush_core(fb);
280 }
281 fb->outchunk = fb->outcnt;
282 fb->outcnt += CHUNK_HEADER_SIZE;
283 }
284
285
286 /*
287 * end a chunk -- tweak the chunk_header from start_chunk, and add a trailer
288 */
end_chunk(BUFF * fb)289 static void end_chunk(BUFF *fb)
290 {
291 int i;
292 unsigned char *strp;
293
294 if (fb->outchunk == -1) {
295 /* not chunking */
296 return;
297 }
298
299 if (fb->outchunk + CHUNK_HEADER_SIZE == fb->outcnt) {
300 /* nothing was written into this chunk, and we can't write a 0 size
301 * chunk because that signifies EOF, so just erase it
302 */
303 fb->outcnt = fb->outchunk;
304 fb->outchunk = -1;
305 return;
306 }
307
308 /* we know this will fit because of how we wrote it in start_chunk() */
309 i = snprintf((char *) &fb->outbase[fb->outchunk], CHUNK_HEADER_SIZE,
310 "%x", fb->outcnt - fb->outchunk - CHUNK_HEADER_SIZE);
311
312 /* we may have to tack some trailing spaces onto the number we just wrote
313 * in case it was smaller than our estimated size. We've also written
314 * a \0 into the buffer with snprintf so we might have to put a
315 * \r back in.
316 */
317 strp = &fb->outbase[fb->outchunk + i];
318 while (i < CHUNK_HEADER_SIZE - 2) {
319 *strp++ = ' ';
320 ++i;
321 }
322 *strp++ = CR;
323 *strp = LF;
324
325 /* tack on the trailing CRLF, we've reserved room for this */
326 fb->outbase[fb->outcnt++] = CR;
327 fb->outbase[fb->outcnt++] = LF;
328
329 fb->outchunk = -1;
330 }
331
332
333 /*
334 * Set a flag on (1) or off (0).
335 */
ap_bsetflag(BUFF * fb,int flag,int value)336 API_EXPORT(int) ap_bsetflag(BUFF *fb, int flag, int value)
337 {
338 if (value) {
339 fb->flags |= flag;
340 if (flag & B_CHUNK) {
341 start_chunk(fb);
342 }
343 }
344 else {
345 fb->flags &= ~flag;
346 if (flag & B_CHUNK) {
347 end_chunk(fb);
348 }
349 }
350 return value;
351 }
352
353
ap_bnonblock(BUFF * fb,int direction)354 API_EXPORT(int) ap_bnonblock(BUFF *fb, int direction)
355 {
356 int fd;
357
358 fd = (direction == B_RD) ? fb->fd_in : fb->fd;
359 return fcntl(fd, F_SETFL, O_NONBLOCK);
360 }
361
ap_bfileno(BUFF * fb,int direction)362 API_EXPORT(int) ap_bfileno(BUFF *fb, int direction)
363 {
364 return (direction == B_RD) ? fb->fd_in : fb->fd;
365 }
366
367 /*
368 * This is called instead of read() everywhere in here. It implements
369 * the B_SAFEREAD functionality -- which is to force a flush() if a read()
370 * would block. It also deals with the EINTR errno result from read().
371 * return code is like read() except EINTR is eliminated.
372 */
373
374 #define saferead saferead_guts
375
376 /* Test the descriptor and flush the output buffer if it looks like
377 * we will block on the next read.
378 *
379 * Note we assume the caller has ensured that fb->fd_in <= FD_SETSIZE
380 */
ap_bhalfduplex(BUFF * fb)381 API_EXPORT(void) ap_bhalfduplex(BUFF *fb)
382 {
383 int rv;
384 fd_set fds;
385 struct timeval tv;
386
387 /* We don't need to do anything if the connection has been closed
388 * or there is something readable in the incoming buffer
389 * or there is nothing flushable in the output buffer.
390 */
391 if (fb == NULL || fb->fd_in < 0 || fb->incnt > 0 || fb->outcnt == 0) {
392 return;
393 }
394 /* test for a block */
395 do {
396 FD_ZERO(&fds);
397 FD_SET(fb->fd_in, &fds);
398 tv.tv_sec = 0;
399 tv.tv_usec = 0;
400 rv = ap_select(fb->fd_in + 1, &fds, NULL, NULL, &tv);
401 } while (rv < 0 && errno == EINTR && !(fb->flags & B_EOUT));
402
403 /* treat any error as if it would block as well */
404 if (rv != 1) {
405 ap_bflush(fb);
406 }
407 }
408
saferead_guts(BUFF * fb,void * buf,int nbyte)409 static ap_inline int saferead_guts(BUFF *fb, void *buf, int nbyte)
410 {
411 int rv;
412
413 if (fb->flags & B_SAFEREAD) {
414 ap_bhalfduplex(fb);
415 }
416 do {
417 rv = buff_read(fb, buf, nbyte);
418 } while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT));
419 return (rv);
420 }
421
422
423 /* A wrapper around saferead which does error checking and EOF checking
424 * yeah, it's confusing, this calls saferead, which calls buff_read...
425 * and then there's the SFIO case. Note that saferead takes care
426 * of EINTR.
427 */
read_with_errors(BUFF * fb,void * buf,int nbyte)428 static int read_with_errors(BUFF *fb, void *buf, int nbyte)
429 {
430 int rv;
431
432 rv = saferead(fb, buf, nbyte);
433 if (rv == 0) {
434 fb->flags |= B_EOF;
435 }
436 else if (rv == -1 && errno != EAGAIN) {
437 doerror(fb, B_RD);
438 }
439 return rv;
440 }
441
442
443 /*
444 * Read up to nbyte bytes into buf.
445 * If fewer than byte bytes are currently available, then return those.
446 * Returns 0 for EOF, -1 for error.
447 * NOTE EBCDIC: The readahead buffer _always_ contains *unconverted* data.
448 * Only when the caller retrieves data from the buffer (calls bread)
449 * is a conversion done, if the conversion flag is set at that time.
450 */
ap_bread(BUFF * fb,void * buf,int nbyte)451 API_EXPORT(int) ap_bread(BUFF *fb, void *buf, int nbyte)
452 {
453 int i, nrd;
454
455 if (fb->flags & B_RDERR)
456 return -1;
457 if (nbyte == 0)
458 return 0;
459
460 if (!(fb->flags & B_RD)) {
461 /* Unbuffered reading. First check if there was something in the
462 * buffer from before we went unbuffered. */
463 if (fb->incnt) {
464 i = (fb->incnt > nbyte) ? nbyte : fb->incnt;
465 memcpy(buf, fb->inptr, i);
466 fb->incnt -= i;
467 fb->inptr += i;
468 return i;
469 }
470 i = read_with_errors(fb, buf, nbyte);
471 return i;
472 }
473
474 nrd = fb->incnt;
475 /* can we fill the buffer */
476 if (nrd >= nbyte) {
477 memcpy(buf, fb->inptr, nbyte);
478 fb->incnt = nrd - nbyte;
479 fb->inptr += nbyte;
480 return nbyte;
481 }
482
483 if (nrd > 0) {
484 memcpy(buf, fb->inptr, nrd);
485 nbyte -= nrd;
486 buf = nrd + (char *) buf;
487 fb->incnt = 0;
488 }
489 if (fb->flags & B_EOF)
490 return nrd;
491
492 /* do a single read */
493 if (nbyte >= fb->bufsiz) {
494 /* read directly into caller's buffer */
495 i = read_with_errors(fb, buf, nbyte);
496 if (i == -1) {
497 return nrd ? nrd : -1;
498 }
499 }
500 else {
501 /* read into hold buffer, then memcpy */
502 fb->inptr = fb->inbase;
503 i = read_with_errors(fb, fb->inptr, fb->bufsiz);
504 if (i == -1) {
505 return nrd ? nrd : -1;
506 }
507 fb->incnt = i;
508 if (i > nbyte)
509 i = nbyte;
510 memcpy(buf, fb->inptr, i);
511 fb->incnt -= i;
512 fb->inptr += i;
513 }
514 return nrd + i;
515 }
516
517
518 /*
519 * Reads from the stream into the array pointed to by buff, until
520 * a (CR)LF sequence is read, or end-of-file condition is encountered
521 * or until n-1 bytes have been stored in buff. If a CRLF sequence is
522 * read, it is replaced by a newline character. The string is then
523 * terminated with a null character.
524 *
525 * Returns the number of bytes stored in buff, or zero on end of
526 * transmission, or -1 on an error.
527 *
528 * Notes:
529 * If null characters are expected in the data stream, then
530 * buff should not be treated as a null terminated C string; instead
531 * the returned count should be used to determine the length of the
532 * string.
533 * CR characters in the byte stream not immediately followed by a LF
534 * will be preserved.
535 */
ap_bgets(char * buff,int n,BUFF * fb)536 API_EXPORT(int) ap_bgets(char *buff, int n, BUFF *fb)
537 {
538 int i, ch, ct;
539
540 /* Can't do bgets on an unbuffered stream */
541 if (!(fb->flags & B_RD)) {
542 errno = EINVAL;
543 return -1;
544 }
545 if (fb->flags & B_RDERR)
546 return -1;
547
548 ct = 0;
549 i = 0;
550 for (;;) {
551 if (i == fb->incnt) {
552 /* no characters left */
553 fb->inptr = fb->inbase;
554 fb->incnt = 0;
555 if (fb->flags & B_EOF)
556 break;
557 i = read_with_errors(fb, fb->inptr, fb->bufsiz);
558 if (i == -1) {
559 buff[ct] = '\0';
560 return ct ? ct : -1;
561 }
562 fb->incnt = i;
563 if (i == 0)
564 break; /* EOF */
565 i = 0;
566 continue; /* restart with the new data */
567 }
568
569 ch = fb->inptr[i++];
570 if (ch == LF) { /* got LF */
571 if (ct == 0)
572 buff[ct++] = '\n';
573 /* if just preceded by CR, replace CR with LF */
574 else if (buff[ct - 1] == CR)
575 buff[ct - 1] = '\n';
576 else if (ct < n - 1)
577 buff[ct++] = '\n';
578 else
579 i--; /* no room for LF */
580 break;
581 }
582 if (ct == n - 1) {
583 i--; /* push back ch */
584 break;
585 }
586
587 buff[ct++] = ch;
588 }
589 fb->incnt -= i;
590 fb->inptr += i;
591
592 buff[ct] = '\0';
593 return ct;
594 }
595
596 /*
597 * Looks at the stream fb and places the first character into buff
598 * without removing it from the stream buffer.
599 *
600 * Returns 1 on success, zero on end of transmission, or -1 on an error.
601 *
602 */
ap_blookc(char * buff,BUFF * fb)603 API_EXPORT(int) ap_blookc(char *buff, BUFF *fb)
604 {
605 int i;
606
607 *buff = '\0';
608
609 if (!(fb->flags & B_RD)) { /* Can't do blookc on an unbuffered stream */
610 errno = EINVAL;
611 return -1;
612 }
613 if (fb->flags & B_RDERR)
614 return -1;
615
616 if (fb->incnt == 0) { /* no characters left in stream buffer */
617 fb->inptr = fb->inbase;
618 if (fb->flags & B_EOF)
619 return 0;
620
621 i = read_with_errors(fb, fb->inptr, fb->bufsiz);
622 if (i <= 0) {
623 return i;
624 }
625 fb->incnt = i;
626 }
627
628 *buff = fb->inptr[0];
629 return 1;
630 }
631
632 /*
633 * Skip data until a linefeed character is read
634 * Returns 1 on success, 0 if no LF found, or -1 on error
635 */
ap_bskiplf(BUFF * fb)636 API_EXPORT(int) ap_bskiplf(BUFF *fb)
637 {
638 unsigned char *x;
639 int i;
640
641 /* Can't do bskiplf on an unbuffered stream */
642 if (!(fb->flags & B_RD)) {
643 errno = EINVAL;
644 return -1;
645 }
646 if (fb->flags & B_RDERR)
647 return -1;
648
649 for (;;) {
650 x = (unsigned char *) memchr(fb->inptr, '\012', fb->incnt);
651 if (x != NULL) {
652 x++;
653 fb->incnt -= x - fb->inptr;
654 fb->inptr = x;
655 return 1;
656 }
657
658 fb->inptr = fb->inbase;
659 fb->incnt = 0;
660 if (fb->flags & B_EOF)
661 return 0;
662 i = read_with_errors(fb, fb->inptr, fb->bufsiz);
663 if (i <= 0)
664 return i;
665 fb->incnt = i;
666 }
667 }
668
669 /*
670 * output a single character. Used by ap_bputs when the buffer
671 * is full... and so it'll cause the buffer to be flushed first.
672 */
ap_bflsbuf(int c,BUFF * fb)673 API_EXPORT(int) ap_bflsbuf(int c, BUFF *fb)
674 {
675 char ss[1];
676
677 ss[0] = c;
678 return ap_bwrite(fb, ss, 1);
679 }
680
681 /*
682 * Fill the buffer and read a character from it
683 */
ap_bfilbuf(BUFF * fb)684 API_EXPORT(int) ap_bfilbuf(BUFF *fb)
685 {
686 int i;
687 char buf[1];
688
689 i = ap_bread(fb, buf, 1);
690 if (i == 0)
691 errno = 0; /* no error; EOF */
692 if (i != 1)
693 return EOF;
694 else
695 return buf[0];
696 }
697
698
699 /*
700 * When doing chunked encodings we really have to write everything in the
701 * chunk before proceeding onto anything else. This routine either writes
702 * nbytes and returns 0 or returns -1 indicating a failure.
703 *
704 * This is *seriously broken* if used on a non-blocking fd. It will poll.
705 *
706 * Deals with calling doerror and setting bytes_sent.
707 */
write_it_all(BUFF * fb,const void * buf,int nbyte)708 static int write_it_all(BUFF *fb, const void *buf, int nbyte)
709 {
710 int i;
711
712 if (fb->flags & (B_WRERR | B_EOUT))
713 return -1;
714
715 while (nbyte > 0) {
716 i = buff_write(fb, buf, nbyte);
717 if (i < 0) {
718 if (errno != EAGAIN && errno != EINTR) {
719 doerror(fb, B_WR);
720 return -1;
721 }
722 }
723 else {
724 nbyte -= i;
725 buf = i + (const char *) buf;
726 fb->bytes_sent += i;
727 }
728 if (fb->flags & B_EOUT)
729 return -1;
730 }
731 return 0;
732 }
733
734
735 /* Similar to previous, but uses writev. Note that it modifies vec.
736 * return 0 if successful, -1 otherwise.
737 *
738 * Deals with doerror() and bytes_sent.
739 */
writev_it_all(BUFF * fb,struct iovec * vec,int nvec)740 static int writev_it_all(BUFF *fb, struct iovec *vec, int nvec)
741 {
742 int i, rv;
743
744 if (fb->filter_callback != NULL) {
745 for (i = 0; i < nvec; i++) {
746 fb->filter_callback(fb, vec[i].iov_base, vec[i].iov_len);
747 }
748 }
749
750 /* while it's nice an easy to build the vector and crud, it's painful
751 * to deal with a partial writev()
752 */
753 i = 0;
754 while (i < nvec) {
755 do
756 if (!ap_hook_call("ap::buff::writev", &rv, fb, &vec[i], nvec -i))
757 rv = writev(fb->fd, &vec[i], nvec - i);
758 while (rv == -1 && (errno == EINTR || errno == EAGAIN)
759 && !(fb->flags & B_EOUT));
760 if (rv == -1) {
761 if (errno != EINTR && errno != EAGAIN) {
762 doerror(fb, B_WR);
763 }
764 return -1;
765 }
766 fb->bytes_sent += rv;
767 /* recalculate vec to deal with partial writes */
768 while (rv > 0) {
769 if (rv < vec[i].iov_len) {
770 vec[i].iov_base = (char *) vec[i].iov_base + rv;
771 vec[i].iov_len -= rv;
772 rv = 0;
773 }
774 else {
775 rv -= vec[i].iov_len;
776 ++i;
777 }
778 }
779 if (fb->flags & B_EOUT)
780 return -1;
781 }
782 /* if we got here, we wrote it all */
783 return 0;
784 }
785
786 /* A wrapper for buff_write which deals with error conditions and
787 * bytes_sent. Also handles non-blocking writes.
788 */
write_with_errors(BUFF * fb,const void * buf,int nbyte)789 static int write_with_errors(BUFF *fb, const void *buf, int nbyte)
790 {
791 int rv;
792
793 do
794 rv = buff_write(fb, buf, nbyte);
795 while (rv == -1 && errno == EINTR && !(fb->flags & B_EOUT));
796 if (rv == -1) {
797 if (errno != EAGAIN) {
798 doerror(fb, B_WR);
799 }
800 return -1;
801 }
802 else if (rv == 0) {
803 errno = EAGAIN;
804 return -1;
805 }
806 fb->bytes_sent += rv;
807 return rv;
808 }
809
810
811 /*
812 * A hook to write() that deals with chunking. This is really a protocol-
813 * level issue, but we deal with it here because it's simpler; this is
814 * an interim solution pending a complete rewrite of all this stuff in
815 * 2.0, using something like sfio stacked disciplines or BSD's funopen().
816 *
817 * Can be used on non-blocking descriptors, but only if they're not chunked.
818 * Deals with doerror() and bytes_sent.
819 */
bcwrite(BUFF * fb,const void * buf,int nbyte)820 static int bcwrite(BUFF *fb, const void *buf, int nbyte)
821 {
822 char chunksize[16]; /* Big enough for practically anything */
823 struct iovec vec[3];
824
825 if (fb->flags & (B_WRERR | B_EOUT))
826 return -1;
827
828 if (!(fb->flags & B_CHUNK)) {
829 return write_with_errors(fb, buf, nbyte);
830 }
831
832 vec[0].iov_base = chunksize;
833 vec[0].iov_len = snprintf(chunksize, sizeof(chunksize), "%x" CRLF,
834 nbyte);
835 vec[1].iov_base = (void *) buf; /* cast is to avoid const warning */
836 vec[1].iov_len = nbyte;
837 vec[2].iov_base = ascii_CRLF;
838 vec[2].iov_len = 2;
839
840 return writev_it_all(fb, vec, (sizeof(vec) / sizeof(vec[0]))) ? -1 : nbyte;
841 }
842
843
844 /*
845 * Used to combine the contents of the fb buffer, and a large buffer
846 * passed in.
847 */
large_write(BUFF * fb,const void * buf,int nbyte)848 static int large_write(BUFF *fb, const void *buf, int nbyte)
849 {
850 struct iovec vec[4];
851 int nvec;
852 char chunksize[16];
853
854 /* it's easiest to end the current chunk */
855 if (fb->flags & B_CHUNK) {
856 end_chunk(fb);
857 }
858 nvec = 0;
859 if (fb->outcnt > 0) {
860 vec[nvec].iov_base = (void *) fb->outbase;
861 vec[nvec].iov_len = fb->outcnt;
862 ++nvec;
863 }
864 if (fb->flags & B_CHUNK) {
865 vec[nvec].iov_base = chunksize;
866 vec[nvec].iov_len = snprintf(chunksize, sizeof(chunksize),
867 "%x" CRLF, nbyte);
868 ++nvec;
869 vec[nvec].iov_base = (void *) buf;
870 vec[nvec].iov_len = nbyte;
871 ++nvec;
872 vec[nvec].iov_base = ascii_CRLF;
873 vec[nvec].iov_len = 2;
874 ++nvec;
875 }
876 else {
877 vec[nvec].iov_base = (void *) buf;
878 vec[nvec].iov_len = nbyte;
879 ++nvec;
880 }
881
882 fb->outcnt = 0;
883 if (writev_it_all(fb, vec, nvec)) {
884 return -1;
885 }
886 else if (fb->flags & B_CHUNK) {
887 start_chunk(fb);
888 }
889 return nbyte;
890 }
891
892
893 /*
894 * Write nbyte bytes.
895 * Only returns fewer than nbyte if an error ocurred.
896 * Returns -1 if no bytes were written before the error ocurred.
897 * It is worth noting that if an error occurs, the buffer is in an unknown
898 * state.
899 */
ap_bwrite(BUFF * fb,const void * buf,int nbyte)900 API_EXPORT(int) ap_bwrite(BUFF *fb, const void *buf, int nbyte)
901 {
902 int i, nwr, useable_bufsiz;
903
904 if (fb->flags & (B_WRERR | B_EOUT))
905 return -1;
906 if (nbyte == 0)
907 return 0;
908
909 if (!(fb->flags & B_WR)) {
910 /* unbuffered write -- have to use bcwrite since we aren't taking care
911 * of chunking any other way */
912 return bcwrite(fb, buf, nbyte);
913 }
914
915 /*
916 * Detect case where we're asked to write a large buffer, and combine our
917 * current buffer with it in a single writev(). Note we don't consider
918 * the case nbyte == 1 because modules which use rputc() loops will cause
919 * us to use writev() too frequently. In those cases we really should just
920 * start a new buffer.
921 */
922 if (fb->outcnt > 0 && nbyte > LARGE_WRITE_THRESHOLD
923 && nbyte + fb->outcnt >= fb->bufsiz) {
924 return large_write(fb, buf, nbyte);
925 }
926
927 /*
928 * Whilst there is data in the buffer, keep on adding to it and writing it
929 * out
930 */
931 nwr = 0;
932 while (fb->outcnt > 0) {
933 /* can we accept some data? */
934 i = fb->bufsiz - fb->outcnt;
935 if (i > 0) {
936 if (i > nbyte)
937 i = nbyte;
938 memcpy(fb->outbase + fb->outcnt, buf, i);
939 fb->outcnt += i;
940 nbyte -= i;
941 buf = i + (const char *) buf;
942 nwr += i;
943 if (nbyte == 0)
944 return nwr; /* return if none left */
945 }
946
947 /* the buffer must be full */
948 if (fb->flags & B_CHUNK) {
949 end_chunk(fb);
950 /* it is just too painful to try to re-cram the buffer while
951 * chunking
952 */
953 if (write_it_all(fb, fb->outbase, fb->outcnt) == -1) {
954 /* we cannot continue after a chunked error */
955 return -1;
956 }
957 fb->outcnt = 0;
958 break;
959 }
960 i = write_with_errors(fb, fb->outbase, fb->outcnt);
961 if (i <= 0) {
962 return nwr ? nwr : -1;
963 }
964
965 /* deal with a partial write */
966 if (i < fb->outcnt) {
967 int j, n = fb->outcnt;
968 unsigned char *x = fb->outbase;
969 for (j = i; j < n; j++)
970 x[j - i] = x[j];
971 fb->outcnt -= i;
972 }
973 else
974 fb->outcnt = 0;
975
976 if (fb->flags & B_EOUT)
977 return -1;
978 }
979 /* we have emptied the file buffer. Now try to write the data from the
980 * original buffer until there is less than bufsiz left. Note that we
981 * use bcwrite() to do this for us, it will do the chunking so that
982 * we don't have to dink around building a chunk in our own buffer.
983 *
984 * Note also that bcwrite never does a partial write if we're chunking,
985 * so we're guaranteed to either end in an error state, or make it
986 * out of this loop and call start_chunk() below.
987 *
988 * Remember we may not be able to use the entire buffer if we're
989 * chunking.
990 */
991 useable_bufsiz = fb->bufsiz;
992 if (fb->flags & B_CHUNK) useable_bufsiz -= CHUNK_HEADER_SIZE;
993 while (nbyte >= useable_bufsiz) {
994 i = bcwrite(fb, buf, nbyte);
995 if (i <= 0) {
996 return nwr ? nwr : -1;
997 }
998
999 buf = i + (const char *) buf;
1000 nwr += i;
1001 nbyte -= i;
1002
1003 if (fb->flags & B_EOUT)
1004 return -1;
1005 }
1006 /* copy what's left to the file buffer */
1007 fb->outcnt = 0;
1008 if (fb->flags & B_CHUNK)
1009 start_chunk(fb);
1010 if (nbyte > 0)
1011 memcpy(fb->outbase + fb->outcnt, buf, nbyte);
1012 fb->outcnt += nbyte;
1013 nwr += nbyte;
1014 return nwr;
1015 }
1016
1017
bflush_core(BUFF * fb)1018 static int bflush_core(BUFF *fb)
1019 {
1020 int i;
1021
1022 while (fb->outcnt > 0) {
1023 i = write_with_errors(fb, fb->outbase, fb->outcnt);
1024 if (i <= 0)
1025 return -1;
1026
1027 /*
1028 * We should have written all the data, but if the fd was in a
1029 * strange (non-blocking) mode, then we might not have done so.
1030 */
1031 if (i < fb->outcnt) {
1032 int j, n = fb->outcnt;
1033 unsigned char *x = fb->outbase;
1034 for (j = i; j < n; j++)
1035 x[j - i] = x[j];
1036 }
1037 fb->outcnt -= i;
1038
1039 /* If a soft timeout occurs while flushing, the handler should
1040 * have set the buffer flag B_EOUT.
1041 */
1042 if (fb->flags & B_EOUT)
1043 return -1;
1044 }
1045
1046 return 0;
1047 }
1048
1049 /*
1050 * Flushes the buffered stream.
1051 * Returns 0 on success or -1 on error
1052 */
ap_bflush(BUFF * fb)1053 API_EXPORT(int) ap_bflush(BUFF *fb)
1054 {
1055 int ret;
1056
1057 if ((fb->flags & (B_WRERR | B_EOUT | B_WR)) != B_WR)
1058 return -1;
1059
1060 if (fb->flags & B_CHUNK)
1061 end_chunk(fb);
1062
1063 ret = bflush_core(fb);
1064
1065 if (ret == 0 && (fb->flags & B_CHUNK)) {
1066 start_chunk(fb);
1067 }
1068
1069 return ret;
1070 }
1071
1072 /*
1073 * Flushes and closes the file, even if an error occurred.
1074 * Discards an data that was not read, or not written by bflush()
1075 * Sets the EOF flag to indicate no further data can be read,
1076 * and the EOUT flag to indicate no further data can be written.
1077 */
ap_bclose(BUFF * fb)1078 API_EXPORT(int) ap_bclose(BUFF *fb)
1079 {
1080 int rc1, rc2, rc3;
1081
1082 if (fb->flags & B_WR)
1083 rc1 = ap_bflush(fb);
1084 else
1085 rc1 = 0;
1086 if (fb->flags & B_SOCKET) {
1087 rc2 = ap_pclosesocket(fb->pool, fb->fd);
1088 if (fb->fd_in != fb->fd) {
1089 rc3 = ap_pclosesocket(fb->pool, fb->fd_in);
1090 }
1091 else {
1092 rc3 = 0;
1093 }
1094 } else {
1095 rc2 = ap_pclosef(fb->pool, fb->fd);
1096 if (fb->fd_in != fb->fd) {
1097 rc3 = ap_pclosef(fb->pool, fb->fd_in);
1098 }
1099 else {
1100 rc3 = 0;
1101 }
1102 }
1103
1104 fb->inptr = fb->inbase;
1105 fb->incnt = 0;
1106 fb->outcnt = 0;
1107
1108 fb->flags |= B_EOF | B_EOUT;
1109 fb->fd = -1;
1110 fb->fd_in = -1;
1111
1112 if (rc1 != 0)
1113 return rc1;
1114 else if (rc2 != 0)
1115 return rc2;
1116 else
1117 return rc3;
1118 }
1119
1120 /*
1121 * returns the number of bytes written or -1 on error
1122 */
ap_bputs(const char * x,BUFF * fb)1123 API_EXPORT(int) ap_bputs(const char *x, BUFF *fb)
1124 {
1125 int i, j = strlen(x);
1126 i = ap_bwrite(fb, x, j);
1127 if (i != j)
1128 return -1;
1129 else
1130 return j;
1131 }
1132
1133 /*
1134 * returns the number of bytes written or -1 on error
1135 */
ap_bvputs(BUFF * fb,...)1136 API_EXPORT_NONSTD(int) ap_bvputs(BUFF *fb,...)
1137 {
1138 int i, j, k;
1139 va_list v;
1140 const char *x;
1141
1142 va_start(v, fb);
1143 for (k = 0;;) {
1144 x = va_arg(v, const char *);
1145 if (x == NULL)
1146 break;
1147 j = strlen(x);
1148 i = ap_bwrite(fb, x, j);
1149 if (i != j) {
1150 va_end(v);
1151 return -1;
1152 }
1153 k += i;
1154 }
1155
1156 va_end(v);
1157
1158 return k;
1159 }
1160
ap_bonerror(BUFF * fb,void (* error)(BUFF *,int,void *),void * data)1161 API_EXPORT(void) ap_bonerror(BUFF *fb, void (*error) (BUFF *, int, void *),
1162 void *data)
1163 {
1164 fb->error = error;
1165 fb->error_data = data;
1166 }
1167
1168 struct bprintf_data {
1169 ap_vformatter_buff vbuff;
1170 BUFF *fb;
1171 };
1172
bprintf_flush(ap_vformatter_buff * vbuff)1173 static int bprintf_flush(ap_vformatter_buff *vbuff)
1174 {
1175 struct bprintf_data *b = (struct bprintf_data *)vbuff;
1176 BUFF *fb = b->fb;
1177
1178 fb->outcnt += b->vbuff.curpos - (char *)&fb->outbase[fb->outcnt];
1179 if (fb->outcnt == fb->bufsiz) {
1180 if (ap_bflush(fb)) {
1181 return -1;
1182 }
1183 }
1184 vbuff->curpos = (char *)&fb->outbase[fb->outcnt];
1185 vbuff->endpos = (char *)&fb->outbase[fb->bufsiz];
1186 return 0;
1187 }
1188
ap_bprintf(BUFF * fb,const char * fmt,...)1189 API_EXPORT_NONSTD(int) ap_bprintf(BUFF *fb, const char *fmt, ...)
1190 {
1191 va_list ap;
1192 int res;
1193 struct bprintf_data b;
1194
1195 /* XXX: only works with buffered writes */
1196 if ((fb->flags & (B_WRERR | B_EOUT | B_WR)) != B_WR)
1197 return -1;
1198 b.vbuff.curpos = (char *)&fb->outbase[fb->outcnt];
1199 b.vbuff.endpos = (char *)&fb->outbase[fb->bufsiz];
1200 b.fb = fb;
1201 va_start(ap, fmt);
1202 res = ap_vformatter(bprintf_flush, &b.vbuff, fmt, ap);
1203 va_end(ap);
1204 if (res != -1) {
1205 fb->outcnt += b.vbuff.curpos - (char *)&fb->outbase[fb->outcnt];
1206 }
1207 return res;
1208 }
1209
ap_vbprintf(BUFF * fb,const char * fmt,va_list ap)1210 API_EXPORT(int) ap_vbprintf(BUFF *fb, const char *fmt, va_list ap)
1211 {
1212 struct bprintf_data b;
1213 int res;
1214
1215 /* XXX: only works with buffered writes */
1216 if ((fb->flags & (B_WRERR | B_EOUT | B_WR)) != B_WR)
1217 return -1;
1218 b.vbuff.curpos = (char *)&fb->outbase[fb->outcnt];
1219 b.vbuff.endpos = (char *)&fb->outbase[fb->bufsiz];
1220 b.fb = fb;
1221 res = ap_vformatter(bprintf_flush, &b.vbuff, fmt, ap);
1222 if (res != -1) {
1223 fb->outcnt += b.vbuff.curpos - (char *)&fb->outbase[fb->outcnt];
1224 }
1225 return res;
1226 }
1227