diff options
Diffstat (limited to 'incoming.c')
-rw-r--r-- | incoming.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/incoming.c b/incoming.c new file mode 100644 index 0000000000000..40562fac89ab8 --- /dev/null +++ b/incoming.c @@ -0,0 +1,176 @@ +/* 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. + */ + +#include <apr_pools.h> +#include <apr_poll.h> +#include <apr_version.h> + +#include "serf.h" +#include "serf_bucket_util.h" + +#include "serf_private.h" + +static apr_status_t read_from_client(serf_incoming_t *client) +{ + return APR_ENOTIMPL; +} + +static apr_status_t write_to_client(serf_incoming_t *client) +{ + return APR_ENOTIMPL; +} + +apr_status_t serf__process_client(serf_incoming_t *client, apr_int16_t events) +{ + apr_status_t rv; + if ((events & APR_POLLIN) != 0) { + rv = read_from_client(client); + if (rv) { + return rv; + } + } + + if ((events & APR_POLLHUP) != 0) { + return APR_ECONNRESET; + } + + if ((events & APR_POLLERR) != 0) { + return APR_EGENERAL; + } + + if ((events & APR_POLLOUT) != 0) { + rv = write_to_client(client); + if (rv) { + return rv; + } + } + + return APR_SUCCESS; +} + +apr_status_t serf__process_listener(serf_listener_t *l) +{ + apr_status_t rv; + apr_socket_t *in; + apr_pool_t *p; + /* THIS IS NOT OPTIMAL */ + apr_pool_create(&p, l->pool); + + rv = apr_socket_accept(&in, l->skt, p); + + if (rv) { + apr_pool_destroy(p); + return rv; + } + + rv = l->accept_func(l->ctx, l, l->accept_baton, in, p); + + if (rv) { + apr_pool_destroy(p); + return rv; + } + + return rv; +} + + +apr_status_t serf_incoming_create( + serf_incoming_t **client, + serf_context_t *ctx, + apr_socket_t *insock, + void *request_baton, + serf_incoming_request_cb_t request, + apr_pool_t *pool) +{ + apr_status_t rv; + serf_incoming_t *ic = apr_palloc(pool, sizeof(*ic)); + + ic->ctx = ctx; + ic->baton.type = SERF_IO_CLIENT; + ic->baton.u.client = ic; + ic->request_baton = request_baton; + ic->request = request; + ic->skt = insock; + ic->desc.desc_type = APR_POLL_SOCKET; + ic->desc.desc.s = ic->skt; + ic->desc.reqevents = APR_POLLIN; + + rv = ctx->pollset_add(ctx->pollset_baton, + &ic->desc, &ic->baton); + *client = ic; + + return rv; +} + + +apr_status_t serf_listener_create( + serf_listener_t **listener, + serf_context_t *ctx, + const char *host, + apr_uint16_t port, + void *accept_baton, + serf_accept_client_t accept, + apr_pool_t *pool) +{ + apr_sockaddr_t *sa; + apr_status_t rv; + serf_listener_t *l = apr_palloc(pool, sizeof(*l)); + + l->ctx = ctx; + l->baton.type = SERF_IO_LISTENER; + l->baton.u.listener = l; + l->accept_func = accept; + l->accept_baton = accept_baton; + + apr_pool_create(&l->pool, pool); + + rv = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, l->pool); + if (rv) + return rv; + + rv = apr_socket_create(&l->skt, sa->family, + SOCK_STREAM, +#if APR_MAJOR_VERSION > 0 + APR_PROTO_TCP, +#endif + l->pool); + if (rv) + return rv; + + rv = apr_socket_opt_set(l->skt, APR_SO_REUSEADDR, 1); + if (rv) + return rv; + + rv = apr_socket_bind(l->skt, sa); + if (rv) + return rv; + + rv = apr_socket_listen(l->skt, 5); + if (rv) + return rv; + + l->desc.desc_type = APR_POLL_SOCKET; + l->desc.desc.s = l->skt; + l->desc.reqevents = APR_POLLIN; + + rv = ctx->pollset_add(ctx->pollset_baton, + &l->desc, &l->baton); + if (rv) + return rv; + + *listener = l; + + return APR_SUCCESS; +} |