From 8d33491211f9e4d8bdfcf09528c0d291b5f772c3 Mon Sep 17 00:00:00 2001 From: Unbit Date: Thu, 24 Jan 2013 19:31:50 +0100 Subject: [PATCH] added magix gzipper in http corerouter and added sessions counter in corerouters --- core/zlib.c | 21 +++++++++++++++------ plugins/corerouter/corerouter.c | 12 +++++++++++- plugins/corerouter/cr.h | 5 +++++ plugins/http/http.c | 24 +++++++++++++++++++++--- plugins/http/https.c | 8 ++++++++ 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/core/zlib.c b/core/zlib.c index 4362a8cf..32c0a02d 100644 --- a/core/zlib.c +++ b/core/zlib.c @@ -6,6 +6,7 @@ int uwsgi_deflate_init(z_stream *z, char *dict, size_t dict_len) { z->zfree = Z_NULL; z->opaque = Z_NULL; if (deflateInit2(z, Z_DEFAULT_COMPRESSION, Z_DEFLATED, -15, 9, Z_DEFAULT_STRATEGY) != Z_OK) { + //if (deflateInit(z, Z_DEFAULT_COMPRESSION)) { return -1; } if (dict && dict_len) { @@ -18,6 +19,7 @@ int uwsgi_deflate_init(z_stream *z, char *dict, size_t dict_len) { char *uwsgi_deflate(z_stream *z, char *buf, size_t len, size_t *dlen) { + // calculate the amount of bytes needed for output (+30 should be enough) Bytef *dbuf = uwsgi_malloc(len+30); z->avail_in = len; @@ -25,14 +27,21 @@ char *uwsgi_deflate(z_stream *z, char *buf, size_t len, size_t *dlen) { z->avail_out = len+30; z->next_out = dbuf; - if (deflate(z, Z_SYNC_FLUSH) != Z_OK) { - free(dbuf); - return NULL; + if (len > 0) { + if (deflate(z, Z_SYNC_FLUSH) != Z_OK) { + free(dbuf); + return NULL; + } + } + else { + if (deflate(z, Z_FINISH) != Z_STREAM_END) { + free(dbuf); + return NULL; + } + deflateEnd(z); } - uwsgi_log("%d %d\n", z->avail_in, z->next_out - dbuf); - - *dlen = z->next_out - dbuf; + *dlen = (z->next_out - dbuf); return (char *) dbuf; } diff --git a/plugins/corerouter/corerouter.c b/plugins/corerouter/corerouter.c index 20bc81e4..36dcd5eb 100644 --- a/plugins/corerouter/corerouter.c +++ b/plugins/corerouter/corerouter.c @@ -376,7 +376,7 @@ end: corerouter_close_session(ucr, cs); } else { - if (cs->can_keepalive == 0) { + if (cs->can_keepalive == 0 && cs->wait_full_write == 0) { corerouter_close_session(ucr, cs); } } @@ -403,6 +403,12 @@ void corerouter_close_session(struct uwsgi_corerouter *ucr, struct corerouter_se cr_session->close(cr_session); free(cr_session); + + if (ucr->active_sessions == 0) { + uwsgi_log("[BUG] number of active sessions already 0 !!!\n"); + return; + } + ucr->active_sessions--; } struct uwsgi_rb_timer *corerouter_reset_timeout(struct uwsgi_corerouter *ucr, struct corerouter_peer *peer) { @@ -560,6 +566,8 @@ struct corerouter_session *corerouter_alloc_session(struct uwsgi_corerouter *ucr cs = NULL; } + ucr->active_sessions++; + return cs; } @@ -920,6 +928,8 @@ void corerouter_send_stats(struct uwsgi_corerouter *ucr) { char *cwd = uwsgi_get_cwd(); if (uwsgi_stats_keyval_comma(us, "cwd", cwd)) goto end0; + if (uwsgi_stats_keylong_comma(us, "active_sessions", (unsigned long long) ucr->active_sessions)) goto end; + if (uwsgi_stats_key(us , ucr->short_name)) goto end0; if (uwsgi_stats_list_open(us)) goto end0; diff --git a/plugins/corerouter/cr.h b/plugins/corerouter/cr.h index 1a23d1c5..516bbe4a 100644 --- a/plugins/corerouter/cr.h +++ b/plugins/corerouter/cr.h @@ -251,6 +251,8 @@ struct uwsgi_corerouter { int interesting_fd; + uint64_t active_sessions; + }; // a session is started when a client connect to the router @@ -271,7 +273,10 @@ struct corerouter_session { void (*close)(struct corerouter_session *); int (*retry)(struct corerouter_peer *); + // leave the main peer alive int can_keepalive; + // destroy the main peer after the last full write + int wait_full_write; // this is the peer of the client struct corerouter_peer *main_peer; diff --git a/plugins/http/http.c b/plugins/http/http.c index 8c480806..d07a14a1 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -431,6 +431,10 @@ ssize_t hr_write(struct corerouter_peer *main_peer) { if (cr_write_complete(main_peer)) { // reset the original read buffer main_peer->out->pos = 0; + if (main_peer->session->wait_full_write) { + main_peer->session->wait_full_write = 0; + return 0; + } cr_reset_hooks(main_peer); } @@ -523,6 +527,13 @@ ssize_t hr_instance_read(struct corerouter_peer *peer) { } if (hr->force_gzip) { hr->force_gzip = 0; + size_t zlen = 0; + char *gzipped = uwsgi_deflate(&hr->z, NULL, 0, &zlen); + if (!gzipped) return -1; + if (uwsgi_buffer_append_chunked(hr->last_chunked, zlen)) {free(gzipped) ; return -1;} + if (uwsgi_buffer_append(hr->last_chunked, gzipped, zlen)) {free(gzipped) ; return -1;} + free(gzipped); + if (uwsgi_buffer_append(hr->last_chunked, "\r\n", 2)) return -1; if (uwsgi_buffer_append_chunked(hr->last_chunked, 8)) return -1; if (uwsgi_buffer_u32le(hr->last_chunked, hr->gzip_crc32)) return -1; if (uwsgi_buffer_u32le(hr->last_chunked, hr->gzip_size)) return -1; @@ -532,6 +543,9 @@ ssize_t hr_instance_read(struct corerouter_peer *peer) { peer->session->main_peer->out = hr->last_chunked; peer->session->main_peer->out_pos = 0; cr_write_to_main(peer, hr->func_write); + if (!hr->session.can_keepalive) { + hr->session.wait_full_write = 1; + } } else { cr_reset_hooks(peer); @@ -551,14 +565,12 @@ ssize_t hr_instance_read(struct corerouter_peer *peer) { #ifdef UWSGI_ZLIB else if (hr->force_gzip) { size_t zlen = 0; - uwsgi_log("%d|%.*s|\n", peer->in->pos, peer->in->pos, peer->in->buf); char *gzipped = uwsgi_deflate(&hr->z, peer->in->buf, peer->in->pos, &zlen); - uwsgi_log("gzipped = %d\n", zlen); if (!gzipped) return -1; hr->gzip_size += peer->in->pos; uwsgi_crc32(&hr->gzip_crc32, peer->in->buf, peer->in->pos); peer->in->pos = 0; - if (uwsgi_buffer_insert_chunked(peer->in, 0, zlen)) return -1; + if (uwsgi_buffer_insert_chunked(peer->in, 0, zlen)) {free(gzipped); return -1;} if (uwsgi_buffer_append(peer->in, gzipped, zlen)) { free(gzipped); return -1; @@ -722,6 +734,12 @@ void hr_session_close(struct corerouter_session *cs) { if (hr->last_chunked) { uwsgi_buffer_destroy(hr->last_chunked); } + +#ifdef UWSGI_ZLIB + if (hr->z.next_in) { + deflateEnd(&hr->z); + } +#endif } ssize_t hr_recv_stud4(struct corerouter_peer * main_peer) { diff --git a/plugins/http/https.c b/plugins/http/https.c index d8766612..3b45d194 100644 --- a/plugins/http/https.c +++ b/plugins/http/https.c @@ -262,6 +262,10 @@ void hr_session_ssl_close(struct corerouter_session *cs) { if (hr->spdy_ping) { uwsgi_buffer_destroy(hr->spdy_ping); } + if (hr->spdy) { + deflateEnd(&hr->spdy_z_in); + deflateEnd(&hr->spdy_z_out); + } #endif SSL_free(hr->ssl); @@ -277,6 +281,10 @@ ssize_t hr_ssl_write(struct corerouter_peer *main_peer) { if (main_peer->out->pos == main_peer->out_pos) { // reset the buffer (if needed) main_peer->out->pos = 0; + if (main_peer->session->wait_full_write) { + main_peer->session->wait_full_write = 0; + return 0; + } cr_reset_hooks(main_peer); } return ret;