static void finalostream_start_pull(h2o_ostream_t *_self, h2o_ostream_pull_cb cb) { struct st_h2o_http1_conn_t *conn = H2O_STRUCT_FROM_MEMBER(struct st_h2o_http1_conn_t, _ostr_final.super, _self); const char *connection = conn->req.http1_is_persistent ? "keep-alive" : "close"; size_t bufsz, headers_len; assert(conn->req._ostr_top == &conn->_ostr_final.super); assert(!conn->_ostr_final.sent_headers); conn->req.timestamps.response_start_at = *h2o_get_timestamp(conn->super.ctx, NULL, NULL); /* register the pull callback */ conn->_ostr_final.pull.cb = cb; /* setup the buffer */ bufsz = flatten_headers_estimate_size(&conn->req, conn->super.ctx->globalconf->server_name.len + strlen(connection)); if (bufsz < MAX_PULL_BUF_SZ) { if (MAX_PULL_BUF_SZ - bufsz < conn->req.res.content_length) { bufsz = MAX_PULL_BUF_SZ; } else { bufsz += conn->req.res.content_length; } } conn->_ostr_final.pull.buf = h2o_mem_alloc_pool(&conn->req.pool, bufsz); /* fill-in the header */ headers_len = flatten_headers(conn->_ostr_final.pull.buf, &conn->req, connection); conn->_ostr_final.sent_headers = 1; proceed_pull(conn, headers_len); }
static uintmax_t add_iovec(mustache_api_t *api, void *userdata, const char *buffer, uintmax_t buffer_size) { IGNORE_FUNCTION_PARAMETER(api); fortune_ctx_t * const fortune_ctx = userdata; iovec_list_t *iovec_list = fortune_ctx->iovec_list_iter; uintmax_t ret = 1; if (iovec_list->iovcnt >= iovec_list->max_iovcnt) { const size_t sz = offsetof(iovec_list_t, iov) + MAX_IOVEC * sizeof(h2o_iovec_t); iovec_list = h2o_mem_alloc_pool(&fortune_ctx->req->pool, sz); if (iovec_list) { memset(iovec_list, 0, offsetof(iovec_list_t, iov)); iovec_list->max_iovcnt = MAX_IOVEC; fortune_ctx->iovec_list_iter->l.next = &iovec_list->l; fortune_ctx->iovec_list_iter = iovec_list; } else ret = 0; } if (ret) { memset(iovec_list->iov + iovec_list->iovcnt, 0, sizeof(*iovec_list->iov)); iovec_list->iov[iovec_list->iovcnt].base = (char *) buffer; iovec_list->iov[iovec_list->iovcnt++].len = buffer_size; fortune_ctx->content_length += buffer_size; } return ret; }
static void link_shared(h2o_mem_pool_t *pool, struct st_h2o_mem_pool_shared_entry_t *entry) { struct st_h2o_mem_pool_shared_ref_t *ref = h2o_mem_alloc_pool(pool, sizeof(struct st_h2o_mem_pool_shared_ref_t)); ref->entry = entry; ref->next = pool->shared_refs; pool->shared_refs = ref; }
static h2o_iovec_t log_request_index(h2o_req_t *req) { struct st_h2o_http1_conn_t *conn = (void *)req->conn; char *s = h2o_mem_alloc_pool(&req->pool, sizeof(H2O_UINT64_LONGEST_STR)); size_t len = sprintf(s, "%" PRIu64, conn->_req_index); return h2o_iovec_init(s, len); }
void finalostream_send(h2o_ostream_t *_self, h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_send_state_t send_state) { struct st_h2o_http1_finalostream_t *self = (void *)_self; struct st_h2o_http1_conn_t *conn = (struct st_h2o_http1_conn_t *)req->conn; h2o_iovec_t *bufs = alloca(sizeof(h2o_iovec_t) * (inbufcnt + 1)); int bufcnt = 0; assert(self == &conn->_ostr_final); if (!self->sent_headers) { conn->req.timestamps.response_start_at = *h2o_get_timestamp(conn->super.ctx, NULL, NULL); /* build headers and send */ const char *connection = req->http1_is_persistent ? "keep-alive" : "close"; bufs[bufcnt].base = h2o_mem_alloc_pool( &req->pool, flatten_headers_estimate_size(req, conn->super.ctx->globalconf->server_name.len + strlen(connection))); bufs[bufcnt].len = flatten_headers(bufs[bufcnt].base, req, connection); ++bufcnt; self->sent_headers = 1; } memcpy(bufs + bufcnt, inbufs, sizeof(h2o_iovec_t) * inbufcnt); bufcnt += inbufcnt; if (send_state == H2O_SEND_STATE_ERROR) { conn->req.http1_is_persistent = 0; } if (bufcnt != 0) { h2o_socket_write(conn->sock, bufs, bufcnt, h2o_send_state_is_in_progress(send_state) ? on_send_next_push : on_send_complete); } else { on_send_complete(conn->sock, 0); } }
h2o_iovec_t h2o_decode_base64url(h2o_mem_pool_t *pool, const char *src, size_t len) { h2o_iovec_t decoded; uint32_t t; uint8_t *dst; char remaining_input[4]; decoded.len = len * 3 / 4; decoded.base = pool != NULL ? h2o_mem_alloc_pool(pool, decoded.len + 1) : h2o_mem_alloc(decoded.len + 1); dst = (uint8_t *)decoded.base; while (len >= 4) { if ((t = decode_base64url_quad(src)) == UINT32_MAX) goto Error; *dst++ = t >> 16; *dst++ = t >> 8; *dst++ = t; src += 4; len -= 4; } switch (len) { case 0: break; case 1: goto Error; case 2: remaining_input[0] = *src++; remaining_input[1] = *src++; remaining_input[2] = 'A'; remaining_input[3] = 'A'; if ((t = decode_base64url_quad(remaining_input)) == UINT32_MAX) goto Error; *dst++ = t >> 16; break; case 3: remaining_input[0] = *src++; remaining_input[1] = *src++; remaining_input[2] = *src++; remaining_input[3] = 'A'; if ((t = decode_base64url_quad(remaining_input)) == UINT32_MAX) goto Error; *dst++ = t >> 16; *dst++ = t >> 8; break; } assert((char *)dst - decoded.base == decoded.len); decoded.base[decoded.len] = '\0'; return decoded; Error: if (pool == NULL) free(decoded.base); return h2o_iovec_init(NULL, 0); }
static mrb_value h2o_mrb_set_request_headers_in(mrb_state *mrb, mrb_value self) { h2o_mruby_internal_context_t *mruby_ctx = (h2o_mruby_internal_context_t *)mrb->ud; mrb_value key, val; char *key_cstr, *val_cstr; mrb_get_args(mrb, "oo", &key, &val); key = mrb_funcall(mrb, key, "downcase", 0); key_cstr = h2o_mem_alloc_pool(&mruby_ctx->req->pool, RSTRING_LEN(key)); val_cstr = h2o_mem_alloc_pool(&mruby_ctx->req->pool, RSTRING_LEN(val)); memcpy(key_cstr, RSTRING_PTR(key), RSTRING_LEN(key)); memcpy(val_cstr, RSTRING_PTR(val), RSTRING_LEN(val)); h2o_set_header_by_str(&mruby_ctx->req->pool, &mruby_ctx->req->headers, key_cstr, RSTRING_LEN(key), 0, val_cstr, RSTRING_LEN(val), 1); return key; }
static void do_multirange_proceed(h2o_generator_t *_self, h2o_req_t *req) { struct st_h2o_sendfile_generator_t *self = (void *)_self; size_t rlen, used_buf = 0; ssize_t rret, vecarrsize; h2o_iovec_t vec[2]; int is_finished; if (self->bytesleft == 0) { size_t *range_cur = self->ranged.range_infos + 2 * self->ranged.current_range; size_t range_end = *range_cur + *(range_cur + 1) - 1; if (H2O_LIKELY(self->ranged.current_range != 0)) used_buf = sprintf(self->buf, "\r\n--%s\r\nContent-Type: %s\r\nContent-Range: bytes %zd-%zd/%zd\r\n\r\n", self->ranged.boundary.base, self->ranged.mimetype.base, *range_cur, range_end, self->ranged.filesize); else used_buf = sprintf(self->buf, "--%s\r\nContent-Type: %s\r\nContent-Range: bytes %zd-%zd/%zd\r\n\r\n", self->ranged.boundary.base, self->ranged.mimetype.base, *range_cur, range_end, self->ranged.filesize); self->ranged.current_range++; self->file.off = *range_cur; self->bytesleft = *++range_cur; } rlen = self->bytesleft; if (rlen + used_buf > MAX_BUF_SIZE) rlen = MAX_BUF_SIZE - used_buf; while ((rret = pread(self->file.ref->fd, self->buf + used_buf, rlen, self->file.off)) == -1 && errno == EINTR) ; if (rret == -1) goto Error; self->file.off += rret; self->bytesleft -= rret; vec[0].base = self->buf; vec[0].len = rret + used_buf; if (self->ranged.current_range == self->ranged.range_count && self->bytesleft == 0) { vec[1].base = h2o_mem_alloc_pool(&req->pool, sizeof("\r\n--") - 1 + BOUNDARY_SIZE + sizeof("--\r\n")); vec[1].len = sprintf(vec[1].base, "\r\n--%s--\r\n", self->ranged.boundary.base); vecarrsize = 2; is_finished = 1; } else { vecarrsize = 1; is_finished = 0; } h2o_send(req, vec, vecarrsize, is_finished); if (is_finished) do_close(&self->super, req); return; Error: req->http1_is_persistent = 0; h2o_send(req, NULL, 0, 1); do_close(&self->super, req); return; }
static int create_content_length_entity_reader(struct st_h2o_http1_conn_t *conn, size_t content_length) { struct st_h2o_http1_content_length_entity_reader *reader = h2o_mem_alloc_pool(&conn->req.pool, sizeof(*reader)); conn->_req_entity_reader = &reader->super; reader->super.handle_incoming_entity = handle_content_length_entity_read; reader->content_length = content_length; conn->_reqsize += content_length; return 0; }
static int create_chunked_entity_reader(struct st_h2o_http1_conn_t *conn) { struct st_h2o_http1_chunked_entity_reader *reader = h2o_mem_alloc_pool(&conn->req.pool, sizeof(*reader)); conn->_req_entity_reader = &reader->super; reader->super.handle_incoming_entity = handle_chunked_entity_read; memset(&reader->decoder, 0, sizeof(reader->decoder)); reader->decoder.consume_trailer = 1; reader->prev_input_size = conn->_reqsize; return 0; }
h2o_ostream_t *h2o_add_ostream(h2o_req_t *req, size_t sz, h2o_ostream_t **slot) { h2o_ostream_t *ostr = h2o_mem_alloc_pool(&req->pool, sz); ostr->next = *slot; ostr->do_send = NULL; ostr->stop = NULL; ostr->start_pull = NULL; *slot = ostr; return ostr; }
h2o_iovec_t h2o_socket_log_ssl_cipher_bits(h2o_socket_t *sock, h2o_mem_pool_t *pool) { int bits = h2o_socket_get_ssl_cipher_bits(sock); if (bits != 0) { char *s = (char *)(pool != NULL ? h2o_mem_alloc_pool(pool, sizeof(H2O_INT16_LONGEST_STR)) : h2o_mem_alloc(sizeof(H2O_INT16_LONGEST_STR))); size_t len = sprintf(s, "%" PRId16, (int16_t)bits); return h2o_iovec_init(s, len); } else { return h2o_iovec_init(H2O_STRLIT("-")); } }
static mrb_value h2o_mrb_set_request_headers_out(mrb_state *mrb, mrb_value self) { h2o_mruby_internal_context_t *mruby_ctx = (h2o_mruby_internal_context_t *)mrb->ud; mrb_value key, val; char *key_cstr, *val_cstr; if (mruby_ctx->state != H2O_MRUBY_STATE_UNDETERMINED) mrb_raise(mrb, E_RUNTIME_ERROR, "response already sent"); mrb_get_args(mrb, "oo", &key, &val); key = mrb_funcall(mrb, key, "downcase", 0); key_cstr = h2o_mem_alloc_pool(&mruby_ctx->req->pool, RSTRING_LEN(key)); val_cstr = h2o_mem_alloc_pool(&mruby_ctx->req->pool, RSTRING_LEN(val)); memcpy(key_cstr, RSTRING_PTR(key), RSTRING_LEN(key)); memcpy(val_cstr, RSTRING_PTR(val), RSTRING_LEN(val)); h2o_set_header_by_str(&mruby_ctx->req->pool, &mruby_ctx->req->res.headers, key_cstr, RSTRING_LEN(key), 0, val_cstr, RSTRING_LEN(val), 1); return key; }
h2o_iovec_t h2o_strdup_slashed(h2o_mem_pool_t *pool, const char *src, size_t len) { h2o_iovec_t ret; ret.len = len != SIZE_MAX ? len : strlen(src); ret.base = pool != NULL ? h2o_mem_alloc_pool(pool, ret.len + 2) : h2o_mem_alloc(ret.len + 2); memcpy(ret.base, src, ret.len); if (ret.len != 0 && ret.base[ret.len - 1] != '/') ret.base[ret.len++] = '/'; ret.base[ret.len] = '\0'; return ret; }
void h2o_http1_upgrade(h2o_http1_conn_t *conn, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_http1_upgrade_cb on_complete, void *user_data) { h2o_iovec_t *bufs = alloca(sizeof(h2o_iovec_t) * (inbufcnt + 1)); conn->upgrade.data = user_data; conn->upgrade.cb = on_complete; bufs[0].base = h2o_mem_alloc_pool( &conn->req.pool, flatten_headers_estimate_size(&conn->req, conn->super.ctx->globalconf->server_name.len + sizeof("upgrade") - 1)); bufs[0].len = flatten_headers(bufs[0].base, &conn->req, "upgrade"); memcpy(bufs + 1, inbufs, sizeof(h2o_iovec_t) * inbufcnt); h2o_socket_write(conn->sock, bufs, (int)(inbufcnt + 1), on_upgrade_complete); }
static h2o_iovec_t build_request(h2o_req_t *req, h2o_proxy_location_t *upstream, int keepalive) { h2o_iovec_t buf; size_t bufsz; const h2o_header_t *h, * h_end; char *p; /* calc buffer length */ bufsz = sizeof(" HTTP/1.1\r\nhost: :65535\r\nconnection: keep-alive\r\ncontent-length: 18446744073709551615\r\n\r\n") + req->method.len + req->path.len - req->pathconf->path.len + upstream->path.len + upstream->host.len; for (h = req->headers.entries, h_end = h + req->headers.size; h != h_end; ++h) bufsz += h->name->len + h->value.len + 4; /* allocate */ buf.base = h2o_mem_alloc_pool(&req->pool, bufsz); /* build response */ p = buf.base; p += sprintf(p, "%.*s %.*s%.*s HTTP/1.1\r\nconnection: %s\r\n", (int)req->method.len, req->method.base, (int)upstream->path.len, upstream->path.base, (int)(req->path.len - req->pathconf->path.len), req->path.base + req->pathconf->path.len, keepalive ? "keep-alive" : "close"); if (upstream->port == 80) p += sprintf(p, "host: %.*s\r\n", (int)upstream->host.len, upstream->host.base); else p += sprintf(p, "host: %.*s:%u\r\n", (int)upstream->host.len, upstream->host.base, (unsigned)upstream->port); if (req->entity.base != NULL) { p += sprintf(p, "content-length: %zu\r\n", req->entity.len); } for (h = req->headers.entries, h_end = h + req->headers.size; h != h_end; ++h) { if (h2o_iovec_is_token(h->name) && ((h2o_token_t*)h->name)->is_connection_specific) continue; p += sprintf(p, "%.*s: %.*s\r\n", (int)h->name->len, h->name->base, (int)h->value.len, h->value.base); } *p++ = '\r'; *p++ = '\n'; /* set the length */ buf.len = p - buf.base; assert(buf.len < bufsz); return buf; }
void h2o_vector__expand(h2o_mem_pool_t *pool, h2o_vector_t *vector, size_t element_size, size_t new_capacity) { void *new_entries; assert(vector->capacity < new_capacity); if (vector->capacity == 0) vector->capacity = 4; while (vector->capacity < new_capacity) vector->capacity *= 2; if (pool != NULL) { new_entries = h2o_mem_alloc_pool(pool, element_size * vector->capacity); memcpy(new_entries, vector->entries, element_size * vector->size); } else { new_entries = h2o_mem_realloc(vector->entries, element_size * vector->capacity); } vector->entries = new_entries; }
ssize_t h2o_add_header_by_str(h2o_mem_pool_t *pool, h2o_headers_t *headers, const char *name, size_t name_len, int maybe_token, const char *orig_name, const char *value, size_t value_len) { h2o_iovec_t *name_buf; if (maybe_token) { const h2o_token_t *token = h2o_lookup_token(name, name_len); if (token != NULL) { return add_header(pool, headers, (h2o_iovec_t *)token, orig_name, value, value_len, (h2o_header_flags_t){0}); } } name_buf = h2o_mem_alloc_pool(pool, *name_buf, 1); name_buf->base = (char *)name; name_buf->len = name_len; return add_header(pool, headers, name_buf, orig_name, value, value_len, (h2o_header_flags_t){0}); }
h2o_iovec_t h2o_strdup(h2o_mem_pool_t *pool, const char *s, size_t slen) { h2o_iovec_t ret; if (slen == SIZE_MAX) slen = strlen(s); if (pool != NULL) { ret.base = h2o_mem_alloc_pool(pool, slen + 1); } else { ret.base = h2o_mem_alloc(slen + 1); } memcpy(ret.base, s, slen); ret.base[slen] = '\0'; ret.len = slen; return ret; }
static h2o_iovec_t build_request_merge_headers(h2o_mem_pool_t *pool, h2o_iovec_t merged, h2o_iovec_t added, int seperator) { if (added.len == 0) return merged; if (merged.len == 0) return added; size_t newlen = merged.len + 2 + added.len; char *buf = h2o_mem_alloc_pool(pool, newlen); memcpy(buf, merged.base, merged.len); buf[merged.len] = seperator; buf[merged.len + 1] = ' '; memcpy(buf + merged.len + 2, added.base, added.len); merged.base = buf; merged.len = newlen; return merged; }
static int delegate_dynamic_request(h2o_req_t *req, size_t url_path_len, const char *local_path, size_t local_path_len, h2o_mimemap_type_t *mime_type) { h2o_filereq_t *filereq; h2o_handler_t *handler; assert(mime_type->data.dynamic.pathconf.handlers.size == 1); filereq = h2o_mem_alloc_pool(&req->pool, sizeof(*filereq)); filereq->url_path_len = url_path_len; filereq->local_path = h2o_strdup(&req->pool, local_path, local_path_len); h2o_req_bind_conf(req, req->hostconf, &mime_type->data.dynamic.pathconf); req->filereq = filereq; handler = mime_type->data.dynamic.pathconf.handlers.entries[0]; return handler->on_req(handler, req); }
static h2o_http1client_head_cb on_connect(h2o_http1client_t *client, const char *errstr, h2o_iovec_t **reqbufs, size_t *reqbufcnt, int *method_is_head) { struct st_h2o_mruby_http_request_context_t *ctx = client->data; if (errstr != NULL) { post_error(ctx, errstr); return NULL; } *reqbufs = h2o_mem_alloc_pool(&ctx->generator->req->pool, sizeof(**reqbufs) * 2); **reqbufs = h2o_iovec_init(ctx->req.buf->bytes, ctx->req.buf->size); *reqbufcnt = 1; if (ctx->req.body.base != NULL) (*reqbufs)[(*reqbufcnt)++] = ctx->req.body; *method_is_head = ctx->req.method_is_head; return on_head; }
void h2o_http1_upgrade(h2o_req_t *req, h2o_iovec_t *inbufs, size_t inbufcnt, h2o_http1_upgrade_cb on_complete, void *user_data) { struct st_h2o_http1_conn_t *conn = (void *)req->conn; assert(req->version <= 0x200); /* TODO find a better way to assert instanceof(req->conn) == struct st_h2o_http1_conn_t */ h2o_iovec_t *bufs = alloca(sizeof(h2o_iovec_t) * (inbufcnt + 1)); conn->upgrade.data = user_data; conn->upgrade.cb = on_complete; bufs[0].base = h2o_mem_alloc_pool(&conn->req.pool, flatten_headers_estimate_size(&conn->req, conn->super.ctx->globalconf->server_name.len + sizeof("upgrade") - 1)); bufs[0].len = flatten_headers(bufs[0].base, &conn->req, "upgrade"); memcpy(bufs + 1, inbufs, sizeof(h2o_iovec_t) * inbufcnt); h2o_socket_write(conn->sock, bufs, inbufcnt + 1, on_upgrade_complete); }
int fortunes(struct st_h2o_handler_t *self, h2o_req_t *req) { IGNORE_FUNCTION_PARAMETER(self); thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t, event_loop.h2o_ctx, req->conn->ctx); fortune_ctx_t * const fortune_ctx = h2o_mem_alloc_shared(&req->pool, sizeof(*fortune_ctx), cleanup_fortunes); if (fortune_ctx) { fortune_t * const fortune = h2o_mem_alloc_pool(&req->pool, sizeof(*fortune)); if (fortune) { memset(fortune, 0, sizeof(*fortune)); fortune->id.base = NEW_FORTUNE_ID; fortune->id.len = sizeof(NEW_FORTUNE_ID) - 1; fortune->message.base = NEW_FORTUNE_MESSAGE; fortune->message.len = sizeof(NEW_FORTUNE_MESSAGE) - 1; memset(fortune_ctx, 0, sizeof(*fortune_ctx)); fortune_ctx->generator.proceed = complete_fortunes; fortune_ctx->num_result = 1; fortune_ctx->param.command = FORTUNE_TABLE_NAME; fortune_ctx->param.on_error = on_fortune_error; fortune_ctx->param.on_result = on_fortune_result; fortune_ctx->param.on_timeout = on_fortune_timeout; fortune_ctx->param.flags = IS_PREPARED; fortune_ctx->req = req; fortune_ctx->result = &fortune->l; if (execute_query(ctx, &fortune_ctx->param)) send_service_unavailable_error(DB_REQ_ERROR, req); } else send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req); } else send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, req); return 0; }
static int write_bio(BIO *b, const char *in, int len) { h2o_socket_t *sock = b->ptr; void *bytes_alloced; /* FIXME no support for SSL renegotiation (yet) */ if (sock->ssl->did_write_in_read != NULL) { *sock->ssl->did_write_in_read = 1; return -1; } if (len == 0) return 0; bytes_alloced = h2o_mem_alloc_pool(&sock->ssl->output.pool, len); memcpy(bytes_alloced, in, len); h2o_vector_reserve(&sock->ssl->output.pool, (h2o_vector_t*)&sock->ssl->output.bufs, sizeof(h2o_iovec_t), sock->ssl->output.bufs.size + 1); sock->ssl->output.bufs.entries[sock->ssl->output.bufs.size++] = h2o_iovec_init(bytes_alloced, len); return len; }
static int on_req(h2o_handler_t *_self, h2o_req_t *req) { struct rp_handler_t *self = (void *)_self; h2o_req_overrides_t *overrides = h2o_mem_alloc_pool(&req->pool, *overrides, 1); struct rp_handler_context_t *handler_ctx = h2o_context_get_handler_context(req->conn->ctx, &self->super); /* setup overrides */ *overrides = (h2o_req_overrides_t){NULL}; overrides->connpool = &handler_ctx->connpool; overrides->location_rewrite.path_prefix = req->pathconf->path; overrides->use_proxy_protocol = self->config.use_proxy_protocol; overrides->client_ctx = handler_ctx->client_ctx; overrides->headers_cmds = self->config.headers_cmds; overrides->proxy_preserve_host = self->config.preserve_host; /* request reprocess (note: path may become an empty string, to which one of the target URL within the socketpool will be * right-padded when lib/core/proxy connects to upstream; see #1563) */ h2o_iovec_t path = h2o_build_destination(req, NULL, 0, 0); h2o_reprocess_request(req, req->method, req->scheme, req->authority, path, overrides, 0); return 0; }
mrb_value h2o_mruby_send_chunked_init(h2o_mruby_generator_t *generator, mrb_value body) { h2o_mruby_chunked_t *chunked = h2o_mem_alloc_pool(&generator->req->pool, sizeof(*chunked)); h2o_doublebuffer_init(&chunked->sending, &h2o_socket_buffer_prototype); chunked->bytes_left = h2o_memis(generator->req->method.base, generator->req->method.len, H2O_STRLIT("HEAD")) ? 0 : generator->req->res.content_length; generator->super.proceed = do_proceed; generator->chunked = chunked; if ((chunked->shortcut.client = h2o_mruby_http_set_shortcut(generator->ctx->shared->mrb, body, on_shortcut_notify)) != NULL) { chunked->type = H2O_MRUBY_CHUNKED_TYPE_SHORTCUT; chunked->shortcut.remaining = NULL; on_shortcut_notify(generator); return mrb_nil_value(); } else { chunked->type = H2O_MRUBY_CHUNKED_TYPE_CALLBACK; h2o_buffer_init(&chunked->callback.receiving, &h2o_socket_buffer_prototype); mrb_gc_register(generator->ctx->shared->mrb, body); chunked->callback.body_obj = body; return mrb_ary_entry(generator->ctx->shared->constants, H2O_MRUBY_CHUNKED_PROC_EACH_TO_FIBER); } }
/** Get a list of document keys where the key prefix matches the provided key */ static int __get_keys(h2o_req_t *req, kstr_t* key) { get_keys_generator_t *gen = h2o_mem_alloc_pool(&req->pool, sizeof(*gen)); gen->super.proceed = __get_keys_proceed; gen->super.stop = __get_keys_close; gen->req = req; gen->key = key; req->res.status = 200; req->res.reason = "OK"; h2o_start_response(req, &gen->super); int e; e = mdb_txn_begin(sv->db_env, NULL, MDB_RDONLY, &gen->txn); if (0 != e) mdb_fatal(e); e = mdb_cursor_open(gen->txn, sv->docs, &gen->curs); if (0 != e) mdb_fatal(e); MDB_val k = { .mv_size = key->len, .mv_data = key->s }, v;
static int on_req(h2o_handler_t *_self, h2o_req_t *req) { struct rp_handler_t *self = (void *)_self; h2o_req_overrides_t *overrides = h2o_mem_alloc_pool(&req->pool, sizeof(*overrides)); const h2o_url_scheme_t *scheme; h2o_iovec_t *authority; /* setup overrides */ *overrides = (h2o_req_overrides_t) {}; if (self->sockpool != NULL) { overrides->socketpool = self->sockpool; } else if (self->config.preserve_host) { overrides->hostport.host = self->upstream.host; overrides->hostport.port = h2o_url_get_port(&self->upstream); } overrides->location_rewrite.match = &self->upstream; overrides->location_rewrite.path_prefix = req->pathconf->path; overrides->client_ctx = h2o_context_get_handler_context(req->conn->ctx, &self->super); /* determine the scheme and authority */ if (self->config.preserve_host) { scheme = req->scheme; authority = &req->authority; } else { scheme = self->upstream.scheme; authority = &self->upstream.authority; } /* request reprocess */ h2o_reprocess_request(req, req->method, scheme, *authority, h2o_concat(&req->pool, self->upstream.path, h2o_iovec_init(req->path.base + req->pathconf->path.len, req->path.len - req->pathconf->path.len)), overrides, 0); return 0; }
static void expand_buf(h2o_mem_pool_t *pool, iovec_vector_t *bufs) { h2o_vector_push_back(pool, bufs, h2o_iovec_init(h2o_mem_alloc_pool(pool, BUF_SIZE), 0)); }