static void gzip1_compress(coa_t coa, __u8 * src_first, size_t src_len, __u8 * dst_first, size_t *dst_len) { int ret = 0; struct z_stream_s stream; assert("edward-842", coa != NULL); assert("edward-875", src_len != 0); stream.workspace = coa; ret = zlib_deflateInit2(&stream, GZIP1_DEF_LEVEL, Z_DEFLATED, -GZIP1_DEF_WINBITS, GZIP1_DEF_MEMLEVEL, Z_DEFAULT_STRATEGY); if (ret != Z_OK) { warning("edward-771", "zlib_deflateInit2 returned %d\n", ret); goto rollback; } ret = zlib_deflateReset(&stream); if (ret != Z_OK) { warning("edward-772", "zlib_deflateReset returned %d\n", ret); goto rollback; } stream.next_in = src_first; stream.avail_in = src_len; stream.next_out = dst_first; stream.avail_out = *dst_len; ret = zlib_deflate(&stream, Z_FINISH); if (ret != Z_STREAM_END) { if (ret != Z_OK) warning("edward-773", "zlib_deflate returned %d\n", ret); goto rollback; } *dst_len = stream.total_out; return; rollback: *dst_len = src_len; return; }
/* * Compresses the source buffer into the destination buffer. The level * parameter has the same meaning as in deflateInit. sourceLen is the byte * length of the source buffer. Upon entry, destLen is the total size of the * destination buffer, which must be at least 0.1% larger than sourceLen plus * 12 bytes. Upon exit, destLen is the actual size of the compressed buffer. * * compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough * memory, Z_BUF_ERROR if there was not enough room in the output buffer, * Z_STREAM_ERROR if the level parameter is invalid. */ int z_compress_level(void *dest, size_t *destLen, const void *source, size_t sourceLen, int level) { z_stream stream; int err; stream.next_in = (Byte *)source; stream.avail_in = (uInt)sourceLen; stream.next_out = dest; stream.avail_out = (uInt)*destLen; if ((size_t)stream.avail_out != *destLen) return Z_BUF_ERROR; stream.workspace = zlib_workspace_alloc(KM_SLEEP); if (!stream.workspace) return Z_MEM_ERROR; err = zlib_deflateInit(&stream, level); if (err != Z_OK) { zlib_workspace_free(stream.workspace); return err; } err = zlib_deflate(&stream, Z_FINISH); if (err != Z_STREAM_END) { zlib_deflateEnd(&stream); zlib_workspace_free(stream.workspace); return err == Z_OK ? Z_BUF_ERROR : err; } *destLen = stream.total_out; err = zlib_deflateEnd(&stream); zlib_workspace_free(stream.workspace); return err; }
static int zlib_compress_update(struct crypto_pcomp *tfm, struct comp_request *req) { int ret; struct zlib_ctx *dctx = crypto_tfm_ctx(crypto_pcomp_tfm(tfm)); struct z_stream_s *stream = &dctx->comp_stream; pr_debug("avail_in %u, avail_out %u\n", req->avail_in, req->avail_out); stream->next_in = req->next_in; stream->avail_in = req->avail_in; stream->next_out = req->next_out; stream->avail_out = req->avail_out; ret = zlib_deflate(stream, Z_NO_FLUSH); switch (ret) { case Z_OK: break; case Z_BUF_ERROR: pr_debug("zlib_deflate could not make progress\n"); return -EAGAIN; default: pr_debug("zlib_deflate failed %d\n", ret); return -EINVAL; } ret = req->avail_out - stream->avail_out; pr_debug("avail_in %u, avail_out %u (consumed %u, produced %u)\n", stream->avail_in, stream->avail_out, req->avail_in - stream->avail_in, ret); req->next_in = stream->next_in; req->avail_in = stream->avail_in; req->next_out = stream->next_out; req->avail_out = stream->avail_out; return ret; }
/** * z_compress - compress a PPP packet with Deflate compression. * @arg: pointer to private state for the compressor * @rptr: uncompressed packet (input) * @obuf: compressed packet (output) * @isize: size of uncompressed packet * @osize: space available at @obuf * * Returns the length of the compressed packet, or 0 if the * packet is incompressible. */ static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf, int isize, int osize) { struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; int r, proto, off, olen, oavail; unsigned char *wptr; /* * Check that the protocol is in the range we handle. */ proto = PPP_PROTOCOL(rptr); if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) return 0; /* Don't generate compressed packets which are larger than the uncompressed packet. */ if (osize > isize) osize = isize; wptr = obuf; /* * Copy over the PPP header and store the 2-byte sequence number. */ wptr[0] = PPP_ADDRESS(rptr); wptr[1] = PPP_CONTROL(rptr); wptr[2] = PPP_COMP >> 8; wptr[3] = PPP_COMP; wptr += PPP_HDRLEN; wptr[0] = state->seqno >> 8; wptr[1] = state->seqno; wptr += DEFLATE_OVHD; olen = PPP_HDRLEN + DEFLATE_OVHD; state->strm.next_out = wptr; state->strm.avail_out = oavail = osize - olen; ++state->seqno; off = (proto > 0xff) ? 2 : 3; /* skip 1st proto byte if 0 */ rptr += off; state->strm.next_in = rptr; state->strm.avail_in = (isize - off); for (;;) { r = zlib_deflate(&state->strm, Z_PACKET_FLUSH); if (r != Z_OK) { if (state->debug) printk(KERN_ERR "z_compress: deflate returned %d\n", r); break; } if (state->strm.avail_out == 0) { olen += oavail; state->strm.next_out = NULL; state->strm.avail_out = oavail = 1000000; } else { break; /* all done */ } } olen += oavail - state->strm.avail_out; /* * See if we managed to reduce the size of the packet. */ if (olen < isize) { state->stats.comp_bytes += olen; state->stats.comp_packets++; } else { state->stats.inc_bytes += isize; state->stats.inc_packets++; olen = 0; } state->stats.unc_bytes += isize; state->stats.unc_packets++; return olen; }
CAMLprim value zlib_deflate_bytecode(value *arg, int nargs) { return zlib_deflate(arg[0], arg[1], arg[2], arg[3], arg[4], arg[5], arg[6], arg[7]); }
static int write_zip_entry(struct archiver_args *args, const unsigned char *sha1, const char *path, size_t pathlen, unsigned int mode, int big_file_threshold, int zip_dir_size, int zip_dir_offset, int zip_dir, int zip_time, int zip_date, int zip_offset, int zip_dir_entries) { struct zip_local_header header; struct zip_dir_header dirent; struct zip_extra_mtime extra; unsigned long attr2 = 0; unsigned long compressed_size = 0; unsigned long crc = 0; unsigned long direntsize = 0; int method = 0; int out = 0; int deflated = 0; int buffer = 0; int stream = 0; unsigned long flags = 0; unsigned long size = 0; crc = crc32(0, NULL, 0); if (!has_only_ascii(path)) { if (is_utf8(path)) flags |= ZIP_UTF8; else warning("Path is not valid UTF-8: %s", path); } if (pathlen > 0xffff) { return error("path too long (%d chars, SHA1: %s): %s", (int)pathlen, sha1_to_hex(sha1), path); } if (S_ISDIR(mode) || S_ISGITLINK(mode)) { method = 0; attr2 = 16; out = NULL; size = 0; compressed_size = 0; buffer = NULL; } else if (S_ISREG(mode) || S_ISLNK(mode)) { int type = sha1_object_info(sha1, &size); method = 0; attr2 = S_ISLNK(mode) ? ((mode | 0777) << 16) : (mode & 0111) ? ((mode) << 16) : 0; if (S_ISREG(mode) && args->compression_level != 0 && size > 0) method = 8; if (method == 0) { compressed_size = size; } else { compressed_size = 0; } if (S_ISREG(mode) && type == OBJ_BLOB && !args->convert && size > big_file_threshold) { stream = open_istream(sha1, &type, &size, NULL); if (!stream) return error("cannot stream blob %s", sha1_to_hex(sha1)); flags |= ZIP_STREAM; out = buffer = NULL; } else { buffer = sha1_file_to_archive(args, path, sha1, mode, &type, &size); if (!buffer) return error("cannot read %s", sha1_to_hex(sha1)); crc = crc32(crc, buffer, size); out = buffer; } } else { return error("unsupported file mode: 0%o (SHA1: %s)", mode, sha1_to_hex(sha1)); } if (buffer && method == 8) { deflated = zlib_deflate(buffer, size, args->compression_level, &compressed_size); if (deflated && compressed_size - 6 < size) { /* ZLIB --> raw compressed data (see RFC 1950) */ /* CMF and FLG ... */ out = deflated + 2; compressed_size -= 6; /* ... and ADLER32 */ } else { method = 0; compressed_size = size; } } copy_le16(extra.magic, 0x5455); copy_le16(extra.extra_size, ZIP_EXTRA_MTIME_PAYLOAD_SIZE); extra.flags[0] = 1; /* just mtime */ copy_le32(extra.mtime, args->time); /* make sure we have enough free space in the dictionary */ direntsize = ZIP_DIR_HEADER_SIZE + pathlen + ZIP_EXTRA_MTIME_SIZE; while (zip_dir_size < zip_dir_offset + direntsize) { zip_dir_size += ZIP_DIRECTORY_MIN_SIZE; zip_dir = xrealloc(zip_dir, zip_dir_size); } copy_le32(dirent.magic, 0x02014b50); copy_le16(dirent.creator_version, S_ISLNK(mode) || (S_ISREG(mode) && (mode & 0111)) ? 0x0317 : 0); copy_le16(dirent.version, 10); copy_le16(dirent.flags, flags); copy_le16(dirent.compression_method, method); copy_le16(dirent.mtime, zip_time); copy_le16(dirent.mdate, zip_date); set_zip_dir_data_desc(&dirent, size, compressed_size, crc); copy_le16(dirent.filename_length, pathlen); copy_le16(dirent.extra_length, ZIP_EXTRA_MTIME_SIZE); copy_le16(dirent.comment_length, 0); copy_le16(dirent.disk, 0); copy_le16(dirent.attr1, 0); copy_le32(dirent.attr2, attr2); copy_le32(dirent.offset, zip_offset); copy_le32(header.magic, 0x04034b50); copy_le16(header.version, 10); copy_le16(header.flags, flags); copy_le16(header.compression_method, method); copy_le16(header.mtime, zip_time); copy_le16(header.mdate, zip_date); set_zip_header_data_desc(&header, size, compressed_size, crc); copy_le16(header.filename_length, pathlen); copy_le16(header.extra_length, ZIP_EXTRA_MTIME_SIZE); write_or_die(1, &header, ZIP_LOCAL_HEADER_SIZE); zip_offset += ZIP_LOCAL_HEADER_SIZE; write_or_die(1, path, pathlen); zip_offset += pathlen; write_or_die(1, &extra, ZIP_EXTRA_MTIME_SIZE); zip_offset += ZIP_EXTRA_MTIME_SIZE; if (stream && method == 0) { unsigned char buf[STREAM_BUFFER_SIZE]; ssize_t readlen = 0; for (;;) { readlen = read_istream(stream, buf, sizeof(buf)); if (readlen <= 0) break; crc = crc32(crc, buf, readlen); write_or_die(1, buf, readlen); } close_istream(stream); if (readlen) return readlen; compressed_size = size; zip_offset += compressed_size; write_zip_data_desc(size, compressed_size, crc); zip_offset += ZIP_DATA_DESC_SIZE; set_zip_dir_data_desc(&dirent, size, compressed_size, crc); } else if (stream && method == 8) { int buf; ssize_t readlen; git_zstream zstream; int result; size_t out_len; int compressed; memset(&zstream, 0, sizeof(zstream)); git_deflate_init(&zstream, args->compression_level); compressed_size = 0; zstream.next_out = compressed; zstream.avail_out = sizeof(compressed); for (;;) { readlen = read_istream(stream, buf, sizeof(buf)); if (readlen <= 0) break; crc = crc32(crc, buf, readlen); zstream.next_in = buf; zstream.avail_in = readlen; result = git_deflate(&zstream, 0); if (result != Z_OK) die("deflate error (%d)", result); out = compressed; if (!compressed_size) out += 2; out_len = zstream.next_out - out; if (out_len > 0) { write_or_die(1, out, out_len); compressed_size += out_len; zstream.next_out = compressed; zstream.avail_out = sizeof(compressed); } } close_istream(stream); if (readlen) return readlen; zstream.next_in = buf; zstream.avail_in = 0; result = git_deflate(&zstream, Z_FINISH); if (result != Z_STREAM_END) die("deflate error (%d)", result); git_deflate_end(&zstream); out = compressed; if (!compressed_size) out += 2; out_len = zstream.next_out - out - 4; write_or_die(1, out, out_len); compressed_size += out_len; zip_offset += compressed_size; write_zip_data_desc(size, compressed_size, crc); zip_offset += ZIP_DATA_DESC_SIZE; set_zip_dir_data_desc(&dirent, size, compressed_size, crc); } else if (compressed_size > 0) { write_or_die(1, out, compressed_size); zip_offset += compressed_size; } free(deflated); free(buffer); memcpy(zip_dir + zip_dir_offset, &dirent, ZIP_DIR_HEADER_SIZE); zip_dir_offset += ZIP_DIR_HEADER_SIZE; memcpy(zip_dir + zip_dir_offset, path, pathlen); zip_dir_offset += pathlen; memcpy(zip_dir + zip_dir_offset, &extra, ZIP_EXTRA_MTIME_SIZE); zip_dir_offset += ZIP_EXTRA_MTIME_SIZE; zip_dir_entries++; return 0; }
static int _compress(FILE *in, FILE *out, int level, int method, int threshold){ //align not supported yet... CISO_H header; memset(&header,0,sizeof(header)); memcpy(header.magic,"CISO",4); header.header_size=sizeof(header); header.total_bytes=filelengthi64(fileno(in)); header.block_size=2048; header.ver=1; header.align=0; long long total_block=align2p(header.block_size,header.total_bytes)/header.block_size; memset(buf,0,4*(total_block+1)); fwrite(&header,1,sizeof(header),out); fwrite(buf,1,4*(total_block+1),out); void* coder=NULL; lzmaCreateCoder(&coder,0x040108,1,level); long long i=0; for(;i<total_block;i++){ write32(buf+4*i,ftell(out)); size_t readlen=fread(__decompbuf,1,header.block_size,in); size_t compsize=COMPBUFLEN; if(method==DEFLATE_ZLIB){ int r=zlib_deflate(__compbuf,&compsize,__decompbuf,readlen,level); if(r){ fprintf(stderr,"deflate %d\n",r); return 1; } } if(method==DEFLATE_7ZIP){ if(coder){ int r=lzmaCodeOneshot(coder,__decompbuf,readlen,__compbuf,&compsize); if(r){ fprintf(stderr,"NDeflate::CCoder::Code %d\n",r); return 1; } } } if(method==DEFLATE_ZOPFLI){ int r=zopfli_deflate(__compbuf,&compsize,__decompbuf,readlen,level); if(r){ fprintf(stderr,"zopfli_deflate %d\n",r); return 1; } } if(method==DEFLATE_MINIZ){ int r=miniz_deflate(__compbuf,&compsize,__decompbuf,readlen,level); if(r){ fprintf(stderr,"miniz_deflate %d\n",r); return 1; } } if(method==DEFLATE_SLZ){ int r=slz_deflate(__compbuf,&compsize,__decompbuf,readlen,level); if(r){ fprintf(stderr,"slz_deflate %d\n",r); return 1; } } if(method==DEFLATE_LIBDEFLATE){ int r=libdeflate_deflate(__compbuf,&compsize,__decompbuf,readlen,level); if(r){ fprintf(stderr,"libdeflate_deflate %d\n",r); return 1; } } if(compsize>header.block_size*threshold/100){ //store fwrite(__decompbuf,1,readlen,out); write32(buf+4*i,0x80000000|read32(buf+4*i)); }else{ fwrite(__compbuf,1,compsize,out); } if((i+1)%256==0)fprintf(stderr,"%"LLD" / %"LLD"\r",i+1,total_block); } write32(buf+4*i,ftell(out)); fseek(out,sizeof(header),SEEK_SET); fwrite(buf,1,4*(total_block+1),out); fprintf(stderr,"%"LLD" / %"LLD" done.\n",i,total_block); lzmaDestroyCoder(&coder); return 0; }
static int z_compress(void *arg, unsigned char *rptr, unsigned char *obuf, int isize, int osize) { struct ppp_deflate_state *state = (struct ppp_deflate_state *) arg; int r, proto, off, olen, oavail; unsigned char *wptr; /* */ proto = PPP_PROTOCOL(rptr); if (proto > 0x3fff || proto == 0xfd || proto == 0xfb) return 0; /* */ if (osize > isize) osize = isize; wptr = obuf; /* */ wptr[0] = PPP_ADDRESS(rptr); wptr[1] = PPP_CONTROL(rptr); put_unaligned_be16(PPP_COMP, wptr + 2); wptr += PPP_HDRLEN; put_unaligned_be16(state->seqno, wptr); wptr += DEFLATE_OVHD; olen = PPP_HDRLEN + DEFLATE_OVHD; state->strm.next_out = wptr; state->strm.avail_out = oavail = osize - olen; ++state->seqno; off = (proto > 0xff) ? 2 : 3; /* */ rptr += off; state->strm.next_in = rptr; state->strm.avail_in = (isize - off); for (;;) { r = zlib_deflate(&state->strm, Z_PACKET_FLUSH); if (r != Z_OK) { if (state->debug) printk(KERN_ERR "z_compress: deflate returned %d\n", r); break; } if (state->strm.avail_out == 0) { olen += oavail; state->strm.next_out = NULL; state->strm.avail_out = oavail = 1000000; } else { break; /* */ } } olen += oavail - state->strm.avail_out; /* */ if (olen < isize) { state->stats.comp_bytes += olen; state->stats.comp_packets++; } else { state->stats.inc_bytes += isize; state->stats.inc_packets++; olen = 0; } state->stats.unc_bytes += isize; state->stats.unc_packets++; return olen; }
bool kzip_add_file(struct kzip_file *zfile, const struct kzip_memlist *memlist, const char *zfilename) { int ret, flush; z_stream strm; struct aee_timer zip_time; if (zfile->entries_num >= KZIP_ENTRY_MAX) { voprintf_error("Too manry zip entry %d\n", zfile->entries_num); return false; } voprintf_debug("%s: zf %p(%p) %s\n", __func__, zfile, zfile->write_cb, zfilename); struct kzip_entry *zentry = &zfile->zentries[zfile->entries_num++]; zentry->filename = strdup(zfilename); zentry->localheader_offset = zfile->current_size; zentry->level = DEF_MEM_LEVEL; KZIP_DEBUG("%s: write local header\n", __func__); uint8_t zip_localheader[128]; int hsize = put_localheader(zip_localheader, zfilename, DEF_MEM_LEVEL); if (kzip_write_current(zfile, zip_localheader, hsize) != hsize) { return false; } KZIP_DEBUG("%s: init compressor\n", __func__); /* allocate deflate state */ strm.workspace = malloc(zlib_deflate_workspacesize(-MAX_WBITS, DEF_MEM_LEVEL)); ret = zlib_deflateInit2(&strm, zentry->level, Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY); if (ret != Z_OK) { voprintf_error("zlib compress init failed\n"); free(strm.workspace); return false; } uint8_t *out = malloc(CHUNK); aee_timer_init(&zip_time); aee_timer_start(&zip_time); /* compress until end of file */ do { flush = (memlist->size == 0) ? Z_FINISH : Z_NO_FLUSH; KZIP_DEBUG("-- Compress memory %x, size %d\n", memlist->address, memlist->size); strm.avail_in = memlist->size; strm.next_in = memlist->address; /* run deflate() on input until output buffer not full, finish compression if all of source has been read in */ do { strm.avail_out = CHUNK; strm.next_out = out; ret = zlib_deflate(&strm, flush); /* no bad return value */ assert(ret != Z_STREAM_ERROR); /* state not clobbered */ int have = CHUNK - strm.avail_out; if (have > 0) { aee_timer_stop(&zip_time); if (kzip_write_current(zfile, out, have) != have) { goto error; } aee_timer_start(&zip_time); } } while (strm.avail_out == 0); assert(strm.avail_in == 0); /* all input will be used */ memlist++; /* done when last data in file processed */ } while (flush != Z_FINISH); assert(ret == Z_STREAM_END); /* stream will be complete */ /* clean up and return */ (void)zlib_deflateEnd(&strm); free(strm.workspace); free(out); aee_timer_stop(&zip_time); voprintf_info("Zip time: %d sec\n", zip_time.acc_ms / 1000); zentry->comp_size = strm.total_out; zentry->uncomp_size = strm.total_in; zentry->crc32 = strm.crc32 ^ 0xffffffffUL; return true; error: free(strm.workspace); free(out); (void)zlib_deflateEnd(&strm); return false; }
static ErlDrvSSizeT zlib_ctl(ErlDrvData drv_data, unsigned int command, char *buf, ErlDrvSizeT len, char **rbuf, ErlDrvSizeT rlen) { ZLibData* d = (ZLibData*)drv_data; int res; switch(command) { case DEFLATE_INIT: if (len != 4) goto badarg; if (d->state != ST_NONE) goto badarg; res = deflateInit(&d->s, i32(buf)); if (res == Z_OK) { d->state = ST_DEFLATE; d->want_crc = 0; d->crc = crc32(0L, Z_NULL, 0); } return zlib_return(res, rbuf, rlen); case DEFLATE_INIT2: { int wbits; if (len != 20) goto badarg; if (d->state != ST_NONE) goto badarg; wbits = i32(buf+8); res = deflateInit2(&d->s, i32(buf), i32(buf+4), wbits, i32(buf+12), i32(buf+16)); if (res == Z_OK) { d->state = ST_DEFLATE; d->want_crc = (wbits < 0); d->crc = crc32(0L, Z_NULL, 0); } return zlib_return(res, rbuf, rlen); } case DEFLATE_SETDICT: if (d->state != ST_DEFLATE) goto badarg; res = deflateSetDictionary(&d->s, (unsigned char*)buf, len); if (res == Z_OK) { return zlib_value(d->s.adler, rbuf, rlen); } else { return zlib_return(res, rbuf, rlen); } case DEFLATE_RESET: if (len != 0) goto badarg; if (d->state != ST_DEFLATE) goto badarg; driver_deq(d->port, driver_sizeq(d->port)); res = deflateReset(&d->s); return zlib_return(res, rbuf, rlen); case DEFLATE_END: if (len != 0) goto badarg; if (d->state != ST_DEFLATE) goto badarg; driver_deq(d->port, driver_sizeq(d->port)); res = deflateEnd(&d->s); d->state = ST_NONE; return zlib_return(res, rbuf, rlen); case DEFLATE_PARAMS: if (len != 8) goto badarg; if (d->state != ST_DEFLATE) goto badarg; res = deflateParams(&d->s, i32(buf), i32(buf+4)); return zlib_return(res, rbuf, rlen); case DEFLATE: if (d->state != ST_DEFLATE) goto badarg; if (len != 4) goto badarg; res = zlib_deflate(d, i32(buf)); return zlib_return(res, rbuf, rlen); case INFLATE_INIT: if (len != 0) goto badarg; if (d->state != ST_NONE) goto badarg; res = inflateInit(&d->s); if (res == Z_OK) { d->state = ST_INFLATE; d->inflate_eos_seen = 0; d->want_crc = 0; d->crc = crc32(0L, Z_NULL, 0); } return zlib_return(res, rbuf, rlen); case INFLATE_INIT2: { int wbits; if (len != 4) goto badarg; if (d->state != ST_NONE) goto badarg; wbits = i32(buf); res = inflateInit2(&d->s, wbits); if (res == Z_OK) { d->state = ST_INFLATE; d->inflate_eos_seen = 0; d->want_crc = (wbits < 0); d->crc = crc32(0L, Z_NULL, 0); } return zlib_return(res, rbuf, rlen); } case INFLATE_SETDICT: if (d->state != ST_INFLATE) goto badarg; res = inflateSetDictionary(&d->s, (unsigned char*)buf, len); return zlib_return(res, rbuf, rlen); case INFLATE_SYNC: if (d->state != ST_INFLATE) goto badarg; if (len != 0) goto badarg; if (driver_sizeq(d->port) == 0) { res = Z_BUF_ERROR; } else { int vlen; SysIOVec* iov = driver_peekq(d->port, &vlen); d->s.next_in = iov[0].iov_base; d->s.avail_in = iov[0].iov_len; res = inflateSync(&d->s); } return zlib_return(res, rbuf, rlen); case INFLATE_RESET: if (d->state != ST_INFLATE) goto badarg; if (len != 0) goto badarg; driver_deq(d->port, driver_sizeq(d->port)); res = inflateReset(&d->s); d->inflate_eos_seen = 0; return zlib_return(res, rbuf, rlen); case INFLATE_END: if (d->state != ST_INFLATE) goto badarg; if (len != 0) goto badarg; driver_deq(d->port, driver_sizeq(d->port)); res = inflateEnd(&d->s); if (res == Z_OK && d->inflate_eos_seen == 0) { res = Z_DATA_ERROR; } d->state = ST_NONE; return zlib_return(res, rbuf, rlen); case INFLATE: if (d->state != ST_INFLATE) goto badarg; if (len != 4) goto badarg; res = zlib_inflate(d, i32(buf)); if (res == Z_NEED_DICT) { return zlib_value2(3, d->s.adler, rbuf, rlen); } else { return zlib_return(res, rbuf, rlen); } case GET_QSIZE: return zlib_value(driver_sizeq(d->port), rbuf, rlen); case GET_BUFSZ: return zlib_value(d->binsz_need, rbuf, rlen); case SET_BUFSZ: { int need; if (len != 4) goto badarg; need = i32(buf); if ((need < 16) || (need > 0x00ffffff)) goto badarg; if (d->binsz_need != need) { d->binsz_need = need; if (d->bin != NULL) { if (d->s.avail_out == d->binsz) { driver_free_binary(d->bin); d->bin = NULL; d->binsz = 0; } else zlib_output(d); } } return zlib_return(Z_OK, rbuf, rlen); } case CRC32_0: return zlib_value(d->crc, rbuf, rlen); case CRC32_1: { uLong crc = crc32(0L, Z_NULL, 0); crc = crc32(crc, (unsigned char*) buf, len); return zlib_value(crc, rbuf, rlen); } case CRC32_2: { uLong crc; if (len < 4) goto badarg; crc = (unsigned int) i32(buf); crc = crc32(crc, (unsigned char*) buf+4, len-4); return zlib_value(crc, rbuf, rlen); } case ADLER32_1: { uLong adler = adler32(0L, Z_NULL, 0); adler = adler32(adler, (unsigned char*) buf, len); return zlib_value(adler, rbuf, rlen); } case ADLER32_2: { uLong adler; if (len < 4) goto badarg; adler = (unsigned int) i32(buf); adler = adler32(adler, (unsigned char*) buf+4, len-4); return zlib_value(adler, rbuf, rlen); } case CRC32_COMBINE: { uLong crc, crc1, crc2, len2; if (len != 12) goto badarg; crc1 = (unsigned int) i32(buf); crc2 = (unsigned int) i32(buf+4); len2 = (unsigned int) i32(buf+8); crc = crc32_combine(crc1, crc2, len2); return zlib_value(crc, rbuf, rlen); } case ADLER32_COMBINE: { uLong adler, adler1, adler2, len2; if (len != 12) goto badarg; adler1 = (unsigned int) i32(buf); adler2 = (unsigned int) i32(buf+4); len2 = (unsigned int) i32(buf+8); adler = adler32_combine(adler1, adler2, len2); return zlib_value(adler, rbuf, rlen); } } badarg: errno = EINVAL; return zlib_return(Z_ERRNO, rbuf, rlen); }
HttpMessage RequestHandler :: handleRequest( HttpMessage& request ){ HttpMessage response; std::string body, path, ckey; handler_function func = NULL; size_t pattern_length = 0; uint64_t cache_key; std::unordered_map<uint64_t, CachedEntry>::iterator cache_it; path = request.get_path(); response.set_version( "HTTP/1.1" ); response.set_header_field( "Server", SERVER_VERSION ); response.set_header_field( "Content-Type", "text/html" ); response.set_header_field( "Date", get_gmt_time(0) ); /* ckey = request.get_method() + ":" + path; cache_key = fnv1a_hash( ckey ); */ cache_key = compute_hash( request ); pthread_rwlock_rdlock( &RequestHandler::cache_lock ); cache_it = cache.find( cache_key ); if( cache_it != cache.end() ){ if( (cache_it->second).is_valid() ){ pthread_rwlock_unlock( &RequestHandler::cache_lock ); //std::cerr << "Found @ cache" << std::endl; return (cache_it->second).get_content(); } } pthread_rwlock_unlock( &RequestHandler::cache_lock ); for( std::map< std::string, handler_function >::iterator it = handlers.begin() ; it != handlers.end() ; it++ ){ if( string_startswith( it->first, path ) ){ if( (it->first).size() > pattern_length ){ pattern_length = (it->first).size(); func = it->second; } } } if( func == NULL ){ response.set_code( 404 ); response.set_code_string( "Not found." ); response.set_version( "HTTP/1.1" ); response.set_header_field( "Connection", "close" ); response.set_header_field( "Date", get_gmt_time(0) ); response.set_header_field( "Server", SERVER_VERSION ); response.set_header_field( "Last-Modified", get_gmt_time(0) ); response.set_header_field( "Content-Type", "text/plain" ); response.set_body( "Error 404 - Not found!\n" ); } else{ response_options_t result; try{ result = func( request, response ); } catch( std::string error ){ response.set_code( 500 ); response.set_code_string( "Internal server error." ); } if( !result.ok ){ response.set_code( 404 ); response.set_code_string( "Not found." ); response.set_version( "HTTP/1.1" ); response.set_header_field( "Connection", "close" ); response.set_header_field( "Date", get_gmt_time(0) ); response.set_header_field( "Server", SERVER_VERSION ); response.set_header_field( "Last-Modified", get_gmt_time(0) ); response.set_header_field( "Content-Type", "text/plain" ); response.set_body( "Error 404 - Not found!\n" ); } else{ if( request.has_header_field( "Accept-Encoding" ) ){ if( request.get_header_field( "Accept-Encoding" ).find( "gzip" ) != std::string::npos ){ response.set_body( zlib_gzip_deflate( response.get_body() ) ); response.set_header_field( "Content-Encoding", "gzip" ); } else{ if( request.get_header_field( "Accept-Encoding" ).find( "deflate" ) != std::string::npos ){ response.set_body( zlib_deflate( response.get_body() ) ); response.set_header_field( "Content-Encoding", "deflate" ); } } } if( result.cached ){ add_cache( cache_key, response, result.expires ); } } } return response; }