Example #1
0
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;
}
Example #2
0
/*
 * 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;
}
Example #3
0
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;
}
Example #4
0
/**
 *	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;
}
Example #5
0
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]);
}
Example #6
0
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;
}
Example #7
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;
}
Example #9
0
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;
}
Example #10
0
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);
}
Example #11
0
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;
	}