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