|
Server 0.0.1
HTTP/REST server implementation
|
#include "server.h"#include "logger.h"#include "utils/signalHandling.h"
Go to the source code of this file.
Functions | |
| int | serverPoll (Server) |
| int | serverHandleAccept (Server, unsigned int) |
| void | serverCloseConn (Server, unsigned int) |
| ssize_t | serverRead (Server, unsigned int) |
| ssize_t | serverWrite (Server, unsigned int) |
| void | serverRun (Server this) |
Copyright © 2012 Georg Hopp
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>.
Definition in file run.c.
| void serverCloseConn | ( | Server | , |
| unsigned | int | ||
| ) |
Definition at line 31 of file close_conn.c.
{
int fd = (this->fds)[i].fd;
Stream st = (this->conns[fd]).stream;
delete((this->conns)[fd].sock);
delete((this->conns)[fd].worker);
if (NULL != st && STREAM_SSL == st->type) {
SSL_shutdown((st->handle).ssl);
SSL_free((st->handle).ssl);
}
delete(st);
memset(&(this->fds[i]), 0, sizeof(struct pollfd));
}
| int serverHandleAccept | ( | Server | , |
| unsigned | int | ||
| ) |
Definition at line 36 of file handle_accept.c.
{
char remoteAddr[16] = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0";
Sock acc = NULL;
Stream st;
if (this->nfds >= this->max_fds) {
return -1;
}
acc = socketAccept((0 == i)? this->sock : this->sockSSL, &remoteAddr);
if (-1 != acc->handle) {
switch(i) {
case 0:
// no SSL
st = new(Stream, STREAM_FD, acc->handle);
break;
case 1:
// SSL
{
SSL * ssl = SSL_new(this->ctx);
SSL_set_fd(ssl, acc->handle);
SSL_accept(ssl);
st = new(Stream, STREAM_SSL, ssl);
}
break;
default:
break;
}
// save the socket handle
(this->conns)[acc->handle].sock = acc;
// clone worker
(this->conns)[acc->handle].worker = clone(this->worker);
(this->conns)[acc->handle].stream = st;
(this->fds)[this->nfds].fd = acc->handle;
(this->fds)[this->nfds].events = POLLIN;
this->nfds++;
} else {
delete(acc);
switch(errno) {
case EAGAIN:
loggerLog(this->logger,
LOGGER_DEBUG,
"server accept blocks");
break;
default:
loggerLog(this->logger,
LOGGER_DEBUG,
"server accept error");
break;
}
}
return (acc)? acc->handle : -1;
}


| int serverPoll | ( | Server | ) |
put all closed fds to end of array in O(this->nfds)
Definition at line 34 of file poll.c.
{
int events;
struct pollfd * fda = &(this->fds[2]);
struct pollfd * fdb = &(this->fds[this->nfds-1]);
while (fda <= fdb) {
while (0 == fdb->fd && fda <= fdb) {
fdb--;
this->nfds--;
}
while (0 != fda->fd && fda <= fdb) fda++;
if (fda < fdb) {
memcpy(fda, fdb, sizeof(struct pollfd));
fdb--;
this->nfds--;
}
}
/*
* wait for handles to become ready
*/
if (-1 == (events = poll(this->fds, this->nfds, -1))) {
switch (errno) {
default:
case EBADF:
case EINVAL:
case ENOMEM:
doShutdown = 1;
// DROP THROUGH
case EINTR:
loggerLog(this->logger, LOGGER_CRIT,
"poll systemcall failed: [%s] - service terminated",
strerror(errno));
}
}
return events;
}


| ssize_t serverRead | ( | Server | , |
| unsigned | int | ||
| ) |
normal close: this must be mapped to -2 within the underlying read call.
Definition at line 30 of file read.c.
{
int fd = (this->fds)[i].fd;
ssize_t size;
if (NULL == (this->conns)[fd].worker) {
loggerLog(
this->logger,
LOGGER_INFO,
"initialization error: NULL reader");
return -1;
}
switch ((size = streamReaderRead(
(this->conns)[fd].worker,
(this->conns)[fd].stream)))
{
case -2:
// DROP-THROUGH
case -1:
/*
* read failure / close connection
*/
loggerLog(this->logger, LOGGER_INFO,
"connection[%d] closed...%s",
fd,
inet_ntoa((((this->conns)[fd].sock)->addr).sin_addr));
serverCloseConn(this, i);
break;
case 0:
break;
default:
(this->fds)[i].events |= POLLOUT;
break;
}
return size;
}


| void serverRun | ( | Server | this | ) |
until error or signal
handle accept
handle accept SSL
handle reads
handle writes
Definition at line 35 of file run.c.
{
loggerLog(this->logger, LOGGER_INFO, "service started");
while (!doShutdown)
{
int events;
unsigned int i;
int naccs = 10;
events = serverPoll(this);
if (doShutdown || 0 >= events) break;
if (0 != ((this->fds)[0].revents & POLLIN)) {
events--;
while(-1 != serverHandleAccept(this, 0) && 0 < naccs) {
naccs--;
}
}
if (0 != ((this->fds)[1].revents & POLLIN)) {
events--;
while(-1 != serverHandleAccept(this, 1) && 0 < naccs) {
naccs--;
}
}
for (i=2; i < this->nfds; i++) {
int nreads = 10, nwrites = 10;
if (0 != ((this->fds)[i].revents & POLLIN) && 0 < nreads) {
events--;
nreads--;
serverRead(this, i);
}
if (0 != ((this->fds)[i].revents & POLLOUT) && 0 < nwrites) {
events--;
nwrites--;
serverWrite(this, i);
}
if (0 > events)
break; // no more events to handle
}
}
}


| ssize_t serverWrite | ( | Server | , |
| unsigned | int | ||
| ) |
Definition at line 30 of file write.c.
{
int fd = (this->fds)[i].fd;
ssize_t remaining;
if (NULL == (this->conns)[fd].worker) {
loggerLog(
this->logger,
LOGGER_INFO,
"initialization error: NULL worker");
return -1;
}
remaining = streamWriterWrite(
(this->conns)[fd].worker,
(this->conns)[fd].stream);
switch(remaining) {
case -1:
serverCloseConn(this, i);
break;
case 0:
(this->fds)[i].events &= ~POLLOUT;
break;
default:
break;
}
return remaining;
}

