eagain_bucket.c revision 362181
175631Salfred/* 275631Salfred * eagain_bucket.c : a serf bucket that handles slowing down data 375631Salfred * for specific readers that would have unwanted 475631Salfred * behavior if they read everything too fast 575631Salfred * ==================================================================== 675631Salfred * Licensed to the Apache Software Foundation (ASF) under one 775631Salfred * or more contributor license agreements. See the NOTICE file 875631Salfred * distributed with this work for additional information 975631Salfred * regarding copyright ownership. The ASF licenses this file 1075631Salfred * to you under the Apache License, Version 2.0 (the 1175631Salfred * "License"); you may not use this file except in compliance 1275631Salfred * with the License. You may obtain a copy of the License at 1375631Salfred * 1475631Salfred * http://www.apache.org/licenses/LICENSE-2.0 1575631Salfred * 1675631Salfred * Unless required by applicable law or agreed to in writing, 1775631Salfred * software distributed under the License is distributed on an 1875631Salfred * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1975631Salfred * KIND, either express or implied. See the License for the 2075631Salfred * specific language governing permissions and limitations 2175631Salfred * under the License. 2275631Salfred * ==================================================================== 2375631Salfred */ 2475631Salfred 2575631Salfred#include <serf.h> 2675631Salfred#include <serf_bucket_util.h> 2775631Salfred 2875631Salfred#include "svn_private_config.h" 2975631Salfred 3075631Salfred#include "ra_serf.h" 3175631Salfred 3275631Salfredtypedef struct eagain_baton_t 3375631Salfred{ 3475631Salfred const char *data; 3575631Salfred apr_size_t remaining; 3675631Salfred} eagain_baton_t; 3775631Salfred 3875631Salfredstatic apr_status_t 3975631Salfredeagain_bucket_read(serf_bucket_t *bucket, 4075631Salfred apr_size_t requested, 4186279Salfred const char **data, 4275631Salfred apr_size_t *len) 4375631Salfred{ 4475631Salfred eagain_baton_t *eab = bucket->data; 4575631Salfred 4675631Salfred if (eab->remaining > 0) 4775631Salfred { 4875631Salfred *data = eab->data; 4983653Speter if (requested > eab->remaining || requested == SERF_READ_ALL_AVAIL) 5083653Speter { 5183653Speter *len = eab->remaining; 5275631Salfred eab->data = NULL; 5375631Salfred eab->remaining = 0; 5475631Salfred } 5583653Speter else 5675631Salfred { 5786279Salfred *len = requested; 5886279Salfred eab->data += requested; 5975631Salfred eab->remaining -= requested; 6075631Salfred } 6183653Speter 6275631Salfred if (eab->remaining) 6375631Salfred return APR_SUCCESS; 6475631Salfred } 6575631Salfred 6675631Salfred return APR_EAGAIN; 6775631Salfred} 6875631Salfred 6975631Salfred#if !SERF_VERSION_AT_LEAST(1, 4, 0) 7075631Salfredstatic apr_status_t 7175631Salfredeagain_bucket_readline(serf_bucket_t *bucket, 7275631Salfred int acceptable, 7375631Salfred int *found, 7475631Salfred const char **data, 7575631Salfred apr_size_t *len) 7675631Salfred{ 7775631Salfred /* ### for now, we know callers won't use this function. */ 7875631Salfred svn_error_clear(svn_error__malfunction(TRUE, __FILE__, __LINE__, 7975631Salfred "Not implemented.")); 8075631Salfred return APR_ENOTIMPL; 8175631Salfred} 8275979Salfred#endif 8375979Salfred 8475631Salfred 8575979Salfredstatic apr_status_t 8675979Salfredeagain_bucket_peek(serf_bucket_t *bucket, 8775979Salfred const char **data, 8875631Salfred apr_size_t *len) 8975631Salfred{ 9075631Salfred const eagain_baton_t *eab = bucket->data; 9175631Salfred 9275631Salfred *data = eab->data ? eab->data : ""; 9375631Salfred *len = eab->remaining; 9475631Salfred 9575631Salfred return APR_SUCCESS; 9675631Salfred} 9775631Salfred 9875631Salfred 9975631Salfredstatic const serf_bucket_type_t delay_bucket_vtable = { 10075631Salfred "BUF-EAGAIN", 10175631Salfred eagain_bucket_read, 10275631Salfred#if SERF_VERSION_AT_LEAST(1, 4, 0) 10375631Salfred serf_default_readline, 10475631Salfred#else 10575631Salfred eagain_bucket_readline, 10675631Salfred#endif 10775631Salfred serf_default_read_iovec, 10875631Salfred serf_default_read_for_sendfile, 10975631Salfred serf_default_read_bucket, 11086279Salfred eagain_bucket_peek, 11186279Salfred serf_default_destroy_and_data, 11286279Salfred}; 11375631Salfred 11475631Salfred 11575631Salfredserf_bucket_t * 11686279Salfredsvn_ra_serf__create_bucket_with_eagain(const char *data, 11775631Salfred apr_size_t len, 11875631Salfred serf_bucket_alloc_t *allocator) 11975631Salfred{ 12075631Salfred eagain_baton_t *eab; 12186279Salfred 12275631Salfred eab = serf_bucket_mem_alloc(allocator, sizeof(*eab)); 12375631Salfred eab->data = data; 12475631Salfred eab->remaining = len; 12575631Salfred 12675631Salfred return serf_bucket_create(&delay_bucket_vtable, allocator, eab); 12775631Salfred} 12875631Salfred