static int brigade_putc(lua_State*L) { apr_bucket_brigade *bb = (apr_bucket_brigade *) CHECK_BUCKETBRIGADE_OBJECT(1); const char c = (const char)luaL_checkint(L,2); apr_status_t rc = apr_brigade_putc(bb, NULL,NULL, c); lua_pushinteger(L,rc); return 1; }
static apr_status_t upload_filter(ap_filter_t *f, apr_bucket_brigade *bbout, ap_input_mode_t mode, apr_read_type_e block, apr_off_t nbytes) { char* buf = 0 ; char* p = buf ; char* e ; int ret = APR_SUCCESS ; apr_size_t bytes = 0 ; apr_bucket* b ; apr_bucket_brigade* bbin ; upload_ctx* ctx = (upload_ctx*) f->ctx ; if ( ctx->parse_state == p_done ) { // send an EOS APR_BRIGADE_INSERT_TAIL(bbout, apr_bucket_eos_create(bbout->bucket_alloc) ) ; return APR_SUCCESS ; } /* should be more efficient to do this in-place without resorting * to a new brigade */ bbin = apr_brigade_create(f->r->pool, f->r->connection->bucket_alloc) ; if ( ret = ap_get_brigade(f->next, bbin, mode, block, nbytes) , ret != APR_SUCCESS ) return ret ; for ( b = APR_BRIGADE_FIRST(bbin) ; b != APR_BRIGADE_SENTINEL(bbin) ; b = APR_BUCKET_NEXT(b) ) { const char* ptr = buf ; if ( APR_BUCKET_IS_EOS(b) ) { ctx->parse_state = p_done ; APR_BRIGADE_INSERT_TAIL(bbout, apr_bucket_eos_create(bbout->bucket_alloc) ) ; apr_brigade_destroy(bbin) ; return APR_SUCCESS ; } else if ( apr_bucket_read(b, &ptr, &bytes, APR_BLOCK_READ) == APR_SUCCESS ) { const char* p = ptr ; while ( e = strchr(p, '\n'), ( e && ( e < (ptr+bytes) ) ) ) { const char* ptmp = p ; *e = 0 ; if ( ctx->leftover ) { // this'll be grossly inefficient if we get lots of // little buckets (we don't in my setup:-) ptmp = apr_pstrcat(f->r->pool, ctx->leftover, p, NULL) ; ctx->leftover = 0 ; } switch ( ctx->parse_state ) { case p_none: if ( is_boundary(ctx, ptmp) == boundary_part ) ctx->parse_state = p_head ; break ; case p_head: if ( (! *ptmp) || ( *ptmp == '\r') ) ctx->parse_state = p_field ; else set_header(ctx, ptmp) ; break ; case p_field: switch ( is_boundary(ctx, ptmp) ) { case boundary_part: end_body(ctx) ; ctx->parse_state = p_head ; break ; case boundary_end: end_body(ctx) ; ctx->parse_state = p_end ; break ; case boundary_none: if ( ctx->is_file ) { apr_brigade_puts(bbout, ap_filter_flush, f, ptmp) ; apr_brigade_putc(bbout, ap_filter_flush, f, '\n') ; } else set_body(ctx, ptmp) ; break ; } break ; case p_end: //APR_BRIGADE_INSERT_TAIL(bbout, // apr_bucket_eos_create(bbout->bucket_alloc) ) ; ctx->parse_state = p_done ; case p_done: break ; } if ( e - ptr >= bytes ) break ; p = e + 1 ; } if ( ( ctx->parse_state != p_end ) && ( ctx->parse_state != p_done ) ) { size_t bleft = bytes - (p-ptr) ; ctx->leftover = apr_pstrndup(f->r->pool, p, bleft ) ; #ifdef DEBUG ap_log_rerror(APLOG_MARK,APLOG_DEBUG,0, f->r, "leftover %d bytes\n\t%s\n\t%s\n", bleft, ctx->leftover, p) ; #endif } } } apr_brigade_destroy(bbin) ; return ret ; }