Esempio n. 1
0
static int read_msg(request_rec *r, msg_t **msg)
{
    conn_rec *c = r->connection;
    apr_bucket_brigade *bb = apr_brigade_create(r->pool, c->bucket_alloc);
    char *dbuf = apr_palloc(r->pool, MAX_MSG_SIZE);
    int dbpos = 0;
    int seen_eos = 0;

    do {
        apr_status_t rv;
        apr_bucket *bucket;

        rv = ap_get_brigade(r->input_filters, bb, AP_MODE_READBYTES,
                            APR_BLOCK_READ, HUGE_STRING_LEN);

        if (rv != APR_SUCCESS) {
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          "reading request entity data");
            return HTTP_INTERNAL_SERVER_ERROR;
        }

        for (bucket = APR_BRIGADE_FIRST(bb);
                bucket != APR_BRIGADE_SENTINEL(bb);
                bucket = APR_BUCKET_NEXT(bucket))
        {
            const char *data;
            apr_size_t len;

            if (APR_BUCKET_IS_EOS(bucket)) {
                seen_eos = 1;
                break;
            }

            /* We can't do much with this. */
            if (APR_BUCKET_IS_FLUSH(bucket))
                continue;

            /* read */
            apr_bucket_read(bucket, &data, &len, APR_BLOCK_READ);

            if (dbpos < MAX_MSG_SIZE) {
                int cursize = (dbpos + len) > MAX_MSG_SIZE ?
                              (MAX_MSG_SIZE - dbpos) : len;

                memcpy(dbuf + dbpos, data, cursize);
                dbpos += cursize;
            }
        }

        apr_brigade_cleanup(bb);

    } while (!seen_eos);

    (*msg) = apr_pcalloc(r->pool, sizeof(msg_t));
    (*msg)->data = dbuf;
    (*msg)->data[dbpos] = '\0';
    (*msg)->size = dbpos;

    return OK;
}
Esempio n. 2
0
/*
 * This function assumes that either ctx->buffered_bb == NULL, or
 * ctx->buffered_bb is empty, or ctx->buffered_bb == bb
 */
static void setaside_remaining_output(ap_filter_t *f,
                                      core_output_filter_ctx_t *ctx,
                                      apr_bucket_brigade *bb,
                                      conn_rec *c)
{
    if (bb == NULL) {
        return;
    }
    remove_empty_buckets(bb);
    if (!APR_BRIGADE_EMPTY(bb)) {
        c->data_in_output_filters = 1;
        if (bb != ctx->buffered_bb) {
            if (!ctx->deferred_write_pool) {
                apr_pool_create(&ctx->deferred_write_pool, c->pool);
                apr_pool_tag(ctx->deferred_write_pool, "deferred_write");
            }
            ap_save_brigade(f, &(ctx->buffered_bb), &bb,
                            ctx->deferred_write_pool);
            apr_brigade_cleanup(bb);
        }
    }
    else if (ctx->deferred_write_pool) {
        /*
         * There are no more requests in the pipeline. We can just clear the
         * pool.
         */
        apr_pool_clear(ctx->deferred_write_pool);
    }
}
Esempio n. 3
0
apr_status_t h2_stream_prep_read(h2_stream *stream, 
                                 apr_size_t *plen, int *peos)
{
    apr_status_t status = APR_SUCCESS;
    const char *src;
    
    if (stream->bbout && !APR_BRIGADE_EMPTY(stream->bbout)) {
        src = "stream";
        status = h2_util_bb_avail(stream->bbout, plen, peos);
        if (status == APR_SUCCESS && !*peos && !*plen) {
            apr_brigade_cleanup(stream->bbout);
            return h2_stream_prep_read(stream, plen, peos);
        }
    }
    else {
        src = "mplx";
        status = h2_mplx_out_readx(stream->m, stream->id, 
                                   NULL, NULL, plen, peos);
    }
    if (status == APR_SUCCESS && !*peos && !*plen) {
        status = APR_EAGAIN;
    }
    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->m->c,
                  "h2_stream(%ld-%d): prep_read %s, len=%ld eos=%d",
                  stream->m->id, stream->id, 
                  src, (long)*plen, *peos);
    return status;
}
Esempio n. 4
0
static int
php_apache_sapi_read_post(char *buf, uint count_bytes)
{
	apr_size_t len;
	php_struct *ctx = SG(server_context);
	apr_bucket_brigade *brigade;
	apr_bucket *partition;

	brigade = ctx->post_data;
	len = count_bytes;

	switch (apr_brigade_partition(ctx->post_data, count_bytes, &partition)) {
	case APR_SUCCESS:
		apr_brigade_flatten(ctx->post_data, buf, &len);
		brigade = apr_brigade_split(ctx->post_data, partition);
		apr_brigade_destroy(ctx->post_data);
		ctx->post_data = brigade;
		break;
	case APR_INCOMPLETE:
		apr_brigade_flatten(ctx->post_data, buf, &len);
		apr_brigade_cleanup(ctx->post_data);
		break;
	}

	return len;
}
Esempio n. 5
0
static ssize_t write_flush(mgs_handle_t * ctxt) {
    apr_bucket *e;

    if (!(ctxt->output_blen || ctxt->output_length)) {
        ctxt->output_rc = APR_SUCCESS;
        return 1;
    }

    if (ctxt->output_blen) {
        e = apr_bucket_transient_create(ctxt->output_buffer,
                ctxt->output_blen,
                ctxt->output_bb->
                bucket_alloc);
        /* we filled this buffer first so add it to the
         * 		 * head of the brigade
         * 		 		 */
        APR_BRIGADE_INSERT_HEAD(ctxt->output_bb, e);
        ctxt->output_blen = 0;
    }

    ctxt->output_length = 0;
    e = apr_bucket_flush_create(ctxt->output_bb->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(ctxt->output_bb, e);

    ctxt->output_rc = ap_pass_brigade(ctxt->output_filter->next,
            ctxt->output_bb);
    /* clear the brigade to be ready for next time */
    apr_brigade_cleanup(ctxt->output_bb);

    return (ctxt->output_rc == APR_SUCCESS) ? 1 : -1;
}
Esempio n. 6
0
static apr_status_t pass_out(apr_bucket_brigade *bb, void *ctx) 
{
    h2_conn_io *io = (h2_conn_io*)ctx;
    apr_status_t status;
    apr_off_t bblen;
    
    if (APR_BRIGADE_EMPTY(bb)) {
        return APR_SUCCESS;
    }
    
    ap_update_child_status(io->connection->sbh, SERVER_BUSY_WRITE, NULL);
    status = apr_brigade_length(bb, 0, &bblen);
    if (status == APR_SUCCESS) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, io->connection,
                      "h2_conn_io(%ld): pass_out brigade %ld bytes",
                      io->connection->id, (long)bblen);
        status = ap_pass_brigade(io->connection->output_filters, bb);
        if (status == APR_SUCCESS) {
            io->bytes_written += (apr_size_t)bblen;
            io->last_write = apr_time_now();
        }
        apr_brigade_cleanup(bb);
    }
    return status;
}
Esempio n. 7
0
static int php_input_filter(ap_filter_t *f, apr_bucket_brigade *bb,
		ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes)
{
	php_struct *ctx;
	apr_status_t rv;

	if (f->r->proxyreq) {
		return ap_get_brigade(f->next, bb, mode, block, readbytes);
	}

	ctx = SG(server_context);
	if (ctx == NULL) {
		ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, f->r,
					 "php failed to get server context");
		return HTTP_INTERNAL_SERVER_ERROR;
	}

	if ((rv = ap_get_brigade(f->next, bb, mode, block, readbytes)) != APR_SUCCESS) {
		return rv;
	}

	if (!ctx->post_data) {
		ctx->post_data = apr_brigade_create(f->r->pool, f->c->bucket_alloc);
	}
	if ((rv = ap_save_brigade(f, &ctx->post_data, &bb, f->r->pool)) != APR_SUCCESS) {
		return rv;
	}
	apr_brigade_cleanup(bb);
	APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_eos_create(bb->bucket_alloc));

	return APR_SUCCESS;
}
Esempio n. 8
0
/**
 * This works right now because all timers are invoked in the single listener
 * thread in the Event MPM -- the same thread that serf callbacks are made
 * from, so we don't technically need a mutex yet, but with the Simple MPM,
 * invocations are made from worker threads, and we need to figure out locking
 */
static void timed_cleanup_callback(void *baton)
{
    s_baton_t *ctx = baton;

    /* Causes all serf connections to unregister from the event mpm */
    if (ctx->rstatus) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, ctx->rstatus, ctx->r, APLOGNO(01119)
                      "serf: request returned: %d", ctx->rstatus);
        ctx->r->status = HTTP_OK;
        apr_pool_destroy(ctx->serf_pool);
        ap_die(ctx->rstatus, ctx->r);
    }
    else {
        apr_bucket *e;
        apr_brigade_cleanup(ctx->tmpbb);
        e = apr_bucket_flush_create(ctx->r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, e);
        e = apr_bucket_eos_create(ctx->r->connection->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, e);

        /* TODO: return code? bleh */
        ap_pass_brigade(ctx->r->output_filters, ctx->tmpbb);

        apr_pool_destroy(ctx->serf_pool);

        ap_finalize_request_protocol(ctx->r);
        ap_process_request_after_handler(ctx->r);
        return;
    }
}
Esempio n. 9
0
static apr_status_t flush_out(apr_bucket_brigade *bb, void *ctx) 
{
    h2_conn_io *io = (h2_conn_io*)ctx;
    apr_status_t status = ap_pass_brigade(io->connection->output_filters, bb);
    apr_brigade_cleanup(bb);
    return status;
}
Esempio n. 10
0
static int brigade_cleanup(lua_State*L)
{
	apr_bucket_brigade *bb = (apr_bucket_brigade *)CHECK_BUCKETBRIGADE_OBJECT(1);
	apr_status_t rc = apr_brigade_cleanup(bb);
	lua_pushinteger(L,rc);
	return 1;
}
Esempio n. 11
0
APU_DECLARE(apr_bucket_brigade *) apr_brigade_split_ex(apr_bucket_brigade *b,
                                                       apr_bucket *e,
                                                       apr_bucket_brigade *a)
{
    apr_bucket *f;

    if (!a) {
        a = apr_brigade_create(b->p, b->bucket_alloc);
    }
    else if (!APR_BRIGADE_EMPTY(a)) {
        apr_brigade_cleanup(a);
    }
    /* Return an empty brigade if there is nothing left in 
     * the first brigade to split off 
     */
    if (e != APR_BRIGADE_SENTINEL(b)) {
        f = APR_RING_LAST(&b->list);
        APR_RING_UNSPLICE(e, f, link);
        APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
    }

    APR_BRIGADE_CHECK_CONSISTENCY(a);
    APR_BRIGADE_CHECK_CONSISTENCY(b);

    return a;
}
Esempio n. 12
0
static apr_size_t
php_apache_sapi_read_post(char *buf, size_t count_bytes)
{
	apr_size_t len, tlen=0;
	php_struct *ctx = SG(server_context);
	request_rec *r;
	apr_bucket_brigade *brigade;

	r = ctx->r;
	brigade = ctx->brigade;
	len = count_bytes;

	/*
	 * This loop is needed because ap_get_brigade() can return us partial data
	 * which would cause premature termination of request read. Therefor we
	 * need to make sure that if data is available we fill the buffer completely.
	 */

	while (ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) {
		apr_brigade_flatten(brigade, buf, &len);
		apr_brigade_cleanup(brigade);
		tlen += len;
		if (tlen == count_bytes || !len) {
			break;
		}
		buf += len;
		len = count_bytes - tlen;
	}

	return tlen;
}
Esempio n. 13
0
static apr_status_t
read_complete_body(request_rec *r, apr_bucket_brigade *kept_body)
{
    apr_bucket_brigade *tmp_bb;
    apr_bucket *t_bucket1, *t_bucket2;
    unsigned short eos_seen = 0;
    apr_status_t status;

    tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);

    while (!eos_seen) {
        status = ap_get_brigade(
                        r->input_filters,
                        tmp_bb,
                        AP_MODE_READBYTES,
                        APR_BLOCK_READ,
                        HUGE_STRING_LEN);

        /* This means the filter discovered an error.
         * Furthermore input-filter already handeld the error and sends
         * something to the output chain.
         * For example ap_http_filter does this if LimitRequestBody is reached
         */
        if (status == AP_FILTER_ERROR) {
            apr_brigade_destroy(tmp_bb);
            return AP_FILTER_ERROR;
        }

        /* Cool no need to search for the eos bucket */
        if (APR_STATUS_IS_EOF(status)) {
            apr_brigade_destroy(tmp_bb);
            return APR_SUCCESS;
        }

        if (status != APR_SUCCESS) {
            apr_brigade_destroy(tmp_bb);
            return status;
        }

        ITER_BRIGADE(t_bucket1, tmp_bb) {

            apr_bucket_copy(t_bucket1, &t_bucket2);

            /* If SSL is used TRANSIENT buckets are returned.
             * However we need this bucket for a longer period than
             * this function call, hence 'setaside' the bucket.
             */
            if APR_BUCKET_IS_TRANSIENT(t_bucket2) {
                apr_bucket_setaside(t_bucket2, r->pool);
            }

            APR_BRIGADE_INSERT_TAIL(kept_body, t_bucket2);

            if (!eos_seen && APR_BUCKET_IS_EOS(t_bucket1)) {
                eos_seen = 1;
            }
        }
        apr_brigade_cleanup(tmp_bb);
    }
Esempio n. 14
0
static int process_fortune_connection(conn_rec *c)
{
    apr_status_t rv;
    apr_procattr_t *pattr;
    apr_pool_t *p = c->pool;

    apr_bucket *b;
    apr_bucket_brigade *bb;

    const char *err_msg = "200 OK\n";

    fortune_conf_t *fconf =
        ap_get_module_config(c->base_server->module_config,
                             &fortune_module);

    if (!fconf->enabled) {
        return DECLINED;
    }

    bb = apr_brigade_create(p, c->bucket_alloc);

    /* prepare process attribute */
    if ((rv = apr_procattr_create(&pattr, c->pool)) != APR_SUCCESS) {
        goto error;
    }
    if ((rv =
         apr_procattr_io_set(pattr, APR_NO_PIPE, APR_FULL_BLOCK, APR_NO_PIPE))
        != APR_SUCCESS) {
        goto error;
    }
    /* default value: APR_PROGRAM */
    if ((rv =
         apr_procattr_cmdtype_set(pattr, APR_PROGRAM_ENV)) != APR_SUCCESS) {
        goto error;
    }

    /* run the program and read the output from the pipe */
    if ((rv = fortune_process(c, pattr, bb)) != APR_SUCCESS) {
        apr_brigade_cleanup(bb);
    }

  error:
    if (rv != APR_SUCCESS) {
        err_msg = "500 ERROR\n";
    }

    b = apr_bucket_pool_create(err_msg, strlen(err_msg), p, c->bucket_alloc);
    APR_BRIGADE_INSERT_HEAD(bb, b);

    b = apr_bucket_flush_create(c->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, b);

    rv = ap_pass_brigade(c->output_filters, bb);

    return OK;
}
static apr_status_t tmpfile_filter(ap_filter_t *f, apr_bucket_brigade *bbout,
	ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes) {

  apr_bucket_brigade* bbin = apr_brigade_create(f->r->pool,
	     f->r->connection->bucket_alloc);

  apr_file_t* tmpfile ;
  char* tmpname = apr_pstrdup(f->r->pool, "/tmp/mod-upload.XXXXXX") ;

  if ( f->ctx ) {
    APR_BRIGADE_INSERT_TAIL(bbout, apr_bucket_eos_create(bbout->bucket_alloc)) ;
    return APR_SUCCESS ;
  }
  if ( apr_file_mktemp(&tmpfile, tmpname, KEEPONCLOSE, f->r->pool) != APR_SUCCESS ) {
	            // error
    ap_remove_input_filter(f) ;
  }
  apr_pool_cleanup_register(f->r->pool, tmpfile,
		(void*)apr_file_close, apr_pool_cleanup_null) ;

  for ( ; ; ) {
    apr_bucket* b ;
    const char* ptr = 0 ;
    apr_size_t bytes ;
#ifdef DEBUG
    ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0, f->r, "get_brigade") ;
#endif
    ap_get_brigade(f->next, bbin, AP_MODE_READBYTES, APR_BLOCK_READ, BUFLEN) ;
    for ( b = APR_BRIGADE_FIRST(bbin) ;
	b != APR_BRIGADE_SENTINEL(bbin) && ! f->ctx ;
	b = APR_BUCKET_NEXT(b) ) {
      if ( APR_BUCKET_IS_EOS(b) ) {
	f->ctx = f ;	// just using it as a flag; any nonzero will do
	apr_file_flush(tmpfile) ;
	apr_brigade_puts(bbout, ap_filter_flush, f, tmpname) ;
	APR_BRIGADE_INSERT_TAIL(bbout,
		apr_bucket_eos_create(bbout->bucket_alloc) ) ;
      } else if ( apr_bucket_read(b, &ptr, &bytes, APR_BLOCK_READ)
		== APR_SUCCESS ) {
#ifdef DEBUG
  ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0, f->r, "	%d bytes in bucket", bytes) ;
#endif
	apr_file_write(tmpfile, ptr, &bytes) ;
      }
    }
    if ( f->ctx )
      break ;
    else
      apr_brigade_cleanup(bbin) ;
  }

  apr_brigade_destroy(bbin) ;

  return APR_SUCCESS ;
}
Esempio n. 16
0
apr_status_t h2_conn_io_read(h2_conn_io *io,
                             apr_read_type_e block,
                             h2_conn_io_on_read_cb on_read_cb,
                             void *puser)
{
    apr_status_t status;
    int done = 0;
    ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, io->connection,
                  "h2_conn_io: try read, block=%d", block);
    
    if (!APR_BRIGADE_EMPTY(io->input)) {
        /* Seems something is left from a previous read, lets
         * satisfy our caller with the data we already have. */
        status = h2_conn_io_bucket_read(io, block, on_read_cb, puser, &done);
        apr_brigade_cleanup(io->input);
        if (status != APR_SUCCESS || done) {
            return status;
        }
    }

    /* We only do a blocking read when we have no streams to process. So,
     * in httpd scoreboard lingo, we are in a KEEPALIVE connection state.
     * When reading non-blocking, we do have streams to process and update
     * child with NULL request. That way, any current request information
     * in the scoreboard is preserved.
     */
    if (block == APR_BLOCK_READ) {
        ap_update_child_status_from_conn(io->connection->sbh, 
                                         SERVER_BUSY_KEEPALIVE, 
                                         io->connection);
    }
    else {
        ap_update_child_status(io->connection->sbh, SERVER_BUSY_READ, NULL);
    }

    /* TODO: replace this with a connection filter itself, so that we
     * no longer need to transfer incoming buckets to our own brigade. 
     */
    status = ap_get_brigade(io->connection->input_filters,
                            io->input, AP_MODE_READBYTES,
                            block, 64 * 4096);
    switch (status) {
        case APR_SUCCESS:
            return h2_conn_io_bucket_read(io, block, on_read_cb, puser, &done);
        case APR_EOF:
        case APR_EAGAIN:
            break;
        default:
            ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, io->connection,
                          "h2_conn_io: error reading");
            break;
    }
    return status;
}
Esempio n. 17
0
static apr_status_t send_bucket_downstream(ap_filter_t *f, apr_bucket *b)
{
    charset_filter_ctx_t *ctx = f->ctx;
    apr_status_t rv;

    APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
    rv = ap_pass_brigade(f->next, ctx->tmpbb);
    if (rv != APR_SUCCESS) {
        ctx->ees = EES_DOWNSTREAM;
    }
    apr_brigade_cleanup(ctx->tmpbb);
    return rv;
}
Esempio n. 18
0
static apr_status_t CaseFilterOutFilter(ap_filter_t *f,
                                        apr_bucket_brigade *pbbIn)
    {
    request_rec *r = f->r;
    conn_rec *c = r->connection;
    apr_bucket *pbktIn;
    apr_bucket_brigade *pbbOut;

    pbbOut=apr_brigade_create(r->pool, c->bucket_alloc);
    for (pbktIn = APR_BRIGADE_FIRST(pbbIn);
         pbktIn != APR_BRIGADE_SENTINEL(pbbIn);
         pbktIn = APR_BUCKET_NEXT(pbktIn))
    {
        const char *data;
        apr_size_t len;
        char *buf;
        apr_size_t n;
        apr_bucket *pbktOut;

        if(APR_BUCKET_IS_EOS(pbktIn))
            {
            apr_bucket *pbktEOS=apr_bucket_eos_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS);
            continue;
            }

        /* read */
        apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);

        /* write */
        buf = apr_bucket_alloc(len, c->bucket_alloc);
        for(n=0 ; n < len ; ++n)
            buf[n] = apr_toupper(data[n]);

        pbktOut = apr_bucket_heap_create(buf, len, apr_bucket_free,
                                         c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(pbbOut,pbktOut);
        }

    /* Q: is there any advantage to passing a brigade for each bucket?
     * A: obviously, it can cut down server resource consumption, if this
     * experimental module was fed a file of 4MB, it would be using 8MB for
     * the 'read' buckets and the 'write' buckets.
     *
     * Note it is more efficient to consume (destroy) each bucket as it's
     * processed above than to do a single cleanup down here.  In any case,
     * don't let our caller pass the same buckets to us, twice;
     */
    apr_brigade_cleanup(pbbIn);
    return ap_pass_brigade(f->next,pbbOut);
    }
static apr_status_t ef_output_filter(ap_filter_t *f, apr_bucket_brigade *bb)
{
    request_rec *r = f->r;
    ef_ctx_t *ctx = f->ctx;
    apr_status_t rv;

    if (!ctx) {
        if ((rv = init_filter_instance(f)) != APR_SUCCESS) {
            ctx = f->ctx;
            ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                          "can't initialise output filter %s: %s",
                          f->frec->name,
                          (ctx->dc->onfail == 1) ? "removing" : "aborting");
            ap_remove_output_filter(f);
            if (ctx->dc->onfail == 1) {
                return ap_pass_brigade(f->next, bb);
            }
            else {
                apr_bucket *e;
                f->r->status_line = "500 Internal Server Error";

                apr_brigade_cleanup(bb);
                e = ap_bucket_error_create(HTTP_INTERNAL_SERVER_ERROR,
                                           NULL, r->pool,
                                           f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                e = apr_bucket_eos_create(f->c->bucket_alloc);
                APR_BRIGADE_INSERT_TAIL(bb, e);
                ap_pass_brigade(f->next, bb);
                return AP_FILTER_ERROR;
            }
        }
        ctx = f->ctx;
    }
    if (ctx->noop) {
        ap_remove_output_filter(f);
        return ap_pass_brigade(f->next, bb);
    }

    rv = ef_unified_filter(f, bb);
    if (rv != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                      "ef_unified_filter() failed");
    }

    if ((rv = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
        ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
                      "ap_pass_brigade() failed");
    }
    return rv;
}
Esempio n. 20
0
static int proxy_wstunnel_transfer(request_rec *r, conn_rec *c_i, conn_rec *c_o,
                                     apr_bucket_brigade *bb, char *name)
{
    int rv;
#ifdef DEBUGGING
    apr_off_t len;
#endif

    do {
        apr_brigade_cleanup(bb);
        rv = ap_get_brigade(c_i->input_filters, bb, AP_MODE_READBYTES,
                            APR_NONBLOCK_READ, AP_IOBUFSIZE);
        if (rv == APR_SUCCESS) {
            if (c_o->aborted) {
                return APR_EPIPE;
            }
            if (APR_BRIGADE_EMPTY(bb)) {
                break;
            }
#ifdef DEBUGGING
            len = -1;
            apr_brigade_length(bb, 0, &len);
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02440)
                          "read %" APR_OFF_T_FMT
                          " bytes from %s", len, name);
#endif
            rv = ap_pass_brigade(c_o->output_filters, bb);
            if (rv == APR_SUCCESS) {
                ap_fflush(c_o->output_filters, bb);
            }
            else {
                ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02441)
                              "error on %s - ap_pass_brigade",
                              name);
            }
        } else if (!APR_STATUS_IS_EAGAIN(rv) && !APR_STATUS_IS_EOF(rv)) {
            ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, APLOGNO(02442)
                          "error on %s - ap_get_brigade",
                          name);
        }
    } while (rv == APR_SUCCESS);

    ap_log_rerror(APLOG_MARK, APLOG_TRACE2, rv, r, "wstunnel_transfer complete");

    if (APR_STATUS_IS_EAGAIN(rv)) {
        rv = APR_SUCCESS;
    }
   
    return rv;
}
Esempio n. 21
0
apr_status_t h2_stream_readx(h2_stream *stream, 
                             h2_io_data_cb *cb, void *ctx,
                             apr_off_t *plen, int *peos)
{
    apr_status_t status = APR_SUCCESS;
    apr_table_t *trailers = NULL;
    const char *src;
    
    H2_STREAM_OUT(APLOG_TRACE2, stream, "h2_stream readx_pre");
    if (stream->rst_error) {
        return APR_ECONNRESET;
    }
    *peos = 0;
    if (!APR_BRIGADE_EMPTY(stream->bbout)) {
        apr_off_t origlen = *plen;
        
        src = "stream";
        status = h2_util_bb_readx(stream->bbout, cb, ctx, plen, peos);
        if (status == APR_SUCCESS && !*peos && !*plen) {
            apr_brigade_cleanup(stream->bbout);
            *plen = origlen;
            return h2_stream_readx(stream, cb, ctx, plen, peos);
        }
    }
    else {
        src = "mplx";
        status = h2_mplx_out_readx(stream->session->mplx, stream->id, 
                                   cb, ctx, plen, peos, &trailers);
    }
    
    if (trailers && stream->response) {
        ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c,
                      "h2_stream(%ld-%d): readx, saving trailers",
                      stream->session->id, stream->id);
        h2_response_set_trailers(stream->response, trailers);
    }
    
    if (status == APR_SUCCESS && !*peos && !*plen) {
        status = APR_EAGAIN;
    }
    
    H2_STREAM_OUT(APLOG_TRACE2, stream, "h2_stream readx_post");
    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c,
                  "h2_stream(%ld-%d): readx %s, len=%ld eos=%d",
                  stream->session->id, stream->id, src, (long)*plen, *peos);
    H2_STREAM_OUT(APLOG_TRACE2, stream, "h2_stream readx_post");
    
    return status;
}
Esempio n. 22
0
static apr_status_t bail_out_on_error(apr_bucket_brigade *bb,
                                      ap_filter_t *f,
                                      int http_error)
{
    apr_bucket *e;

    apr_brigade_cleanup(bb);
    e = ap_bucket_error_create(http_error,
                               NULL, f->r->pool,
                               f->c->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, e);
    e = apr_bucket_eos_create(f->c->bucket_alloc);
    APR_BRIGADE_INSERT_TAIL(bb, e);
    return ap_pass_brigade(f->r->output_filters, bb);
}
Esempio n. 23
0
apr_status_t h2_io_out_write(h2_io *io, apr_bucket_brigade *bb, 
                             apr_size_t maxlen, int *pfile_handles_allowed)
{
    apr_status_t status;
    int start_allowed;
    
    if (io->rst_error) {
        return APR_ECONNABORTED;
    }

    if (io->eos_out) {
        apr_off_t len;
        /* We have already delivered an EOS bucket to a reader, no
         * sense in storing anything more here.
         */
        status = apr_brigade_length(bb, 1, &len);
        if (status == APR_SUCCESS) {
            if (len > 0) {
                /* someone tries to write real data after EOS, that
                 * does not look right. */
                status = APR_EOF;
            }
            /* cleanup, as if we had moved the data */
            apr_brigade_cleanup(bb);
        }
        return status;
    }
    
    /* Let's move the buckets from the request processing in here, so
     * that the main thread can read them when it has time/capacity.
     *
     * Move at most "maxlen" memory bytes. If buckets remain, it is
     * the caller's responsibility to take care of this.
     *
     * We allow passing of file buckets as long as we do not have too
     * many open files already buffered. Otherwise we will run out of
     * file handles.
     */
    start_allowed = *pfile_handles_allowed;

    status = h2_util_move(io->bbout, bb, maxlen, pfile_handles_allowed, 
                          "h2_io_out_write");
    /* track # file buckets moved into our pool */
    if (start_allowed != *pfile_handles_allowed) {
        io->files_handles_owned += (start_allowed - *pfile_handles_allowed);
    }
    return status;
}
Esempio n. 24
0
MP_INLINE static int get_bucket(modperl_filter_t *filter)
{
    if (!filter->bb_in || MP_FILTER_EMPTY(filter)) {
        MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
                   "read in: bucket brigade is empty",
                   MP_FILTER_NAME(filter->f));
        return 0;
    }

    if (!filter->bucket) {
        filter->bucket = MP_FILTER_FIRST(filter);
    }
    else if (filter->bucket != MP_FILTER_SENTINEL(filter)) {
        filter->bucket = MP_FILTER_NEXT(filter);
    }

    if (filter->bucket == MP_FILTER_SENTINEL(filter)) {
        filter->bucket = NULL;
        /* can't destroy bb_in since the next read will need a brigade
         * to try to read from */
        apr_brigade_cleanup(filter->bb_in);
        return 0;
    }

    if (MP_FILTER_IS_EOS(filter)) {
        MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
                   "read in: EOS bucket",
                   MP_FILTER_NAME(filter->f));

        filter->seen_eos = 1;
        /* there should be only one EOS sent, modperl_filter_read will
         * not come here, since filter->seen_eos is set
         */
        return 0;
    }
    else if (MP_FILTER_IS_FLUSH(filter)) {
        MP_TRACE_f(MP_FUNC, MP_FILTER_NAME_FORMAT
                   "read in: FLUSH bucket",
                   MP_FILTER_NAME(filter->f));
        filter->flush = 1;
        return 0;
    }
    else {
        return 1;
    }
}
Esempio n. 25
0
static int cdn_html_filter(ap_filter_t * f, apr_bucket_brigade * bb)
{
  apr_bucket *b;
  const char *buf = 0;
  apr_size_t bytes = 0;

  /* now do HTML filtering if necessary, and pass the brigade onward */
  saxctxt *ctxt = check_html_filter_init(f);
  if (!ctxt)
    return ap_pass_brigade(f->next, bb);

  for(b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) {
    if(APR_BUCKET_IS_EOS(b) || APR_BUCKET_IS_FLUSH(b)) {
      consume_buffer(ctxt, buf, 0, 1);
      APR_BUCKET_REMOVE(b);
      APR_BRIGADE_INSERT_TAIL(ctxt->bb, b);
      ap_pass_brigade(ctxt->f->next, ctxt->bb);
      return APR_SUCCESS;
    }

    if(apr_bucket_read(b, &buf, &bytes, APR_BLOCK_READ) == APR_SUCCESS && buf) {
      if(ctxt->parser == NULL) {

        /*
         * for now, always output utf-8; we could incorporate
         * mod_proxy_html's output transcoding with little problem if
         * necessary
         */
        ap_set_content_type(f->r, "text/html;charset=utf-8");

        if(!initialize_parser(f, ctxt, &buf, bytes)) {
          apr_status_t rv = ap_pass_brigade(ctxt->f->next, bb);
          ap_remove_output_filter(f);
          return rv;
        } else
          ap_fputs(f->next, ctxt->bb, ctxt->cfg->doctype);
      }
      consume_buffer(ctxt, buf, bytes, 0);
    }

  }

  /*ap_fflush(ctxt->f->next, ctxt->bb) ; */      /* uncomment for debug */
  apr_brigade_cleanup(bb);
  return APR_SUCCESS;
}
Esempio n. 26
0
static void
read_post_data(sl_vm_t* vm, sl_request_opts_t* opts, request_rec* r)
{
    apr_bucket_brigade* brigade = apr_brigade_create(r->pool, r->connection->bucket_alloc);
    size_t len = 1024;
    opts->post_length = 0;
    opts->post_data = NULL;
    while(ap_get_brigade(r->input_filters, brigade, AP_MODE_READBYTES, APR_BLOCK_READ, len) == APR_SUCCESS) {
        opts->post_data = sl_realloc(vm->arena, opts->post_data, opts->post_length + len);
        apr_brigade_flatten(brigade, opts->post_data + opts->post_length, &len);
        apr_brigade_cleanup(brigade);
        opts->post_length += len;
        if(!len) {
            break;
        }
        len = 1024;
    }
}
Esempio n. 27
0
void pstar_io::write_immortal(const char *str, int len) {
	if (!headers_sent) {
		output_headers();
	}
	apr_status_t rv;
	apr_bucket *b;

	b = apr_bucket_immortal_create (str, len, ba);
	APR_BRIGADE_INSERT_TAIL(bb, b);

	if (waiting_buckets++ % 100 == 0) {
		rv = ap_pass_brigade(r->output_filters, bb);
		if (rv != APR_SUCCESS) {
			throw runtime_error("pstar_io::write(); Could not write to client");
		}
		apr_brigade_cleanup(bb);
	}
}
Esempio n. 28
0
/* Return a pool-allocated NUL-terminated line, with CRLF stripped,
 * read from brigade 'bbin' using 'bbout' as temporary storage. */
static char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin,
                      conn_rec *c, apr_pool_t *p)
{
    apr_status_t rv;
    apr_size_t len;
    char *line;

    apr_brigade_cleanup(bbout);

    rv = apr_brigade_split_line(bbout, bbin, APR_BLOCK_READ, 8192);
    if (rv) {
        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01977)
                      "failed reading line from OCSP server");
        return NULL;
    }

    rv = apr_brigade_pflatten(bbout, &line, &len, p);
    if (rv) {
        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01978)
                      "failed reading line from OCSP server");
        return NULL;
    }

    if (len == 0) {
        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(02321)
                      "empty response from OCSP server");
        return NULL;
    }

    if (line[len-1] != APR_ASCII_LF) {
        ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979)
                      "response header line too long from OCSP server");
        return NULL;
    }

    line[len-1] = '\0';
    if (len > 1 && line[len-2] == APR_ASCII_CR) {
        line[len-2] = '\0';
    }

    return line;
}
Esempio n. 29
0
apr_status_t h2_stream_prep_read(h2_stream *stream, 
                                 apr_off_t *plen, int *peos)
{
    apr_status_t status = APR_SUCCESS;
    const char *src;
    apr_table_t *trailers = NULL;
    int test_read = (*plen == 0);
    
    if (stream->rst_error) {
        return APR_ECONNRESET;
    }

    H2_STREAM_OUT(APLOG_TRACE2, stream, "h2_stream prep_read_pre");
    if (!APR_BRIGADE_EMPTY(stream->bbout)) {
        src = "stream";
        status = h2_util_bb_avail(stream->bbout, plen, peos);
        if (!test_read && status == APR_SUCCESS && !*peos && !*plen) {
            apr_brigade_cleanup(stream->bbout);
            return h2_stream_prep_read(stream, plen, peos);
        }
        trailers = stream->response? stream->response->trailers : NULL;
    }
    else {
        src = "mplx";
        status = h2_mplx_out_readx(stream->session->mplx, stream->id, 
                                   NULL, NULL, plen, peos, &trailers);
        if (trailers && stream->response) {
            h2_response_set_trailers(stream->response, trailers);
        }    
    }
    
    if (!test_read && status == APR_SUCCESS && !*peos && !*plen) {
        status = APR_EAGAIN;
    }
    
    H2_STREAM_OUT(APLOG_TRACE2, stream, "h2_stream prep_read_post");
    ap_log_cerror(APLOG_MARK, APLOG_TRACE1, status, stream->session->c,
                  "h2_stream(%ld-%d): prep_read %s, len=%ld eos=%d, trailers=%s",
                  stream->session->id, stream->id, src, (long)*plen, *peos,
                  trailers? "yes" : "no");
    return status;
}
static apr_status_t urlReplaceFilterOutFilter(ap_filter_t *f,
                                        apr_bucket_brigade *pbbIn)
{
    request_rec *r = f->r;
    conn_rec *c = r->connection;
    apr_bucket *pbktIn;
    apr_bucket_brigade *pbbOut;

    pbbOut=apr_brigade_create(r->pool, c->bucket_alloc);
    for (pbktIn = APR_BRIGADE_FIRST(pbbIn);
            pbktIn != APR_BRIGADE_SENTINEL(pbbIn);
            pbktIn = APR_BUCKET_NEXT(pbktIn))
    {
        const char *data;
        apr_size_t len;
        char *buf;
        apr_size_t n;
        apr_bucket *pbktOut;

        if (APR_BUCKET_IS_EOS(pbktIn))
        {
            apr_bucket *pbktEOS=apr_bucket_eos_create(c->bucket_alloc);
            APR_BRIGADE_INSERT_TAIL(pbbOut,pbktEOS);
            continue;
        }

        /* read */
        apr_bucket_read(pbktIn,&data,&len,APR_BLOCK_READ);

        /* write */
        buf = apr_bucket_alloc(len, c->bucket_alloc);
        for (n=0 ; n < len ; ++n)
            buf[n] = apr_toupper(data[n]);

        pbktOut = apr_bucket_heap_create(buf, len, apr_bucket_free,
                                         c->bucket_alloc);
        APR_BRIGADE_INSERT_TAIL(pbbOut,pbktOut);
    }
    apr_brigade_cleanup(pbbIn);
    return ap_pass_brigade(f->next,pbbOut);
}