static void do_send(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_send_state_t state) { if (inbufcnt == 0 && h2o_send_state_is_in_progress(state)) { h2o_ostream_send_next(_self, req, inbufs, inbufcnt, state); return; } struct st_compress_encoder_t *self = (void *)_self; h2o_iovec_t *outbufs; size_t outbufcnt; self->compressor->transform(self->compressor, inbufs, inbufcnt, state, &outbufs, &outbufcnt); h2o_ostream_send_next(&self->super, req, outbufs, outbufcnt, state); }
static void send_gzip(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, int is_final) { gzip_encoder_t *self = (void *)_self; size_t outbufindex; /* initialize deflate (Z_BEST_SPEED for on-the-fly compression, memlevel set to 8 as suggested by the manual) */ if (self->bufs.size == 0) { deflateInit2(&self->zstream, Z_BEST_SPEED, Z_DEFLATED, WINDOW_BITS, 8, Z_DEFAULT_STRATEGY); expand_buf(&req->pool, &self->bufs); } /* compress */ outbufindex = 0; self->bufs.entries[0].len = 0; if (inbufcnt != 0) { size_t i; for (i = 0; i != inbufcnt - 1; ++i) if (inbufs[i].len != 0) outbufindex = compress_chunk(&req->pool, &self->zstream, inbufs[i].base, inbufs[i].len, Z_NO_FLUSH, &self->bufs, outbufindex); outbufindex = compress_chunk(&req->pool, &self->zstream, inbufs[i].base, inbufs[i].len, is_final ? Z_FINISH : Z_SYNC_FLUSH, &self->bufs, outbufindex); } else { outbufindex = compress_chunk(&req->pool, &self->zstream, "", 0, Z_FINISH, &self->bufs, outbufindex); } /* destroy deflate */ if (is_final) deflateEnd(&self->zstream); h2o_ostream_send_next(&self->super, req, self->bufs.entries, outbufindex + 1, is_final); }
static void send_chunk(h2o_ostream_t *_self, h2o_req_t *req, h2o_buf_t *inbufs, size_t inbufcnt, int is_final) { chunked_encoder_t *self = (void*)_self; h2o_buf_t *outbufs = alloca(sizeof(h2o_buf_t) * (inbufcnt + 2)); size_t chunk_size, outbufcnt = 0, i; /* calc chunk size */ chunk_size = 0; for (i = 0; i != inbufcnt; ++i) chunk_size += inbufs[i].len; /* create chunk header */ if (chunk_size != 0) { outbufs[outbufcnt].base = self->buf; outbufs[outbufcnt].len = h2o_snprintf(self->buf, sizeof(self->buf), "%zx\r\n", chunk_size); outbufcnt++; } /* set output data */ memcpy(outbufs + outbufcnt, inbufs, sizeof(h2o_buf_t) * inbufcnt); outbufcnt += inbufcnt; /* set EOF chunk header if is_final */ if (is_final) { outbufs[outbufcnt].base = "\r\n0\r\n\r\n"; outbufs[outbufcnt].len = 7; outbufcnt++; } else { outbufs[outbufcnt].base = "\r\n"; outbufs[outbufcnt].len = 2; } h2o_ostream_send_next(&self->super, req, outbufs, outbufcnt, is_final); }
static void do_send(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_send_state_t state) { struct st_compress_encoder_t *self = (void *)_self; h2o_iovec_t *outbufs; size_t outbufcnt; self->compressor->compress(self->compressor, inbufs, inbufcnt, state, &outbufs, &outbufcnt); h2o_ostream_send_next(&self->super, req, outbufs, outbufcnt, state); }
static void send_chunk(h2o_ostream_t *_self, h2o_req_t *req, h2o_buf_t *inbufs, size_t inbufcnt, int is_final) { struct rproxy_t *self = (void*)_self; const char *host, *path; uint16_t port; /* throw away all data */ if (! is_final) { h2o_ostream_send_next(&self->super, req, NULL, 0, 0); return; } /* end of the original stream, start retreiving the data from the reproxy-url */ if (! parse_url(&req->pool, self->reproxy_url, &host, &port, &path)) { host = NULL; path = NULL; port = 0; } /* NOT IMPLEMENTED!!! */ h2o_buf_t body = h2o_sprintf( &req->pool, "reproxy request to URL: %s\n" " host: %s\n" " port: %u\n" " path: %s\n", self->reproxy_url, host, (int)port, path); req->res.status = 200; req->res.reason = "Internal Server Error"; req->res.content_length = SIZE_MAX; h2o_set_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, H2O_STRLIT("text/plain; charset=utf-8"), 1); h2o_setup_next_ostream(self->filter, req, &self->super.next); assert(is_final); h2o_ostream_send_next(&self->super, req, &body, 1, is_final); }
static void send_chunk(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_send_state_t state) { chunked_encoder_t *self = (void *)_self; h2o_iovec_t *outbufs = alloca(sizeof(h2o_iovec_t) * (inbufcnt + 2)); size_t chunk_size, outbufcnt = 0, i; /* calc chunk size */ chunk_size = 0; for (i = 0; i != inbufcnt; ++i) chunk_size += inbufs[i].len; /* create chunk header and output data */ if (chunk_size != 0) { outbufs[outbufcnt].base = self->buf; outbufs[outbufcnt].len = sprintf(self->buf, "%zx\r\n", chunk_size); assert(outbufs[outbufcnt].len < sizeof(self->buf)); outbufcnt++; memcpy(outbufs + outbufcnt, inbufs, sizeof(h2o_iovec_t) * inbufcnt); outbufcnt += inbufcnt; if (state != H2O_SEND_STATE_ERROR) { outbufs[outbufcnt].base = "\r\n0\r\n\r\n"; outbufs[outbufcnt].len = state == H2O_SEND_STATE_FINAL ? 7 : 2; outbufcnt++; } } else if (state == H2O_SEND_STATE_FINAL) { outbufs[outbufcnt].base = "0\r\n\r\n"; outbufs[outbufcnt].len = 5; outbufcnt++; } /* if state is error, send a broken chunk to pass the error down to the browser */ if (state == H2O_SEND_STATE_ERROR) { outbufs[outbufcnt].base = "\r\n1\r\n"; outbufs[outbufcnt].len = 5; outbufcnt++; } h2o_ostream_send_next(&self->super, req, outbufs, outbufcnt, state); }