Exemple #1
0
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 result_return_t on_fortune_result(db_query_param_t *param, PGresult *result)
{
	fortune_ctx_t * const fortune_ctx = H2O_STRUCT_FROM_MEMBER(fortune_ctx_t, param, param);
	int ret = DONE;
	const ExecStatusType status = PQresultStatus(result);

	if (status == PGRES_TUPLES_OK) {
		const size_t num_rows = PQntuples(result);

		ret = SUCCESS;

		for (size_t i = 0; i < num_rows; i++) {
			fortune_t * const fortune = h2o_mem_alloc_pool(&fortune_ctx->req->pool,
			                                               sizeof(*fortune));

			if (fortune) {
				memset(fortune, 0, sizeof(*fortune));
				fortune->id.base = PQgetvalue(result, i, 0);
				fortune->id.len = PQgetlength(result, i, 0);
				fortune->message = h2o_htmlescape(&fortune_ctx->req->pool,
				                                  PQgetvalue(result, i, 1),
				                                  PQgetlength(result, i, 1));
				fortune->l.next = fortune_ctx->result;
				fortune_ctx->result = &fortune->l;
				fortune_ctx->num_result++;

				if (!i)
					fortune->data = result;
			}
			else {
				send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, fortune_ctx->req);
				ret = DONE;

				if (!i)
					PQclear(result);

				break;
			}
		}
	}
	else if (result) {
		LIBRARY_ERROR("PQresultStatus", PQresultErrorMessage(result));
		send_error(BAD_GATEWAY, DB_ERROR, fortune_ctx->req);
		PQclear(result);
	}
	else {
		mustache_api_t api = {.sectget = on_fortune_section,
		                      .varget = on_fortune_variable,
		                      .write = add_iovec};
		thread_context_t * const ctx = H2O_STRUCT_FROM_MEMBER(thread_context_t,
		                                                      event_loop.h2o_ctx,
		                                                      fortune_ctx->req->conn->ctx);
		const size_t iovcnt = MIN(MAX_IOVEC, fortune_ctx->num_result * 5 + 2);
		const size_t sz = offsetof(iovec_list_t, iov) + iovcnt * sizeof(h2o_iovec_t);
		char _Alignas(iovec_list_t) mem[sz];
		iovec_list_t * const restrict iovec_list = (iovec_list_t *) mem;

		memset(iovec_list, 0, offsetof(iovec_list_t, iov));
		iovec_list->max_iovcnt = iovcnt;
		fortune_ctx->iovec_list_iter = iovec_list;
		fortune_ctx->result = sort_fortunes(fortune_ctx->result);

		if (mustache_render(&api, fortune_ctx, ctx->global_data->fortunes_template)) {
			fortune_ctx->iovec_list = iovec_list->l.next;
			set_default_response_param(HTML, fortune_ctx->content_length, fortune_ctx->req);
			h2o_start_response(fortune_ctx->req, &fortune_ctx->generator);

			const h2o_send_state_t state = fortune_ctx->iovec_list ?
			                               H2O_SEND_STATE_IN_PROGRESS :
			                               H2O_SEND_STATE_FINAL;

			h2o_send(fortune_ctx->req, iovec_list->iov, iovec_list->iovcnt, state);
		}
		else
			send_error(INTERNAL_SERVER_ERROR, REQ_ERROR, fortune_ctx->req);
	}

	return ret;
}