static void do_proceed(h2o_generator_t *_generator, h2o_req_t *req) { h2o_mruby_generator_t *generator = (void *)_generator; h2o_mruby_chunked_t *chunked = generator->chunked; h2o_buffer_t **input; int is_final; h2o_doublebuffer_consume(&chunked->sending); switch (chunked->type) { case H2O_MRUBY_CHUNKED_TYPE_CALLBACK: input = &chunked->callback.receiving; is_final = mrb_nil_p(chunked->body_obj); break; case H2O_MRUBY_CHUNKED_TYPE_SHORTCUT: if (chunked->shortcut.client != NULL) { input = h2o_mruby_http_peek_content(chunked->shortcut.client, &is_final); assert(!is_final); } else { input = &chunked->shortcut.remaining; is_final = 1; } break; default: h2o_fatal("unexpected type"); break; } do_send(generator, input, is_final); }
static void on_shortcut_notify(h2o_mruby_generator_t *generator) { h2o_mruby_chunked_t *chunked = generator->chunked; int is_final; h2o_buffer_t **input = h2o_mruby_http_peek_content(chunked->shortcut.client, &is_final); /* trim data too long */ if (chunked->bytes_left != SIZE_MAX && chunked->bytes_left < (*input)->size) (*input)->size = chunked->bytes_left; /* if final, steal socket input buffer to shortcut.remaining, and reset pointer to client */ if (is_final) { chunked->shortcut.remaining = *input; h2o_buffer_init(input, &h2o_socket_buffer_prototype); input = &chunked->shortcut.remaining; chunked->shortcut.client = NULL; } if (chunked->sending.bytes_inflight == 0) do_send(generator, input, is_final); }