static size_t read_from_buffer(struct icy_metadata *icy_metadata, GQueue *buffers, void *dest0, size_t length) { struct buffer *buffer = g_queue_pop_head(buffers); uint8_t *dest = dest0; size_t nbytes = 0; assert(buffer->size > 0); assert(buffer->consumed < buffer->size); if (length > buffer->size - buffer->consumed) length = buffer->size - buffer->consumed; while (true) { size_t chunk; chunk = icy_data(icy_metadata, length); if (chunk > 0) { memcpy(dest, buffer->data + buffer->consumed, chunk); buffer = consume_buffer(buffer, chunk); nbytes += chunk; dest += chunk; length -= chunk; if (length == 0) break; assert(buffer != NULL); } chunk = icy_meta(icy_metadata, buffer->data + buffer->consumed, length); if (chunk > 0) { buffer = consume_buffer(buffer, chunk); length -= chunk; if (length == 0) break; assert(buffer != NULL); } } if (buffer != NULL) g_queue_push_head(buffers, buffer); return nbytes; }
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; }
void ssl_read_buffer_consume(SSL *ssl, size_t len) { SSL3_BUFFER *buf = &ssl->s3->read_buffer; consume_buffer(buf, len); if (!SSL_IS_DTLS(ssl)) { /* The TLS stack never reads beyond the current record, so there will never * be unconsumed data. If read-ahead is ever reimplemented, * |ssl_read_buffer_discard| will require a |memcpy| to shift the excess * back to the front of the buffer, to ensure there is enough space for the * next record. */ assert(buf->len == 0); } }
static int tls_write_buffer_flush(SSL *ssl) { SSL3_BUFFER *buf = &ssl->s3->write_buffer; while (buf->len > 0) { int ret = BIO_write(ssl->wbio, buf->buf + buf->offset, buf->len); if (ret <= 0) { ssl->rwstate = SSL_WRITING; return ret; } consume_buffer(buf, (size_t)ret); } ssl_write_buffer_clear(ssl); return 1; }
static bool input_curl_seek(struct input_stream *is, goffset offset, int whence, GError **error_r) { struct input_curl *c = (struct input_curl *)is; bool ret; assert(is->ready); if (whence == SEEK_SET && offset == is->offset) /* no-op */ return true; if (!is->seekable) return false; /* calculate the absolute offset */ switch (whence) { case SEEK_SET: break; case SEEK_CUR: offset += is->offset; break; case SEEK_END: if (is->size < 0) /* stream size is not known */ return false; offset += is->size; break; default: return false; } if (offset < 0) return false; /* check if we can fast-forward the buffer */ while (offset > is->offset && !g_queue_is_empty(c->buffers)) { struct buffer *buffer; size_t length; buffer = (struct buffer *)g_queue_pop_head(c->buffers); length = buffer->size - buffer->consumed; if (offset - is->offset < (goffset)length) length = offset - is->offset; buffer = consume_buffer(buffer, length); if (buffer != NULL) g_queue_push_head(c->buffers, buffer); is->offset += length; } if (offset == is->offset) return true; /* close the old connection and open a new one */ input_curl_easy_free(c); is->offset = offset; if (is->offset == is->size) { /* seek to EOF: simulate empty result; avoid triggering a "416 Requested Range Not Satisfiable" response */ c->eof = true; return true; } ret = input_curl_easy_init(c, error_r); if (!ret) return false; /* send the "Range" header */ if (is->offset > 0) { c->range = g_strdup_printf("%lld-", (long long)is->offset); curl_easy_setopt(c->easy, CURLOPT_RANGE, c->range); } ret = input_curl_send_request(c, error_r); if (!ret) return false; return input_curl_multi_info_read(c, error_r); }