incoming.c revision 251886
1/* Copyright 2002-2004 Justin Erenkrantz and Greg Stein 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <apr_pools.h> 17#include <apr_poll.h> 18#include <apr_version.h> 19 20#include "serf.h" 21#include "serf_bucket_util.h" 22 23#include "serf_private.h" 24 25static apr_status_t read_from_client(serf_incoming_t *client) 26{ 27 return APR_ENOTIMPL; 28} 29 30static apr_status_t write_to_client(serf_incoming_t *client) 31{ 32 return APR_ENOTIMPL; 33} 34 35apr_status_t serf__process_client(serf_incoming_t *client, apr_int16_t events) 36{ 37 apr_status_t rv; 38 if ((events & APR_POLLIN) != 0) { 39 rv = read_from_client(client); 40 if (rv) { 41 return rv; 42 } 43 } 44 45 if ((events & APR_POLLHUP) != 0) { 46 return APR_ECONNRESET; 47 } 48 49 if ((events & APR_POLLERR) != 0) { 50 return APR_EGENERAL; 51 } 52 53 if ((events & APR_POLLOUT) != 0) { 54 rv = write_to_client(client); 55 if (rv) { 56 return rv; 57 } 58 } 59 60 return APR_SUCCESS; 61} 62 63apr_status_t serf__process_listener(serf_listener_t *l) 64{ 65 apr_status_t rv; 66 apr_socket_t *in; 67 apr_pool_t *p; 68 /* THIS IS NOT OPTIMAL */ 69 apr_pool_create(&p, l->pool); 70 71 rv = apr_socket_accept(&in, l->skt, p); 72 73 if (rv) { 74 apr_pool_destroy(p); 75 return rv; 76 } 77 78 rv = l->accept_func(l->ctx, l, l->accept_baton, in, p); 79 80 if (rv) { 81 apr_pool_destroy(p); 82 return rv; 83 } 84 85 return rv; 86} 87 88 89apr_status_t serf_incoming_create( 90 serf_incoming_t **client, 91 serf_context_t *ctx, 92 apr_socket_t *insock, 93 void *request_baton, 94 serf_incoming_request_cb_t request, 95 apr_pool_t *pool) 96{ 97 apr_status_t rv; 98 serf_incoming_t *ic = apr_palloc(pool, sizeof(*ic)); 99 100 ic->ctx = ctx; 101 ic->baton.type = SERF_IO_CLIENT; 102 ic->baton.u.client = ic; 103 ic->request_baton = request_baton; 104 ic->request = request; 105 ic->skt = insock; 106 ic->desc.desc_type = APR_POLL_SOCKET; 107 ic->desc.desc.s = ic->skt; 108 ic->desc.reqevents = APR_POLLIN; 109 110 rv = ctx->pollset_add(ctx->pollset_baton, 111 &ic->desc, &ic->baton); 112 *client = ic; 113 114 return rv; 115} 116 117 118apr_status_t serf_listener_create( 119 serf_listener_t **listener, 120 serf_context_t *ctx, 121 const char *host, 122 apr_uint16_t port, 123 void *accept_baton, 124 serf_accept_client_t accept, 125 apr_pool_t *pool) 126{ 127 apr_sockaddr_t *sa; 128 apr_status_t rv; 129 serf_listener_t *l = apr_palloc(pool, sizeof(*l)); 130 131 l->ctx = ctx; 132 l->baton.type = SERF_IO_LISTENER; 133 l->baton.u.listener = l; 134 l->accept_func = accept; 135 l->accept_baton = accept_baton; 136 137 apr_pool_create(&l->pool, pool); 138 139 rv = apr_sockaddr_info_get(&sa, host, APR_UNSPEC, port, 0, l->pool); 140 if (rv) 141 return rv; 142 143 rv = apr_socket_create(&l->skt, sa->family, 144 SOCK_STREAM, 145#if APR_MAJOR_VERSION > 0 146 APR_PROTO_TCP, 147#endif 148 l->pool); 149 if (rv) 150 return rv; 151 152 rv = apr_socket_opt_set(l->skt, APR_SO_REUSEADDR, 1); 153 if (rv) 154 return rv; 155 156 rv = apr_socket_bind(l->skt, sa); 157 if (rv) 158 return rv; 159 160 rv = apr_socket_listen(l->skt, 5); 161 if (rv) 162 return rv; 163 164 l->desc.desc_type = APR_POLL_SOCKET; 165 l->desc.desc.s = l->skt; 166 l->desc.reqevents = APR_POLLIN; 167 168 rv = ctx->pollset_add(ctx->pollset_baton, 169 &l->desc, &l->baton); 170 if (rv) 171 return rv; 172 173 *listener = l; 174 175 return APR_SUCCESS; 176} 177