Пример #1
0
static void on_setup_ostream(h2o_filter_t *self, h2o_req_t *req, h2o_ostream_t **slot)
{
    h2o_iovec_t dest, method;
    ssize_t xru_index;

    /* obtain x-reproxy-url header, or skip to next ostream */
    if ((xru_index = h2o_find_header(&req->res.headers, H2O_TOKEN_X_REPROXY_URL, -1)) == -1) {
        h2o_setup_next_ostream(req, slot);
        return;
    }
    dest = req->res.headers.entries[xru_index].value;
    h2o_delete_header(&req->res.headers, xru_index);

    /* setup params */
    switch (req->res.status) {
    case 307:
    case 308:
        method = req->method;
        break;
    default:
        method = h2o_iovec_init(H2O_STRLIT("GET"));
        req->entity = (h2o_iovec_t){NULL};
        break;
    }

    /* request internal redirect (is deferred) */
    h2o_send_redirect_internal(req, method, dest.base, dest.len, 0);

    /* setup filter (that swallows the response until the timeout gets fired) */
    h2o_ostream_t *ostream = h2o_add_ostream(req, H2O_ALIGNOF(*ostream), sizeof(*ostream), slot);
    ostream->do_send = on_send;
}
Пример #2
0
Файл: rproxy.c Проект: Gwill/h2o
static void on_setup_ostream(h2o_filter_t *self, h2o_req_t *req, h2o_ostream_t **slot)
{
    struct rproxy_t *rproxy;
    ssize_t reproxy_header_index;
    h2o_buf_t reproxy_url;

    /* do nothing unless 200 */
    if (req->res.status != 200)
        goto SkipMe;
    if ((reproxy_header_index = h2o_find_header(&req->res.headers, H2O_TOKEN_X_REPROXY_URL, -1)) == -1)
        goto SkipMe;
    reproxy_url = req->res.headers.entries[reproxy_header_index].value;
    h2o_delete_header(&req->res.headers, reproxy_header_index);

    /* setup */
    rproxy = (void*)h2o_add_ostream(req, sizeof(struct rproxy_t), slot);
    rproxy->filter = self;
    rproxy->super.do_send = send_chunk;
    rproxy->reproxy_url = h2o_strdup(&req->pool, reproxy_url.base, reproxy_url.len).base;

    /* next ostream is setup when send_chunk receives EOS */
    return;

SkipMe:
    h2o_setup_next_ostream(self, req, slot);
}
Пример #3
0
static mrb_value h2o_mrb_req_send_file(mrb_state *mrb, mrb_value self)
{
    h2o_mruby_internal_context_t *mruby_ctx = (h2o_mruby_internal_context_t *)mrb->ud;
    char *fn;
    int status;
    h2o_iovec_t content_type;
    int content_type_header_removed = 0;

    if (mruby_ctx->state != H2O_MRUBY_STATE_UNDETERMINED)
        mrb_raise(mrb, E_RUNTIME_ERROR, "response already sent");

    mrb_get_args(mrb, "z", &fn);

    /* determine status and reason to be used */
    if ((status = mruby_ctx->req->res.status) == 0)
        status = 200;

    { /* determine content-type (removing existing header, since it is added by h2o_file_send) */
        ssize_t header_index;
        if ((header_index = h2o_find_header(&mruby_ctx->req->res.headers, H2O_TOKEN_CONTENT_TYPE, -1)) != -1) {
            content_type = mruby_ctx->req->res.headers.entries[header_index].value;
            h2o_delete_header(&mruby_ctx->req->res.headers, header_index);
            content_type_header_removed = 1;
        } else {
            const char *ext = h2o_get_filext(fn, strlen(fn));
            h2o_mimemap_type_t *m = h2o_mimemap_get_type_by_extension(mruby_ctx->req->pathconf->mimemap, ext);
            if (m == NULL || m->type != H2O_MIMEMAP_TYPE_MIMETYPE) {
                m = h2o_mimemap_get_default_type(mruby_ctx->req->pathconf->mimemap);
                assert(m->type == H2O_MIMEMAP_TYPE_MIMETYPE);
            }
            content_type = m->data.mimetype;
        }
    }

    if (h2o_file_send(mruby_ctx->req, status, mruby_ctx->req->res.reason, fn, content_type, H2O_FILE_FLAG_SEND_GZIP) == 0) {
        /* succeeded, return true */
        mruby_ctx->state = H2O_MRUBY_STATE_RESPONSE_SENT;
        return mrb_true_value();
    } else {
        /* failed, restore content-type header and return false */
        if (content_type_header_removed)
            h2o_add_header(&mruby_ctx->req->pool, &mruby_ctx->req->res.headers, H2O_TOKEN_CONTENT_TYPE, content_type.base,
                           content_type.len);
        return mrb_false_value();
    }
}