00001 #include <sys/select.h>
00002 #include <string.h>
00003 #include <stdlib.h>
00004 #include <errno.h>
00005 #include <unistd.h>
00006
00007 #include <expat.h>
00008
00009 #include "../include/appConfig.h"
00010 #include "../include/server.h"
00011 #include "../include/client.h"
00012 #include "../include/socket.h"
00013 #include "../include/monitor.h"
00014 #include "../include/logRotate.h"
00015 #include "../include/signalHandling.h"
00016 #include "../include/httpRequest.h"
00017
00018 #define RESPONSE " 200 OK\r\nServer: xmlrpc\r\nStatus: 200\r\nContent-Length: 10\r\nContent-Type: text/plain\r\n\r\n0123456789"
00019
00020 int Depth;
00021
00022 void XMLCALL
00023 start(void *data, const char *el, const char **attr) {
00024 int i;
00025
00026 for (i = 0; i < Depth; i++)
00027 printf(" ");
00028
00029 printf("%s", el);
00030
00031 for (i = 0; attr[i]; i += 2) {
00032 printf(" %s='%s'", attr[i], attr[i + 1]);
00033 }
00034
00035 printf("\n");
00036 Depth++;
00037 }
00038
00039 void XMLCALL
00040 end(void *data, const char *el) {
00041 int i;
00042
00043 Depth--;
00044 for (i = 0; i < Depth; i++)
00045 printf(" ");
00046 printf("--\n");
00047 }
00048
00049 void
00050 serverRun(tServer * server)
00051 {
00052 syslogMonitor(LOG_INFO, MON_INFO, "startup", "service started");
00053
00054 while (!doShutdown)
00055 {
00056 fd_set rfds;
00057 fd_set wfds;
00058 int i;
00059
00060 memcpy(&rfds, &(server->socks), sizeof(fd_set));
00061
00062 FD_ZERO(&wfds);
00063 for (i=3; i<=server->maxFd; i++) {
00064 tClient * actClient = &(server->clients)[i];
00065
00066 if (FD_ISSET(i, &(server->socks))
00067 && NULL != actClient->writeBuffer
00068 && 0 != strlen(actClient->writeBuffer)) {
00069 FD_SET(i, &wfds);
00070 }
00071 }
00072
00073
00074
00075
00076 if (-1 == select((server->maxFd)+1, &rfds, &wfds, NULL, NULL))
00077 {
00078 switch (errno) {
00079 default:
00080 case EBADF:
00081 case EINVAL:
00082 case ENOMEM:
00083 doShutdown = 1;
00084
00085
00086 case EINTR:
00087 syslogMonitor(LOG_ERR, MON_INFO, "select",
00088 "select systemcall failed: [%s] - service terminated",
00089 strerror(errno));
00090 continue;
00091 }
00092 }
00093
00094
00095
00096
00097 if (FD_ISSET(server->servSock, &rfds)) {
00098 int fd;
00099 char remoteAddr[16] = "";
00100
00101 if (-1 != (fd = acceptConnection(server->servSock, remoteAddr))) {
00102 (server->clients)[fd].socket = fd;
00103 strncpy(
00104 (server->clients)[fd].remoteAddr,
00105 remoteAddr,
00106 sizeof((server->clients)[fd].remoteAddr)-1);
00107 FD_SET(fd, &(server->socks));
00108 server->maxFd = MAX(fd, server->maxFd);
00109
00110 (server->clients)[fd].parser = XML_ParserCreate("UTF-8");
00111 XML_SetElementHandler((server->clients)[fd].parser, &start, &end);
00112
00113 }
00114
00115 FD_CLR(server->servSock, &rfds);
00116 }
00117
00118
00119 for (i=3; i<=server->maxFd; i++) {
00120
00121 tClient * actClient = &(server->clients)[i];
00122
00123 if (FD_ISSET(i, &rfds)) {
00124 switch (clientRead(actClient)) {
00125 case -1:
00126 syslogMonitor(LOG_WARNING, MON_INFO, "socket.read",
00127 "read on socket for %s returns -1: %s",
00128 actClient->remoteAddr, strerror(errno));
00129
00130
00131 case 0:
00132 clientClose(actClient);
00133 FD_CLR(i, &(server->socks));
00134 break;
00135
00136 default:
00137 if (! httpHeaderIsComplete(&(actClient->httpHeader))) {
00138 char delim[] = "\r\n";
00139 unsigned int len = strlen(delim);
00140 char * line = clientGetLine(actClient, delim, &len);
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 while (! httpHeaderIsStarted(&(actClient->httpHeader))) {
00152
00153 if (0 != len) {
00154 httpHeaderParseRequestLine(&(actClient->httpHeader), line, len);
00155
00156 }
00157
00158 len = strlen(delim);
00159 clientRemoveLine(actClient, delim, &len);
00160 len = strlen(delim);
00161 line = clientGetLine(actClient, delim, &len);
00162
00163 }
00164
00165 while (NULL != line) {
00166 if (NULL == actClient->httpHeader.req.method) {
00167 }
00168 }
00169 }
00170
00171 if (!httpHeaderIsComplete(&(actClient->httpHeader))) {
00172 actClient->bodyLenRemaining = httpHeaderGet(
00173 &(actClient->readBuffer),
00174 &(actClient->readPos),
00175 &(actClient->httpHeader));
00176 }
00177
00178 if (httpHeaderIsComplete(&(actClient->httpHeader))) {
00179 size_t size = MIN(actClient->bodyLenRemaining, actClient->readPos);
00180 unsigned int isLast = !(size - actClient->bodyLenRemaining);
00181
00182 enum XML_Status expatStat;
00183
00184 expatStat = XML_Parse(actClient->parser, actClient->readBuffer, size, isLast);
00185
00186 actClient->readPos -= size;
00187 actClient->bodyLenRemaining -= size;
00188 memmove(actClient->readBuffer, actClient->readBuffer + size, actClient->readPos);
00189 memset(actClient->readBuffer + actClient->readPos, 0, size);
00190
00191 if (isLast && NULL == actClient->writeBuffer) {
00192
00193 actClient->writeBuffer = calloc(
00194 strlen(actClient->httpHeader.req.httpVersion) +
00195 strlen(RESPONSE) + 3,
00196 sizeof(char));
00197 sprintf(actClient->writeBuffer, "%s%s",
00198 actClient->httpHeader.req.httpVersion,
00199 RESPONSE);
00200
00201 freeHttpHeader(&(actClient->httpHeader));
00202 XML_ParserFree(actClient->parser);
00203 actClient->parser = NULL;
00204 }
00205 }
00206 break;
00207 }
00208 }
00209 }
00210
00211
00212 for (i=3; i<=server->maxFd; i++) {
00213
00214 tClient * actClient = &(server->clients)[i];
00215
00216
00217 if (FD_ISSET(i, &wfds) && NULL != actClient->writeBuffer) {
00218 int writeSize = 0;
00219 int toWrite = strlen(actClient->writeBuffer);
00220
00221 writeSize = write(actClient->socket, actClient->writeBuffer, toWrite);
00222
00223 if (0 < writeSize) {
00224 if (writeSize == toWrite) {
00225 free(actClient->writeBuffer);
00226 actClient->writeBuffer = NULL;
00227
00228 clientClose(actClient);
00229 FD_CLR(i, &(server->socks));
00230 } else {
00231 memmove(actClient->writeBuffer, actClient->writeBuffer + writeSize, toWrite - writeSize);
00232 memset(actClient->writeBuffer + (toWrite - writeSize), 0, writeSize);
00233 }
00234 }
00235 }
00236 }
00237 }
00238 }