/** * Searches the input request for a flash socket policy request. This request, * unfortunately, does not follow the HTTP protocol and cannot be handled * via a special HTTP handler. Instead, it is a short xml string followed by * a null character: * * '<policy-file-request/>\0' * * A peek into the incoming data checks the first character of the stream to * see if it is '<' (as opposed to typically something else for HTTP). If it * is not, then this function returns and HTTP input is read normally. If it * is, then the remaining bytes in the policy-file-request are read and * checked. If a match is found, then the filter state will be updated to * inform the output filter to send a cross-domain policy as a response. If * no match is found, HTTP traffic will proceed as usual. * * @param f the input filter. * @param state the filter state. * * @return APR_SUCCESS on success, some other status on failure. */ static apr_status_t find_policy_file_request( ap_filter_t* f, filter_state* state) { apr_status_t rval = APR_SUCCESS; // create a temp buffer for speculative reads apr_bucket_brigade* tmp = apr_brigade_create(f->c->pool, f->c->bucket_alloc); // FIXME: not sure how blocking mode works ... can it return fewer than // the number of specified bytes? // peek at the first PFR_LENGTH bytes rval = ap_get_brigade( f->next, tmp, AP_MODE_SPECULATIVE, APR_BLOCK_READ, PFR_LENGTH); if(rval == APR_SUCCESS) { // quickly check the first bucket for the beginning of a pfr const char* data; apr_size_t length; apr_bucket* b = APR_BRIGADE_FIRST(tmp); rval = apr_bucket_read(b, &data, &length, APR_BLOCK_READ); if(rval == APR_SUCCESS && length > 0 && data[0] == '<') { // possible policy file request, fill local buffer char pfr[PFR_LENGTH]; char* ptr = pfr; memcpy(ptr, data, length); ptr += length; memset(ptr, '\0', PFR_LENGTH - length); b = APR_BUCKET_NEXT(b); while(rval == APR_SUCCESS && b != APR_BRIGADE_SENTINEL(tmp)) { rval = apr_bucket_read(b, &data, &length, APR_BLOCK_READ); if(rval == APR_SUCCESS) { memcpy(ptr, data, length); ptr += length; b = APR_BUCKET_NEXT(b); } } if(rval == APR_SUCCESS) { // see if pfr is a policy file request: '<policy-file-request/>\0' if((ptr - pfr == PFR_LENGTH) && (pfr[PFR_LENGTH - 1] == '\0') && (strncmp(pfr, "<policy-file-request/>", PFR_LENGTH -1) == 0)) { // pfr found state->found = 1; } } } } return rval; }
APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b, struct iovec *vec, int *nvec) { int left = *nvec; apr_bucket *e; struct iovec *orig; apr_size_t iov_len; apr_status_t rv; orig = vec; for (e = APR_BRIGADE_FIRST(b); e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) { if (left-- == 0) break; rv = apr_bucket_read(e, (const char **)&vec->iov_base, &iov_len, APR_NONBLOCK_READ); if (rv != APR_SUCCESS) return rv; vec->iov_len = iov_len; /* set indirectly in case size differs */ ++vec; } *nvec = vec - orig; return APR_SUCCESS; }
static apr_status_t CaseFilterInFilter(ap_filter_t *f, apr_bucket_brigade *pbbOut, ap_input_mode_t eMode, apr_read_type_e eBlock, apr_off_t nBytes) { request_rec *r = f->r; conn_rec *c = r->connection; CaseFilterInContext *pCtx; apr_status_t ret; if (!(pCtx = f->ctx)) { f->ctx = pCtx = apr_palloc(r->pool, sizeof *pCtx); pCtx->pbbTmp = apr_brigade_create(r->pool, c->bucket_alloc); } if (APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { ret = ap_get_brigade(f->next, pCtx->pbbTmp, eMode, eBlock, nBytes); if (eMode == AP_MODE_EATCRLF || ret != APR_SUCCESS) return ret; } while (!APR_BRIGADE_EMPTY(pCtx->pbbTmp)) { apr_bucket *pbktIn = APR_BRIGADE_FIRST(pCtx->pbbTmp); apr_bucket *pbktOut; const char *data; apr_size_t len; char *buf; apr_size_t n; /* It is tempting to do this... * APR_BUCKET_REMOVE(pB); * APR_BRIGADE_INSERT_TAIL(pbbOut,pB); * and change the case of the bucket data, but that would be wrong * for a file or socket buffer, for example... */ if (APR_BUCKET_IS_EOS(pbktIn)) { APR_BUCKET_REMOVE(pbktIn); APR_BRIGADE_INSERT_TAIL(pbbOut, pbktIn); break; } ret=apr_bucket_read(pbktIn, &data, &len, eBlock); if (ret != APR_SUCCESS) return ret; buf = ap_malloc(len); for (n=0 ; n < len ; ++n) { buf[n] = apr_toupper(data[n]); } pbktOut = apr_bucket_heap_create(buf, len, 0, c->bucket_alloc); APR_BRIGADE_INSERT_TAIL(pbbOut, pbktOut); apr_bucket_delete(pbktIn); } return APR_SUCCESS; }
static triger_bucket_t *get_data_at_tail(ap_filter_t * f, apr_bucket_brigade * bb) { const char *data; apr_bucket *b = APR_BRIGADE_LAST(bb); apr_size_t len = 0; triger_module_ctx_t *ctx = f->ctx; triger_bucket_t *rv = ctx->triger_bucket; rv->len = 0; rv->data = NULL; rv->b = NULL; rv->body_end_tag_pos = rv->body_start_tag_pos = rv->html_start_tag_pos = rv->head_start_tag_pos = rv->body_start_tag_pos = -1; while (APR_BUCKET_IS_METADATA(b) && b != APR_BRIGADE_SENTINEL(bb)) b = APR_BUCKET_PREV(b); if (APR_BUCKET_IS_METADATA(b) || b == APR_BRIGADE_SENTINEL(bb)) return rv; apr_bucket_read(b, &data, &len, APR_BLOCK_READ); rv->len = len; rv->data = data; rv->b = b; return rv; }
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; }
APU_DECLARE(apr_status_t) apr_brigade_to_iovec(apr_bucket_brigade *b, struct iovec *vec, int *nvec) { int left = *nvec; apr_bucket *e; struct iovec *orig; apr_size_t iov_len; const char *iov_base; apr_status_t rv; orig = vec; for (e = APR_BRIGADE_FIRST(b); e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) { if (left-- == 0) break; rv = apr_bucket_read(e, &iov_base, &iov_len, APR_NONBLOCK_READ); if (rv != APR_SUCCESS) return rv; /* Set indirectly since types differ: */ vec->iov_len = iov_len; vec->iov_base = (void *)iov_base; ++vec; } *nvec = (int)(vec - orig); return APR_SUCCESS; }
APU_DECLARE(apr_status_t) apr_brigade_length(apr_bucket_brigade *bb, int read_all, apr_off_t *length) { apr_off_t total = 0; apr_bucket *bkt; apr_status_t status = APR_SUCCESS; for (bkt = APR_BRIGADE_FIRST(bb); bkt != APR_BRIGADE_SENTINEL(bb); bkt = APR_BUCKET_NEXT(bkt)) { if (bkt->length == (apr_size_t)(-1)) { const char *ignore; apr_size_t len; if (!read_all) { total = -1; break; } if ((status = apr_bucket_read(bkt, &ignore, &len, APR_BLOCK_READ)) != APR_SUCCESS) { break; } } total += bkt->length; } *length = total; return status; }
static int ef_input_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { apr_status_t rv; apr_bucket *b; char *buf; apr_ssize_t len; char *zero; rv = ap_get_brigade(f->next, bb, mode, block, readbytes); if (rv != APR_SUCCESS) { return rv; } APR_BRIGADE_FOREACH(b, bb) { if (!APR_BUCKET_IS_EOS(b)) { if ((rv = apr_bucket_read(b, (const char **)&buf, &len, APR_BLOCK_READ)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, f->r, "apr_bucket_read() failed"); return rv; } ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "apr_bucket_read -> %d bytes", len); while ((zero = memchr(buf, '0', len))) { *zero = 'a'; } } else ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL, "got eos bucket"); } return rv; }
/* Regression test for PR 34708, where a file bucket will keep * duplicating itself on being read() when EOF is reached * prematurely. */ static void test_truncfile(abts_case *tc, void *data) { apr_bucket_alloc_t *ba = apr_bucket_alloc_create(p); apr_bucket_brigade *bb = apr_brigade_create(p, ba); apr_file_t *f = make_test_file(tc, "testfile.txt", "hello"); apr_bucket *e; const char *buf; apr_size_t len; apr_brigade_insert_file(bb, f, 0, 5, p); apr_file_trunc(f, 0); e = APR_BRIGADE_FIRST(bb); ABTS_ASSERT(tc, "single bucket in brigade", APR_BUCKET_NEXT(e) == APR_BRIGADE_SENTINEL(bb)); apr_bucket_file_enable_mmap(e, 0); ABTS_ASSERT(tc, "read gave APR_EOF", apr_bucket_read(e, &buf, &len, APR_BLOCK_READ) == APR_EOF); ABTS_ASSERT(tc, "read length 0", len == 0); ABTS_ASSERT(tc, "still a single bucket in brigade", APR_BUCKET_NEXT(e) == APR_BRIGADE_SENTINEL(bb)); apr_file_close(f); apr_brigade_destroy(bb); apr_bucket_alloc_destroy(ba); }
/** * This input filter will basically sniff on a connection and analyse * the packets when it detects SSL. */ static apr_status_t mod_sslhaf_in_filter(ap_filter_t *f, apr_bucket_brigade *bb, ap_input_mode_t mode, apr_read_type_e block, apr_off_t readbytes) { sslhaf_cfg_t *cfg = ap_get_module_config(f->c->conn_config, &sslhaf_module); apr_status_t status; apr_bucket *bucket; // Return straight away if there's no configuration if (cfg == NULL) { return ap_get_brigade(f->next, bb, mode, block, readbytes); } // Sanity check first if (cfg->state == SSLHAF_STATE_GOAWAY) { return ap_get_brigade(f->next, bb, mode, block, readbytes); } // Get brigade status = ap_get_brigade(f->next, bb, mode, block, readbytes); if (status != APR_SUCCESS) { // Do not log, since we're passing the status anyway cfg->state = SSLHAF_STATE_GOAWAY; return status; } // Loop through the buckets for(bucket = APR_BRIGADE_FIRST(bb); bucket != APR_BRIGADE_SENTINEL(bb); bucket = APR_BUCKET_NEXT(bucket)) { const char *buf = NULL; apr_size_t buflen = 0; if (!(APR_BUCKET_IS_METADATA(bucket))) { // Get bucket data status = apr_bucket_read(bucket, &buf, &buflen, APR_BLOCK_READ); if (status != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, status, f->c->base_server, "mod_sslhaf [%s]: Error while reading input bucket", SSLHAF_AP_CONN_REMOTE_IP(f->c)); return status; } // Look into the bucket if (sslhaf_decode_buffer(cfg, (const unsigned char *)buf, buflen) <= 0) { cfg->state = SSLHAF_STATE_GOAWAY; } } } return APR_SUCCESS; }
static apr_status_t last_not_included(apr_bucket_brigade *bb, apr_size_t maxlen, int same_alloc, int *pfile_buckets_allowed, apr_bucket **pend) { apr_bucket *b; apr_status_t status = APR_SUCCESS; int files_allowed = pfile_buckets_allowed? *pfile_buckets_allowed : 0; if (maxlen > 0) { /* Find the bucket, up to which we reach maxlen/mem bytes */ for (b = APR_BRIGADE_FIRST(bb); (b != APR_BRIGADE_SENTINEL(bb)); b = APR_BUCKET_NEXT(b)) { if (APR_BUCKET_IS_METADATA(b)) { /* included */ } else { if (maxlen == 0) { *pend = b; return status; } if (b->length == ((apr_size_t)-1)) { const char *ign; apr_size_t ilen; status = apr_bucket_read(b, &ign, &ilen, APR_BLOCK_READ); if (status != APR_SUCCESS) { return status; } } if (same_alloc && APR_BUCKET_IS_FILE(b)) { /* we like it move it, always */ } else if (files_allowed > 0 && APR_BUCKET_IS_FILE(b)) { /* this has no memory footprint really unless * it is read, disregard it in length count, * unless we do not move the file buckets */ --files_allowed; } else if (maxlen < b->length) { apr_bucket_split(b, maxlen); maxlen = 0; } else { maxlen -= b->length; } } } } *pend = APR_BRIGADE_SENTINEL(bb); return status; }
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 ; }
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); }
APU_DECLARE(apr_status_t) apr_brigade_split_line(apr_bucket_brigade *bbOut, apr_bucket_brigade *bbIn, apr_read_type_e block, apr_off_t maxbytes) { apr_off_t readbytes = 0; while (!APR_BRIGADE_EMPTY(bbIn)) { const char *pos; const char *str; apr_size_t len; apr_status_t rv; apr_bucket *e; e = APR_BRIGADE_FIRST(bbIn); rv = apr_bucket_read(e, &str, &len, block); if (rv != APR_SUCCESS) { return rv; } pos = memchr(str, APR_ASCII_LF, len); /* We found a match. */ if (pos != NULL) { apr_bucket_split(e, pos - str + 1); APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(bbOut, e); return APR_SUCCESS; } APR_BUCKET_REMOVE(e); if (APR_BUCKET_IS_METADATA(e) || len > APR_BUCKET_BUFF_SIZE/4) { APR_BRIGADE_INSERT_TAIL(bbOut, e); } else { if (len > 0) { rv = apr_brigade_write(bbOut, NULL, NULL, str, len); if (rv != APR_SUCCESS) { return rv; } } apr_bucket_destroy(e); } readbytes += len; /* We didn't find an APR_ASCII_LF within the maximum line length. */ if (readbytes >= maxbytes) { break; } } return APR_SUCCESS; }
static apr_status_t h2_conn_io_bucket_read(h2_conn_io *io, apr_read_type_e block, h2_conn_io_on_read_cb on_read_cb, void *puser, int *pdone) { apr_status_t status = APR_SUCCESS; apr_size_t readlen = 0; *pdone = 0; while (status == APR_SUCCESS && !*pdone && !APR_BRIGADE_EMPTY(io->input)) { apr_bucket* bucket = APR_BRIGADE_FIRST(io->input); if (APR_BUCKET_IS_METADATA(bucket)) { /* we do nothing regarding any meta here */ } else { const char *bucket_data = NULL; apr_size_t bucket_length = 0; status = apr_bucket_read(bucket, &bucket_data, &bucket_length, block); if (status == APR_SUCCESS && bucket_length > 0) { if (APLOGctrace2(io->connection)) { char buffer[32]; h2_util_hex_dump(buffer, sizeof(buffer)/sizeof(buffer[0]), bucket_data, bucket_length); ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, io->connection, "h2_conn_io(%ld): read %d bytes: %s", io->connection->id, (int)bucket_length, buffer); } if (bucket_length > 0) { apr_size_t consumed = 0; status = on_read_cb(bucket_data, bucket_length, &consumed, pdone, puser); if (status == APR_SUCCESS && bucket_length > consumed) { /* We have data left in the bucket. Split it. */ status = apr_bucket_split(bucket, consumed); } readlen += consumed; } } } apr_bucket_delete(bucket); } if (readlen == 0 && status == APR_SUCCESS && block == APR_NONBLOCK_READ) { return APR_EAGAIN; } return status; }
apr_status_t jxr_append_brigade(request_rec *r, apr_bucket_brigade *dest, apr_bucket_brigade *bb, int *eos_seen) { apr_size_t max_msglen = MAX_PACKET_SIZE - sizeof(Jaxer_Header); apr_status_t rv; while (!APR_BRIGADE_EMPTY(bb)) { apr_size_t readlen; const char *buffer; apr_bucket *e = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_EOS(e) ) { apr_bucket_delete(e); if (eos_seen) *eos_seen = 1; continue; } if (APR_BUCKET_IS_METADATA(e)) { apr_bucket_delete(e); continue; } /* Read the bucket now */ if ((rv = apr_bucket_read(e, &buffer, &readlen, APR_BLOCK_READ)) != APR_SUCCESS) { ap_log_perror(APLOG_MARK, APLOG_INFO, rv, r->pool, "mod_jaxer: can't read data from handler"); return rv; } if (readlen > max_msglen) { apr_bucket_split(e, max_msglen); }else { APR_BUCKET_REMOVE(e); APR_BRIGADE_INSERT_TAIL(dest, e); } } if ((rv=apr_brigade_destroy(bb)) != APR_SUCCESS) { ap_log_perror(APLOG_MARK, APLOG_INFO, rv, r->pool, "mod_jaxer: failed to destroy brigade."); return rv; } return APR_SUCCESS; }
/* Test that bucket E has content EDATA of length ELEN. */ static void test_bucket_content(abts_case *tc, apr_bucket *e, const char *edata, apr_size_t elen) { const char *adata; apr_size_t alen; apr_assert_success(tc, "read from bucket", apr_bucket_read(e, &adata, &alen, APR_BLOCK_READ)); ABTS_ASSERT(tc, "read expected length", alen == elen); ABTS_STR_NEQUAL(tc, edata, adata, elen); }
apr_status_t jxr_send_brigade(jaxer_connection * ac, apr_bucket_brigade * bb) { apr_bucket *bucket; apr_status_t rv; compat_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ac->request, "mod_jaxer: sending a brigade (sock=%d)", ac->sock); for (bucket = APR_BRIGADE_FIRST(bb); bucket != APR_BRIGADE_SENTINEL(bb); bucket = APR_BUCKET_NEXT(bucket)) { char *write_buf; apr_size_t write_buf_len; if (APR_BUCKET_IS_EOS(bucket)) break; if (APR_BUCKET_IS_FLUSH(bucket)) continue; if ((rv = apr_bucket_read(bucket, (const char **)&write_buf, &write_buf_len, APR_BLOCK_READ)) != APR_SUCCESS) { compat_log_rerror(APLOG_MARK, APLOG_WARNING, rv, ac->request, "mod_jaxer: can't read request from bucket"); return rv; } { int type = jxr_msg_get_type(write_buf); apr_size_t pos; // not used apr_size_t len = jxr_msg_get_length(write_buf, &pos); compat_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ac->request, "mod_jaxer: sending a brigade (type=%s len=%d)", sBlockType[type], len); } /* Write the buffer to jaxer server */ if(0 > jxr_socket_sendfull(ac, write_buf, (int) write_buf_len)) { compat_log_rerror(APLOG_MARK, APLOG_WARNING, APR_FROM_OS_ERROR(rv), ac->request, "mod_jaxer: can't write to socket"); return apr_get_os_error(); } } compat_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, ac->request, "mod_jaxer: sent a brigade (sock=%d)", ac->sock); return APR_SUCCESS; }
static apr_status_t beam_bucket_read(apr_bucket *b, const char **str, apr_size_t *len, apr_read_type_e block) { h2_beam_proxy *d = b->data; if (d->bred) { const char *data; apr_status_t status = apr_bucket_read(d->bred, &data, len, block); if (status == APR_SUCCESS) { *str = data + b->start; *len = b->length; } return status; } *str = &Dummy; *len = 0; return APR_ECONNRESET; }
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; }
AP_DECLARE(apr_status_t) ap_save_brigade(ap_filter_t *f, apr_bucket_brigade **saveto, apr_bucket_brigade **b, apr_pool_t *p) { apr_bucket *e; apr_status_t rv, srv = APR_SUCCESS; /* If have never stored any data in the filter, then we had better * create an empty bucket brigade so that we can concat. */ if (!(*saveto)) { *saveto = apr_brigade_create(p, f->c->bucket_alloc); } for (e = APR_BRIGADE_FIRST(*b); e != APR_BRIGADE_SENTINEL(*b); e = APR_BUCKET_NEXT(e)) { rv = apr_bucket_setaside(e, p); /* If the bucket type does not implement setaside, then * (hopefully) morph it into a bucket type which does, and set * *that* aside... */ if (rv == APR_ENOTIMPL) { const char *s; apr_size_t n; rv = apr_bucket_read(e, &s, &n, APR_BLOCK_READ); if (rv == APR_SUCCESS) { rv = apr_bucket_setaside(e, p); } } if (rv != APR_SUCCESS) { srv = rv; /* Return an error but still save the brigade if * ->setaside() is really not implemented. */ if (rv != APR_ENOTIMPL) { return rv; } } } APR_BRIGADE_CONCAT(*saveto, *b); return srv; }
static int getsfunc_BRIGADE(char *buf, int len, void *arg) { apr_bucket_brigade *bb = (apr_bucket_brigade *)arg; const char *dst_end = buf + len - 1; /* leave room for terminating null */ char *dst = buf; apr_bucket *e = APR_BRIGADE_FIRST(bb); apr_status_t rv; int done = 0; while ((dst < dst_end) && !done && e != APR_BRIGADE_SENTINEL(bb) && !APR_BUCKET_IS_EOS(e)) { const char *bucket_data; apr_size_t bucket_data_len; const char *src; const char *src_end; apr_bucket * next; rv = apr_bucket_read(e, &bucket_data, &bucket_data_len, APR_BLOCK_READ); if (rv != APR_SUCCESS || (bucket_data_len == 0)) { *dst = '\0'; return APR_STATUS_IS_TIMEUP(rv) ? -1 : 0; } src = bucket_data; src_end = bucket_data + bucket_data_len; while ((src < src_end) && (dst < dst_end) && !done) { if (*src == '\n') { done = 1; } else if (*src != '\r') { *dst++ = *src; } src++; } if (src < src_end) { apr_bucket_split(e, src - bucket_data); } next = APR_BUCKET_NEXT(e); apr_bucket_delete(e); e = next; } *dst = 0; return done; }
static void discard_script_output(apr_bucket_brigade *bb) { apr_bucket *e; const char *buf; apr_size_t len; apr_status_t rv; e = APR_BRIGADE_FIRST(bb); while (e != APR_BRIGADE_SENTINEL(bb)) { if (APR_BUCKET_IS_EOS(e)) { break; } rv = apr_bucket_read(e, &buf, &len, APR_BLOCK_READ); if (rv != APR_SUCCESS) { break; } e = APR_BUCKET_NEXT(e); } }
APU_DECLARE(apr_status_t) apr_brigade_flatten(apr_bucket_brigade *bb, char *c, apr_size_t *len) { apr_size_t actual = 0; apr_bucket *b; for (b = APR_BRIGADE_FIRST(bb); b != APR_BRIGADE_SENTINEL(bb); b = APR_BUCKET_NEXT(b)) { const char *str; apr_size_t str_len; apr_status_t status; status = apr_bucket_read(b, &str, &str_len, APR_BLOCK_READ); if (status != APR_SUCCESS) { return status; } /* If we would overflow. */ if (str_len + actual > *len) { str_len = *len - actual; } /* XXX: It appears that overflow of the final bucket * is DISCARDED without any warning to the caller. * * No, we only copy the data up to their requested size. -- jre */ memcpy(c, str, str_len); c += str_len; actual += str_len; /* This could probably be actual == *len, but be safe from stray * photons. */ if (actual >= *len) { break; } } *len = actual; return APR_SUCCESS; }
static triger_bucket_t *get_triger_bucket(ap_filter_t * f, apr_bucket * b) { const char *data; apr_size_t len = 0; triger_module_ctx_t *ctx = f->ctx; triger_bucket_t *rv = ctx->triger_bucket; rv->len = 0; rv->data = NULL; rv->b = NULL; rv->body_end_tag_pos = rv->body_start_tag_pos = rv->html_start_tag_pos = rv->head_start_tag_pos = rv->body_start_tag_pos = -1; apr_bucket_read(b, &data, &len, APR_BLOCK_READ); rv->len = len; rv->data = data; rv->b = b; return rv; }
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); }
/** * Sends bucket data to ironbee for processing. */ static void process_bucket(ap_filter_t *f, apr_bucket *b) { conn_rec *c = f->c; ironbee_conn_context *ctx = f->ctx; ib_conndata_t icdata; const char *bdata; apr_size_t nbytes; apr_status_t rc; if (APR_BUCKET_IS_METADATA(b)) { return; } /* Translate a bucket to a ib_conndata_t structure to be passed * to IronBee. */ rc = apr_bucket_read(b, &bdata, &nbytes, APR_BLOCK_READ); if (rc != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, c->base_server, IB_PRODUCT_NAME ": %s (%s): error reading %s data", f->frec->name, b->type->name, ((ctx->direction == IRONBEE_REQUEST) ? "request" : "response")); return; } icdata.conn = ctx->iconn; icdata.dlen = nbytes; icdata.data = (uint8_t *)bdata; if (ctx->direction == IRONBEE_REQUEST) { ctx->status = ib_state_notify_conn_data_in(ironbee, &icdata); } else { ctx->status = ib_state_notify_conn_data_out(ironbee, &icdata); } if (ctx->status != IB_OK) { ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, IB_PRODUCT_NAME ": signaled error in %s", ((ctx->direction == IRONBEE_REQUEST) ? "request" : "response")); } }
static apr_status_t brigade_peek(apr_bucket_brigade *bbIn, char *buff, apr_size_t bufflen) { apr_bucket *b; apr_size_t readbytes = 0; if (bufflen--) /* compensate for NULL */ *buff = '\0'; else return APR_EGENERAL; if (APR_BRIGADE_EMPTY(bbIn)) return APR_EGENERAL; b = APR_BRIGADE_FIRST(bbIn); while ((b != APR_BRIGADE_SENTINEL(bbIn)) && (readbytes < bufflen)) { const char *pos; const char *str; apr_size_t len; apr_status_t rv; if ((rv = apr_bucket_read(b, &str, &len, APR_NONBLOCK_READ)) != APR_SUCCESS) return rv; if ((pos = memchr(str, APR_ASCII_LF, len)) != NULL) len = pos - str; if (len > bufflen - readbytes) len = bufflen - readbytes; memcpy (buff + readbytes, str, len); readbytes += len; buff[readbytes] = '\0'; b = APR_BUCKET_NEXT(b); } return APR_SUCCESS; }
static apr_status_t consume_brigade(h2_filter_cin *cin, apr_bucket_brigade *bb, apr_read_type_e block) { apr_status_t status = APR_SUCCESS; apr_size_t readlen = 0; while (status == APR_SUCCESS && !APR_BRIGADE_EMPTY(bb)) { apr_bucket* bucket = APR_BRIGADE_FIRST(bb); if (APR_BUCKET_IS_METADATA(bucket)) { /* we do nothing regarding any meta here */ } else { const char *bucket_data = NULL; apr_size_t bucket_length = 0; status = apr_bucket_read(bucket, &bucket_data, &bucket_length, block); if (status == APR_SUCCESS && bucket_length > 0) { apr_size_t consumed = 0; status = cin->cb(cin->cb_ctx, bucket_data, bucket_length, &consumed); if (status == APR_SUCCESS && bucket_length > consumed) { /* We have data left in the bucket. Split it. */ status = apr_bucket_split(bucket, consumed); } readlen += consumed; cin->start_read = apr_time_now(); } } apr_bucket_delete(bucket); } if (readlen == 0 && status == APR_SUCCESS && block == APR_NONBLOCK_READ) { return APR_EAGAIN; } return status; }
/* * Workhorse function: simply log to the current error_log * info about the data in the bucket as well as the data itself */ static void dumpit(ap_filter_t *f, apr_bucket *b) { conn_rec *c = f->c; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "mod_dumpio: %s (%s-%s): %" APR_SIZE_T_FMT " bytes", f->frec->name, (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data", b->type->name, b->length) ; if (!(APR_BUCKET_IS_METADATA(b))) { const char *buf; apr_size_t nbytes; char *obuf; if (apr_bucket_read(b, &buf, &nbytes, APR_BLOCK_READ) == APR_SUCCESS) { if (nbytes) { obuf = malloc(nbytes+1); /* use pool? */ memcpy(obuf, buf, nbytes); obuf[nbytes] = '\0'; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "mod_dumpio: %s (%s-%s): %s", f->frec->name, (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data", b->type->name, obuf); free(obuf); } } else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, c->base_server, "mod_dumpio: %s (%s-%s): %s", f->frec->name, (APR_BUCKET_IS_METADATA(b)) ? "metadata" : "data", b->type->name, "error reading data"); } } }