allow copress body with zlib

This commit is contained in:
lxsang 2020-01-08 22:04:10 +01:00
parent 4608ae874f
commit 189120bd88
3 changed files with 63 additions and 72 deletions

View File

@ -691,6 +691,7 @@ void *serve_file(void *data)
rhd.status = 200; rhd.status = 200;
rhd.header = dict(); rhd.header = dict();
dput(rhd.header, "Content-Type", strdup(mime_type)); dput(rhd.header, "Content-Type", strdup(mime_type));
if(!compressable(mime_type) || rq->client->z_level == ANTD_CNONE)
dput(rhd.header, "Content-Length", strdup(ibuf)); dput(rhd.header, "Content-Length", strdup(ibuf));
antd_send_header(rq->client, &rhd); antd_send_header(rq->client, &rhd);
@ -1372,7 +1373,7 @@ void plugindir(char* dest)
int compressable(char* ctype) int compressable(char* ctype)
{ {
if(!server_config.gzip_enable || server_config.gzip_types == NULL) if(!server_config.gzip_enable || server_config.gzip_types == NULL)
return ANTD_CNONE; return 0;
item_t it; item_t it;
list_for_each(it, server_config.gzip_types) list_for_each(it, server_config.gzip_types)
{ {

View File

@ -184,6 +184,7 @@ void antd_send_header(void* cl, antd_response_header_t* res)
res->header = dict(); res->header = dict();
antd_client_t* client = (antd_client_t*) cl; antd_client_t* client = (antd_client_t*) cl;
#ifdef USE_ZLIB #ifdef USE_ZLIB
antd_compress_t current_zlevel = client->z_level;
char* str = dvalue(res->header,"Content-Encoding"); char* str = dvalue(res->header,"Content-Encoding");
if(!str) if(!str)
{ {
@ -191,17 +192,16 @@ void antd_send_header(void* cl, antd_response_header_t* res)
str = dvalue(res->header,"Content-Type"); str = dvalue(res->header,"Content-Type");
if(str) if(str)
{ {
if(compressable(str)) if(compressable(str) && client->z_level != ANTD_CNONE)
{ {
switch (client->z_level)
{
case ANTD_CGZ:
client->zstream = (z_stream *) malloc(sizeof(z_stream)); client->zstream = (z_stream *) malloc(sizeof(z_stream));
if(client->zstream) if(client->zstream)
{ {
((z_stream*)client->zstream)->zalloc = Z_NULL; ((z_stream*)client->zstream)->zalloc = Z_NULL;
((z_stream*)client->zstream)->zfree = Z_NULL; ((z_stream*)client->zstream)->zfree = Z_NULL;
((z_stream*)client->zstream)->opaque = Z_NULL; ((z_stream*)client->zstream)->opaque = Z_NULL;
if(client->z_level == ANTD_CGZ)
{
if(deflateInit2(client->zstream,Z_BEST_COMPRESSION,Z_DEFLATED,15 | 16, 8,Z_DEFAULT_STRATEGY) != Z_OK) if(deflateInit2(client->zstream,Z_BEST_COMPRESSION,Z_DEFLATED,15 | 16, 8,Z_DEFAULT_STRATEGY) != Z_OK)
{ {
ERROR("Cannot init gzip stream"); ERROR("Cannot init gzip stream");
@ -214,15 +214,8 @@ void antd_send_header(void* cl, antd_response_header_t* res)
dput(res->header,"Content-Encoding", strdup("gzip")); dput(res->header,"Content-Encoding", strdup("gzip"));
} }
} }
break; else
case ANTD_CDEFL:
client->zstream = (z_stream *) malloc(sizeof(z_stream));
if(client->zstream)
{ {
((z_stream*)client->zstream)->zalloc = Z_NULL;
((z_stream*)client->zstream)->zfree = Z_NULL;
((z_stream*)client->zstream)->opaque = Z_NULL;
if(deflateInit(client->zstream, Z_BEST_COMPRESSION) != Z_OK) if(deflateInit(client->zstream, Z_BEST_COMPRESSION) != Z_OK)
{ {
ERROR("Cannot init deflate stream"); ERROR("Cannot init deflate stream");
@ -235,14 +228,11 @@ void antd_send_header(void* cl, antd_response_header_t* res)
dput(res->header,"Content-Encoding", strdup("deflate")); dput(res->header,"Content-Encoding", strdup("deflate"));
} }
} }
break;
default:
break;
} }
} }
} }
} }
client->z_level = ANTD_CNONE;
#endif #endif
dput(res->header,"Server", strdup(SERVER_NAME)); dput(res->header,"Server", strdup(SERVER_NAME));
const char* stat_str = get_status_str(res->status); const char* stat_str = get_status_str(res->status);
@ -267,6 +257,9 @@ void antd_send_header(void* cl, antd_response_header_t* res)
res->cookie = NULL; res->cookie = NULL;
} }
__b(client, (unsigned char*)"\r\n", 2); __b(client, (unsigned char*)"\r\n", 2);
#ifdef USE_ZLIB
client->z_level = current_zlevel;
#endif
freedict(res->header); freedict(res->header);
res->header = NULL; res->header = NULL;
} }
@ -281,23 +274,6 @@ void octstream(void* client, char* name)
//Content-Disposition: attachment; filename="fname.ext" //Content-Disposition: attachment; filename="fname.ext"
}*/ }*/
#ifdef USE_ZLIB
int zcompress(antd_client_t * cl, uint8_t* data, int len, uint8_t* dest)
{
z_stream* zstream = (z_stream*) cl->zstream;
zstream->avail_in = (uInt)len;
zstream->next_in = (Bytef *)data;
zstream->avail_out = len;
zstream->next_out = dest;
if(deflate(zstream, cl->status) == Z_STREAM_ERROR)
{
free(dest);
return -1;
}
return zstream->total_out;
}
#endif
int antd_send(void *src, const void* data_in, int len_in) int antd_send(void *src, const void* data_in, int len_in)
{ {
@ -306,25 +282,44 @@ int antd_send(void *src, const void* data_in, int len_in)
antd_client_t * source = (antd_client_t *) src; antd_client_t * source = (antd_client_t *) src;
#ifdef USE_ZLIB #ifdef USE_ZLIB
if(source->zstream && source->z_level != ANTD_CNONE) if(source->zstream && source->z_level != ANTD_CNONE)
{ {
data = (uint8_t*) malloc(len); antd_compress_t current_zlevel = source->z_level;
if(data) source->z_level = ANTD_CNONE;
uint8_t buf[BUFFLEN];
z_stream* zstream = (z_stream*) source->zstream;
zstream->avail_in = (uInt)len;
zstream->next_in = (Bytef *)data_in;
len = 0;
int have = 0;
do
{ {
len = zcompress(source,data_in, len, data); zstream->avail_out = BUFFLEN;
zstream->next_out = buf;
if(deflate(zstream, source->status) == Z_STREAM_ERROR)
{
source->z_level = current_zlevel;
data = NULL;
return -1;
} }
else
{
have = BUFFLEN - zstream->avail_out;
antd_send(source, buf, have);
len += have;
}
} while(zstream->avail_out == 0);
source->z_level = current_zlevel;
//printf("data length %d\n", len);
return len;
} }
#endif #endif
if(!src || !data) if(!src || !data)
{ {
#ifdef USE_ZLIB
if(source->zstream && source->z_level != ANTD_CNONE && data)
free(data);
#endif
return -1; return -1;
} }
int written; int written;
char* ptr; char* ptr;
int writelen = 0; int writelen = 0;
@ -656,24 +651,15 @@ int antd_close(void* src)
//TODO: send finish data to the socket before quit //TODO: send finish data to the socket before quit
if(source->zstream) if(source->zstream)
{ {
printf("Close the stream now\n"); if(source->status == Z_NO_FLUSH && source->z_level != ANTD_CNONE)
if(source->status == Z_NO_FLUSH)
{ {
uint8_t buf[512];
// send finish data
z_stream* zstream = (z_stream*) cl->zstream;
source->status = Z_FINISH; source->status = Z_FINISH;
zstream->avail_in = 0;
zstream->next_in = "";
zstream->avail_out = 512;
zstream->next_out = buf;
antd_send(source, "", 0); antd_send(source, "", 0);
deflateEnd(source->zstream);
} }
deflateEnd(source->zstream); deflateEnd(source->zstream);
free(source->zstream); free(source->zstream);
source->zstream = NULL;
source->z_level = ANTD_CNONE;
} }
#endif #endif
#ifdef USE_OPENSSL #ifdef USE_OPENSSL
@ -725,11 +711,10 @@ int __t(void* client, const char* fstring,...)
} }
int __b(void* client, const unsigned char* data, int size) int __b(void* client, const unsigned char* data, int size)
{ {
char buf[BUFFLEN];
int sent = 0; int sent = 0;
int buflen = 0; int buflen = 0;
int nbytes = 0; int nbytes = 0;
char* ptr = (char*)data;
/*if(size <= BUFFLEN) /*if(size <= BUFFLEN)
{ {
nbytes = antd_send(client,data,size); nbytes = antd_send(client,data,size);
@ -743,13 +728,13 @@ int __b(void* client, const unsigned char* data, int size)
buflen = BUFFLEN; buflen = BUFFLEN;
else else
buflen = size - sent; buflen = size - sent;
memcpy(buf,data+sent,buflen); nbytes = antd_send(client,ptr,buflen);
nbytes = antd_send(client,buf,buflen);
if(nbytes == -1) if(nbytes == -1)
{ {
return 0; return 0;
} }
sent += nbytes; sent += buflen;
ptr += buflen;
} }
//} //}
return 1; return 1;
@ -768,7 +753,7 @@ int __f(void* client, const char* file)
while(!feof(ptr)) while(!feof(ptr))
{ {
size = fread(buffer,1,BUFFLEN,ptr); size = fread(buffer,1,BUFFLEN,ptr);
if(!__b(client,buffer,size)) return 0; if(antd_send(client,buffer,size) == -1) return 0;
} }
fclose(ptr); fclose(ptr);
return 1; return 1;
@ -809,7 +794,8 @@ void antd_error(void* client, int status, const char* msg)
rsh.cookie = NULL; rsh.cookie = NULL;
const char* stat_str = get_status_str(status); const char* stat_str = get_status_str(status);
rsh.status = status; rsh.status = status;
dput(rsh.header, "Content-Type", strdup("text/html; charset=utf-8")); char* ctype = "text/html; charset=utf-8";
dput(rsh.header, "Content-Type", strdup(ctype));
char * res_str = __s(HTML_TPL, stat_str, msg); char * res_str = __s(HTML_TPL, stat_str, msg);
int clen = 0; int clen = 0;
if(res_str) if(res_str)
@ -818,6 +804,7 @@ void antd_error(void* client, int status, const char* msg)
} }
char ibuf[20]; char ibuf[20];
snprintf (ibuf, sizeof(ibuf), "%d",clen); snprintf (ibuf, sizeof(ibuf), "%d",clen);
if(((antd_client_t*)client)->z_level == ANTD_CNONE || !compressable(ctype))
dput(rsh.header, "Content-Length", strdup(ibuf)); dput(rsh.header, "Content-Length", strdup(ibuf));
antd_send_header(client, &rsh); antd_send_header(client, &rsh);
if(res_str) if(res_str)

View File

@ -36,13 +36,15 @@ struct plugin_entry *plugin_load(char *name)
unsigned hashval; unsigned hashval;
if ((np = plugin_lookup(name)) == NULL) { /* not found */ if ((np = plugin_lookup(name)) == NULL) { /* not found */
np = (struct plugin_entry *) malloc(sizeof(*np)); np = (struct plugin_entry *) malloc(sizeof(*np));
if (np == NULL || (np->pname = strdup(name)) == NULL) if (np == NULL || name == NULL)
{ {
if(np) free(np); if(np) free(np);
return NULL; return NULL;
} }
np->pname = strdup(name);
if ((np->handle = plugin_from_file(name)) == NULL) if ((np->handle = plugin_from_file(name)) == NULL)
{ {
if(np->pname) free(np->pname);
if(np) free(np); if(np) free(np);
return NULL; return NULL;
} }
@ -102,6 +104,7 @@ void unload_plugin(struct plugin_entry* np)
} }
dlclose(np->handle); dlclose(np->handle);
//free((void *) np->handle); //free((void *) np->handle);
if(np->pname)
free((void *) np->pname); free((void *) np->pname);
} }
/* /*