CVS update: php31/main

From: Date: Sun, 08 Nov 1998 02:43:36 +0000
Subject: CVS update: php31/main
Groups: php.dev 
Request: Send a blank email to php-dev+get-2280@lists.php.net to get a copy of this message
Date: Saturday November 7, 1998 @ 21:43 Author: cschneid Update of /repository/php31/main In directory asf:/u2/tmp/cvs-serv18111/main Modified Files: main.c Log Message: Added on the fly output compression. It requires zlib support and includes configure option --disable-output-compression and php31.ini option compress_output=yes|no Output is sent compressed with Content-encoding: gzip if browser sent Accept-encoding: *gzip* before. All code related to output compression is enclosed in #if PHP3_COMPRESS_OUTPUT set by configure. Index: php31/main/main.c diff -c php31/main/main.c:2.47 php31/main/main.c:2.48 *** php31/main/main.c:2.47 Thu Nov 5 16:45:10 1998 --- php31/main/main.c Sat Nov 7 21:43:35 1998 *************** *** 29,35 **** +----------------------------------------------------------------------+ */ ! /* $Id: main.c,v 2.47 1998/11/05 21:45:10 cschneid Exp $ */ /* #define CRASH_DETECTION */ --- 29,35 ---- +----------------------------------------------------------------------+ */ ! /* $Id: main.c,v 2.48 1998/11/08 02:43:35 cschneid Exp $ */ /* #define CRASH_DETECTION */ *************** *** 137,142 **** --- 137,334 ---- static void php3_set_timeout(long seconds INLINE_TLS); extern void php3_treat_headers(INLINE_TLS_VOID); + #if PHP3_COMPRESS_OUTPUT + static voidpf compress_output_zalloc(voidpf opaque, uInt items, uInt size) + { + return emalloc(items * size); + } + + static void compress_output_zfree(voidpf opaque, voidpf address) + { + efree(address); + } + + static void compress_output_putlong (struct sapi_request_info *sapi_info, uLong x) + { + unsigned char buf[4]; + + buf[0] = x & 0xff; + buf[1] = (x >> 8) & 0xff; + buf[2] = (x >> 16) & 0xff; + buf[3] = (x >> 24) & 0xff; + + sapi_info->savedwriteclient(buf, sizeof(buf) _INLINE_TLS); + } + + static int compress_output_writeclient(SAPI_GLOBAL_INCLUDE unsigned char *buf, int size) + { + int written; + + int zerr = Z_OK; + + GLOBAL(sapi_rqst)->zstream.next_in = (Bytef*)buf; + GLOBAL(sapi_rqst)->zstream.avail_in = size; + + /* Basic compression loop adapted from gzwrite in zlib gzio.c */ + while (GLOBAL(sapi_rqst)->zstream.avail_in > 0) { + if (GLOBAL(sapi_rqst)->zstream.avail_out == 0) { + GLOBAL(sapi_rqst)->zstream.next_out = GLOBAL(sapi_rqst)->zoutbuf; + + if (GLOBAL(sapi_rqst)->savedwriteclient(SAPI_GLOBAL_PASS GLOBAL(sapi_rqst)->zoutbuf, ZOUTBUF_SIZE) != ZOUTBUF_SIZE) { + zerr = Z_ERRNO; + break; + } + + GLOBAL(sapi_rqst)->zstream.avail_out = ZOUTBUF_SIZE; + } + + zerr = deflate(&GLOBAL(sapi_rqst)->zstream, Z_NO_FLUSH); + + if (zerr != Z_OK) + break; + } + + GLOBAL(sapi_rqst)->zcrc = crc32(GLOBAL(sapi_rqst)->zcrc, (const Bytef *)buf, size); + + written = (zerr == Z_OK) ? size : -1; + + return written; + } + + static int compress_output_flush(SAPI_GLOBAL_INCLUDE_V) + { + uInt len; + int done = 0; + int zerr = Z_OK; + + /* Flush loop adapted from do_flush in zlib gzio.c */ + for (;;) { + len = ZOUTBUF_SIZE - GLOBAL(sapi_rqst)->zstream.avail_out; + + if (len != 0) { + if (GLOBAL(sapi_rqst)->savedwriteclient(SAPI_GLOBAL_PASS GLOBAL(sapi_rqst)->zoutbuf, len _INLINE_TLS) != len) { + zerr = Z_ERRNO; + break; + } + GLOBAL(sapi_rqst)->zstream.next_out = GLOBAL(sapi_rqst)->zoutbuf; + GLOBAL(sapi_rqst)->zstream.avail_out = ZOUTBUF_SIZE; + } + + if (done) + break; + + zerr = deflate(&GLOBAL(sapi_rqst)->zstream, Z_SYNC_FLUSH); + + /* deflate has finished flushing only when it used all input: + */ + done = (GLOBAL(sapi_rqst)->zstream.avail_in == 0); + + if (zerr != Z_OK) + break; + } + + return GLOBAL(sapi_rqst)->savedflush(SAPI_GLOBAL_PASS_V); + } + + static void compress_output_init(struct sapi_request_info *sapi_info) + { + /* Protect against being called twice on same sapi_info */ + if (sapi_info && (sapi_info->writeclient != compress_output_writeclient)) { + long compress_output; + + sapi_info->savedwriteclient = NULL; + sapi_info->savedflush = NULL; + + if ((ini_get_long("compress_output", &compress_output) != FAILURE) && (compress_output)) { + char *s = sapi_info->getenv("HTTP_ACCEPT_ENCODING"); + + if (s && strstr(s, "gzip")) { + sapi_info->zoutbuf = emalloc(ZOUTBUF_SIZE); + + if (sapi_info->zoutbuf) { + sapi_info->zstream.zalloc = compress_output_zalloc; + sapi_info->zstream.zfree = compress_output_zfree; + sapi_info->zstream.opaque = Z_NULL; + + /* windowBits < 0 to suppress zlib header if gzip mode */ + if (deflateInit2(&(sapi_info->zstream), Z_DEFAULT_COMPRESSION, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY) == Z_OK) { + /* Prefill output buffer with gzip file header */ + static Bytef gz_header[] = { 0x1f, 0x8b, Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE }; + + sapi_info->zstream.next_out = sapi_info->zoutbuf; + sapi_info->zstream.avail_out = ZOUTBUF_SIZE; + + memcpy(sapi_info->zoutbuf, gz_header, sizeof(gz_header)); + sapi_info->zstream.next_out += sizeof(gz_header); + sapi_info->zstream.avail_out -= sizeof(gz_header); + sapi_info->zcrc = 0; + sapi_info->insert_header("Content-encoding: gzip"); + + /* Wedge into output functions */ + sapi_info->savedwriteclient = sapi_info->writeclient; + sapi_info->writeclient = compress_output_writeclient; + sapi_info->savedflush = sapi_info->flush; + sapi_info->flush = compress_output_flush; + } + } + } + } + } + } + + static void compress_output_exit(struct sapi_request_info *sapi_info) + { + if (sapi_info && sapi_info->savedwriteclient) { + uInt len; + int done = 0; + int zerr = Z_OK; + + /* Flush loop adapted from do_flush in zlib gzio.c */ + for (;;) { + len = ZOUTBUF_SIZE - sapi_info->zstream.avail_out; + + if (len != 0) { + if (sapi_info->savedwriteclient(SAPI_GLOBAL_PASS sapi_info->zoutbuf, len _INLINE_TLS) != len) { + zerr = Z_ERRNO; + break; + } + sapi_info->zstream.next_out = sapi_info->zoutbuf; + sapi_info->zstream.avail_out = ZOUTBUF_SIZE; + } + + if (done) + break; + + zerr = deflate(&sapi_info->zstream, Z_FINISH); + + /* deflate has finished flushing only when it hasn't used up + * all the available space in the output buffer: + */ + done = (sapi_info->zstream.avail_out != 0 || zerr == Z_STREAM_END); + + if (zerr != Z_OK && zerr != Z_STREAM_END) + break; + } + + compress_output_putlong(sapi_info, sapi_info->zcrc); + compress_output_putlong(sapi_info, sapi_info->zstream.total_in); + } + + if (sapi_info->zoutbuf) { + efree(sapi_info->zoutbuf); + sapi_info->zoutbuf = NULL; + } + + if (sapi_info->savedwriteclient) { + deflateEnd(&sapi_info->zstream); + + /* Undo wedge into output functions */ + sapi_info->writeclient = sapi_info->savedwriteclient; + sapi_info->flush = sapi_info->savedflush; + } + } + #endif + #if defined(CRASH_DETECTION) /* * function to log debug messages *************** *** 247,252 **** --- 439,445 ---- PHPAPI int php3_sapi_writeclient(void *buf, int size INLINE_TLS) { int ret; + if (GLOBAL(sapi_rqst)->buffered_output) { string_buffer_concat(&GLOBAL(sapi_rqst)->output_buffer, buf, size); return size; *************** *** 1516,1521 **** --- 1709,1718 ---- } php3_treat_headers(_INLINE_TLS_VOID); + #if PHP3_COMPRESS_OUTPUT + compress_output_init(sapi_info); + #endif + #if defined(CRASH_DETECTION) debug_log("%d:request startup success\n", GetCurrentThreadId()); #endif *************** *** 1655,1660 **** --- 1852,1860 ---- debug_log("%d:start request shutdown\n", GetCurrentThreadId()); #endif php3_header(); /* Make sure headers have been sent */ + #if PHP3_COMPRESS_OUTPUT + compress_output_exit(sapi_info); + #endif php3_request_shutdown((void *) GLOBAL(sapi_rqst) _INLINE_TLS); #if defined(CRASH_DETECTION) debug_log("%d:request shutdown done\n", GetCurrentThreadId()); -- PHP Development Mailing List http://www.php.net/ To unsubscribe send an empty message to php-dev-unsubscribe@lists.php.net For help: php-dev-help@lists.php.net

« previous php.dev (#2280) next »