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