root/trunk/wifidog/libhttpd/api.c @ 290

Revision 290, 19.4 KB (checked in by alexcv, 8 years ago)

Massive update

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1/*
2** Copyright (c) 2002  Hughes Technologies Pty Ltd.  All rights
3** reserved.
4**
5** Terms under which this software may be used or copied are
6** provided in the  specific license associated with this product.
7**
8** Hughes Technologies disclaims all warranties with regard to this
9** software, including all implied warranties of merchantability and
10** fitness, in no event shall Hughes Technologies be liable for any
11** special, indirect or consequential damages or any damages whatsoever
12** resulting from loss of use, data or profits, whether in an action of
13** contract, negligence or other tortious action, arising out of or in
14** connection with the use or performance of this software.
15**
16**
17** $Id$
18**
19*/
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <ctype.h>
25#include <sys/types.h>
26#include <sys/stat.h>
27#include <time.h>
28
29#if defined(_WIN32)
30#include <winsock2.h>
31#else
32#include <unistd.h>
33#include <sys/file.h>
34#include <netinet/in.h>
35#include <arpa/inet.h>
36#include <netdb.h>
37#include <sys/socket.h>
38#include <netdb.h>
39#endif
40
41#include "config.h"
42#include "httpd.h"
43#include "httpd_priv.h"
44
45#ifdef HAVE_STDARG_H
46#  include <stdarg.h>
47#else
48#  include <varargs.h>
49#endif
50
51
52char *httpdUrlEncode(str)
53        char    *str;
54{
55        char    *new,
56                *cp;
57
58        new = (char *)_httpd_escape(str);
59        if (new == NULL)
60        {
61                return(NULL);
62        }
63        cp = new;
64        while(*cp)
65        {
66                if (*cp == ' ')
67                        *cp = '+';
68                cp++;
69        }
70        return(new);
71}
72
73
74
75char *httpdRequestMethodName(request *r)
76{
77        static  char    tmpBuf[255];
78
79        switch(r->request.method)
80        {
81                case HTTP_GET: return("GET");
82                case HTTP_POST: return("POST");
83                default: 
84                        snprintf(tmpBuf,255,"Invalid method '%d'", 
85                                r->request.method);
86                        return(tmpBuf);
87        }
88}
89
90
91httpVar *httpdGetVariableByName(request *r, char *name)
92{
93        httpVar *curVar;
94
95        curVar = r->variables;
96        while(curVar)
97        {
98                if (strcmp(curVar->name, name) == 0)
99                        return(curVar);
100                curVar = curVar->nextVariable;
101        }
102        return(NULL);
103}
104
105
106
107httpVar *httpdGetVariableByPrefix(request *r, char *prefix)
108{
109        httpVar *curVar;
110
111        if (prefix == NULL)
112                return(r->variables);
113        curVar = r->variables;
114        while(curVar)
115        {
116                if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
117                        return(curVar);
118                curVar = curVar->nextVariable;
119        }
120        return(NULL);
121}
122
123
124httpVar *httpdGetVariableByPrefixedName(request *r, char *prefix, char *name)
125{
126        httpVar *curVar;
127        int     prefixLen;
128
129        if (prefix == NULL)
130                return(r->variables);
131        curVar = r->variables;
132        prefixLen = strlen(prefix);
133        while(curVar)
134        {
135                if (strncmp(curVar->name, prefix, prefixLen) == 0 &&
136                        strcmp(curVar->name + prefixLen, name) == 0)
137                {
138                        return(curVar);
139                }
140                curVar = curVar->nextVariable;
141        }
142        return(NULL);
143}
144
145
146httpVar *httpdGetNextVariableByPrefix(curVar, prefix)
147        httpVar *curVar;
148        char    *prefix;
149{
150        if(curVar)
151                curVar = curVar->nextVariable;
152        while(curVar)
153        {
154                if (strncmp(curVar->name, prefix, strlen(prefix)) == 0)
155                        return(curVar);
156                curVar = curVar->nextVariable;
157        }
158        return(NULL);
159}
160
161
162int httpdAddVariable(request *r, char *name, char *value)
163{
164        httpVar *curVar, *lastVar, *newVar;
165
166        while(*name == ' ' || *name == '\t')
167                name++;
168        newVar = malloc(sizeof(httpVar));
169        bzero(newVar, sizeof(httpVar));
170        newVar->name = strdup(name);
171        newVar->value = strdup(value);
172        lastVar = NULL;
173        curVar = r->variables;
174        while(curVar)
175        {
176                if (strcmp(curVar->name, name) != 0)
177                {
178                        lastVar = curVar;
179                        curVar = curVar->nextVariable;
180                        continue;
181                }
182                while(curVar)
183                {
184                        lastVar = curVar;
185                        curVar = curVar->nextValue;
186                }
187                lastVar->nextValue = newVar;
188                return(0);
189        }
190        if (lastVar)
191                lastVar->nextVariable = newVar;
192        else
193                r->variables = newVar;
194        return(0);
195}
196
197httpd *httpdCreate(host, port)
198        char    *host;
199        int     port;
200{
201        httpd   *new;
202        int     sock,
203                opt;
204        struct  sockaddr_in     addr;
205
206        /*
207        ** Create the handle and setup it's basic config
208        */
209        new = malloc(sizeof(httpd));
210        if (new == NULL)
211                return(NULL);
212        bzero(new, sizeof(httpd));
213        new->port = port;
214        if (host == HTTP_ANY_ADDR)
215                new->host = HTTP_ANY_ADDR;
216        else
217                new->host = strdup(host);
218        new->content = (httpDir*)malloc(sizeof(httpDir));
219        bzero(new->content,sizeof(httpDir));
220        new->content->name = strdup("");
221
222        /*
223        ** Setup the socket
224        */
225#ifdef _WIN32
226        { 
227        WORD    wVersionRequested;
228        WSADATA wsaData;
229        int     err;
230
231        wVersionRequested = MAKEWORD( 2, 2 );
232
233        err = WSAStartup( wVersionRequested, &wsaData );
234       
235        /* Found a usable winsock dll? */
236        if( err != 0 ) 
237           return NULL;
238
239        /*
240        ** Confirm that the WinSock DLL supports 2.2.
241        ** Note that if the DLL supports versions greater
242        ** than 2.2 in addition to 2.2, it will still return
243        ** 2.2 in wVersion since that is the version we
244        ** requested.
245        */
246
247        if( LOBYTE( wsaData.wVersion ) != 2 || 
248            HIBYTE( wsaData.wVersion ) != 2 ) {
249
250                /*
251                ** Tell the user that we could not find a usable
252                ** WinSock DLL.
253                */
254                WSACleanup( );
255                return NULL;
256        }
257
258        /* The WinSock DLL is acceptable. Proceed. */
259        }
260#endif
261
262        sock = socket(AF_INET, SOCK_STREAM, 0);
263        if (sock  < 0)
264        {
265                free(new);
266                return(NULL);
267        }
268#       ifdef SO_REUSEADDR
269        opt = 1;
270        setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt,sizeof(int));
271#       endif
272        new->serverSock = sock;
273        bzero(&addr, sizeof(addr));
274        addr.sin_family = AF_INET;
275        if (new->host == HTTP_ANY_ADDR)
276        {
277                addr.sin_addr.s_addr = htonl(INADDR_ANY);
278        }
279        else
280        {
281                addr.sin_addr.s_addr = inet_addr(new->host);
282        }
283        addr.sin_port = htons((u_short)new->port);
284        if (bind(sock,(struct sockaddr *)&addr,sizeof(addr)) <0)
285        {
286                close(sock);
287                free(new);
288                return(NULL);
289        }
290        listen(sock, 128);
291        new->startTime = time(NULL);
292        return(new);
293}
294
295void httpdDestroy(server)
296        httpd   *server;
297{
298        if (server == NULL)
299                return;
300        if (server->host)
301                free(server->host);
302        free(server);
303}
304
305
306
307request *httpdGetConnection(server, timeout)
308        httpd   *server;
309        struct  timeval *timeout;
310{
311        int     result;
312        fd_set  fds;
313        struct  sockaddr_in     addr;
314        size_t  addrLen;
315        char    *ipaddr;
316        request *r;
317
318        FD_ZERO(&fds);
319        FD_SET(server->serverSock, &fds);
320        result = 0;
321        while(result == 0)
322        {
323                result = select(server->serverSock + 1, &fds, 0, 0, timeout);
324                if (result < 0)
325                {
326                        server->lastError = -1;
327                        return(NULL);
328                }
329                if (timeout != 0 && result == 0)
330                {
331                        return(NULL);
332                        server->lastError = 0;
333                }
334                if (result > 0)
335                {
336                        break;
337                }
338        }
339        /* Allocate request struct */
340        r = (request *)malloc(sizeof(request));
341        if (r == NULL) {
342                server->lastError = -3;
343                return(NULL);
344        }
345        memset((void *)r, 0, sizeof(request));
346        /* Get on with it */
347        bzero(&addr, sizeof(addr));
348        addrLen = sizeof(addr);
349        r->clientSock = accept(server->serverSock,(struct sockaddr *)&addr,
350                &addrLen);
351        ipaddr = inet_ntoa(addr.sin_addr);
352        if (ipaddr)
353                strncpy(r->clientAddr, ipaddr, HTTP_IP_ADDR_LEN);
354        else
355                *r->clientAddr = 0;
356        r->readBufRemain = 0;
357        r->readBufPtr = NULL;
358
359        /*
360        ** Check the default ACL
361        */
362        if (server->defaultAcl)
363        {
364                if (httpdCheckAcl(server, r, server->defaultAcl)
365                                == HTTP_ACL_DENY)
366                {
367                        httpdEndRequest(r);
368                        server->lastError = 2;
369                        return(NULL);
370                }
371        }
372        return(r);
373}
374
375
376
377int httpdReadRequest(httpd *server, request *r)
378{
379        static  char    buf[HTTP_MAX_LEN];
380        int     count,
381                inHeaders;
382        char    *cp, *cp2;
383        int     _httpd_decode();
384
385
386        /*
387        ** Setup for a standard response
388        */
389        strcpy(r->response.headers,
390                "Server: Hughes Technologies Embedded Server\n"); 
391        strcpy(r->response.contentType, "text/html");
392        strcpy(r->response.response,"200 Output Follows\n");
393        r->response.headersSent = 0;
394
395
396        /*
397        ** Read the request
398        */
399        count = 0;
400        inHeaders = 1;
401        while(_httpd_readLine(r, buf, HTTP_MAX_LEN) > 0)
402        {
403                count++;
404
405                /*
406                ** Special case for the first line.  Scan the request
407                ** method and path etc
408                */
409                if (count == 1)
410                {
411                        /*
412                        ** First line.  Scan the request info
413                        */
414                        cp = cp2 = buf;
415                        while(isalpha(*cp2))
416                                cp2++;
417                        *cp2 = 0;
418                        if (strcasecmp(cp,"GET") == 0)
419                                r->request.method = HTTP_GET;
420                        if (strcasecmp(cp,"POST") == 0)
421                                r->request.method = HTTP_POST;
422                        if (r->request.method == 0)
423                        {
424                                _httpd_net_write( r->clientSock,
425                                      HTTP_METHOD_ERROR,
426                                      strlen(HTTP_METHOD_ERROR));
427                                _httpd_net_write( r->clientSock, cp, 
428                                      strlen(cp));
429                                _httpd_writeErrorLog(server, r, LEVEL_ERROR, 
430                                        "Invalid method received");
431                                return(-1);
432                        }
433                        cp = cp2+1;
434                        while(*cp == ' ')
435                                cp++;
436                        cp2 = cp;
437                        while(*cp2 != ' ' && *cp2 != 0)
438                                cp2++;
439                        *cp2 = 0;
440                        strncpy(r->request.path,cp,HTTP_MAX_URL);
441                        _httpd_sanitiseUrl(r->request.path);
442                        continue;
443                }
444
445                /*
446                ** Process the headers
447                */
448                if (inHeaders)
449                {
450                        if (*buf == 0)
451                        {
452                                /*
453                                ** End of headers.  Continue if there's
454                                ** data to read
455                                */
456                                if (r->request.contentLength == 0)
457                                        break;
458                                inHeaders = 0;
459                                break;
460                        }
461#if 0
462            /**
463             * Philippe commenting this out, it crashed with a
464             * particular pattern sent from the browser
465             * and we don't need it
466                        if (strncasecmp(buf,"Cookie: ",7) == 0)
467                        {
468                                char    *var,
469                                        *val,
470                                        *end;
471
472                                var = index(buf,':');
473                                while(var)
474                                {
475                                        var++;
476                                        val = index(var, '=');
477                                        *val = 0;
478                                        val++;
479                                        end = index(val,';');
480                                        if(end)
481                                                *end = 0;
482                                        httpdAddVariable(r, var, val);
483                                        var = end;
484                                }
485                        }
486                        */
487#endif
488#if 0
489                        if (strncasecmp(buf,"Authorization: ",15) == 0)
490                        {
491                                cp = index(buf,':') + 2;
492                                if (strncmp(cp,"Basic ", 6) != 0)
493                                {
494                                        /* Unknown auth method */
495                                }
496                                else
497                                {
498                                        char    authBuf[100];
499
500                                        cp = index(cp,' ') + 1;
501                                        _httpd_decode(cp, authBuf, 100);
502                                        r->request.authLength =
503                                                strlen(authBuf);
504                                        cp = index(authBuf,':');
505                                        if (cp)
506                                        {
507                                                *cp = 0;
508                                                strncpy(
509                                                   r->request.authPassword,
510                                                   cp+1, HTTP_MAX_AUTH);
511                                        }
512                                        strncpy(r->request.authUser,
513                                                authBuf, HTTP_MAX_AUTH);
514                                }
515                        }
516#endif
517#if 0
518                        if (strncasecmp(buf,"Referer: ",9) == 0)
519                        {
520                                cp = index(buf,':') + 2;
521                                if(cp)
522                                {
523                                        strncpy(r->request.referer,cp,
524                                                HTTP_MAX_URL);
525                                }
526                        }
527#endif
528                        /* acv@acv.ca/wifidog: Added decoding of host: if
529                         * present. */
530                        if (strncasecmp(buf,"Host: ",6) == 0)
531                        {
532                                cp = index(buf,':') + 2;
533                                if(cp)
534                                {
535                                        strncpy(r->request.host,cp,
536                                                HTTP_MAX_URL);
537                                }
538                        }
539                        /* End modification */
540#if 0
541                        if (strncasecmp(buf,"If-Modified-Since: ",19) == 0)
542                        {
543                                cp = index(buf,':') + 2;
544                                if(cp)
545                                {
546                                        strncpy(r->request.ifModified,cp,
547                                                HTTP_MAX_URL);
548                                        cp = index(r->request.ifModified,
549                                                ';');
550                                        if (cp)
551                                                *cp = 0;
552                                }
553                        }
554                        if (strncasecmp(buf,"Content-Type: ",14) == 0)
555                        {
556                                cp = index(buf,':') + 2;
557                                if(cp)
558                                {
559                                        strncpy(r->request.contentType,cp,
560                                                HTTP_MAX_URL);
561                                }
562                        }
563                        if (strncasecmp(buf,"Content-Length: ",16) == 0)
564                        {
565                                cp = index(buf,':') + 2;
566                                if(cp)
567                                        r->request.contentLength=atoi(cp);
568                        }
569#endif
570                        continue;
571                }
572        }
573
574        /*
575        ** Process and POST data
576        */
577#if 0
578        if (r->request.contentLength > 0)
579        {
580                bzero(buf, HTTP_MAX_LEN);
581                _httpd_readBuf(r, buf, r->request.contentLength);
582                _httpd_storeData(r, buf);
583               
584        }
585#endif
586       
587        /*
588        ** Process any URL data
589        */
590        cp = index(r->request.path,'?');
591        if (cp != NULL)
592        {
593                *cp = 0;
594                cp++;
595                _httpd_storeData(r, cp);
596        }
597        return(0);
598}
599
600
601void httpdEndRequest(request *r)
602{
603        _httpd_freeVariables(r->variables);
604        shutdown(r->clientSock,2);
605        close(r->clientSock);
606        free(r);
607}
608
609
610void httpdFreeVariables(request *r)
611{
612        _httpd_freeVariables(r->variables);
613}
614
615
616
617void httpdDumpVariables(request *r)
618{
619        httpVar *curVar,
620                *curVal;
621
622        curVar = r->variables;
623        while(curVar)
624        {
625                printf("Variable '%s'\n", curVar->name);
626                curVal = curVar;
627                while(curVal)
628                {
629                        printf("\t= '%s'\n",curVal->value);
630                        curVal = curVal->nextValue;
631                }
632                curVar = curVar->nextVariable;
633        }
634}
635
636void httpdSetFileBase(server, path)
637        httpd   *server;
638        char    *path;
639{
640        strncpy(server->fileBasePath, path, HTTP_MAX_URL);
641}
642
643
644int httpdAddFileContent(server, dir, name, indexFlag, preload, path)
645        httpd   *server;
646        char    *dir,
647                *name;
648        int     (*preload)();
649        int     indexFlag;
650        char    *path;
651{
652        httpDir *dirPtr;
653        httpContent *newEntry;
654
655        dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
656        newEntry =  malloc(sizeof(httpContent));
657        if (newEntry == NULL)
658                return(-1);
659        bzero(newEntry,sizeof(httpContent));
660        newEntry->name = strdup(name);
661        newEntry->type = HTTP_FILE;
662        newEntry->indexFlag = indexFlag;
663        newEntry->preload = preload;
664        newEntry->next = dirPtr->entries;
665        dirPtr->entries = newEntry;
666        if (*path == '/')
667        {
668                /* Absolute path */
669                newEntry->path = strdup(path);
670        }
671        else
672        {
673                /* Path relative to base path */
674                newEntry->path = malloc(strlen(server->fileBasePath) +
675                        strlen(path) + 2);
676                snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
677                        server->fileBasePath, path);
678        }
679        return(0);
680}
681
682
683
684int httpdAddWildcardContent(server, dir, preload, path)
685        httpd   *server;
686        char    *dir;
687        int     (*preload)();
688        char    *path;
689{
690        httpDir *dirPtr;
691        httpContent *newEntry;
692
693        dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
694        newEntry =  malloc(sizeof(httpContent));
695        if (newEntry == NULL)
696                return(-1);
697        bzero(newEntry,sizeof(httpContent));
698        newEntry->name = NULL;
699        newEntry->type = HTTP_WILDCARD;
700        newEntry->indexFlag = HTTP_FALSE;
701        newEntry->preload = preload;
702        newEntry->next = dirPtr->entries;
703        dirPtr->entries = newEntry;
704        if (*path == '/')
705        {
706                /* Absolute path */
707                newEntry->path = strdup(path);
708        }
709        else
710        {
711                /* Path relative to base path */
712                newEntry->path = malloc(strlen(server->fileBasePath) +
713                        strlen(path) + 2);
714                snprintf(newEntry->path, HTTP_MAX_URL, "%s/%s",
715                        server->fileBasePath, path);
716        }
717        return(0);
718}
719
720
721
722
723int httpdAddC404Content(server, function)
724        httpd   *server;
725        void    (*function)();
726{
727        if (!server->handle404) {
728                server->handle404 = (http404*)malloc(sizeof(http404));
729        }
730
731        if (!server->handle404) {
732                return(-1);
733        }
734
735        server->handle404->function = function;
736        return(0);
737}
738
739int httpdAddCContent(server, dir, name, indexFlag, preload, function)
740        httpd   *server;
741        char    *dir;
742        char    *name;
743        int     (*preload)();
744        void    (*function)();
745{
746        httpDir *dirPtr;
747        httpContent *newEntry;
748
749                dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
750        newEntry =  malloc(sizeof(httpContent));
751        if (newEntry == NULL)
752                return(-1);
753        bzero(newEntry,sizeof(httpContent));
754        newEntry->name = strdup(name);
755        newEntry->type = HTTP_C_FUNCT;
756        newEntry->indexFlag = indexFlag;
757        newEntry->function = function;
758        newEntry->preload = preload;
759        newEntry->next = dirPtr->entries;
760        dirPtr->entries = newEntry;
761        return(0);
762}
763
764
765int httpdAddCWildcardContent(server, dir, preload, function)
766        httpd   *server;
767        char    *dir;
768        int     (*preload)();
769        void    (*function)();
770{
771        httpDir *dirPtr;
772        httpContent *newEntry;
773
774        dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
775        newEntry =  malloc(sizeof(httpContent));
776        if (newEntry == NULL)
777                return(-1);
778        bzero(newEntry,sizeof(httpContent));
779        newEntry->name = NULL;
780        newEntry->type = HTTP_C_WILDCARD;
781        newEntry->indexFlag = HTTP_FALSE;
782        newEntry->function = function;
783        newEntry->preload = preload;
784        newEntry->next = dirPtr->entries;
785        dirPtr->entries = newEntry;
786        return(0);
787}
788
789int httpdAddStaticContent(server, dir, name, indexFlag, preload, data)
790        httpd   *server;
791        char    *dir;
792        char    *name;
793        int     (*preload)();
794        char    *data;
795{
796        httpDir *dirPtr;
797        httpContent *newEntry;
798
799        dirPtr = _httpd_findContentDir(server, dir, HTTP_TRUE);
800        newEntry =  malloc(sizeof(httpContent));
801        if (newEntry == NULL)
802                return(-1);
803        bzero(newEntry,sizeof(httpContent));
804        newEntry->name = strdup(name);
805        newEntry->type = HTTP_STATIC;
806        newEntry->indexFlag = indexFlag;
807        newEntry->data = data;
808        newEntry->preload = preload;
809        newEntry->next = dirPtr->entries;
810        dirPtr->entries = newEntry;
811        return(0);
812}
813
814void httpdSendHeaders(request *r)
815{
816        _httpd_sendHeaders(r, 0, 0);
817}
818
819void httpdSetResponse(request *r, char *msg)
820{
821        strncpy(r->response.response, msg, HTTP_MAX_URL);
822}
823
824void httpdSetContentType(request *r, char *type)
825{
826        strcpy(r->response.contentType, type);
827}
828
829
830void httpdAddHeader(request *r, char *msg)
831{
832        strcat(r->response.headers,msg);
833        if (msg[strlen(msg) - 1] != '\n')
834                strcat(r->response.headers,"\n");
835}
836
837void httpdSetCookie(request *r, char *name, char *value)
838{
839        char    buf[HTTP_MAX_URL];
840
841        snprintf(buf,HTTP_MAX_URL, "Set-Cookie: %s=%s; path=/;", name, value);
842        httpdAddHeader(r, buf);
843}
844
845void httpdOutput(request *r, char *msg)
846{
847        char    buf[HTTP_MAX_LEN],
848                varName[80],
849                *src,
850                *dest;
851        int     count;
852
853        src = msg;
854        dest = buf;
855        count = 0;
856        while(*src && count < HTTP_MAX_LEN)
857        {
858                if (*src == '$')
859                {
860                        char    *cp,
861                                *tmp;
862                        int     count2;
863                        httpVar *curVar;
864
865                        tmp = src + 1;
866                        cp = varName;
867                        count2 = 0;
868                        while(*tmp&&(isalnum(*tmp)||*tmp == '_')&&count2 < 80)
869                        {
870                                *cp++ = *tmp++;
871                                count2++;
872                        }
873                        *cp = 0;
874                        curVar = httpdGetVariableByName(r,varName);
875                        if (curVar)
876                        {
877                                strcpy(dest, curVar->value);
878                                dest = dest + strlen(dest);
879                                count += strlen(dest);
880                        }
881                        else
882                        {
883                                *dest++ = '$';
884                                strcpy(dest, varName);
885                                dest += strlen(varName);
886                                count += 1 + strlen(varName);
887                        }
888                        src = src + strlen(varName) + 1;
889                        continue;
890                }
891                *dest++ = *src++;
892                count++;
893        }       
894        *dest = 0;
895        r->response.responseLength += strlen(buf);
896        if (r->response.headersSent == 0)
897                httpdSendHeaders(r);
898        _httpd_net_write( r->clientSock, buf, strlen(buf));
899}
900
901
902
903#ifdef HAVE_STDARG_H
904void httpdPrintf(request *r, char *fmt, ...)
905{
906#else
907void httpdPrintf(va_alist)
908        va_dcl
909{
910        request         *r;;
911        char            *fmt;
912#endif
913        va_list         args;
914        char            buf[HTTP_MAX_LEN];
915
916#ifdef HAVE_STDARG_H
917        va_start(args, fmt);
918#else
919        va_start(args);
920        r = (request *) va_arg(args, request * );
921        fmt = (char *) va_arg(args, char *);
922#endif
923        if (r->response.headersSent == 0)
924                httpdSendHeaders(r);
925        vsnprintf(buf, HTTP_MAX_LEN, fmt, args);
926        r->response.responseLength += strlen(buf);
927        _httpd_net_write( r->clientSock, buf, strlen(buf));
928}
929
930
931
932
933void httpdProcessRequest(httpd *server, request *r)
934{
935        char    dirName[HTTP_MAX_URL],
936                entryName[HTTP_MAX_URL],
937                *cp;
938        httpDir *dir;
939        httpContent *entry;
940
941        r->response.responseLength = 0;
942        strncpy(dirName, httpdRequestPath(r), HTTP_MAX_URL);
943        cp = rindex(dirName, '/');
944        if (cp == NULL)
945        {
946                printf("Invalid request path '%s'\n",dirName);
947                return;
948        }
949        strncpy(entryName, cp + 1, HTTP_MAX_URL);
950        if (cp != dirName)
951                *cp = 0;
952        else
953                *(cp+1) = 0;
954        dir = _httpd_findContentDir(server, dirName, HTTP_FALSE);
955        if (dir == NULL)
956        {
957                _httpd_send404(server, r);
958                _httpd_writeAccessLog(server, r);
959                return;
960        }
961        entry = _httpd_findContentEntry(r, dir, entryName);
962        if (entry == NULL)
963        {
964                _httpd_send404(server, r);
965                _httpd_writeAccessLog(server, r);
966                return;
967        }
968        if (entry->preload)
969        {
970                if ((entry->preload)(server) < 0)
971                {
972                        _httpd_writeAccessLog(server, r);
973                        return;
974                }
975        }
976        switch(entry->type)
977        {
978                case HTTP_C_FUNCT:
979                case HTTP_C_WILDCARD:
980                        (entry->function)(server, r);
981                        break;
982
983                case HTTP_STATIC:
984                        _httpd_sendStatic(server, r, entry->data);
985                        break;
986
987                case HTTP_FILE:
988                        _httpd_sendFile(server, r, entry->path);
989                        break;
990
991                case HTTP_WILDCARD:
992                        if (_httpd_sendDirectoryEntry(server, r, entry,
993                                                entryName)<0)
994                        {
995                                _httpd_send404(server, r);
996                        }
997                        break;
998        }
999        _httpd_writeAccessLog(server, r);
1000}
1001
1002void httpdSetAccessLog(server, fp)
1003        httpd   *server;
1004        FILE    *fp;
1005{
1006        server->accessLog = fp;
1007}
1008
1009void httpdSetErrorLog(server, fp)
1010        httpd   *server;
1011        FILE    *fp;
1012{
1013        server->errorLog = fp;
1014}
1015
1016void httpdAuthenticate(request *r, char *realm)
1017{
1018        char    buffer[255];
1019
1020        if (r->request.authLength == 0)
1021        {
1022                httpdSetResponse(r, "401 Please Authenticate");
1023                snprintf(buffer,sizeof(buffer), 
1024                        "WWW-Authenticate: Basic realm=\"%s\"\n", realm);
1025                httpdAddHeader(r, buffer);
1026                httpdOutput(r,"\n");
1027        }
1028}
1029
1030
1031void httpdForceAuthenticate(request *r, char *realm)
1032{
1033        char    buffer[255];
1034
1035        httpdSetResponse(r, "401 Please Authenticate");
1036        snprintf(buffer,sizeof(buffer), 
1037                "WWW-Authenticate: Basic realm=\"%s\"\n", realm);
1038        httpdAddHeader(r, buffer);
1039        httpdOutput(r,"\n");
1040}
Note: See TracBrowser for help on using the browser.