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