serf.h   serf.h 
skipping to change at line 33 skipping to change at line 33
#include <apr.h> #include <apr.h>
#include <apr_errno.h> #include <apr_errno.h>
#include <apr_allocator.h> #include <apr_allocator.h>
#include <apr_pools.h> #include <apr_pools.h>
#include <apr_network_io.h> #include <apr_network_io.h>
#include <apr_time.h> #include <apr_time.h>
#include <apr_poll.h> #include <apr_poll.h>
#include <apr_uri.h> #include <apr_uri.h>
#include "serf_declare.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* Forward declare some structures */ /* Forward declare some structures */
typedef struct serf_context_t serf_context_t; typedef struct serf_context_t serf_context_t;
typedef struct serf_bucket_t serf_bucket_t; typedef struct serf_bucket_t serf_bucket_t;
typedef struct serf_bucket_type_t serf_bucket_type_t; typedef struct serf_bucket_type_t serf_bucket_type_t;
typedef struct serf_bucket_alloc_t serf_bucket_alloc_t; typedef struct serf_bucket_alloc_t serf_bucket_alloc_t;
skipping to change at line 95 skipping to change at line 93
SERF_ERROR_RANGE + 93) SERF_ERROR_RANGE + 93)
/** /**
* Create a new context for serf operations. * Create a new context for serf operations.
* *
* A serf context defines a control loop which processes multiple * A serf context defines a control loop which processes multiple
* connections simultaneously. * connections simultaneously.
* *
* The context will be allocated within @a pool. * The context will be allocated within @a pool.
*/ */
SERF_DECLARE(serf_context_t *) serf_context_create(apr_pool_t *pool); serf_context_t *serf_context_create(
apr_pool_t *pool);
/** /**
* Callback function. Add a socket to the externally managed poll set. * Callback function. Add a socket to the externally managed poll set.
* *
* Both @a pfd and @a serf_baton should be used when calling serf_event_tri gger * Both @a pfd and @a serf_baton should be used when calling serf_event_tri gger
* later. * later.
*/ */
typedef apr_status_t (*serf_socket_add_t)(void *user_baton, typedef apr_status_t (*serf_socket_add_t)(
apr_pollfd_t *pfd, void *user_baton,
void *serf_baton); apr_pollfd_t *pfd,
void *serf_baton);
/** /**
* Callback function. Remove the socket, identified by both @a pfd and * Callback function. Remove the socket, identified by both @a pfd and
* @a serf_baton from the externally managed poll set. * @a serf_baton from the externally managed poll set.
*/ */
typedef apr_status_t (*serf_socket_remove_t)(void *user_baton, typedef apr_status_t (*serf_socket_remove_t)(
apr_pollfd_t *pfd, void *user_baton,
void *serf_baton); apr_pollfd_t *pfd,
void *serf_baton);
/* Create a new context for serf operations. /* Create a new context for serf operations.
* *
* Use this function to make serf not use its internal control loop, but * Use this function to make serf not use its internal control loop, but
* instead rely on an external event loop. Serf will use the @a addf and @a rmf * instead rely on an external event loop. Serf will use the @a addf and @a rmf
* callbacks to notify of any event on a connection. The @a user_baton will be * callbacks to notify of any event on a connection. The @a user_baton will be
* passed through the addf and rmf callbacks. * passed through the addf and rmf callbacks.
* *
* The context will be allocated within @a pool. * The context will be allocated within @a pool.
*/ */
SERF_DECLARE(serf_context_t *) serf_context_create_ex(void *user_baton, serf_context_t *serf_context_create_ex(
serf_socket_add_t add void *user_baton,
f, serf_socket_add_t addf,
serf_socket_remove_t serf_socket_remove_t rmf,
rmf, apr_pool_t *pool);
apr_pool_t *pool);
/** /**
* Make serf process events on a connection, identified by both @a pfd and * Make serf process events on a connection, identified by both @a pfd and
* @a serf_baton. * @a serf_baton.
* *
* Any outbound data is delivered, and incoming data is made available to * Any outbound data is delivered, and incoming data is made available to
* the associated response handlers and their buckets. * the associated response handlers and their buckets.
* *
* If any data is processed (incoming or outgoing), then this function will * If any data is processed (incoming or outgoing), then this function will
* return with APR_SUCCESS. * return with APR_SUCCESS.
*/ */
SERF_DECLARE(apr_status_t) serf_event_trigger(serf_context_t *s, apr_status_t serf_event_trigger(
void *serf_baton, serf_context_t *s,
const apr_pollfd_t *pfd); void *serf_baton,
const apr_pollfd_t *pfd);
/** @see serf_context_run should not block at all. */ /** @see serf_context_run should not block at all. */
#define SERF_DURATION_NOBLOCK 0 #define SERF_DURATION_NOBLOCK 0
/** @see serf_context_run should run for (nearly) "forever". */ /** @see serf_context_run should run for (nearly) "forever". */
#define SERF_DURATION_FOREVER 2000000000 /* approx 1^31 */ #define SERF_DURATION_FOREVER 2000000000 /* approx 1^31 */
/** /**
* Run the main networking control loop. * Run the main networking control loop.
* *
* The set of connections defined by the serf context @a ctx are processed. * The set of connections defined by the serf context @a ctx are processed.
skipping to change at line 164 skipping to change at line 168
* *
* If any data is processed (incoming or outgoing), then this function will * If any data is processed (incoming or outgoing), then this function will
* return with APR_SUCCESS. Typically, the caller will just want to call it * return with APR_SUCCESS. Typically, the caller will just want to call it
* again to continue processing data. * again to continue processing data.
* *
* If no activity occurs within the specified timeout duration, then * If no activity occurs within the specified timeout duration, then
* APR_TIMEUP is returned. * APR_TIMEUP is returned.
* *
* All temporary allocations will be made in @a pool. * All temporary allocations will be made in @a pool.
*/ */
SERF_DECLARE(apr_status_t) serf_context_run(serf_context_t *ctx, apr_status_t serf_context_run(
apr_short_interval_time_t durat serf_context_t *ctx,
ion, apr_short_interval_time_t duration,
apr_pool_t *pool); apr_pool_t *pool);
SERF_DECLARE(apr_status_t) serf_context_prerun(serf_context_t *ctx); apr_status_t serf_context_prerun(
serf_context_t *ctx);
/** /**
* Callback function for progress information. @a progress indicates cumula tive * Callback function for progress information. @a progress indicates cumula tive
* number of bytes read or written, for the whole context. * number of bytes read or written, for the whole context.
*/ */
typedef void (*serf_progress_t)(void *progress_baton, typedef void (*serf_progress_t)(
apr_off_t read, void *progress_baton,
apr_off_t write); apr_off_t read,
apr_off_t write);
/** /**
* Sets the progress callback function. @a progress_func will be called eve ry * Sets the progress callback function. @a progress_func will be called eve ry
* time bytes are read of or written on a socket. * time bytes are read of or written on a socket.
*/ */
SERF_DECLARE(void) serf_context_set_progress_cb( void serf_context_set_progress_cb(
serf_context_t *ctx, serf_context_t *ctx,
const serf_progress_t progress_func, const serf_progress_t progress_func,
void *progress_baton); void *progress_baton);
/** @} */ /** @} */
/** /**
* @defgroup serf connections and requests * @defgroup serf connections and requests
* @ingroup serf * @ingroup serf
* @{ * @{
skipping to change at line 220 skipping to change at line 227
* ### we may want to create a connection-level allocator and pass that * ### we may want to create a connection-level allocator and pass that
* ### along. however, that allocator would *only* be used for this * ### along. however, that allocator would *only* be used for this
* ### callback. it may be wasteful to create a per-conn allocator, so this * ### callback. it may be wasteful to create a per-conn allocator, so this
* ### baton-based, app-responsible form might be best. * ### baton-based, app-responsible form might be best.
* *
* Responsibility for the buckets is passed to the serf library. They will be * Responsibility for the buckets is passed to the serf library. They will be
* destroyed when the connection is closed. * destroyed when the connection is closed.
* *
* All temporary allocations should be made in @a pool. * All temporary allocations should be made in @a pool.
*/ */
typedef apr_status_t (*serf_connection_setup_t)(apr_socket_t *skt, typedef apr_status_t (*serf_connection_setup_t)(
serf_bucket_t **read_bkt apr_socket_t *skt,
, serf_bucket_t **read_bkt,
serf_bucket_t **write_bk serf_bucket_t **write_bkt,
t, void *setup_baton,
void *setup_baton, apr_pool_t *pool);
apr_pool_t *pool);
/** /**
* ### need to update docco w.r.t socket. became "stream" recently. * ### need to update docco w.r.t socket. became "stream" recently.
* ### the stream does not have a barrier, this callback should generally * ### the stream does not have a barrier, this callback should generally
* ### add a barrier around the stream before incorporating it into a * ### add a barrier around the stream before incorporating it into a
* ### response bucket stack. * ### response bucket stack.
* ### should serf add the barrier automatically to protect its data * ### should serf add the barrier automatically to protect its data
* ### structure? i.e. the passed bucket becomes owned rather than * ### structure? i.e. the passed bucket becomes owned rather than
* ### borrowed. that might suit overall semantics better. * ### borrowed. that might suit overall semantics better.
* Accept an incoming response for @a request, and its @a socket. A bucket * Accept an incoming response for @a request, and its @a socket. A bucket
skipping to change at line 254 skipping to change at line 262
* to bound the amount of memory stored in this pool -- to ensure that * to bound the amount of memory stored in this pool -- to ensure that
* allocations are not proportional to the amount of data in the response. * allocations are not proportional to the amount of data in the response.
* *
* Responsibility for the bucket is passed to the serf library. It will be * Responsibility for the bucket is passed to the serf library. It will be
* destroyed when the response has been fully read (the bucket returns an * destroyed when the response has been fully read (the bucket returns an
* APR_EOF status from its read functions). * APR_EOF status from its read functions).
* *
* All temporary allocations should be made in @a pool. * All temporary allocations should be made in @a pool.
*/ */
/* ### do we need to return an error? */ /* ### do we need to return an error? */
typedef serf_bucket_t * (*serf_response_acceptor_t)(serf_request_t *request typedef serf_bucket_t * (*serf_response_acceptor_t)(
, serf_request_t *request,
serf_bucket_t *stream, serf_bucket_t *stream,
void *acceptor_baton, void *acceptor_baton,
apr_pool_t *pool); apr_pool_t *pool);
/** /**
* Notification callback for when a connection closes. * Notification callback for when a connection closes.
* *
* This callback is used to inform an application that the @a conn * This callback is used to inform an application that the @a conn
* connection has been (abnormally) closed. The @a closed_baton is the * connection has been (abnormally) closed. The @a closed_baton is the
* baton provided when the connection was first opened. The reason for * baton provided when the connection was first opened. The reason for
* closure is given in @a why, and will be APR_SUCCESS if the application * closure is given in @a why, and will be APR_SUCCESS if the application
* requested closure (by clearing the pool used to allocate this * requested closure (by clearing the pool used to allocate this
* connection or calling serf_connection_close). * connection or calling serf_connection_close).
* *
* All temporary allocations should be made in @a pool. * All temporary allocations should be made in @a pool.
*/ */
typedef void (*serf_connection_closed_t)(serf_connection_t *conn, typedef void (*serf_connection_closed_t)(
void *closed_baton, serf_connection_t *conn,
apr_status_t why, void *closed_baton,
apr_pool_t *pool); apr_status_t why,
apr_pool_t *pool);
/** /**
* Response data has arrived and should be processed. * Response data has arrived and should be processed.
* *
* Whenever response data for @a request arrives (initially, or continued d ata * Whenever response data for @a request arrives (initially, or continued d ata
* arrival), this handler is invoked. The response data is available in the * arrival), this handler is invoked. The response data is available in the
* @a response bucket. The @a handler_baton is passed along from the baton * @a response bucket. The @a handler_baton is passed along from the baton
* provided by the request setup callback (@see serf_request_setup_t). * provided by the request setup callback (@see serf_request_setup_t).
* *
* The handler MUST process data from the @a response bucket until the * The handler MUST process data from the @a response bucket until the
skipping to change at line 304 skipping to change at line 314
* Note: if the connection closed (at the request of the application, or * Note: if the connection closed (at the request of the application, or
* because of an (abnormal) termination) while a request is being delivered , * because of an (abnormal) termination) while a request is being delivered ,
* or before a response arrives, then @a response will be NULL. This is the * or before a response arrives, then @a response will be NULL. This is the
* signal that the request was not delivered properly, and no further * signal that the request was not delivered properly, and no further
* response should be expected (this callback will not be invoked again). * response should be expected (this callback will not be invoked again).
* If a request is injected into the connection (during this callback's * If a request is injected into the connection (during this callback's
* execution, or otherwise), then the connection will be reopened. * execution, or otherwise), then the connection will be reopened.
* *
* All temporary allocations should be made in @a pool. * All temporary allocations should be made in @a pool.
*/ */
typedef apr_status_t (*serf_response_handler_t)(serf_request_t *request, typedef apr_status_t (*serf_response_handler_t)(
serf_bucket_t *response, serf_request_t *request,
void *handler_baton, serf_bucket_t *response,
apr_pool_t *pool); void *handler_baton,
apr_pool_t *pool);
/** /**
* Callback function to be implemented by the application, so that serf * Callback function to be implemented by the application, so that serf
* can handle server and proxy authentication. * can handle server and proxy authentication.
* code = 401 (server) or 407 (proxy). * code = 401 (server) or 407 (proxy).
* baton = the baton passed to serf_context_run. * baton = the baton passed to serf_context_run.
* authn_type = one of "Basic", "Digest". * authn_type = one of "Basic", "Digest".
*/ */
typedef apr_status_t (*serf_credentials_callback_t)(char **username, typedef apr_status_t (*serf_credentials_callback_t)(
char **username,
char **password, char **password,
serf_request_t *request, void *baton, serf_request_t *request, void *baton,
int code, const char *authn_type, int code, const char *authn_type,
const char *realm, const char *realm,
apr_pool_t *pool); apr_pool_t *pool);
/** /**
* Create a new connection associated with the @a ctx serf context. * Create a new connection associated with the @a ctx serf context.
* *
* A connection will be created to (eventually) connect to the address * A connection will be created to (eventually) connect to the address
skipping to change at line 344 skipping to change at line 356
* When the connection is closed (upon request or because of an error), * When the connection is closed (upon request or because of an error),
* then the @a closed callback is invoked, and @a closed_baton is passed. * then the @a closed callback is invoked, and @a closed_baton is passed.
* *
* ### doc on setup(_baton). tweak below comment re: acceptor. * ### doc on setup(_baton). tweak below comment re: acceptor.
* NULL may be passed for @a acceptor and @a closed; default implementation s * NULL may be passed for @a acceptor and @a closed; default implementation s
* will be used. * will be used.
* *
* Note: the connection is not made immediately. It will be opened on * Note: the connection is not made immediately. It will be opened on
* the next call to @see serf_context_run. * the next call to @see serf_context_run.
*/ */
SERF_DECLARE(serf_connection_t *) serf_connection_create( serf_connection_t *serf_connection_create(
serf_context_t *ctx, serf_context_t *ctx,
apr_sockaddr_t *address, apr_sockaddr_t *address,
serf_connection_setup_t setup, serf_connection_setup_t setup,
void *setup_baton, void *setup_baton,
serf_connection_closed_t closed, serf_connection_closed_t closed,
void *closed_baton, void *closed_baton,
apr_pool_t *pool); apr_pool_t *pool);
/** /**
* Create a new connection associated with the @a ctx serf context. * Create a new connection associated with the @a ctx serf context.
skipping to change at line 376 skipping to change at line 388
* When the connection is closed (upon request or because of an error), * When the connection is closed (upon request or because of an error),
* then the @a closed callback is invoked, and @a closed_baton is passed. * then the @a closed callback is invoked, and @a closed_baton is passed.
* *
* ### doc on setup(_baton). tweak below comment re: acceptor. * ### doc on setup(_baton). tweak below comment re: acceptor.
* NULL may be passed for @a acceptor and @a closed; default implementation s * NULL may be passed for @a acceptor and @a closed; default implementation s
* will be used. * will be used.
* *
* Note: the connection is not made immediately. It will be opened on * Note: the connection is not made immediately. It will be opened on
* the next call to @see serf_context_run. * the next call to @see serf_context_run.
*/ */
SERF_DECLARE(apr_status_t) serf_connection_create2( apr_status_t serf_connection_create2(
serf_connection_t **conn, serf_connection_t **conn,
serf_context_t *ctx, serf_context_t *ctx,
apr_uri_t host_info, apr_uri_t host_info,
serf_connection_setup_t setup, serf_connection_setup_t setup,
void *setup_baton, void *setup_baton,
serf_connection_closed_t closed, serf_connection_closed_t closed,
void *closed_baton, void *closed_baton,
apr_pool_t *pool); apr_pool_t *pool);
typedef apr_status_t (*serf_accept_client_t)(serf_context_t *ctx, typedef apr_status_t (*serf_accept_client_t)(
serf_listener_t *l, serf_context_t *ctx,
void *accept_baton, serf_listener_t *l,
apr_socket_t *insock, void *accept_baton,
apr_pool_t *pool); apr_socket_t *insock,
apr_pool_t *pool);
SERF_DECLARE(apr_status_t) serf_listener_create( apr_status_t serf_listener_create(
serf_listener_t **listener, serf_listener_t **listener,
serf_context_t *ctx, serf_context_t *ctx,
const char *host, const char *host,
apr_uint16_t port, apr_uint16_t port,
void *accept_baton, void *accept_baton,
serf_accept_client_t accept_func, serf_accept_client_t accept_func,
apr_pool_t *pool); apr_pool_t *pool);
typedef apr_status_t (*serf_incoming_request_cb_t)(serf_context_t *ctx, typedef apr_status_t (*serf_incoming_request_cb_t)(
serf_incoming_request_t *req, serf_context_t *ctx,
void *request_baton, serf_incoming_request_t *req,
apr_pool_t *pool); void *request_baton,
apr_pool_t *pool);
SERF_DECLARE(apr_status_t) serf_incoming_create( apr_status_t serf_incoming_create(
serf_incoming_t **client, serf_incoming_t **client,
serf_context_t *ctx, serf_context_t *ctx,
apr_socket_t *insock, apr_socket_t *insock,
void *request_baton, void *request_baton,
serf_incoming_request_cb_t request, serf_incoming_request_cb_t request,
apr_pool_t *pool); apr_pool_t *pool);
/** /**
* Reset the connection, but re-open the socket again. * Reset the connection, but re-open the socket again.
*/ */
SERF_DECLARE(apr_status_t) serf_connection_reset( apr_status_t serf_connection_reset(
serf_connection_t *conn); serf_connection_t *conn);
/** /**
* Close the connection associated with @a conn and cancel all pending requ ests. * Close the connection associated with @a conn and cancel all pending requ ests.
* *
* The closed callback passed to serf_connection_create() will be invoked * The closed callback passed to serf_connection_create() will be invoked
* with APR_SUCCESS. * with APR_SUCCESS.
*/ */
SERF_DECLARE(apr_status_t) serf_connection_close( apr_status_t serf_connection_close(
serf_connection_t *conn); serf_connection_t *conn);
/** /**
* Sets the maximum number of outstanding requests @a max_requests on the * Sets the maximum number of outstanding requests @a max_requests on the
* connection @a conn. Setting max_requests to 0 means unlimited (the defau lt). * connection @a conn. Setting max_requests to 0 means unlimited (the defau lt).
* Ex.: setting max_requests to 1 means a request is sent when a response o n the * Ex.: setting max_requests to 1 means a request is sent when a response o n the
* previous request was received and handled. * previous request was received and handled.
*/ */
SERF_DECLARE(void) void serf_connection_set_max_outstanding_requests(
serf_connection_set_max_outstanding_requests(serf_connection_t *conn, serf_connection_t *conn,
unsigned int max_requests); unsigned int max_requests);
SERF_DECLARE(void) void serf_connection_set_async_responses(
serf_connection_set_async_responses(serf_connection_t *conn, serf_connection_t *conn,
serf_response_acceptor_t acceptor, serf_response_acceptor_t acceptor,
void *acceptor_baton, void *acceptor_baton,
serf_response_handler_t handler, serf_response_handler_t handler,
void *handler_baton); void *handler_baton);
/** /**
* Setup the @a request for delivery on its connection. * Setup the @a request for delivery on its connection.
* *
* Right before this is invoked, @a pool will be built within the * Right before this is invoked, @a pool will be built within the
* connection's pool for the request to use. The associated response will * connection's pool for the request to use. The associated response will
* be allocated within that subpool. An associated bucket allocator will * be allocated within that subpool. An associated bucket allocator will
* be built. These items may be fetched from the request object through * be built. These items may be fetched from the request object through
* @see serf_request_get_pool or @see serf_request_get_alloc. * @see serf_request_get_pool or @see serf_request_get_alloc.
* *
* The content of the request is specified by the @a req_bkt bucket. When * The content of the request is specified by the @a req_bkt bucket. When
* a response arrives, the @a acceptor callback will be invoked (along with * a response arrives, the @a acceptor callback will be invoked (along with
* the @a acceptor_baton) to produce a response bucket. That bucket will th en * the @a acceptor_baton) to produce a response bucket. That bucket will th en
* be passed to @a handler, along with the @a handler_baton. * be passed to @a handler, along with the @a handler_baton.
* *
* The responsibility for the request bucket is passed to the request * The responsibility for the request bucket is passed to the request
* object. When the request is done with the bucket, it will be destroyed. * object. When the request is done with the bucket, it will be destroyed.
*/ */
typedef apr_status_t (*serf_request_setup_t)(serf_request_t *request, typedef apr_status_t (*serf_request_setup_t)(
void *setup_baton, serf_request_t *request,
serf_bucket_t **req_bkt, void *setup_baton,
serf_response_acceptor_t *acce serf_bucket_t **req_bkt,
ptor, serf_response_acceptor_t *acceptor,
void **acceptor_baton, void **acceptor_baton,
serf_response_handler_t *handl serf_response_handler_t *handler,
er, void **handler_baton,
void **handler_baton, apr_pool_t *pool);
apr_pool_t *pool);
/** /**
* Construct a request object for the @a conn connection. * Construct a request object for the @a conn connection.
* *
* When it is time to deliver the request, the @a setup callback will * When it is time to deliver the request, the @a setup callback will
* be invoked with the @a setup_baton passed into it to complete the * be invoked with the @a setup_baton passed into it to complete the
* construction of the request object. * construction of the request object.
* *
* If the request has not (yet) been delivered, then it may be canceled * If the request has not (yet) been delivered, then it may be canceled
* with @see serf_request_cancel. * with @see serf_request_cancel.
* *
* Invoking any calls other than @see serf_request_cancel before the setup * Invoking any calls other than @see serf_request_cancel before the setup
* callback executes is not supported. * callback executes is not supported.
*/ */
SERF_DECLARE(serf_request_t *) serf_connection_request_create( serf_request_t *serf_connection_request_create(
serf_connection_t *conn, serf_connection_t *conn,
serf_request_setup_t setup, serf_request_setup_t setup,
void *setup_baton); void *setup_baton);
/** /**
* Construct a request object for the @a conn connection, add it in the * Construct a request object for the @a conn connection, add it in the
* list as the next to-be-written request before all unwritten requests. * list as the next to-be-written request before all unwritten requests.
* *
* When it is time to deliver the request, the @a setup callback will * When it is time to deliver the request, the @a setup callback will
* be invoked with the @a setup_baton passed into it to complete the * be invoked with the @a setup_baton passed into it to complete the
* construction of the request object. * construction of the request object.
* *
* If the request has not (yet) been delivered, then it may be canceled * If the request has not (yet) been delivered, then it may be canceled
* with @see serf_request_cancel. * with @see serf_request_cancel.
* *
* Invoking any calls other than @see serf_request_cancel before the setup * Invoking any calls other than @see serf_request_cancel before the setup
* callback executes is not supported. * callback executes is not supported.
*/ */
SERF_DECLARE(serf_request_t *) serf_connection_priority_request_create( serf_request_t *serf_connection_priority_request_create(
serf_connection_t *conn, serf_connection_t *conn,
serf_request_setup_t setup, serf_request_setup_t setup,
void *setup_baton); void *setup_baton);
/** /**
* Cancel the request specified by the @a request object. * Cancel the request specified by the @a request object.
* *
* If the request has been scheduled for delivery, then its response * If the request has been scheduled for delivery, then its response
* handler will be run, passing NULL for the response bucket. * handler will be run, passing NULL for the response bucket.
* *
* If the request has already been (partially or fully) delivered, then * If the request has already been (partially or fully) delivered, then
* APR_EBUSY is returned and the request is *NOT* canceled. To properly * APR_EBUSY is returned and the request is *NOT* canceled. To properly
* cancel the request, the connection must be closed (by clearing or * cancel the request, the connection must be closed (by clearing or
* destroying its associated pool). * destroying its associated pool).
*/ */
SERF_DECLARE(apr_status_t) serf_request_cancel(serf_request_t *request); apr_status_t serf_request_cancel(
serf_request_t *request);
/** /**
* Return the pool associated with @a request. * Return the pool associated with @a request.
* *
* WARNING: be very careful about the kinds of things placed into this * WARNING: be very careful about the kinds of things placed into this
* pool. In particular, all allocation should be bounded in size, rather * pool. In particular, all allocation should be bounded in size, rather
* than proportional to any data stream. * than proportional to any data stream.
*/ */
SERF_DECLARE(apr_pool_t *) serf_request_get_pool( apr_pool_t *serf_request_get_pool(
const serf_request_t *request); const serf_request_t *request);
/** /**
* Return the bucket allocator associated with @a request. * Return the bucket allocator associated with @a request.
*/ */
SERF_DECLARE(serf_bucket_alloc_t *) serf_request_get_alloc( serf_bucket_alloc_t *serf_request_get_alloc(
const serf_request_t *request); const serf_request_t *request);
/** /**
* Return the connection associated with @a request. * Return the connection associated with @a request.
*/ */
SERF_DECLARE(serf_connection_t *) serf_request_get_conn( serf_connection_t *serf_request_get_conn(
const serf_request_t *request); const serf_request_t *request);
/** /**
* Update the @a handler and @a handler_baton for this @a request. * Update the @a handler and @a handler_baton for this @a request.
* *
* This can be called after the request has started processing - * This can be called after the request has started processing -
* subsequent data will be delivered to this new handler. * subsequent data will be delivered to this new handler.
*/ */
SERF_DECLARE(void) serf_request_set_handler( void serf_request_set_handler(
serf_request_t *request, serf_request_t *request,
const serf_response_handler_t handler, const serf_response_handler_t handler,
const void **handler_baton); const void **handler_baton);
/** /**
* Configure proxy server settings, to be used by all connections associate d * Configure proxy server settings, to be used by all connections associate d
* with the @a ctx serf context. * with the @a ctx serf context.
* *
* The next connection will be created to connect to the proxy server * The next connection will be created to connect to the proxy server
* specified by @a address. The address must live at least as long as the * specified by @a address. The address must live at least as long as the
* serf context. * serf context.
*/ */
SERF_DECLARE(void) serf_config_proxy( void serf_config_proxy(
serf_context_t *ctx, serf_context_t *ctx,
apr_sockaddr_t *address); apr_sockaddr_t *address);
/* Supported authentication types. */ /* Supported authentication types. */
#define SERF_AUTHN_NONE 0x00 #define SERF_AUTHN_NONE 0x00
#define SERF_AUTHN_BASIC 0x01 #define SERF_AUTHN_BASIC 0x01
#define SERF_AUTHN_DIGEST 0x02 #define SERF_AUTHN_DIGEST 0x02
#define SERF_AUTHN_NTLM 0x04 #define SERF_AUTHN_NTLM 0x04
#define SERF_AUTHN_NEGOTIATE 0x08 #define SERF_AUTHN_NEGOTIATE 0x08
#define SERF_AUTHN_ALL 0xFF #define SERF_AUTHN_ALL 0xFF
/** /**
* Define the authentication handlers that serf will try on incoming reques ts. * Define the authentication handlers that serf will try on incoming reques ts.
*/ */
SERF_DECLARE(void) serf_config_authn_types( void serf_config_authn_types(
serf_context_t *ctx, serf_context_t *ctx,
int authn_types); int authn_types);
/** /**
* Set the credentials callback handler. * Set the credentials callback handler.
*/ */
SERF_DECLARE(void) serf_config_credentials_callback( void serf_config_credentials_callback(
serf_context_t *ctx, serf_context_t *ctx,
serf_credentials_callback_t cred_cb); serf_credentials_callback_t cred_cb);
/* ### maybe some connection control functions for flood? */ /* ### maybe some connection control functions for flood? */
/*** Special bucket creation functions ***/ /*** Special bucket creation functions ***/
/** /**
* Create a bucket of type 'socket bucket'. * Create a bucket of type 'socket bucket'.
* This is basically a wrapper around @a serf_bucket_socket_create, which * This is basically a wrapper around @a serf_bucket_socket_create, which
* initializes the bucket using connection and/or context specific settings . * initializes the bucket using connection and/or context specific settings .
*/ */
SERF_DECLARE(serf_bucket_t *) serf_context_bucket_socket_create( serf_bucket_t *serf_context_bucket_socket_create(
serf_context_t *ctx, serf_context_t *ctx,
apr_socket_t *skt, apr_socket_t *skt,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/** /**
* Create a bucket of type 'request bucket'. * Create a bucket of type 'request bucket'.
* This is basically a wrapper around @a serf_bucket_request_create, which * This is basically a wrapper around @a serf_bucket_request_create, which
* initializes the bucket using request, connection and/or context specific * initializes the bucket using request, connection and/or context specific
* settings. * settings.
* *
* This function will set following header(s): * This function will set following header(s):
* - Host: if the connection was created with @a serf_connection_create2. * - Host: if the connection was created with @a serf_connection_create2.
*/ */
SERF_DECLARE(serf_bucket_t *) serf_request_bucket_request_create( serf_bucket_t *serf_request_bucket_request_create(
serf_request_t *request, serf_request_t *request,
const char *method, const char *method,
const char *uri, const char *uri,
serf_bucket_t *body, serf_bucket_t *body,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/** @} */ /** @} */
/** /**
* @defgroup serf buckets * @defgroup serf buckets
skipping to change at line 893 skipping to change at line 909
*/ */
#define SERF_BUCKET_CHECK(b, btype) ((b)->type == &serf_bucket_type_ ## bty pe) #define SERF_BUCKET_CHECK(b, btype) ((b)->type == &serf_bucket_type_ ## bty pe)
/** /**
* Notification callback for a block that was not returned to the bucket * Notification callback for a block that was not returned to the bucket
* allocator when its pool was destroyed. * allocator when its pool was destroyed.
* *
* The block of memory is given by @a block. The baton provided when the * The block of memory is given by @a block. The baton provided when the
* allocator was constructed is passed as @a unfreed_baton. * allocator was constructed is passed as @a unfreed_baton.
*/ */
typedef void (*serf_unfreed_func_t)(void *unfreed_baton, void *block); typedef void (*serf_unfreed_func_t)(
void *unfreed_baton,
void *block);
/** /**
* Create a new allocator for buckets. * Create a new allocator for buckets.
* *
* All buckets are associated with a serf bucket allocator. This allocator * All buckets are associated with a serf bucket allocator. This allocator
* will be created within @a pool and will be destroyed when that pool is * will be created within @a pool and will be destroyed when that pool is
* cleared or destroyed. * cleared or destroyed.
* *
* When the allocator is destroyed, if any allocations were not explicitly * When the allocator is destroyed, if any allocations were not explicitly
* returned (by calling serf_bucket_mem_free), then the @a unfreed callback * returned (by calling serf_bucket_mem_free), then the @a unfreed callback
* will be invoked for each block. @a unfreed_baton will be passed to the * will be invoked for each block. @a unfreed_baton will be passed to the
* callback. * callback.
* *
* If @a unfreed is NULL, then the library will invoke the abort() stdlib * If @a unfreed is NULL, then the library will invoke the abort() stdlib
* call. Any failure to return memory is a bug in the application, and an * call. Any failure to return memory is a bug in the application, and an
* abort can assist with determining what kinds of memory were not freed. * abort can assist with determining what kinds of memory were not freed.
*/ */
SERF_DECLARE(serf_bucket_alloc_t *) serf_bucket_allocator_create( serf_bucket_alloc_t *serf_bucket_allocator_create(
apr_pool_t *pool, apr_pool_t *pool,
serf_unfreed_func_t unfreed, serf_unfreed_func_t unfreed,
void *unfreed_baton); void *unfreed_baton);
/** /**
* Return the pool that was used for this @a allocator. * Return the pool that was used for this @a allocator.
* *
* WARNING: the use of this pool for allocations requires a very * WARNING: the use of this pool for allocations requires a very
* detailed understanding of pool behaviors, the bucket system, * detailed understanding of pool behaviors, the bucket system,
* and knowledge of the bucket's use within the overall pattern * and knowledge of the bucket's use within the overall pattern
* of request/response behavior. * of request/response behavior.
* *
* See design-guide.txt for more information about pool usage. * See design-guide.txt for more information about pool usage.
*/ */
SERF_DECLARE(apr_pool_t *) serf_bucket_allocator_get_pool( apr_pool_t *serf_bucket_allocator_get_pool(
const serf_bucket_alloc_t *allocator); const serf_bucket_alloc_t *allocator);
/** /**
* Utility structure for reading a complete line of input from a bucket. * Utility structure for reading a complete line of input from a bucket.
* *
* Since it is entirely possible for a line to be broken by APR_EAGAIN, * Since it is entirely possible for a line to be broken by APR_EAGAIN,
* this structure can be used to accumulate the data until a complete line * this structure can be used to accumulate the data until a complete line
* has been read from a bucket. * has been read from a bucket.
*/ */
skipping to change at line 963 skipping to change at line 981
apr_size_t used; apr_size_t used;
/* The line is read into this buffer, minus CR/LF */ /* The line is read into this buffer, minus CR/LF */
char line[SERF_LINEBUF_LIMIT]; char line[SERF_LINEBUF_LIMIT];
} serf_linebuf_t; } serf_linebuf_t;
/** /**
* Initialize the @a linebuf structure. * Initialize the @a linebuf structure.
*/ */
SERF_DECLARE(void) serf_linebuf_init(serf_linebuf_t *linebuf); void serf_linebuf_init(serf_linebuf_t *linebuf);
/** /**
* Fetch a line of text from @a bucket, accumulating the line into * Fetch a line of text from @a bucket, accumulating the line into
* @a linebuf. @a acceptable specifies the types of newlines which are * @a linebuf. @a acceptable specifies the types of newlines which are
* acceptable for this fetch. * acceptable for this fetch.
* *
* ### we should return a data/len pair so that we can avoid a copy, * ### we should return a data/len pair so that we can avoid a copy,
* ### rather than having callers look into our state and line buffer. * ### rather than having callers look into our state and line buffer.
*/ */
SERF_DECLARE(apr_status_t) serf_linebuf_fetch( apr_status_t serf_linebuf_fetch(
serf_linebuf_t *linebuf, serf_linebuf_t *linebuf,
serf_bucket_t *bucket, serf_bucket_t *bucket,
int acceptable); int acceptable);
/** @} */ /** @} */
/* Internal functions for bucket use and lifecycle tracking */ /* Internal functions for bucket use and lifecycle tracking */
SERF_DECLARE(apr_status_t) serf_debug__record_read( apr_status_t serf_debug__record_read(
const serf_bucket_t *bucket, const serf_bucket_t *bucket,
apr_status_t status); apr_status_t status);
SERF_DECLARE(void) serf_debug__entered_loop(serf_bucket_alloc_t *allocator) void serf_debug__entered_loop(
; serf_bucket_alloc_t *allocator);
SERF_DECLARE(void) serf_debug__closed_conn(serf_bucket_alloc_t *allocator); void serf_debug__closed_conn(
SERF_DECLARE(void) serf_debug__bucket_destroy(const serf_bucket_t *bucket); serf_bucket_alloc_t *allocator);
SERF_DECLARE(void) serf_debug__bucket_alloc_check(serf_bucket_alloc_t *allo void serf_debug__bucket_destroy(
cator); const serf_bucket_t *bucket);
void serf_debug__bucket_alloc_check(
serf_bucket_alloc_t *allocator);
/* Version info */ /* Version info */
#define SERF_MAJOR_VERSION 0 #define SERF_MAJOR_VERSION 0
#define SERF_MINOR_VERSION 5 #define SERF_MINOR_VERSION 7
#define SERF_PATCH_VERSION 0 #define SERF_PATCH_VERSION 0
/* Version number string */ /* Version number string */
#define SERF_VERSION_STRING APR_STRINGIFY(SERF_MAJOR_VERSION) "." \ #define SERF_VERSION_STRING APR_STRINGIFY(SERF_MAJOR_VERSION) "." \
APR_STRINGIFY(SERF_MINOR_VERSION) "." \ APR_STRINGIFY(SERF_MINOR_VERSION) "." \
APR_STRINGIFY(SERF_PATCH_VERSION) APR_STRINGIFY(SERF_PATCH_VERSION)
/** /**
* Check at compile time if the Serf version is at least a certain * Check at compile time if the Serf version is at least a certain
* level. * level.
skipping to change at line 1023 skipping to change at line 1045
(patch) <= SERF_PATCH_VERSION)) (patch) <= SERF_PATCH_VERSION))
/** /**
* Returns the version of the library the application has linked/loaded. * Returns the version of the library the application has linked/loaded.
* Values are returned in @a major, @a minor, and @a patch. * Values are returned in @a major, @a minor, and @a patch.
* *
* Applications will want to use this function to verify compatibility, * Applications will want to use this function to verify compatibility,
* expecially while serf has not reached a 1.0 milestone. APIs and * expecially while serf has not reached a 1.0 milestone. APIs and
* semantics may change drastically until the library hits 1.0. * semantics may change drastically until the library hits 1.0.
*/ */
SERF_DECLARE(void) serf_lib_version(int *major, int *minor, int *patch); void serf_lib_version(
int *major,
int *minor,
int *patch);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
/* /*
* Every user of serf will want to deal with our various bucket types. * Every user of serf will want to deal with our various bucket types.
* Go ahead and include that header right now. * Go ahead and include that header right now.
* *
* Note: make sure this occurs outside of the C++ namespace block * Note: make sure this occurs outside of the C++ namespace block
 End of changes. 46 change blocks. 
109 lines changed or deleted 124 lines changed or added


 serf_bucket_types.h   serf_bucket_types.h 
skipping to change at line 27 skipping to change at line 27
#define SERF_BUCKET_TYPES_H #define SERF_BUCKET_TYPES_H
#include <apr_mmap.h> #include <apr_mmap.h>
#include <apr_hash.h> #include <apr_hash.h>
/* this header and serf.h refer to each other, so take a little extra care */ /* this header and serf.h refer to each other, so take a little extra care */
#ifndef SERF_H #ifndef SERF_H
#include "serf.h" #include "serf.h"
#endif #endif
#include "serf_declare.h"
/** /**
* @file serf_bucket_types.h * @file serf_bucket_types.h
* @brief serf-supported bucket types * @brief serf-supported bucket types
*/ */
/* ### this whole file needs docco ... */ /* ### this whole file needs docco ... */
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_request; extern const serf_bucket_type_t serf_bucket_type_request;
#define SERF_BUCKET_IS_REQUEST(b) SERF_BUCKET_CHECK((b), request) #define SERF_BUCKET_IS_REQUEST(b) SERF_BUCKET_CHECK((b), request)
SERF_DECLARE(serf_bucket_t *) serf_bucket_request_create( serf_bucket_t *serf_bucket_request_create(
const char *method, const char *method,
const char *URI, const char *URI,
serf_bucket_t *body, serf_bucket_t *body,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_bucket_t *) serf_bucket_request_get_headers( serf_bucket_t *serf_bucket_request_get_headers(
serf_bucket_t *request); serf_bucket_t *request);
SERF_DECLARE(void) serf_bucket_request_become(serf_bucket_t *bucket, void serf_bucket_request_become(
const char *method, serf_bucket_t *bucket,
const char *uri, const char *method,
serf_bucket_t *body); const char *uri,
serf_bucket_t *body);
/** /**
* Sets the root url of the remote host. If this request contains a relativ e * Sets the root url of the remote host. If this request contains a relativ e
* url, it will be prefixed with the root url to form an absolute url. * url, it will be prefixed with the root url to form an absolute url.
* @a bucket is the request bucket. @a root_url is the absolute url of the * @a bucket is the request bucket. @a root_url is the absolute url of the
* root of the remote host, without the closing '/'. * root of the remote host, without the closing '/'.
*/ */
SERF_DECLARE(void) serf_bucket_request_set_root(serf_bucket_t *bucket, void serf_bucket_request_set_root(
const char *root_url); serf_bucket_t *bucket,
const char *root_url);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_response ; extern const serf_bucket_type_t serf_bucket_type_response;
#define SERF_BUCKET_IS_RESPONSE(b) SERF_BUCKET_CHECK((b), response) #define SERF_BUCKET_IS_RESPONSE(b) SERF_BUCKET_CHECK((b), response)
SERF_DECLARE(serf_bucket_t *) serf_bucket_response_create( serf_bucket_t *serf_bucket_response_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
#define SERF_HTTP_VERSION(major, minor) ((major) * 1000 + (minor)) #define SERF_HTTP_VERSION(major, minor) ((major) * 1000 + (minor))
#define SERF_HTTP_11 SERF_HTTP_VERSION(1, 1) #define SERF_HTTP_11 SERF_HTTP_VERSION(1, 1)
#define SERF_HTTP_10 SERF_HTTP_VERSION(1, 0) #define SERF_HTTP_10 SERF_HTTP_VERSION(1, 0)
typedef struct { typedef struct {
int version; int version;
int code; int code;
skipping to change at line 95 skipping to change at line 95
/** /**
* Return the Status-Line information, if available. This function * Return the Status-Line information, if available. This function
* works like other bucket read functions: it may return APR_EAGAIN or * works like other bucket read functions: it may return APR_EAGAIN or
* APR_EOF to signal the state of the bucket for reading. A return * APR_EOF to signal the state of the bucket for reading. A return
* value of APR_SUCCESS will always indicate that status line * value of APR_SUCCESS will always indicate that status line
* information was returned; for other return values the caller must * information was returned; for other return values the caller must
* check the version field in @a sline. A value of 0 means that the * check the version field in @a sline. A value of 0 means that the
* data is not (yet) present. * data is not (yet) present.
*/ */
SERF_DECLARE(apr_status_t) serf_bucket_response_status( apr_status_t serf_bucket_response_status(
serf_bucket_t *bkt, serf_bucket_t *bkt,
serf_status_line *sline); serf_status_line *sline);
/** /**
* Wait for the HTTP headers to be processed for a @a response. * Wait for the HTTP headers to be processed for a @a response.
* *
* If the headers are available, APR_SUCCESS is returned. * If the headers are available, APR_SUCCESS is returned.
* If the headers aren't available, APR_EAGAIN is returned. * If the headers aren't available, APR_EAGAIN is returned.
*/ */
SERF_DECLARE(apr_status_t) serf_bucket_response_wait_for_headers( apr_status_t serf_bucket_response_wait_for_headers(
serf_bucket_t *response); serf_bucket_t *response);
/** /**
* Get the headers bucket for @a response. * Get the headers bucket for @a response.
*/ */
SERF_DECLARE(serf_bucket_t *) serf_bucket_response_get_headers( serf_bucket_t *serf_bucket_response_get_headers(
serf_bucket_t *response); serf_bucket_t *response);
/** /**
* Advise the response @a bucket that this was from a HEAD request and * Advise the response @a bucket that this was from a HEAD request and
* that it should not expect to see a response body. * that it should not expect to see a response body.
*/ */
SERF_DECLARE(void) serf_bucket_response_set_head(serf_bucket_t *bucket); void serf_bucket_response_set_head(
serf_bucket_t *bucket);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_bwtp_fra me; extern const serf_bucket_type_t serf_bucket_type_bwtp_frame;
#define SERF_BUCKET_IS_BWTP_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_frame) #define SERF_BUCKET_IS_BWTP_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_frame)
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_bwtp_inc oming_frame; extern const serf_bucket_type_t serf_bucket_type_bwtp_incoming_frame;
#define SERF_BUCKET_IS_BWTP_INCOMING_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_i ncoming_frame) #define SERF_BUCKET_IS_BWTP_INCOMING_FRAME(b) SERF_BUCKET_CHECK((b), bwtp_i ncoming_frame)
SERF_DECLARE(int) serf_bucket_bwtp_frame_get_channel(serf_bucket_t *hdr); int serf_bucket_bwtp_frame_get_channel(
serf_bucket_t *hdr);
SERF_DECLARE(int) serf_bucket_bwtp_frame_get_type(serf_bucket_t *hdr); int serf_bucket_bwtp_frame_get_type(
serf_bucket_t *hdr);
SERF_DECLARE(const char *) serf_bucket_bwtp_frame_get_phrase(serf_bucket_t const char *serf_bucket_bwtp_frame_get_phrase(
*hdr); serf_bucket_t *hdr);
SERF_DECLARE(serf_bucket_t *) serf_bucket_bwtp_frame_get_headers( serf_bucket_t *serf_bucket_bwtp_frame_get_headers(
serf_bucket_t *hdr); serf_bucket_t *hdr);
SERF_DECLARE(serf_bucket_t *) serf_bucket_bwtp_channel_open( serf_bucket_t *serf_bucket_bwtp_channel_open(
int channel, int channel,
const char *URI, const char *URI,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_bucket_t *) serf_bucket_bwtp_channel_close( serf_bucket_t *serf_bucket_bwtp_channel_close(
int channel, int channel,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_bucket_t *) serf_bucket_bwtp_header_create( serf_bucket_t *serf_bucket_bwtp_header_create(
int channel, int channel,
const char *phrase, const char *phrase,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_bucket_t *) serf_bucket_bwtp_message_create( serf_bucket_t *serf_bucket_bwtp_message_create(
int channel, int channel,
serf_bucket_t *body, serf_bucket_t *body,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_bucket_t *) serf_bucket_bwtp_incoming_frame_create( serf_bucket_t *serf_bucket_bwtp_incoming_frame_create(
serf_bucket_t *bkt, serf_bucket_t *bkt,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(apr_status_t) serf_bucket_bwtp_incoming_frame_wait_for_headers ( apr_status_t serf_bucket_bwtp_incoming_frame_wait_for_headers(
serf_bucket_t *bkt); serf_bucket_t *bkt);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_aggregat e; extern const serf_bucket_type_t serf_bucket_type_aggregate;
#define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate) #define SERF_BUCKET_IS_AGGREGATE(b) SERF_BUCKET_CHECK((b), aggregate)
typedef apr_status_t (*serf_bucket_aggregate_eof_t)(
void *baton,
serf_bucket_t *aggregate_bucket);
/** serf_bucket_aggregate_cleanup will instantly destroy all buckets in /** serf_bucket_aggregate_cleanup will instantly destroy all buckets in
the aggregate bucket that have been read completely. Whereas normally, the aggregate bucket that have been read completely. Whereas normally,
these buckets are destroyed on every read operation. */ these buckets are destroyed on every read operation. */
SERF_DECLARE(void) serf_bucket_aggregate_cleanup( void serf_bucket_aggregate_cleanup(
serf_bucket_t *bucket, serf_bucket_alloc_t *allocator); serf_bucket_t *bucket,
serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_bucket_t *) serf_bucket_aggregate_create( serf_bucket_t *serf_bucket_aggregate_create(
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/* Creates a stream bucket.
A stream bucket is like an aggregate bucket, but:
- it doesn't destroy its child buckets on cleanup
- one can always keep adding child buckets, the handler FN should return
APR_EOF when no more buckets will be added.
Note: keep this factory function internal for now. If it turns out this
bucket type is useful outside serf, we should make it an actual separate
type.
*/
serf_bucket_t *serf__bucket_stream_create(
serf_bucket_alloc_t *allocator,
serf_bucket_aggregate_eof_t fn,
void *baton);
/** Transform @a bucket in-place into an aggregate bucket. */ /** Transform @a bucket in-place into an aggregate bucket. */
SERF_DECLARE(void) serf_bucket_aggregate_become(serf_bucket_t *bucket); void serf_bucket_aggregate_become(
serf_bucket_t *bucket);
SERF_DECLARE(void) serf_bucket_aggregate_prepend( void serf_bucket_aggregate_prepend(
serf_bucket_t *aggregate_bucket, serf_bucket_t *aggregate_bucket,
serf_bucket_t *prepend_bucket); serf_bucket_t *prepend_bucket);
SERF_DECLARE(void) serf_bucket_aggregate_append( void serf_bucket_aggregate_append(
serf_bucket_t *aggregate_bucket, serf_bucket_t *aggregate_bucket,
serf_bucket_t *append_bucket); serf_bucket_t *append_bucket);
typedef apr_status_t (*serf_bucket_aggregate_eof_t)(void *baton, serf_bucke void serf_bucket_aggregate_hold_open(
t_t *aggregate_bucket); serf_bucket_t *aggregate_bucket,
serf_bucket_aggregate_eof_t fn,
SERF_DECLARE(void) serf_bucket_aggregate_hold_open(serf_bucket_t *aggregate void *baton);
_bucket,
serf_bucket_aggregate_eo
f_t fn,
void *baton);
SERF_DECLARE(void) serf_bucket_aggregate_prepend_iovec( void serf_bucket_aggregate_prepend_iovec(
serf_bucket_t *aggregate_bucket, serf_bucket_t *aggregate_bucket,
struct iovec *vecs, struct iovec *vecs,
int vecs_count); int vecs_count);
SERF_DECLARE(void) serf_bucket_aggregate_append_iovec( void serf_bucket_aggregate_append_iovec(
serf_bucket_t *aggregate_bucket, serf_bucket_t *aggregate_bucket,
struct iovec *vecs, struct iovec *vecs,
int vecs_count); int vecs_count);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_file; extern const serf_bucket_type_t serf_bucket_type_file;
#define SERF_BUCKET_IS_FILE(b) SERF_BUCKET_CHECK((b), file) #define SERF_BUCKET_IS_FILE(b) SERF_BUCKET_CHECK((b), file)
SERF_DECLARE(serf_bucket_t *) serf_bucket_file_create( serf_bucket_t *serf_bucket_file_create(
apr_file_t *file, apr_file_t *file,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(apr_file_t *) serf_bucket_file_borrow(serf_bucket_t *bkt);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_socket; extern const serf_bucket_type_t serf_bucket_type_socket;
#define SERF_BUCKET_IS_SOCKET(b) SERF_BUCKET_CHECK((b), socket) #define SERF_BUCKET_IS_SOCKET(b) SERF_BUCKET_CHECK((b), socket)
SERF_DECLARE(serf_bucket_t *) serf_bucket_socket_create( serf_bucket_t *serf_bucket_socket_create(
apr_socket_t *skt, apr_socket_t *skt,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/** /**
* Call @a progress_func every time bytes are read from the socket, pass * Call @a progress_func every time bytes are read from the socket, pass
* the number of bytes read. * the number of bytes read.
* *
* When using serf's bytes read & written progress indicator, pass * When using serf's bytes read & written progress indicator, pass
* @a serf_context_progress_delta for progress_func and the serf_context fo r * @a serf_context_progress_delta for progress_func and the serf_context fo r
* progress_baton. * progress_baton.
*/ */
SERF_DECLARE(void) serf_bucket_socket_set_read_progress_cb( void serf_bucket_socket_set_read_progress_cb(
serf_bucket_t *bucket, serf_bucket_t *bucket,
const serf_progress_t progress_func, const serf_progress_t progress_func,
void *progress_baton); void *progress_baton);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_simple; extern const serf_bucket_type_t serf_bucket_type_simple;
#define SERF_BUCKET_IS_SIMPLE(b) SERF_BUCKET_CHECK((b), simple) #define SERF_BUCKET_IS_SIMPLE(b) SERF_BUCKET_CHECK((b), simple)
typedef void (*serf_simple_freefunc_t)(void *baton, const char *data); typedef void (*serf_simple_freefunc_t)(
void *baton,
const char *data);
SERF_DECLARE(serf_bucket_t *) serf_bucket_simple_create( serf_bucket_t *serf_bucket_simple_create(
const char *data, apr_size_t len, const char *data,
apr_size_t len,
serf_simple_freefunc_t freefunc, serf_simple_freefunc_t freefunc,
void *freefunc_baton, void *freefunc_baton,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/** /**
* Equivalent to serf_bucket_simple_create, except that the bucket takes * Equivalent to serf_bucket_simple_create, except that the bucket takes
* ownership of a private copy of the data. * ownership of a private copy of the data.
*/ */
SERF_DECLARE(serf_bucket_t *) serf_bucket_simple_copy_create( serf_bucket_t *serf_bucket_simple_copy_create(
const char *data, apr_size_t len, const char *data,
apr_size_t len,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
#define SERF_BUCKET_SIMPLE_STRING(s,a) \ #define SERF_BUCKET_SIMPLE_STRING(s,a) \
serf_bucket_simple_create(s, strlen(s), NULL, NULL, a); serf_bucket_simple_create(s, strlen(s), NULL, NULL, a);
#define SERF_BUCKET_SIMPLE_STRING_LEN(s,l,a) \ #define SERF_BUCKET_SIMPLE_STRING_LEN(s,l,a) \
serf_bucket_simple_create(s, l, NULL, NULL, a); serf_bucket_simple_create(s, l, NULL, NULL, a);
/* ==================================================================== */ /* ==================================================================== */
/* Note: apr_mmap_t is always defined, but if APR doesn't have mmaps, then /* Note: apr_mmap_t is always defined, but if APR doesn't have mmaps, then
the caller can never create an apr_mmap_t to pass to this function. */ the caller can never create an apr_mmap_t to pass to this function. */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_mmap; extern const serf_bucket_type_t serf_bucket_type_mmap;
#define SERF_BUCKET_IS_MMAP(b) SERF_BUCKET_CHECK((b), mmap) #define SERF_BUCKET_IS_MMAP(b) SERF_BUCKET_CHECK((b), mmap)
SERF_DECLARE(serf_bucket_t *) serf_bucket_mmap_create( serf_bucket_t *serf_bucket_mmap_create(
apr_mmap_t *mmap, apr_mmap_t *mmap,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_headers; extern const serf_bucket_type_t serf_bucket_type_headers;
#define SERF_BUCKET_IS_HEADERS(b) SERF_BUCKET_CHECK((b), headers) #define SERF_BUCKET_IS_HEADERS(b) SERF_BUCKET_CHECK((b), headers)
SERF_DECLARE(serf_bucket_t *) serf_bucket_headers_create( serf_bucket_t *serf_bucket_headers_create(
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/** /**
* Set, default: value copied. * Set, default: value copied.
* *
* Set the specified @a header within the bucket, copying the @a value * Set the specified @a header within the bucket, copying the @a value
* into space from this bucket's allocator. The header is NOT copied, * into space from this bucket's allocator. The header is NOT copied,
* so it should remain in scope at least as long as the bucket. * so it should remain in scope at least as long as the bucket.
*/ */
SERF_DECLARE(void) serf_bucket_headers_set( void serf_bucket_headers_set(
serf_bucket_t *headers_bucket, serf_bucket_t *headers_bucket,
const char *header, const char *header,
const char *value); const char *value);
/** /**
* Set, copies: header and value copied. * Set, copies: header and value copied.
* *
* Copy the specified @a header and @a value into the bucket, using space * Copy the specified @a header and @a value into the bucket, using space
* from this bucket's allocator. * from this bucket's allocator.
*/ */
SERF_DECLARE(void) serf_bucket_headers_setc( void serf_bucket_headers_setc(
serf_bucket_t *headers_bucket, serf_bucket_t *headers_bucket,
const char *header, const char *header,
const char *value); const char *value);
/** /**
* Set, no copies. * Set, no copies.
* *
* Set the specified @a header and @a value into the bucket, without * Set the specified @a header and @a value into the bucket, without
* copying either attribute. Both attributes should remain in scope at * copying either attribute. Both attributes should remain in scope at
* least as long as the bucket. * least as long as the bucket.
* *
* @note In the case where a header already exists this will result * @note In the case where a header already exists this will result
* in a reallocation and copy, @see serf_bucket_headers_setn. * in a reallocation and copy, @see serf_bucket_headers_setn.
*/ */
SERF_DECLARE(void) serf_bucket_headers_setn( void serf_bucket_headers_setn(
serf_bucket_t *headers_bucket, serf_bucket_t *headers_bucket,
const char *header, const char *header,
const char *value); const char *value);
/** /**
* Set, extended: fine grained copy control of header and value. * Set, extended: fine grained copy control of header and value.
* *
* Set the specified @a header, with length @a header_size with the * Set the specified @a header, with length @a header_size with the
* @a value, and length @a value_size, into the bucket. The header will * @a value, and length @a value_size, into the bucket. The header will
* be copied if @a header_copy is set, and the value is copied if * be copied if @a header_copy is set, and the value is copied if
* @a value_copy is set. If the values are not copied, then they should * @a value_copy is set. If the values are not copied, then they should
* remain in scope at least as long as the bucket. * remain in scope at least as long as the bucket.
* *
* If @a headers_bucket already contains a header with the same name * If @a headers_bucket already contains a header with the same name
* as @a header, then append @a value to the existing value, * as @a header, then append @a value to the existing value,
* separating with a comma (as per RFC 2616, section 4.2). In this * separating with a comma (as per RFC 2616, section 4.2). In this
* case, the new value must be allocated and the header re-used, so * case, the new value must be allocated and the header re-used, so
* behave as if @a value_copy were true and @a header_copy false. * behave as if @a value_copy were true and @a header_copy false.
*/ */
SERF_DECLARE(void) serf_bucket_headers_setx( void serf_bucket_headers_setx(
serf_bucket_t *headers_bucket, serf_bucket_t *headers_bucket,
const char *header, apr_size_t header_size, int header_copy, const char *header,
const char *value, apr_size_t value_size, int value_copy); apr_size_t header_size,
int header_copy,
const char *value,
apr_size_t value_size,
int value_copy);
SERF_DECLARE(const char *) serf_bucket_headers_get( const char *serf_bucket_headers_get(
serf_bucket_t *headers_bucket, serf_bucket_t *headers_bucket,
const char *header); const char *header);
/** /**
* @param baton opaque baton as passed to @see serf_bucket_headers_do * @param baton opaque baton as passed to @see serf_bucket_headers_do
* @param key The header key from this iteration through the table * @param key The header key from this iteration through the table
* @param value The header value from this iteration through the table * @param value The header value from this iteration through the table
*/ */
typedef int (serf_bucket_headers_do_callback_fn_t)( typedef int (serf_bucket_headers_do_callback_fn_t)(
void *baton, void *baton,
skipping to change at line 366 skipping to change at line 396
/** /**
* Iterates over all headers of the message and invokes the callback * Iterates over all headers of the message and invokes the callback
* function with header key and value. Stop iterating when no more * function with header key and value. Stop iterating when no more
* headers are available or when the callback function returned a * headers are available or when the callback function returned a
* non-0 value. * non-0 value.
* *
* @param headers_bucket headers to iterate over * @param headers_bucket headers to iterate over
* @param func callback routine to invoke for every header in the bucket * @param func callback routine to invoke for every header in the bucket
* @param baton baton to pass on each invocation to func * @param baton baton to pass on each invocation to func
*/ */
SERF_DECLARE(void) serf_bucket_headers_do( void serf_bucket_headers_do(
serf_bucket_t *headers_bucket, serf_bucket_t *headers_bucket,
serf_bucket_headers_do_callback_fn_t func, serf_bucket_headers_do_callback_fn_t func,
void *baton); void *baton);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_chunk; extern const serf_bucket_type_t serf_bucket_type_chunk;
#define SERF_BUCKET_IS_CHUNK(b) SERF_BUCKET_CHECK((b), chunk) #define SERF_BUCKET_IS_CHUNK(b) SERF_BUCKET_CHECK((b), chunk)
SERF_DECLARE(serf_bucket_t *) serf_bucket_chunk_create( serf_bucket_t *serf_bucket_chunk_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_dechunk; extern const serf_bucket_type_t serf_bucket_type_dechunk;
#define SERF_BUCKET_IS_DECHUNK(b) SERF_BUCKET_CHECK((b), dechunk) #define SERF_BUCKET_IS_DECHUNK(b) SERF_BUCKET_CHECK((b), dechunk)
SERF_DECLARE(serf_bucket_t *) serf_bucket_dechunk_create( serf_bucket_t *serf_bucket_dechunk_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_deflate; extern const serf_bucket_type_t serf_bucket_type_deflate;
#define SERF_BUCKET_IS_DEFLATE(b) SERF_BUCKET_CHECK((b), deflate) #define SERF_BUCKET_IS_DEFLATE(b) SERF_BUCKET_CHECK((b), deflate)
#define SERF_DEFLATE_GZIP 0 #define SERF_DEFLATE_GZIP 0
#define SERF_DEFLATE_DEFLATE 1 #define SERF_DEFLATE_DEFLATE 1
SERF_DECLARE(serf_bucket_t *) serf_bucket_deflate_create( serf_bucket_t *serf_bucket_deflate_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_bucket_alloc_t *allocator, serf_bucket_alloc_t *allocator,
int format); int format);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_limit; extern const serf_bucket_type_t serf_bucket_type_limit;
#define SERF_BUCKET_IS_LIMIT(b) SERF_BUCKET_CHECK((b), limit) #define SERF_BUCKET_IS_LIMIT(b) SERF_BUCKET_CHECK((b), limit)
SERF_DECLARE(serf_bucket_t *) serf_bucket_limit_create( serf_bucket_t *serf_bucket_limit_create(
serf_bucket_t *stream, serf_bucket_t *stream,
apr_size_t limit, apr_size_t limit,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/* ==================================================================== */ /* ==================================================================== */
#define SERF_SSL_CERT_NOTYETVALID 1 #define SERF_SSL_CERT_NOTYETVALID 1
#define SERF_SSL_CERT_EXPIRED 2 #define SERF_SSL_CERT_EXPIRED 2
#define SERF_SSL_CERT_UNKNOWNCA 4 #define SERF_SSL_CERT_UNKNOWNCA 4
#define SERF_SSL_CERT_SELF_SIGNED 8 #define SERF_SSL_CERT_SELF_SIGNED 8
#define SERF_SSL_CERT_UNKNOWN_FAILURE 16 #define SERF_SSL_CERT_UNKNOWN_FAILURE 16
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_ssl_encr ypt; extern const serf_bucket_type_t serf_bucket_type_ssl_encrypt;
#define SERF_BUCKET_IS_SSL_ENCRYPT(b) SERF_BUCKET_CHECK((b), ssl_encrypt) #define SERF_BUCKET_IS_SSL_ENCRYPT(b) SERF_BUCKET_CHECK((b), ssl_encrypt)
typedef struct serf_ssl_context_t serf_ssl_context_t; typedef struct serf_ssl_context_t serf_ssl_context_t;
typedef struct serf_ssl_certificate_t serf_ssl_certificate_t; typedef struct serf_ssl_certificate_t serf_ssl_certificate_t;
typedef apr_status_t (*serf_ssl_need_client_cert_t)(void *data, typedef apr_status_t (*serf_ssl_need_client_cert_t)(
const char **cert_path) void *data,
; const char **cert_path);
typedef apr_status_t (*serf_ssl_need_cert_password_t)(
void *data,
const char *cert_path,
const char **password);
typedef apr_status_t (*serf_ssl_need_server_cert_t)(
void *data,
int failures,
const serf_ssl_certificate_t *cert);
void serf_ssl_client_cert_provider_set(
serf_ssl_context_t *context,
serf_ssl_need_client_cert_t callback,
void *data,
void *cache_pool);
void serf_ssl_client_cert_password_set(
serf_ssl_context_t *context,
serf_ssl_need_cert_password_t callback,
void *data,
void *cache_pool);
typedef apr_status_t (*serf_ssl_need_cert_password_t)(void *data,
const char *cert_path
,
const char **password
);
typedef apr_status_t
(*serf_ssl_need_server_cert_t)(void *data,
int failures,
const serf_ssl_certificate_t *cert);
SERF_DECLARE(void)
serf_ssl_client_cert_provider_set(serf_ssl_context_t *context,
serf_ssl_need_client_cert_t callback,
void *data,
void *cache_pool);
SERF_DECLARE(void)
serf_ssl_client_cert_password_set(serf_ssl_context_t *context,
serf_ssl_need_cert_password_t callback,
void *data,
void *cache_pool);
/** /**
* Set a callback to override the default SSL server certificate validation * Set a callback to override the default SSL server certificate validation
* algorithm. * algorithm.
*/ */
SERF_DECLARE(void) void serf_ssl_server_cert_callback_set(
serf_ssl_server_cert_callback_set(serf_ssl_context_t *context, serf_ssl_context_t *context,
serf_ssl_need_server_cert_t callback, serf_ssl_need_server_cert_t callback,
void *data); void *data);
/** /**
* Use the default root CA certificates as included with the OpenSSL librar y. * Use the default root CA certificates as included with the OpenSSL librar y.
*/ */
SERF_DECLARE(apr_status_t) apr_status_t serf_ssl_use_default_certificates(
serf_ssl_use_default_certificates(serf_ssl_context_t *context); serf_ssl_context_t *context);
/** /**
* Return the depth of the certificate. * Return the depth of the certificate.
*/ */
SERF_DECLARE(int) serf_ssl_cert_depth(const serf_ssl_certificate_t *cert); int serf_ssl_cert_depth(
const serf_ssl_certificate_t *cert);
/** /**
* Extract the fields of the issuer in a table with keys (E, CN, OU, O, L, * Extract the fields of the issuer in a table with keys (E, CN, OU, O, L,
* ST and C). The returned table will be allocated in @a pool. * ST and C). The returned table will be allocated in @a pool.
*/ */
SERF_DECLARE(apr_hash_t *) apr_hash_t *serf_ssl_cert_issuer(
serf_ssl_cert_issuer(const serf_ssl_certificate_t *cert, apr_pool_t *pool); const serf_ssl_certificate_t *cert,
apr_pool_t *pool);
/** /**
* Extract the fields of the subject in a table with keys (E, CN, OU, O, L, * Extract the fields of the subject in a table with keys (E, CN, OU, O, L,
* ST and C). The returned table will be allocated in @a pool. * ST and C). The returned table will be allocated in @a pool.
*/ */
SERF_DECLARE(apr_hash_t *) apr_hash_t *serf_ssl_cert_subject(
serf_ssl_cert_subject(const serf_ssl_certificate_t *cert, apr_pool_t *pool) const serf_ssl_certificate_t *cert,
; apr_pool_t *pool);
/** /**
* Extract the fields of the certificate in a table with keys (sha1, notBef ore, * Extract the fields of the certificate in a table with keys (sha1, notBef ore,
* notAfter). The returned table will be allocated in @a pool. * notAfter). The returned table will be allocated in @a pool.
*/ */
SERF_DECLARE(apr_hash_t *) apr_hash_t *serf_ssl_cert_certificate(
serf_ssl_cert_certificate(const serf_ssl_certificate_t *cert, apr_pool_t *p const serf_ssl_certificate_t *cert,
ool); apr_pool_t *pool);
/** /**
* Export a certificate to base64-encoded, zero-terminated string. * Export a certificate to base64-encoded, zero-terminated string.
* The returned string is allocated in @a pool. Returns NULL on failure. * The returned string is allocated in @a pool. Returns NULL on failure.
*/ */
SERF_DECLARE(const char *) const char *serf_ssl_cert_export(
serf_ssl_cert_export(const serf_ssl_certificate_t *cert, apr_pool_t *pool); const serf_ssl_certificate_t *cert,
apr_pool_t *pool);
/** /**
* Load a CA certificate file from a path @a file_path. If the file was loa ded * Load a CA certificate file from a path @a file_path. If the file was loa ded
* and parsed correctly, a certificate @a cert will be created and returned . * and parsed correctly, a certificate @a cert will be created and returned .
* This certificate object will be alloced in @a pool. * This certificate object will be alloced in @a pool.
*/ */
SERF_DECLARE(apr_status_t) apr_status_t serf_ssl_load_cert_file(
serf_ssl_load_cert_file(serf_ssl_certificate_t **cert, const char *file_pat serf_ssl_certificate_t **cert,
h, const char *file_path,
apr_pool_t *pool); apr_pool_t *pool);
/** /**
* Adds the certificate @a cert to the list of trusted certificates in * Adds the certificate @a cert to the list of trusted certificates in
* @a ssl_ctx that will be used for verification. * @a ssl_ctx that will be used for verification.
* See also @a serf_ssl_load_cert_file. * See also @a serf_ssl_load_cert_file.
*/ */
SERF_DECLARE(apr_status_t) apr_status_t serf_ssl_trust_cert(
serf_ssl_trust_cert(serf_ssl_context_t *ssl_ctx, serf_ssl_certificate_t *ce serf_ssl_context_t *ssl_ctx,
rt); serf_ssl_certificate_t *cert);
SERF_DECLARE(serf_bucket_t *) serf_bucket_ssl_encrypt_create( serf_bucket_t *serf_bucket_ssl_encrypt_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_ssl_context_t *ssl_context, serf_ssl_context_t *ssl_context,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_ssl_context_t *) serf_bucket_ssl_encrypt_context_get( serf_ssl_context_t *serf_bucket_ssl_encrypt_context_get(
serf_bucket_t *bucket); serf_bucket_t *bucket);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_ssl_decr ypt; extern const serf_bucket_type_t serf_bucket_type_ssl_decrypt;
#define SERF_BUCKET_IS_SSL_DECRYPT(b) SERF_BUCKET_CHECK((b), ssl_decrypt) #define SERF_BUCKET_IS_SSL_DECRYPT(b) SERF_BUCKET_CHECK((b), ssl_decrypt)
SERF_DECLARE(serf_bucket_t *) serf_bucket_ssl_decrypt_create( serf_bucket_t *serf_bucket_ssl_decrypt_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_ssl_context_t *ssl_context, serf_ssl_context_t *ssl_context,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
SERF_DECLARE(serf_ssl_context_t *) serf_bucket_ssl_decrypt_context_get( serf_ssl_context_t *serf_bucket_ssl_decrypt_context_get(
serf_bucket_t *bucket); serf_bucket_t *bucket);
/* ==================================================================== */ /* ==================================================================== */
SERF_DECLARE_DATA extern const serf_bucket_type_t serf_bucket_type_barrier; extern const serf_bucket_type_t serf_bucket_type_barrier;
#define SERF_BUCKET_IS_BARRIER(b) SERF_BUCKET_CHECK((b), barrier) #define SERF_BUCKET_IS_BARRIER(b) SERF_BUCKET_CHECK((b), barrier)
SERF_DECLARE(serf_bucket_t *) serf_bucket_barrier_create( serf_bucket_t *serf_bucket_barrier_create(
serf_bucket_t *stream, serf_bucket_t *stream,
serf_bucket_alloc_t *allocator); serf_bucket_alloc_t *allocator);
/* ==================================================================== */ /* ==================================================================== */
/* ### do we need a PIPE bucket type? they are simple apr_file_t objects */ /* ### do we need a PIPE bucket type? they are simple apr_file_t objects */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
 End of changes. 83 change blocks. 
137 lines changed or deleted 166 lines changed or added


 serf_bucket_util.h   serf_bucket_util.h 
skipping to change at line 27 skipping to change at line 27
#define SERF_BUCKET_UTIL_H #define SERF_BUCKET_UTIL_H
/** /**
* @file serf_bucket_util.h * @file serf_bucket_util.h
* @brief This header defines a set of functions and other utilities * @brief This header defines a set of functions and other utilities
* for implementing buckets. It is not needed by users of the bucket * for implementing buckets. It is not needed by users of the bucket
* system. * system.
*/ */
#include "serf.h" #include "serf.h"
#include "serf_declare.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** /**
* Basic bucket creation function. * Basic bucket creation function.
* *
* This function will create a bucket of @a type, allocating the necessary * This function will create a bucket of @a type, allocating the necessary
* memory from @a allocator. The @a data bucket-private information will * memory from @a allocator. The @a data bucket-private information will
* be stored into the bucket. * be stored into the bucket.
*/ */
SERF_DECLARE(serf_bucket_t *) serf_bucket_create( serf_bucket_t *serf_bucket_create(
const serf_bucket_type_t *type, const serf_bucket_type_t *type,
serf_bucket_alloc_t *allocator, serf_bucket_alloc_t *allocator,
void *data); void *data);
/** /**
* Default implementation of the @see read_iovec functionality. * Default implementation of the @see read_iovec functionality.
* *
* This function will use the @see read function to get a block of memory, * This function will use the @see read function to get a block of memory,
* then return it in the iovec. * then return it in the iovec.
*/ */
SERF_DECLARE(apr_status_t) serf_default_read_iovec( apr_status_t serf_default_read_iovec(
serf_bucket_t *bucket, serf_bucket_t *bucket,
apr_size_t requested, apr_size_t requested,
int vecs_size, int vecs_size,
struct iovec *vecs, struct iovec *vecs,
int *vecs_used); int *vecs_used);
/** /**
* Default implementation of the @see read_for_sendfile functionality. * Default implementation of the @see read_for_sendfile functionality.
* *
* This function will use the @see read function to get a block of memory, * This function will use the @see read function to get a block of memory,
* then return it as a header. No file will be returned. * then return it as a header. No file will be returned.
*/ */
SERF_DECLARE(apr_status_t) serf_default_read_for_sendfile( apr_status_t serf_default_read_for_sendfile(
serf_bucket_t *bucket, serf_bucket_t *bucket,
apr_size_t requested, apr_size_t requested,
apr_hdtr_t *hdtr, apr_hdtr_t *hdtr,
apr_file_t **file, apr_file_t **file,
apr_off_t *offset, apr_off_t *offset,
apr_size_t *len); apr_size_t *len);
/** /**
* Default implementation of the @see read_bucket functionality. * Default implementation of the @see read_bucket functionality.
* *
* This function will always return NULL, indicating that the @a type * This function will always return NULL, indicating that the @a type
* of bucket cannot be found within @a bucket. * of bucket cannot be found within @a bucket.
*/ */
SERF_DECLARE(serf_bucket_t *) serf_default_read_bucket( serf_bucket_t *serf_default_read_bucket(
serf_bucket_t *bucket, serf_bucket_t *bucket,
const serf_bucket_type_t *type); const serf_bucket_type_t *type);
/** /**
* Default implementation of the @see destroy functionality. * Default implementation of the @see destroy functionality.
* *
* This function will return the @a bucket to its allcoator. * This function will return the @a bucket to its allcoator.
*/ */
SERF_DECLARE(void) serf_default_destroy(serf_bucket_t *bucket); void serf_default_destroy(
serf_bucket_t *bucket);
/** /**
* Default implementation of the @see destroy functionality. * Default implementation of the @see destroy functionality.
* *
* This function will return the @a bucket, and the data member to its * This function will return the @a bucket, and the data member to its
* allcoator. * allocator.
*/ */
SERF_DECLARE(void) serf_default_destroy_and_data(serf_bucket_t *bucket); void serf_default_destroy_and_data(
serf_bucket_t *bucket);
/** /**
* Default implementation of the @see snapshot functionality * Default implementation of the @see snapshot functionality
* *
* This function will return an error to indicate it's not implemented. * This function will return an error to indicate it's not implemented.
*/ */
SERF_DECLARE(apr_status_t) serf_default_snapshot(serf_bucket_t *bucket); apr_status_t serf_default_snapshot(
serf_bucket_t *bucket);
/* /*
* Default implementation of the @see restore_snapshot functionality * Default implementation of the @see restore_snapshot functionality
* *
* This function will return an error to indicate it's not implemented. * This function will return an error to indicate it's not implemented.
*/ */
SERF_DECLARE(apr_status_t) serf_default_restore_snapshot(serf_bucket_t *buc apr_status_t serf_default_restore_snapshot(
ket); serf_bucket_t *bucket);
/* /*
* Default implementation of the @see is_snapshot_set functionality * Default implementation of the @see is_snapshot_set functionality
* *
* This function will return 0 (no snapshot set). * This function will return 0 (no snapshot set).
*/ */
SERF_DECLARE(int) serf_default_is_snapshot_set(serf_bucket_t *bucket); int serf_default_is_snapshot_set(
serf_bucket_t *bucket);
/** /**
* Allocate @a size bytes of memory using @a allocator. * Allocate @a size bytes of memory using @a allocator.
*
* Returns NULL of the requested memory size could not be allocated.
*/ */
SERF_DECLARE(void *) serf_bucket_mem_alloc( void *serf_bucket_mem_alloc(
serf_bucket_alloc_t *allocator, serf_bucket_alloc_t *allocator,
apr_size_t size); apr_size_t size);
/** /**
* Allocate @a size bytes of memory using @a allocator and set all of the * Allocate @a size bytes of memory using @a allocator and set all of the
* memory to 0. * memory to 0.
*
* Returns NULL of the requested memory size could not be allocated.
*/ */
SERF_DECLARE(void *) serf_bucket_mem_calloc( void *serf_bucket_mem_calloc(
serf_bucket_alloc_t *allocator, serf_bucket_alloc_t *allocator,
apr_size_t size); apr_size_t size);
/** /**
* Free the memory at @a block, returning it to @a allocator. * Free the memory at @a block, returning it to @a allocator.
*/ */
SERF_DECLARE(void) serf_bucket_mem_free( void serf_bucket_mem_free(
serf_bucket_alloc_t *allocator, serf_bucket_alloc_t *allocator,
void *block); void *block);
/** /**
* Analogous to apr_pstrmemdup, using a bucket allocator instead. * Analogous to apr_pstrmemdup, using a bucket allocator instead.
*/ */
SERF_DECLARE(char *) serf_bstrmemdup(serf_bucket_alloc_t *allocator, char *serf_bstrmemdup(
const char *str, serf_bucket_alloc_t *allocator,
apr_size_t size); const char *str,
apr_size_t size);
/** /**
* Analogous to apr_pmemdup, using a bucket allocator instead. * Analogous to apr_pmemdup, using a bucket allocator instead.
*/ */
SERF_DECLARE(void *) serf_bmemdup(serf_bucket_alloc_t *allocator, void * serf_bmemdup(
const void *mem, serf_bucket_alloc_t *allocator,
apr_size_t size); const void *mem,
apr_size_t size);
/** /**
* Analogous to apr_pstrdup, using a bucket allocator instead. * Analogous to apr_pstrdup, using a bucket allocator instead.
*/ */
SERF_DECLARE(char *) serf_bstrdup(serf_bucket_alloc_t *allocator, char * serf_bstrdup(
const char *str); serf_bucket_alloc_t *allocator,
const char *str);
/** /**
* Read data up to a newline. * Read data up to a newline.
* *
* @a acceptable contains the allowed forms of a newline, and @a found * @a acceptable contains the allowed forms of a newline, and @a found
* will return the particular newline type that was found. If a newline * will return the particular newline type that was found. If a newline
* is not found, then SERF_NEWLINE_NONE will be placed in @a found. * is not found, then SERF_NEWLINE_NONE will be placed in @a found.
* *
* @a data should contain a pointer to the data to be scanned. @a len * @a data should contain a pointer to the data to be scanned. @a len
* should specify the length of that data buffer. On exit, @a data will * should specify the length of that data buffer. On exit, @a data will
skipping to change at line 188 skipping to change at line 199
* This function scans at a byte level for the newline characters. Thus, * This function scans at a byte level for the newline characters. Thus,
* the data buffer may contain NUL characters. As a corollary, this * the data buffer may contain NUL characters. As a corollary, this
* function only works on 8-bit character encodings. * function only works on 8-bit character encodings.
* *
* If the data is fully consumed (@a len gets set to zero) and a CR * If the data is fully consumed (@a len gets set to zero) and a CR
* character is found at the end and the CRLF sequence is allowed, then * character is found at the end and the CRLF sequence is allowed, then
* this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The * this function may store SERF_NEWLINE_CRLF_SPLIT into @a found. The
* caller should take particular consideration for the CRLF sequence * caller should take particular consideration for the CRLF sequence
* that may be split across data buffer boundaries. * that may be split across data buffer boundaries.
*/ */
SERF_DECLARE(void) serf_util_readline(const char **data, apr_size_t *len, void serf_util_readline(
int acceptable, int *found); const char **data,
apr_size_t *len,
int acceptable,
int *found);
/** The buffer size used within @see serf_databuf_t. */ /** The buffer size used within @see serf_databuf_t. */
#define SERF_DATABUF_BUFSIZE 8000 #define SERF_DATABUF_BUFSIZE 8000
/** Callback function which is used to refill the data buffer. /** Callback function which is used to refill the data buffer.
* *
* The function takes @a baton, which is the @see read_baton value * The function takes @a baton, which is the @see read_baton value
* from the serf_databuf_t structure. Data should be placed into * from the serf_databuf_t structure. Data should be placed into
* a buffer specified by @a buf, which is @a bufsize bytes long. * a buffer specified by @a buf, which is @a bufsize bytes long.
* The amount of data read should be returned in @a len. * The amount of data read should be returned in @a len.
* *
* APR_EOF should be returned if no more data is available. APR_EAGAIN * APR_EOF should be returned if no more data is available. APR_EAGAIN
* should be returned, rather than blocking. In both cases, @a buf * should be returned, rather than blocking. In both cases, @a buf
* should be filled in and @a len set, as appropriate. * should be filled in and @a len set, as appropriate.
*/ */
typedef apr_status_t (*serf_databuf_reader_t)(void *baton, typedef apr_status_t (*serf_databuf_reader_t)(
apr_size_t bufsize, void *baton,
char *buf, apr_size_t bufsize,
apr_size_t *len); char *buf,
apr_size_t *len);
/** /**
* This structure is used as an intermediate data buffer for some "external " * This structure is used as an intermediate data buffer for some "external "
* source of data. It works as a scratch pad area for incoming data to be * source of data. It works as a scratch pad area for incoming data to be
* stored, and then returned as a ptr/len pair by the bucket read functions . * stored, and then returned as a ptr/len pair by the bucket read functions .
* *
* This structure should be initialized by calling @see serf_databuf_init. * This structure should be initialized by calling @see serf_databuf_init.
* Users should not bother to zero the structure beforehand. * Users should not bother to zero the structure beforehand.
*/ */
typedef struct { typedef struct {
skipping to change at line 242 skipping to change at line 257
apr_status_t status; apr_status_t status;
/** Holds the data until it can be returned. */ /** Holds the data until it can be returned. */
char buf[SERF_DATABUF_BUFSIZE]; char buf[SERF_DATABUF_BUFSIZE];
} serf_databuf_t; } serf_databuf_t;
/** /**
* Initialize the @see serf_databuf_t structure specified by @a databuf. * Initialize the @see serf_databuf_t structure specified by @a databuf.
*/ */
SERF_DECLARE(void) serf_databuf_init(serf_databuf_t *databuf); void serf_databuf_init(
serf_databuf_t *databuf);
/** /**
* Implement a bucket-style read function from the @see serf_databuf_t * Implement a bucket-style read function from the @see serf_databuf_t
* structure given by @a databuf. * structure given by @a databuf.
* *
* The @a requested, @a data, and @a len fields are interpreted and used * The @a requested, @a data, and @a len fields are interpreted and used
* as in the read function of @see serf_bucket_t. * as in the read function of @see serf_bucket_t.
*/ */
SERF_DECLARE(apr_status_t) serf_databuf_read(serf_databuf_t *databuf, apr_status_t serf_databuf_read(
apr_size_t requested, serf_databuf_t *databuf,
const char **data, apr_size_t requested,
apr_size_t *len); const char **data,
apr_size_t *len);
/** /**
* Implement a bucket-style readline function from the @see serf_databuf_t * Implement a bucket-style readline function from the @see serf_databuf_t
* structure given by @a databuf. * structure given by @a databuf.
* *
* The @a acceptable, @a found, @a data, and @a len fields are interpreted * The @a acceptable, @a found, @a data, and @a len fields are interpreted
* and used as in the read function of @see serf_bucket_t. * and used as in the read function of @see serf_bucket_t.
*/ */
SERF_DECLARE(apr_status_t) serf_databuf_readline(serf_databuf_t *databuf, apr_status_t serf_databuf_readline(
int acceptable, int *found serf_databuf_t *databuf,
, int acceptable,
const char **data, int *found,
apr_size_t *len); const char **data,
apr_size_t *len);
/** /**
* Implement a bucket-style peek function from the @see serf_databuf_t * Implement a bucket-style peek function from the @see serf_databuf_t
* structure given by @a databuf. * structure given by @a databuf.
* *
* The @a data, and @a len fields are interpreted and used as in the * The @a data, and @a len fields are interpreted and used as in the
* peek function of @see serf_bucket_t. * peek function of @see serf_bucket_t.
*/ */
SERF_DECLARE(apr_status_t) serf_databuf_peek(serf_databuf_t *databuf, apr_status_t serf_databuf_peek(
const char **data, serf_databuf_t *databuf,
apr_size_t *len); const char **data,
apr_size_t *len);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* !SERF_BUCKET_UTIL_H */ #endif /* !SERF_BUCKET_UTIL_H */
 End of changes. 25 change blocks. 
42 lines changed or deleted 60 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/