177 lines
3.9 KiB
C
177 lines
3.9 KiB
C
/* 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;
|
|
}
|