diff options
Diffstat (limited to 'serf_private.h')
-rw-r--r-- | serf_private.h | 403 |
1 files changed, 403 insertions, 0 deletions
diff --git a/serf_private.h b/serf_private.h new file mode 100644 index 0000000000000..867d74e4d1425 --- /dev/null +++ b/serf_private.h @@ -0,0 +1,403 @@ +/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef _SERF_PRIVATE_H_ +#define _SERF_PRIVATE_H_ + +/* ### what the hell? why does the APR interface have a "size" ?? + ### the implication is that, if we bust this limit, we'd need to + ### stop, rebuild a pollset, and repopulate it. what suckage. */ +#define MAX_CONN 16 + +/* Windows does not define IOV_MAX, so we need to ensure it is defined. */ +#ifndef IOV_MAX +#define IOV_MAX 16 +#endif + +#define SERF_IO_CLIENT (1) +#define SERF_IO_CONN (2) +#define SERF_IO_LISTENER (3) + +/* Internal logging facilities, set flag to 1 to enable console logging for + the selected component. */ +#define SSL_VERBOSE 0 +#define SSL_MSG_VERBOSE 0 /* logs decrypted requests and responses. */ +#define SOCK_VERBOSE 0 +#define SOCK_MSG_VERBOSE 0 /* logs bytes received from or written to a socket. */ +#define CONN_VERBOSE 0 +#define AUTH_VERBOSE 0 + + +typedef struct serf__authn_scheme_t serf__authn_scheme_t; + +typedef struct serf_io_baton_t { + int type; + union { + serf_incoming_t *client; + serf_connection_t *conn; + serf_listener_t *listener; + } u; +} serf_io_baton_t; + +/* Holds all the information corresponding to a request/response pair. */ +struct serf_request_t { + serf_connection_t *conn; + + apr_pool_t *respool; + serf_bucket_alloc_t *allocator; + + /* The bucket corresponding to the request. Will be NULL once the + * bucket has been emptied (for delivery into the socket). + */ + serf_bucket_t *req_bkt; + + serf_request_setup_t setup; + void *setup_baton; + + serf_response_acceptor_t acceptor; + void *acceptor_baton; + + serf_response_handler_t handler; + void *handler_baton; + + serf_bucket_t *resp_bkt; + + int written; + int priority; + + /* This baton is currently only used for digest authentication, which + needs access to the uri of the request in the response handler. + If serf_request_t is replaced by a serf_http_request_t in the future, + which knows about uri and method and such, this baton won't be needed + anymore. */ + void *auth_baton; + + struct serf_request_t *next; +}; + +typedef struct serf_pollset_t { + /* the set of connections to poll */ + apr_pollset_t *pollset; +} serf_pollset_t; + +typedef struct serf__authn_info_t { + const char *realm; + + const serf__authn_scheme_t *scheme; + + void *baton; +} serf__authn_info_t; + +struct serf_context_t { + /* the pool used for self and for other allocations */ + apr_pool_t *pool; + + void *pollset_baton; + serf_socket_add_t pollset_add; + serf_socket_remove_t pollset_rm; + + /* one of our connections has a dirty pollset state. */ + int dirty_pollset; + + /* the list of active connections */ + apr_array_header_t *conns; +#define GET_CONN(ctx, i) (((serf_connection_t **)(ctx)->conns->elts)[i]) + + /* Proxy server address */ + apr_sockaddr_t *proxy_address; + + /* Progress callback */ + serf_progress_t progress_func; + void *progress_baton; + apr_off_t progress_read; + apr_off_t progress_written; + + /* authentication info for this context, shared by all connections. */ + serf__authn_info_t authn_info; + serf__authn_info_t proxy_authn_info; + + /* List of authn types supported by the client.*/ + int authn_types; + /* Callback function used to get credentials for a realm. */ + serf_credentials_callback_t cred_cb; +}; + +struct serf_listener_t { + serf_context_t *ctx; + serf_io_baton_t baton; + apr_socket_t *skt; + apr_pool_t *pool; + apr_pollfd_t desc; + void *accept_baton; + serf_accept_client_t accept_func; +}; + +struct serf_incoming_t { + serf_context_t *ctx; + serf_io_baton_t baton; + void *request_baton; + serf_incoming_request_cb_t request; + apr_socket_t *skt; + apr_pollfd_t desc; +}; + +/* States for the different stages in the lifecyle of a connection. */ +typedef enum { + SERF_CONN_INIT, /* no socket created yet */ + SERF_CONN_SETUP_SSLTUNNEL, /* ssl tunnel being setup, no requests sent */ + SERF_CONN_CONNECTED, /* conn is ready to send requests */ + SERF_CONN_CLOSING, /* conn is closing, no more requests, + start a new socket */ +} serf__connection_state_t; + +struct serf_connection_t { + serf_context_t *ctx; + + apr_status_t status; + serf_io_baton_t baton; + + apr_pool_t *pool; + serf_bucket_alloc_t *allocator; + + apr_sockaddr_t *address; + + apr_socket_t *skt; + apr_pool_t *skt_pool; + + /* the last reqevents we gave to pollset_add */ + apr_int16_t reqevents; + + /* the events we've seen for this connection in our returned pollset */ + apr_int16_t seen_in_pollset; + + /* are we a dirty connection that needs its poll status updated? */ + int dirty_conn; + + /* number of completed requests we've sent */ + unsigned int completed_requests; + + /* number of completed responses we've got */ + unsigned int completed_responses; + + /* keepalive */ + unsigned int probable_keepalive_limit; + + /* Current state of the connection (whether or not it is connected). */ + serf__connection_state_t state; + + /* This connection may have responses without a request! */ + int async_responses; + serf_bucket_t *current_async_response; + serf_response_acceptor_t async_acceptor; + void *async_acceptor_baton; + serf_response_handler_t async_handler; + void *async_handler_baton; + + /* A bucket wrapped around our socket (for reading responses). */ + serf_bucket_t *stream; + /* A reference to the aggregate bucket that provides the boundary between + * request level buckets and connection level buckets. + */ + serf_bucket_t *ostream_head; + serf_bucket_t *ostream_tail; + + /* Aggregate bucket used to send the CONNECT request. */ + serf_bucket_t *ssltunnel_ostream; + + /* The list of active requests. */ + serf_request_t *requests; + serf_request_t *requests_tail; + + struct iovec vec[IOV_MAX]; + int vec_len; + + serf_connection_setup_t setup; + void *setup_baton; + serf_connection_closed_t closed; + void *closed_baton; + + /* Max. number of outstanding requests. */ + unsigned int max_outstanding_requests; + + int hit_eof; + /* Host info. */ + const char *host_url; + apr_uri_t host_info; + + /* connection and authentication scheme specific information */ + void *authn_baton; + void *proxy_authn_baton; + + /* Time marker when connection begins. */ + apr_time_t connect_time; + + /* Calculated connection latency. Negative value if latency is unknown. */ + apr_interval_time_t latency; +}; + +/*** Internal bucket functions ***/ + +/** Transform a response_bucket in-place into an aggregate bucket. Restore the + status line and all headers, not just the body. + + This can only be used when we haven't started reading the body of the + response yet. + + Keep internal for now, probably only useful within serf. + */ +apr_status_t serf_response_full_become_aggregate(serf_bucket_t *bucket); + +/*** Authentication handler declarations ***/ + +typedef enum { PROXY, HOST } peer_t; + +/** + * For each authentication scheme we need a handler function of type + * serf__auth_handler_func_t. This function will be called when an + * authentication challenge is received in a session. + */ +typedef apr_status_t +(*serf__auth_handler_func_t)(int code, + serf_request_t *request, + serf_bucket_t *response, + const char *auth_hdr, + const char *auth_attr, + void *baton, + apr_pool_t *pool); + +/** + * For each authentication scheme we need an initialization function of type + * serf__init_context_func_t. This function will be called the first time + * serf tries a specific authentication scheme handler. + */ +typedef apr_status_t +(*serf__init_context_func_t)(int code, + serf_context_t *conn, + apr_pool_t *pool); + +/** + * For each authentication scheme we need an initialization function of type + * serf__init_conn_func_t. This function will be called when a new + * connection is opened. + */ +typedef apr_status_t +(*serf__init_conn_func_t)(int code, + serf_connection_t *conn, + apr_pool_t *pool); + +/** + * For each authentication scheme we need a setup_request function of type + * serf__setup_request_func_t. This function will be called when a + * new serf_request_t object is created and should fill in the correct + * authentication headers (if needed). + */ +typedef apr_status_t +(*serf__setup_request_func_t)(peer_t peer, + int code, + serf_connection_t *conn, + serf_request_t *request, + const char *method, + const char *uri, + serf_bucket_t *hdrs_bkt); + +/** + * This function will be called when a response is received, so that the + * scheme handler can validate the Authentication related response headers + * (if needed). + */ +typedef apr_status_t +(*serf__validate_response_func_t)(peer_t peer, + int code, + serf_connection_t *conn, + serf_request_t *request, + serf_bucket_t *response, + apr_pool_t *pool); + +/** + * serf__authn_scheme_t: vtable for an authn scheme provider. + */ +struct serf__authn_scheme_t { + /* The http status code that's handled by this authentication scheme. + Normal values are 401 for server authentication and 407 for proxy + authentication */ + int code; + + /* The name of this authentication scheme. This should be a case + sensitive match of the string sent in the HTTP authentication header. */ + const char *name; + + /* Internal code used for this authn type. */ + int type; + + /* The context initialization function if any; otherwise, NULL */ + serf__init_context_func_t init_ctx_func; + + /* The connection initialization function if any; otherwise, NULL */ + serf__init_conn_func_t init_conn_func; + + /* The authentication handler function */ + serf__auth_handler_func_t handle_func; + + /* Function to set up the authentication header of a request */ + serf__setup_request_func_t setup_request_func; + + /* Function to validate the authentication header of a response */ + serf__validate_response_func_t validate_response_func; +}; + +/** + * Handles a 401 or 407 response, tries the different available authentication + * handlers. + */ +apr_status_t serf__handle_auth_response(int *consumed_response, + serf_request_t *request, + serf_bucket_t *response, + void *baton, + apr_pool_t *pool); + +/* fromt context.c */ +void serf__context_progress_delta(void *progress_baton, apr_off_t read, + apr_off_t written); + +/* from incoming.c */ +apr_status_t serf__process_client(serf_incoming_t *l, apr_int16_t events); +apr_status_t serf__process_listener(serf_listener_t *l); + +/* from outgoing.c */ +apr_status_t serf__open_connections(serf_context_t *ctx); +apr_status_t serf__process_connection(serf_connection_t *conn, + apr_int16_t events); +apr_status_t serf__conn_update_pollset(serf_connection_t *conn); + +/* from ssltunnel.c */ +apr_status_t serf__ssltunnel_connect(serf_connection_t *conn); + + +/** Logging functions. Use one of the [COMP]_VERBOSE flags to enable specific + logging. + **/ + +/* Logs a standard event, with filename & timestamp header */ +void serf__log(int verbose_flag, const char *filename, const char *fmt, ...); + +/* Logs a standard event, but without prefix. This is useful to build up + log lines in parts. */ +void serf__log_nopref(int verbose_flag, const char *fmt, ...); + +/* Logs a socket event, add local and remote ip address:port */ +void serf__log_skt(int verbose_flag, const char *filename, apr_socket_t *skt, + const char *fmt, ...); + +#endif |