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 |
|
30 |
static apr_status_t read_from_client(serf_incoming_t *client) |
31 |
{ |
32 |
return APR_ENOTIMPL; |
33 |
} |
34 |
|
35 |
static apr_status_t write_to_client(serf_incoming_t *client) |
36 |
{ |
37 |
return APR_ENOTIMPL; |
38 |
} |
39 |
|
40 |
apr_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 |
|
68 |
apr_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 |
|
94 |
apr_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 |
|
123 |
apr_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 |
} |