diff --git a/plugins/http/common.h b/plugins/http/common.h index 9cfa31a2..3be8886b 100644 --- a/plugins/http/common.h +++ b/plugins/http/common.h @@ -106,6 +106,8 @@ struct http_session { struct uwsgi_buffer *spdy_ping; + uint32_t spdy_update_window; + ssize_t (*spdy_hook)(struct corerouter_peer *); #endif @@ -165,6 +167,7 @@ int uwsgi_spdy_npn(SSL *ssl, const unsigned char **, unsigned int *, void *); void uwsgi_spdy_info_cb(SSL const *, int, int); ssize_t hr_recv_spdy_control_frame(struct corerouter_peer *); ssize_t spdy_parse(struct corerouter_peer *); +void spdy_window_update(char *, uint32_t, uint32_t); #endif ssize_t hs_http_manage(struct corerouter_peer *, ssize_t); diff --git a/plugins/http/http.c b/plugins/http/http.c index cfe1a59e..001b0831 100644 --- a/plugins/http/http.c +++ b/plugins/http/http.c @@ -363,6 +363,16 @@ ssize_t hr_instance_write(struct corerouter_peer *peer) { #ifdef UWSGI_SPDY struct http_session *hr = (struct http_session *) peer->session; if (hr->spdy) { + if (hr->spdy_update_window) { + if (uwsgi_buffer_fix(peer->in, 16)) return -1; + peer->in->pos = 16; + spdy_window_update(peer->in->buf, hr->spdy_update_window, 8192); + peer->session->main_peer->out = peer->in; + peer->session->main_peer->out_pos = 0; + hr->spdy_update_window = 0; + cr_write_to_main(peer, hr->func_write); + return 1; + } return spdy_parse(peer->session->main_peer); } #endif diff --git a/plugins/http/https.c b/plugins/http/https.c index 9f984275..9c54add6 100644 --- a/plugins/http/https.c +++ b/plugins/http/https.c @@ -278,6 +278,11 @@ ssize_t hr_ssl_write(struct corerouter_peer *main_peer) { return ret; } cr_reset_hooks(main_peer); +#ifdef UWSGI_SPDY + if (hr->spdy) { + return spdy_parse(main_peer); + } +#endif } return ret; } @@ -311,15 +316,12 @@ ssize_t hr_ssl_read(struct corerouter_peer *main_peer) { // try to always leave 4k available if (uwsgi_buffer_ensure(main_peer->in, uwsgi.page_size)) return -1; - uwsgi_log("REMAINS: %llu\n", (unsigned long long) main_peer->in->len - main_peer->in->pos); int ret = SSL_read(hr->ssl, main_peer->in->buf + main_peer->in->pos, main_peer->in->len - main_peer->in->pos); - uwsgi_log("ret = %d\n", ret); if (ret > 0) { // fix the buffer main_peer->in->pos += ret; // check for pending data int ret2 = SSL_pending(hr->ssl); - uwsgi_log("ret2 = %d\n", ret2); if (ret2 > 0) { if (uwsgi_buffer_fix(main_peer->in, main_peer->in->len + ret2 )) { uwsgi_log("[uwsgi-https] cannot fix the buffer to %d\n", main_peer->in->len + ret2); diff --git a/plugins/http/spdy3.c b/plugins/http/spdy3.c index aa7f124f..77c6159f 100644 --- a/plugins/http/spdy3.c +++ b/plugins/http/spdy3.c @@ -263,6 +263,37 @@ static void spdy_reply_header(char *buf, uint32_t len, uint32_t stream_id) { } +// be sure to have at least 16 free bytes +void spdy_window_update(char *buf, uint32_t stream_id, uint32_t wsize) { + buf[0] = 0x80; + buf[1] = 0x03; + buf[2] = 0; + buf[3] = 0x09; + + // flags + buf[4] = 0; + + uint32_t len = 8; + + // length + buf[7] = (uint8_t) (len & 0xff); + buf[6] = (uint8_t) ((len >> 8) & 0xff); + buf[5] = (uint8_t) ((len >> 16) & 0xff); + + // stream id + buf[11] = (uint8_t) (stream_id & 0xff); + buf[10] = (uint8_t) ((stream_id >> 8) & 0xff); + buf[9] = (uint8_t) ((stream_id >> 16) & 0xff); + buf[8] = (uint8_t) ((stream_id >> 24) & 0xff); + + buf[15] = (uint8_t) (wsize & 0xff); + buf[14] = (uint8_t) ((wsize >> 8) & 0xff); + buf[13] = (uint8_t) ((wsize >> 16) & 0xff); + buf[12] = (uint8_t) ((wsize >> 24) & 0xff); + +} + + static ssize_t http_parse_to_spdy(struct corerouter_peer *peer) { size_t i; struct uwsgi_buffer *ub = peer->in; @@ -598,7 +629,6 @@ ssize_t spdy_parse(struct corerouter_peer *main_peer) { for(;;) { size_t len = main_peer->in->pos; - uwsgi_log("available %llu bytes\n", (unsigned long long) len); if (len == 0) { return 1; } @@ -622,7 +652,7 @@ ssize_t spdy_parse(struct corerouter_peer *main_peer) { hr->spdy_data_stream_id = spdy_stream_id(buf); hr->spdy_control_length = spdy_h_read_length(buf); hr->spdy_need = hr->spdy_control_length; - uwsgi_log("need %llu bytes for stream_id %lu\n", (unsigned long long) hr->spdy_need, hr->spdy_data_stream_id); + //uwsgi_log("need %llu bytes for stream_id %lu\n", (unsigned long long) hr->spdy_need, hr->spdy_data_stream_id); } if (uwsgi_buffer_decapitate(main_peer->in, 8)) return -1; continue; @@ -673,6 +703,7 @@ goon: peer->out->pos = 0; if (uwsgi_buffer_append(peer->out, main_peer->in->buf, hr->spdy_need)) return -1; peer->out_pos = 0; + hr->spdy_update_window = hr->spdy_data_stream_id; cr_write_to_backend(peer, hr_instance_write); ret = 1; goto newframe;