static void do_send_file(struct st_h2o_sendfile_generator_t *self, h2o_req_t *req, int status, const char *reason, h2o_buf_t mime_type) { /* link the request */ self->req = req; /* setup response */ req->res.status = status; req->res.reason = reason; req->res.content_length = self->bytesleft; h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, mime_type.base, mime_type.len); h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_LAST_MODIFIED, self->last_modified_buf, H2O_TIMESTR_RFC1123_LEN); h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_ETAG, self->etag_buf, self->etag_len); /* send data */ h2o_start_response(req, &self->super); if (req->_ostr_top->start_pull != NULL) { req->_ostr_top->start_pull(req->_ostr_top, do_pull); } else { size_t bufsz = MAX_BUF_SIZE; if (self->bytesleft < bufsz) bufsz = self->bytesleft; self->buf = h2o_mempool_alloc(&req->pool, bufsz); do_proceed(&self->super, req); } }
void h2o_set_header_by_str(h2o_mempool_t *pool, h2o_headers_t *headers, const char *name, size_t name_len, int maybe_token, const char *value, size_t value_len, int overwrite_if_exists) { ssize_t cursor; if (maybe_token) { const h2o_token_t *token = h2o_lookup_token(name, name_len); if (token != NULL) { h2o_set_header(pool, headers, token ,value, value_len, overwrite_if_exists); return; } } cursor = h2o_find_header_by_str(headers, name, name_len, -1); if (cursor != -1) { if (overwrite_if_exists) { h2o_buf_t *slot = &headers->entries[cursor].value; slot->base = (char*)value; slot->len = value_len; } } else { h2o_buf_t *name_buf = h2o_mempool_alloc(pool, sizeof(h2o_buf_t)); name_buf->base = (char*)name; name_buf->len = name_len; add_header(pool, headers, name_buf, value, value_len); } }
h2o_ostream_t *h2o_add_ostream(h2o_req_t *req, size_t sz, h2o_ostream_t **slot) { h2o_ostream_t *ostr = h2o_mempool_alloc(&req->pool, sz); ostr->next = *slot; ostr->do_send = NULL; *slot = ostr; return ostr; }
static void start_request(h2o_http1client_ctx_t *ctx) { char *scheme, *host, *path; uint16_t port; h2o_iovec_t *req; h2o_http1client_t *client; /* clear memory pool */ h2o_mempool_clear(&pool); /* parse URL */ if (h2o_parse_url(&pool, url, &scheme, &host, &port, &path) != 0) { fprintf(stderr, "unrecognized type of URL: %s\n", url); exit(1); } if (strcmp(scheme, "https") == 0) { fprintf(stderr, "https is not (yet) supported\n"); exit(1); } /* build request */ req = h2o_mempool_alloc(&pool, sizeof(*req)); req->base = h2o_mempool_alloc(&pool, 1024); req->len = snprintf(req->base, 1024, "GET %s HTTP/1.1\r\nhost: %s:%u\r\n\r\n", path, host, (unsigned)port); assert(req->len < 1024); /* initiate the request */ if (1) { if (sockpool == NULL) { sockpool = h2o_malloc(sizeof(*sockpool)); h2o_socketpool_init(sockpool, host, port, 10); h2o_socketpool_set_timeout(sockpool, ctx->loop, 5000 /* in msec */); } client = h2o_http1client_connect_with_pool(ctx, &pool, sockpool, on_connect); } else { client = h2o_http1client_connect(ctx, &pool, host, port, on_connect); } assert(client != NULL); client->data = req; }
static int write_bio(BIO *b, const char *in, int len) { h2o_socket_t *sock = b->ptr; void *bytes_alloced; if (len == 0) return 0; bytes_alloced = h2o_mempool_alloc(&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_buf_t), sock->ssl->output.bufs.size + 1); sock->ssl->output.bufs.entries[sock->ssl->output.bufs.size++] = h2o_buf_init(bytes_alloced, len); return len; }
void h2o_add_header_by_str(h2o_mempool_t *pool, h2o_headers_t *headers, const char *name, size_t name_len, int maybe_token, const char *value, size_t value_len) { h2o_buf_t *name_buf; if (maybe_token) { const h2o_token_t *token = h2o_lookup_token(name, name_len); if (token != NULL) { add_header(pool, headers, (h2o_buf_t*)token, value, value_len); return; } } name_buf = h2o_mempool_alloc(pool, sizeof(h2o_buf_t)); name_buf->base = (char*)name; name_buf->len = name_len; add_header(pool, headers, name_buf, value, value_len); }
static int redirect_to_dir(h2o_req_t *req, const char *path, size_t path_len) { static h2o_generator_t generator = { NULL, NULL }; static const h2o_buf_t body_prefix = { H2O_STRLIT("<!DOCTYPE html><TITLE>301 Moved Permanently</TITLE><P>The document has moved <A HREF=\"") }; static const h2o_buf_t body_suffix = { H2O_STRLIT("\">here</A>") }; h2o_buf_t url; size_t alloc_size; h2o_buf_t bufs[3]; /* determine the size of the memory needed */ alloc_size = sizeof(":///") + req->scheme.len + req->authority.len + path_len; /* allocate and build url */ url.base = h2o_mempool_alloc(&req->pool, alloc_size); url.len = sprintf(url.base, "%.*s://%.*s%.*s/", (int)req->scheme.len, req->scheme.base, (int)req->authority.len, req->authority.base, (int)path_len, path); assert(url.len + 1 == alloc_size); /* build response header */ req->res.status = 301; req->res.reason = "Moved Permanently"; memset(&req->res.headers, 0, sizeof(req->res.headers)); h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_LOCATION, url.base, url.len); h2o_add_header(&req->pool, &req->res.headers, H2O_TOKEN_CONTENT_TYPE, H2O_STRLIT("text/html; charset=utf-8")); /* build response */ bufs[0] = body_prefix; bufs[1] = h2o_htmlescape(&req->pool, url.base, url.len); bufs[2] = body_suffix; /* send */ h2o_start_response(req, &generator); h2o_send(req, bufs, 3, 1); return 0; }
static struct st_h2o_sendfile_generator_t *create_generator(h2o_mempool_t *pool, const char *path, int *is_dir) { struct st_h2o_sendfile_generator_t *self; int fd; struct stat st; size_t bufsz; *is_dir = 0; if ((fd = open(path, O_RDONLY)) == -1) return NULL; if (fstat(fd, &st) != 0) { perror("fstat"); close(fd); return NULL; } if (S_ISDIR(st.st_mode)) { close(fd); *is_dir = 1; return NULL; } bufsz = MAX_BUF_SIZE; if (st.st_size < bufsz) bufsz = st.st_size; self = h2o_mempool_alloc(pool, sizeof(*self)); self->super.proceed = do_proceed; self->super.stop = do_close; self->fd = fd; self->req = NULL; self->bytesleft = st.st_size; h2o_time2str_rfc1123(self->last_modified_buf, st.st_mtime); self->etag_len = sprintf(self->etag_buf, "\"%08x-%zx\"", (unsigned)st.st_mtime, (size_t)st.st_size); return self; }