Changeset 22962


Ignore:
Timestamp:
2010-09-06T22:49:31+02:00 (7 years ago)
Author:
jow
Message:

[backfire] merge r22630, r22692, r22805

Location:
branches/backfire/package/uhttpd
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • branches/backfire/package/uhttpd/Makefile

    r22608 r22962  
    99 
    1010PKG_NAME:=uhttpd 
    11 PKG_RELEASE:=14 
     11PKG_RELEASE:=17 
    1212 
    1313PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME) 
  • branches/backfire/package/uhttpd/files/uhttpd.config

    r22590 r22962  
    2727        # Default is /cgi-bin 
    2828        option cgi_prefix       /cgi-bin 
     29 
     30        # List of extension->interpreter mappings. 
     31        # Files with an associated interpreter can 
     32        # be called outside of the CGI prefix and do 
     33        # not need to be executable. 
     34#       list interpreter        ".php=/usr/bin/php-cgi" 
     35#       list interpreter        ".cgi=/usr/bin/perl" 
    2936 
    3037        # Lua url prefix and handler script. 
  • branches/backfire/package/uhttpd/files/uhttpd.init

    r22594 r22962  
    5757        local cfg="$1" 
    5858        local realm="$(uci_get system.@system[0].hostname)" 
    59         local listen http https 
     59        local listen http https interpreter path 
    6060 
    6161        append_arg "$cfg" home "-h" 
     
    7777        for listen in $http; do 
    7878                append UHTTPD_ARGS "-p $listen" 
     79        done 
     80 
     81        config_get interpreter "$cfg" interpreter 
     82        for path in $interpreter; do 
     83                append UHTTPD_ARGS "-i $path" 
    7984        done 
    8085 
  • branches/backfire/package/uhttpd/src/uhttpd-cgi.c

    r22590 r22962  
    136136 
    137137 
    138 void uh_cgi_request(struct client *cl, struct http_request *req, struct path_info *pi) 
    139 { 
    140         int i, hdroff, bufoff; 
     138void uh_cgi_request( 
     139        struct client *cl, struct http_request *req, 
     140        struct path_info *pi, struct interpreter *ip 
     141) { 
     142        int i, hdroff, bufoff, rv; 
    141143        int hdrlen = 0; 
    142144        int buflen = 0; 
     
    200202                        dup2(wfd[0], 0); 
    201203 
    202                         /* check for regular, world-executable file */ 
    203                         if( (pi->stat.st_mode & S_IFREG) && 
    204                             (pi->stat.st_mode & S_IXOTH) 
     204                        /* check for regular, world-executable file _or_ interpreter */ 
     205                        if( ((pi->stat.st_mode & S_IFREG) && 
     206                             (pi->stat.st_mode & S_IXOTH)) || (ip != NULL) 
    205207                        ) { 
    206208                                /* build environment */ 
     
    321323                                        perror("chdir()"); 
    322324 
    323                                 execl(pi->phys, pi->phys, NULL); 
     325                                if( ip != NULL ) 
     326                                        execl(ip->path, ip->path, pi->phys, NULL); 
     327                                else 
     328                                        execl(pi->phys, pi->phys, NULL); 
    324329 
    325330                                /* in case it fails ... */ 
     
    328333                                        "Unable to launch the requested CGI program:\n" 
    329334                                        "  %s: %s\n", 
    330                                                 pi->phys, strerror(errno) 
     335                                                ip ? ip->path : pi->phys, strerror(errno) 
    331336                                ); 
    332337                        } 
     
    372377                        memset(hdr, 0, sizeof(hdr)); 
    373378 
    374                         timeout.tv_sec = cl->server->conf->script_timeout; 
    375                         timeout.tv_usec = 0; 
    376  
    377 #define ensure(x) \ 
    378         do { if( x < 0 ) goto out; } while(0) 
    379  
    380379                        /* I/O loop, watch our pipe ends and dispatch child reads/writes from/to socket */ 
    381380                        while( 1 ) 
     
    387386                                FD_SET(wfd[1], &writer); 
    388387 
     388                                timeout.tv_sec = (header_sent < 1) ? cl->server->conf->script_timeout : 3; 
     389                                timeout.tv_usec = 0; 
     390 
     391                                ensure_out(rv = select_intr(fd_max, &reader, 
     392                                        (content_length > -1) ? &writer : NULL, NULL, &timeout)); 
     393 
     394                                /* timeout */ 
     395                                if( rv == 0 ) 
     396                                { 
     397                                        ensure_out(kill(child, 0)); 
     398                                } 
     399 
    389400                                /* wait until we can read or write or both */ 
    390                                 if( select_intr(fd_max, &reader, 
    391                                         (content_length > -1) ? &writer : NULL, NULL, 
    392                                         (header_sent < 1) ? &timeout : NULL) > 0 
    393                                 ) { 
     401                                else if( rv > 0 ) 
     402                                { 
    394403                                        /* ready to write to cgi program */ 
    395404                                        if( FD_ISSET(wfd[1], &writer) ) 
     
    399408                                                { 
    400409                                                        /* read it from socket ... */ 
    401                                                         if( (buflen = uh_tcp_recv(cl, buf, min(content_length, sizeof(buf)))) > 0 ) 
     410                                                        ensure_out(buflen = uh_tcp_recv(cl, buf, 
     411                                                                min(content_length, sizeof(buf)))); 
     412 
     413                                                        if( buflen > 0 ) 
    402414                                                        { 
    403415                                                                /* ... and write it to child's stdin */ 
     
    452464                                                                { 
    453465                                                                        /* write status */ 
    454                                                                         ensure(uh_http_sendf(cl, NULL, 
     466                                                                        ensure_out(uh_http_sendf(cl, NULL, 
    455467                                                                                "HTTP/%.1f %03d %s\r\n" 
    456468                                                                                "Connection: close\r\n", 
     
    462474                                                                            !uh_cgi_header_lookup(res, "Content-Type") 
    463475                                                                        ) { 
    464                                                                                 ensure(uh_http_send(cl, NULL, 
     476                                                                                ensure_out(uh_http_send(cl, NULL, 
    465477                                                                                        "Content-Type: text/plain\r\n", -1)); 
    466478                                                                        } 
     
    470482                                                                            !uh_cgi_header_lookup(res, "Transfer-Encoding") 
    471483                                                                        ) { 
    472                                                                                 ensure(uh_http_send(cl, NULL, 
     484                                                                                ensure_out(uh_http_send(cl, NULL, 
    473485                                                                                        "Transfer-Encoding: chunked\r\n", -1)); 
    474486                                                                        } 
     
    477489                                                                        foreach_header(i, res->headers) 
    478490                                                                        { 
    479                                                                                 ensure(uh_http_sendf(cl, NULL, "%s: %s\r\n", 
     491                                                                                ensure_out(uh_http_sendf(cl, NULL, "%s: %s\r\n", 
    480492                                                                                        res->headers[i], res->headers[i+1])); 
    481493                                                                        } 
    482494 
    483495                                                                        /* terminate header */ 
    484                                                                         ensure(uh_http_send(cl, NULL, "\r\n", -1)); 
     496                                                                        ensure_out(uh_http_send(cl, NULL, "\r\n", -1)); 
    485497 
    486498                                                                        /* push out remaining head buffer */ 
    487499                                                                        if( hdroff < hdrlen ) 
    488                                                                                 ensure(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff)); 
     500                                                                                ensure_out(uh_http_send(cl, req, &hdr[hdroff], hdrlen - hdroff)); 
    489501                                                                } 
    490502 
     
    492504                                                                else if( hdrlen >= sizeof(hdr) ) 
    493505                                                                { 
    494                                                                         ensure(uh_cgi_error_500(cl, req, 
     506                                                                        ensure_out(uh_cgi_error_500(cl, req, 
    495507                                                                                "The CGI program generated an invalid response:\n\n")); 
    496508 
    497                                                                         ensure(uh_http_send(cl, req, hdr, hdrlen)); 
     509                                                                        ensure_out(uh_http_send(cl, req, hdr, hdrlen)); 
    498510                                                                } 
    499511 
     
    506518                                                                /* push out remaining read buffer */ 
    507519                                                                if( bufoff < buflen ) 
    508                                                                         ensure(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff)); 
     520                                                                        ensure_out(uh_http_send(cl, req, &buf[bufoff], buflen - bufoff)); 
    509521 
    510522                                                                header_sent = 1; 
     
    514526 
    515527                                                        /* headers complete, pass through buffer to socket */ 
    516                                                         ensure(uh_http_send(cl, req, buf, buflen)); 
     528                                                        ensure_out(uh_http_send(cl, req, buf, buflen)); 
    517529                                                } 
    518530 
     
    534546                                                                 */ 
    535547 
    536                                                                 ensure(uh_http_sendf(cl, NULL, 
     548                                                                ensure_out(uh_http_sendf(cl, NULL, 
    537549                                                                        "HTTP/%.1f 200 OK\r\n" 
    538550                                                                        "Content-Type: text/plain\r\n" 
     
    542554                                                                )); 
    543555 
    544                                                                 ensure(uh_http_send(cl, req, hdr, hdrlen)); 
     556                                                                ensure_out(uh_http_send(cl, req, hdr, hdrlen)); 
    545557                                                        } 
    546558 
    547559                                                        /* send final chunk if we're in chunked transfer mode */ 
    548                                                         ensure(uh_http_send(cl, req, "", 0)); 
     560                                                        ensure_out(uh_http_send(cl, req, "", 0)); 
    549561                                                        break; 
    550562                                                } 
     
    557569                                        if( (errno != EINTR) && ! header_sent ) 
    558570                                        { 
    559                                                 ensure(uh_http_sendhf(cl, 504, "Gateway Timeout", 
     571                                                ensure_out(uh_http_sendhf(cl, 504, "Gateway Timeout", 
    560572                                                        "The CGI script took too long to produce " 
    561573                                                        "a response")); 
     
    563575 
    564576                                        /* send final chunk if we're in chunked transfer mode */ 
    565                                         ensure(uh_http_send(cl, req, "", 0)); 
     577                                        ensure_out(uh_http_send(cl, req, "", 0)); 
    566578 
    567579                                        break; 
  • branches/backfire/package/uhttpd/src/uhttpd-cgi.h

    r20428 r22962  
    2626 
    2727void uh_cgi_request( 
    28         struct client *cl, struct http_request *req, struct path_info *pi 
     28        struct client *cl, struct http_request *req, 
     29        struct path_info *pi, struct interpreter *ip 
    2930); 
    3031 
  • branches/backfire/package/uhttpd/src/uhttpd-file.c

    r22608 r22962  
    9898} 
    9999 
    100 #define ensure_ret(x) \ 
    101         do { if( x < 0 ) return; } while(0) 
    102  
    103 static void uh_file_response_ok_hdrs(struct client *cl, struct http_request *req, struct stat *s) 
     100 
     101static int uh_file_response_ok_hdrs(struct client *cl, struct http_request *req, struct stat *s) 
    104102{ 
    105103        ensure_ret(uh_http_sendf(cl, NULL, "Connection: close\r\n")); 
     
    111109        } 
    112110 
    113         ensure_ret(uh_http_sendf(cl, NULL, "Date: %s\r\n", uh_file_unix2date(time(NULL)))); 
    114 } 
    115  
    116 static void uh_file_response_200(struct client *cl, struct http_request *req, struct stat *s) 
     111        return uh_http_sendf(cl, NULL, "Date: %s\r\n", uh_file_unix2date(time(NULL))); 
     112} 
     113 
     114static int uh_file_response_200(struct client *cl, struct http_request *req, struct stat *s) 
    117115{ 
    118116        ensure_ret(uh_http_sendf(cl, NULL, "HTTP/%.1f 200 OK\r\n", req->version)); 
    119         uh_file_response_ok_hdrs(cl, req, s); 
    120 } 
    121  
    122 static void uh_file_response_304(struct client *cl, struct http_request *req, struct stat *s) 
     117        return uh_file_response_ok_hdrs(cl, req, s); 
     118} 
     119 
     120static int uh_file_response_304(struct client *cl, struct http_request *req, struct stat *s) 
    123121{ 
    124122        ensure_ret(uh_http_sendf(cl, NULL, "HTTP/%.1f 304 Not Modified\r\n", req->version)); 
    125         uh_file_response_ok_hdrs(cl, req, s); 
    126 } 
    127  
    128 static void uh_file_response_412(struct client *cl, struct http_request *req) 
    129 { 
    130         ensure_ret(uh_http_sendf(cl, NULL, 
     123        return uh_file_response_ok_hdrs(cl, req, s); 
     124} 
     125 
     126static int uh_file_response_412(struct client *cl, struct http_request *req) 
     127{ 
     128        return uh_http_sendf(cl, NULL, 
    131129                "HTTP/%.1f 412 Precondition Failed\r\n" 
    132                 "Connection: close\r\n", req->version)); 
    133 } 
    134  
    135 static int uh_file_if_match(struct client *cl, struct http_request *req, struct stat *s) 
     130                "Connection: close\r\n", req->version); 
     131} 
     132 
     133static int uh_file_if_match(struct client *cl, struct http_request *req, struct stat *s, int *ok) 
    136134{ 
    137135        const char *tag = uh_file_mktag(s); 
     
    153151                        else if( !strcmp(p, "*") || !strcmp(p, tag) ) 
    154152                        { 
    155                                 return 1; 
     153                                *ok = 1; 
     154                                return *ok; 
    156155                        } 
    157156                } 
    158157 
    159                 uh_file_response_412(cl, req); 
    160                 return 0; 
    161         } 
    162  
    163         return 1; 
    164 } 
    165  
    166 static int uh_file_if_modified_since(struct client *cl, struct http_request *req, struct stat *s) 
     158                *ok = 0; 
     159                ensure_ret(uh_file_response_412(cl, req)); 
     160                return *ok; 
     161        } 
     162 
     163        *ok = 1; 
     164        return *ok; 
     165} 
     166 
     167static int uh_file_if_modified_since(struct client *cl, struct http_request *req, struct stat *s, int *ok) 
    167168{ 
    168169        char *hdr = uh_file_header_lookup(req, "If-Modified-Since"); 
     170        *ok = 1; 
    169171 
    170172        if( hdr ) 
    171173        { 
    172                 if( uh_file_date2unix(hdr) < s->st_mtime ) 
    173                 { 
    174                         return 1; 
    175                 } 
    176                 else 
    177                 { 
    178                         uh_file_response_304(cl, req, s); 
    179                         return 0; 
    180                 } 
    181         } 
    182  
    183         return 1; 
    184 } 
    185  
    186 static int uh_file_if_none_match(struct client *cl, struct http_request *req, struct stat *s) 
     174                if( uh_file_date2unix(hdr) >= s->st_mtime ) 
     175                { 
     176                        *ok = 0; 
     177                        ensure_ret(uh_file_response_304(cl, req, s)); 
     178                } 
     179        } 
     180 
     181        return *ok; 
     182} 
     183 
     184static int uh_file_if_none_match(struct client *cl, struct http_request *req, struct stat *s, int *ok) 
    187185{ 
    188186        const char *tag = uh_file_mktag(s); 
     
    190188        char *p; 
    191189        int i; 
     190        *ok = 1; 
    192191 
    193192        if( hdr ) 
     
    204203                        else if( !strcmp(p, "*") || !strcmp(p, tag) ) 
    205204                        { 
     205                                *ok = 0; 
     206 
    206207                                if( (req->method == UH_HTTP_MSG_GET) || 
    207208                                    (req->method == UH_HTTP_MSG_HEAD) ) 
    208                                         uh_file_response_304(cl, req, s); 
     209                                        ensure_ret(uh_file_response_304(cl, req, s)); 
    209210                                else 
    210                                         uh_file_response_412(cl, req); 
    211  
    212                                 return 0; 
     211                                        ensure_ret(uh_file_response_412(cl, req)); 
     212 
     213                                break; 
    213214                        } 
    214215                } 
    215216        } 
    216217 
    217         return 1; 
    218 } 
    219  
    220 static int uh_file_if_range(struct client *cl, struct http_request *req, struct stat *s) 
     218        return *ok; 
     219} 
     220 
     221static int uh_file_if_range(struct client *cl, struct http_request *req, struct stat *s, int *ok) 
    221222{ 
    222223        char *hdr = uh_file_header_lookup(req, "If-Range"); 
     224        *ok = 1; 
    223225 
    224226        if( hdr ) 
    225227        { 
    226                 uh_file_response_412(cl, req); 
    227                 return 0; 
    228         } 
    229  
    230         return 1; 
    231 } 
    232  
    233 static int uh_file_if_unmodified_since(struct client *cl, struct http_request *req, struct stat *s) 
     228                *ok = 0; 
     229                ensure_ret(uh_file_response_412(cl, req)); 
     230        } 
     231 
     232        return *ok; 
     233} 
     234 
     235static int uh_file_if_unmodified_since(struct client *cl, struct http_request *req, struct stat *s, int *ok) 
    234236{ 
    235237        char *hdr = uh_file_header_lookup(req, "If-Unmodified-Since"); 
     238        *ok = 1; 
    236239 
    237240        if( hdr ) 
     
    239242                if( uh_file_date2unix(hdr) <= s->st_mtime ) 
    240243                { 
    241                         uh_file_response_412(cl, req); 
    242                         return 0; 
    243                 } 
    244         } 
    245  
    246         return 1; 
    247 } 
    248  
    249  
    250 #define ensure_out(x) \ 
    251         do { if( x < 0 ) goto out; } while(0) 
     244                        *ok = 0; 
     245                        ensure_ret(uh_file_response_412(cl, req)); 
     246                } 
     247        } 
     248 
     249        return *ok; 
     250} 
     251 
    252252 
    253253static int uh_file_scandir_filter_dir(const struct dirent *e) 
     
    336336{ 
    337337        int rlen; 
     338        int ok = 1; 
    338339        int fd = -1; 
    339340        char buf[UH_LIMIT_MSGHEAD]; 
     
    343344        { 
    344345                /* test preconditions */ 
    345                 if( 
    346                         uh_file_if_modified_since(cl, req, &pi->stat)   && 
    347                         uh_file_if_match(cl, req, &pi->stat)            && 
    348                         uh_file_if_range(cl, req, &pi->stat)            && 
    349                         uh_file_if_unmodified_since(cl, req, &pi->stat) && 
    350                         uh_file_if_none_match(cl, req, &pi->stat) 
    351                 ) { 
     346                if(ok) ensure_out(uh_file_if_modified_since(cl, req, &pi->stat, &ok)); 
     347                if(ok) ensure_out(uh_file_if_match(cl, req, &pi->stat, &ok)); 
     348                if(ok) ensure_out(uh_file_if_range(cl, req, &pi->stat, &ok)); 
     349                if(ok) ensure_out(uh_file_if_unmodified_since(cl, req, &pi->stat, &ok)); 
     350                if(ok) ensure_out(uh_file_if_none_match(cl, req, &pi->stat, &ok)); 
     351 
     352                if( ok > 0 ) 
     353                { 
    352354                        /* write status */ 
    353                         uh_file_response_200(cl, req, &pi->stat); 
     355                        ensure_out(uh_file_response_200(cl, req, &pi->stat)); 
    354356 
    355357                        ensure_out(uh_http_sendf(cl, NULL, "Content-Type: %s\r\n", uh_file_mime_lookup(pi->name))); 
     
    386388        { 
    387389                /* write status */ 
    388                 uh_file_response_200(cl, req, NULL); 
     390                ensure_out(uh_file_response_200(cl, req, NULL)); 
    389391 
    390392                if( req->version > 1.0 ) 
  • branches/backfire/package/uhttpd/src/uhttpd-tls.c

    r21763 r22962  
    7171int uh_tls_client_recv(struct client *c, void *buf, int len) 
    7272{ 
    73         return SSL_read(c->tls, buf, len); 
     73        int rv = SSL_read(c->tls, buf, len); 
     74        return (rv > 0) ? rv : -1; 
    7475} 
    7576 
    7677int uh_tls_client_send(struct client *c, void *buf, int len) 
    7778{ 
    78         return SSL_write(c->tls, buf, len); 
     79        int rv = SSL_write(c->tls, buf, len); 
     80        return (rv > 0) ? rv : -1; 
    7981} 
    8082 
  • branches/backfire/package/uhttpd/src/uhttpd-utils.c

    r22590 r22962  
    113113        sigemptyset(&ssn); 
    114114        sigaddset(&ssn, SIGCHLD); 
     115        sigaddset(&ssn, SIGPIPE); 
    115116        sigprocmask(SIG_UNBLOCK, &ssn, &sso); 
    116117 
     
    194195} 
    195196 
    196 #define ensure(x) \ 
    197         do { if( x < 0 ) return -1; } while(0) 
    198197 
    199198int uh_http_sendhf(struct client *cl, int code, const char *summary, const char *fmt, ...) 
     
    212211        ); 
    213212 
    214         ensure(uh_tcp_send(cl, buffer, len)); 
     213        ensure_ret(uh_tcp_send(cl, buffer, len)); 
    215214 
    216215        va_start(ap, fmt); 
     
    218217        va_end(ap); 
    219218 
    220         ensure(uh_http_sendc(cl, buffer, len)); 
    221         ensure(uh_http_sendc(cl, NULL, 0)); 
     219        ensure_ret(uh_http_sendc(cl, buffer, len)); 
     220        ensure_ret(uh_http_sendc(cl, NULL, 0)); 
    222221 
    223222        return 0; 
     
    236235        { 
    237236                clen = snprintf(chunk, sizeof(chunk), "%X\r\n", len); 
    238                 ensure(uh_tcp_send(cl, chunk, clen)); 
    239                 ensure(uh_tcp_send(cl, data, len)); 
    240                 ensure(uh_tcp_send(cl, "\r\n", 2)); 
     237                ensure_ret(uh_tcp_send(cl, chunk, clen)); 
     238                ensure_ret(uh_tcp_send(cl, data, len)); 
     239                ensure_ret(uh_tcp_send(cl, "\r\n", 2)); 
    241240        } 
    242241        else 
    243242        { 
    244                 ensure(uh_tcp_send(cl, "0\r\n\r\n", 5)); 
     243                ensure_ret(uh_tcp_send(cl, "0\r\n\r\n", 5)); 
    245244        } 
    246245 
     
    260259 
    261260        if( (req != NULL) && (req->version > 1.0) ) 
    262                 ensure(uh_http_sendc(cl, buffer, len)); 
     261                ensure_ret(uh_http_sendc(cl, buffer, len)); 
    263262        else if( len > 0 ) 
    264                 ensure(uh_tcp_send(cl, buffer, len)); 
     263                ensure_ret(uh_tcp_send(cl, buffer, len)); 
    265264 
    266265        return 0; 
     
    274273 
    275274        if( (req != NULL) && (req->version > 1.0) ) 
    276                 ensure(uh_http_sendc(cl, buf, len)); 
     275                ensure_ret(uh_http_sendc(cl, buf, len)); 
    277276        else if( len > 0 ) 
    278                 ensure(uh_tcp_send(cl, buf, len)); 
     277                ensure_ret(uh_tcp_send(cl, buf, len)); 
    279278 
    280279        return 0; 
     
    606605 
    607606 
    608 static char uh_realms[UH_LIMIT_AUTHREALMS * sizeof(struct auth_realm)] = { 0 }; 
    609 static int uh_realm_count = 0; 
     607static struct auth_realm *uh_realms = NULL; 
    610608 
    611609struct auth_realm * uh_auth_add(char *path, char *user, char *pass) 
     
    615613        struct spwd *spwd; 
    616614 
    617         if( uh_realm_count < UH_LIMIT_AUTHREALMS ) 
    618         { 
    619                 new = (struct auth_realm *) 
    620                         &uh_realms[uh_realm_count * sizeof(struct auth_realm)]; 
    621  
     615        if((new = (struct auth_realm *)malloc(sizeof(struct auth_realm))) != NULL) 
     616        { 
    622617                memset(new, 0, sizeof(struct auth_realm)); 
    623618 
     
    644639                                memcpy(new->pass, pwd->pw_passwd, 
    645640                                        min(strlen(pwd->pw_passwd), sizeof(new->pass) - 1)); 
    646                         }                        
     641                        } 
    647642                } 
    648643 
     
    656651                if( new->pass[0] ) 
    657652                { 
    658                         uh_realm_count++; 
     653                        new->next = uh_realms; 
     654                        uh_realms = new; 
     655 
    659656                        return new; 
    660657                } 
     658 
     659                free(new); 
    661660        } 
    662661 
     
    678677 
    679678        /* check whether at least one realm covers the requested url */ 
    680         for( i = 0; i < uh_realm_count; i++ ) 
    681         { 
    682                 realm = (struct auth_realm *) 
    683                         &uh_realms[i * sizeof(struct auth_realm)]; 
    684  
     679        for( realm = uh_realms; realm; realm = realm->next ) 
     680        { 
    685681                rlen = strlen(realm->path); 
    686682 
     
    722718                { 
    723719                        /* find matching realm */ 
    724                         for( i = 0, realm = NULL; i < uh_realm_count; i++ ) 
    725                         { 
    726                                 realm = (struct auth_realm *) 
    727                                         &uh_realms[i * sizeof(struct auth_realm)]; 
    728  
     720                        for( realm = uh_realms; realm; realm = realm->next ) 
     721                        { 
    729722                                rlen = strlen(realm->path); 
    730723 
     
    736729                                        break; 
    737730                                } 
    738  
    739                                 realm = NULL; 
    740731                        } 
    741732 
     
    770761 
    771762 
    772 static char uh_listeners[UH_LIMIT_LISTENERS * sizeof(struct listener)] = { 0 }; 
    773 static char uh_clients[UH_LIMIT_CLIENTS * sizeof(struct client)] = { 0 }; 
    774  
    775 static int uh_listener_count = 0; 
    776 static int uh_client_count = 0; 
    777  
     763static struct listener *uh_listeners = NULL; 
     764static struct client *uh_clients = NULL; 
    778765 
    779766struct listener * uh_listener_add(int sock, struct config *conf) 
     
    782769        socklen_t sl; 
    783770 
    784         if( uh_listener_count < UH_LIMIT_LISTENERS ) 
    785         { 
    786                 new = (struct listener *) 
    787                         &uh_listeners[uh_listener_count * sizeof(struct listener)]; 
     771        if( (new = (struct listener *)malloc(sizeof(struct listener))) != NULL ) 
     772        { 
     773                memset(new, 0, sizeof(struct listener)); 
    788774 
    789775                new->socket = sock; 
     
    795781                getsockname(sock, (struct sockaddr *) &(new->addr), &sl); 
    796782 
    797                 uh_listener_count++; 
    798         } 
    799  
    800         return new; 
     783                new->next = uh_listeners; 
     784                uh_listeners = new; 
     785 
     786                return new; 
     787        } 
     788 
     789        return NULL; 
    801790} 
    802791 
     
    804793{ 
    805794        struct listener *cur = NULL; 
    806         int i; 
    807  
    808         for( i = 0; i < uh_listener_count; i++ ) 
    809         { 
    810                 cur = (struct listener *) &uh_listeners[i * sizeof(struct listener)]; 
    811  
     795 
     796        for( cur = uh_listeners; cur; cur = cur->next ) 
    812797                if( cur->socket == sock ) 
    813798                        return cur; 
    814         } 
    815799 
    816800        return NULL; 
     
    823807        socklen_t sl; 
    824808 
    825         if( uh_client_count < UH_LIMIT_CLIENTS ) 
    826         { 
    827                 new = (struct client *) 
    828                         &uh_clients[uh_client_count * sizeof(struct client)]; 
     809        if( (new = (struct client *)malloc(sizeof(struct client))) != NULL ) 
     810        { 
     811                memset(new, 0, sizeof(struct client)); 
    829812 
    830813                new->socket = sock; 
     
    841824                getsockname(sock, (struct sockaddr *) &(new->servaddr), &sl); 
    842825 
    843                 uh_client_count++; 
     826                new->next = uh_clients; 
     827                uh_clients = new; 
    844828        } 
    845829 
     
    850834{ 
    851835        struct client *cur = NULL; 
    852         int i; 
    853  
    854         for( i = 0; i < uh_client_count; i++ ) 
    855         { 
    856                 cur = (struct client *) &uh_clients[i * sizeof(struct client)]; 
    857  
     836 
     837        for( cur = uh_clients; cur; cur = cur->next ) 
    858838                if( cur->socket == sock ) 
    859839                        return cur; 
    860         } 
    861840 
    862841        return NULL; 
     
    865844void uh_client_remove(int sock) 
    866845{ 
    867         struct client *del = uh_client_lookup(sock); 
    868  
    869         if( del ) 
    870         { 
    871                 memmove(del, del + 1, 
    872                         sizeof(uh_clients) - (int)((char *)del - uh_clients) - sizeof(struct client)); 
    873  
    874                 uh_client_count--; 
    875         } 
    876 } 
    877  
    878  
     846        struct client *cur = NULL; 
     847        struct client *prv = NULL; 
     848 
     849        for( cur = uh_clients; cur; prv = cur, cur = cur->next ) 
     850        { 
     851                if( cur->socket == sock ) 
     852                { 
     853                        if( prv ) 
     854                                prv->next = cur->next; 
     855                        else 
     856                                uh_clients = cur->next; 
     857 
     858                        free(cur); 
     859                        break; 
     860                } 
     861        } 
     862} 
     863 
     864 
     865#ifdef HAVE_CGI 
     866static struct interpreter *uh_interpreters = NULL; 
     867 
     868struct interpreter * uh_interpreter_add(const char *extn, const char *path) 
     869{ 
     870        struct interpreter *new = NULL; 
     871 
     872        if( (new = (struct interpreter *) 
     873                        malloc(sizeof(struct interpreter))) != NULL ) 
     874        { 
     875                memset(new, 0, sizeof(struct interpreter)); 
     876 
     877                memcpy(new->extn, extn, min(strlen(extn), sizeof(new->extn)-1)); 
     878                memcpy(new->path, path, min(strlen(path), sizeof(new->path)-1)); 
     879 
     880                new->next = uh_interpreters; 
     881                uh_interpreters = new; 
     882 
     883                return new; 
     884        } 
     885 
     886        return NULL; 
     887} 
     888 
     889struct interpreter * uh_interpreter_lookup(const char *path) 
     890{ 
     891        struct interpreter *cur = NULL; 
     892        const char *e; 
     893 
     894        for( cur = uh_interpreters; cur; cur = cur->next ) 
     895        { 
     896                e = &path[max(strlen(path) - strlen(cur->extn), 0)]; 
     897 
     898                if( !strcmp(e, cur->extn) ) 
     899                        return cur; 
     900        } 
     901 
     902        return NULL; 
     903} 
     904#endif 
  • branches/backfire/package/uhttpd/src/uhttpd-utils.h

    r22590 r22962  
    3636#define fd_cloexec(fd) \ 
    3737        fcntl(fd, F_SETFD, fcntl(fd, F_GETFD) | FD_CLOEXEC) 
     38 
     39#define ensure_out(x) \ 
     40        do { if((x) < 0) goto out; } while(0) 
     41 
     42#define ensure_ret(x) \ 
     43        do { if((x) < 0) return -1; } while(0) 
     44 
    3845 
    3946struct path_info { 
     
    102109void uh_client_remove(int sock); 
    103110 
     111#ifdef HAVE_CGI 
     112struct interpreter * uh_interpreter_add(const char *extn, const char *path); 
     113struct interpreter * uh_interpreter_lookup(const char *path); 
    104114#endif 
     115 
     116#endif 
  • branches/backfire/package/uhttpd/src/uhttpd.c

    r22608 r22962  
    5252        FILE *c; 
    5353        char line[512]; 
    54         char *user = NULL; 
    55         char *pass = NULL; 
     54        char *col1 = NULL; 
     55        char *col2 = NULL; 
    5656        char *eol  = NULL; 
    5757 
     
    6767                        if( (line[0] == '/') && (strchr(line, ':') != NULL) ) 
    6868                        { 
    69                                 if( !(user = strchr(line, ':')) || (*user++ = 0) || 
    70                                     !(pass = strchr(user, ':')) || (*pass++ = 0) || 
    71                                         !(eol = strchr(pass, '\n')) || (*eol++  = 0) ) 
     69                                if( !(col1 = strchr(line, ':')) || (*col1++ = 0) || 
     70                                    !(col2 = strchr(col1, ':')) || (*col2++ = 0) || 
     71                                        !(eol = strchr(col2, '\n')) || (*eol++  = 0) ) 
    7272                                                continue; 
    7373 
    74                                 if( !uh_auth_add(line, user, pass) ) 
     74                                if( !uh_auth_add(line, col1, col2) ) 
    7575                                { 
    7676                                        fprintf(stderr, 
    7777                                                "Notice: No password set for user %s, ignoring " 
    78                                                 "authentication on %s\n", user, line 
     78                                                "authentication on %s\n", col1, line 
    7979                                        ); 
    8080                                } 
     
    8282                        else if( !strncmp(line, "I:", 2) ) 
    8383                        { 
    84                                 if( !(user = strchr(line, ':')) || (*user++ = 0) || 
    85                                     !(eol = strchr(user, '\n')) || (*eol++  = 0) ) 
     84                                if( !(col1 = strchr(line, ':')) || (*col1++ = 0) || 
     85                                    !(eol = strchr(col1, '\n')) || (*eol++  = 0) ) 
    8686                                        continue; 
    8787 
    88                                 conf->index_file = strdup(user); 
     88                                conf->index_file = strdup(col1); 
    8989                        } 
    9090                        else if( !strncmp(line, "E404:", 5) ) 
    9191                        { 
    92                                 if( !(user = strchr(line, ':')) || (*user++ = 0) || 
    93                                     !(eol = strchr(user, '\n')) || (*eol++  = 0) ) 
     92                                if( !(col1 = strchr(line, ':')) || (*col1++ = 0) || 
     93                                    !(eol = strchr(col1, '\n')) || (*eol++  = 0) ) 
    9494                                                continue; 
    9595 
    96                                 conf->error_handler = strdup(user); 
    97                         } 
     96                                conf->error_handler = strdup(col1); 
     97                        } 
     98#ifdef HAVE_CGI 
     99                        else if( (line[0] == '*') && (strchr(line, ':') != NULL) ) 
     100                        { 
     101                                if( !(col1 = strchr(line, '*')) || (*col1++ = 0) || 
     102                                    !(col2 = strchr(col1, ':')) || (*col2++ = 0) || 
     103                                    !(eol = strchr(col2, '\n')) || (*eol++  = 0) ) 
     104                                                continue; 
     105 
     106                                if( !uh_interpreter_add(col1, col2) ) 
     107                                { 
     108                                        fprintf(stderr, 
     109                                                "Unable to add interpreter %s for extension %s: " 
     110                                                "Out of memory\n", col2, col1 
     111                                        ); 
     112                                } 
     113                        } 
     114#endif 
    98115                } 
    99116 
     
    111128        int bound = 0; 
    112129 
     130        int tcp_ka_idl = 1; 
     131        int tcp_ka_int = 1; 
     132        int tcp_ka_cnt = 3; 
     133 
    113134        struct listener *l = NULL; 
    114135        struct addrinfo *addrs = NULL, *p = NULL; 
     
    130151 
    131152                /* "address already in use" */ 
    132                 if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) == -1 ) 
     153                if( setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) ) 
    133154                { 
    134155                        perror("setsockopt()"); 
    135156                        goto error; 
     157                } 
     158 
     159                /* TCP keep-alive */ 
     160                if( setsockopt(sock, SOL_SOCKET, SO_KEEPALIVE, &yes, sizeof(yes)) || 
     161                    setsockopt(sock, SOL_TCP, TCP_KEEPIDLE,  &tcp_ka_idl, sizeof(tcp_ka_idl)) || 
     162                    setsockopt(sock, SOL_TCP, TCP_KEEPINTVL, &tcp_ka_int, sizeof(tcp_ka_int)) || 
     163                    setsockopt(sock, SOL_TCP, TCP_KEEPCNT,   &tcp_ka_cnt, sizeof(tcp_ka_cnt)) ) 
     164                { 
     165                    fprintf(stderr, "Notice: Unable to enable TCP keep-alive: %s\n", 
     166                        strerror(errno)); 
    136167                } 
    137168 
     
    163194                if( ! (l = uh_listener_add(sock, conf)) ) 
    164195                { 
    165                         fprintf(stderr, 
    166                                 "uh_listener_add(): Can not create more than " 
    167                                 "%i listen sockets\n", UH_LIMIT_LISTENERS 
    168                         ); 
    169  
     196                        fprintf(stderr, "uh_listener_add(): Failed to allocate memory\n"); 
    170197                        goto error; 
    171198                } 
     
    344371        ssize_t rlen = 0; 
    345372 
    346  
    347373        memset(buffer, 0, sizeof(buffer)); 
    348374 
     
    360386                { 
    361387                        /* receive data */ 
    362                         rlen = uh_tcp_peek(cl, bufptr, blen); 
    363  
    364                         if( rlen > 0 ) 
     388                        ensure_out(rlen = uh_tcp_peek(cl, bufptr, blen)); 
     389 
     390                        if( (idxptr = strfind(buffer, sizeof(buffer), "\r\n\r\n", 4)) ) 
    365391                        { 
    366                                 if( (idxptr = strfind(buffer, sizeof(buffer), "\r\n\r\n", 4)) ) 
    367                                 { 
    368                                         blen -= uh_tcp_recv(cl, bufptr, (int)(idxptr - bufptr) + 4); 
    369  
    370                                         /* header read complete ... */ 
    371                                         return uh_http_header_parse(cl, buffer, sizeof(buffer) - blen - 1); 
    372                                 } 
    373                                 else 
    374                                 { 
    375                                         rlen = uh_tcp_recv(cl, bufptr, rlen); 
    376                                         blen -= rlen; 
    377                                         bufptr += rlen; 
    378                                 } 
     392                                ensure_out(rlen = uh_tcp_recv(cl, bufptr, 
     393                                        (int)(idxptr - bufptr) + 4)); 
     394 
     395                                /* header read complete ... */ 
     396                                blen -= rlen; 
     397                                return uh_http_header_parse(cl, buffer, 
     398                                        sizeof(buffer) - blen - 1); 
    379399                        } 
    380400                        else 
    381401                        { 
    382                                 /* invalid request (unexpected eof/timeout) */ 
    383                                 uh_http_response(cl, 408, "Request Timeout"); 
    384                                 return NULL; 
     402                                ensure_out(rlen = uh_tcp_recv(cl, bufptr, rlen)); 
     403 
     404                                blen -= rlen; 
     405                                bufptr += rlen; 
    385406                        } 
    386407                } 
     
    388409                { 
    389410                        /* invalid request (unexpected eof/timeout) */ 
    390                         uh_http_response(cl, 408, "Request Timeout"); 
    391411                        return NULL; 
    392412                } 
     
    395415        /* request entity too large */ 
    396416        uh_http_response(cl, 413, "Request Entity Too Large"); 
     417 
     418out: 
    397419        return NULL; 
    398420} 
    399421 
     422#if defined(HAVE_LUA) || defined(HAVE_CGI) 
    400423static int uh_path_match(const char *prefix, const char *url) 
    401424{ 
     
    410433        return 0; 
    411434} 
    412  
    413  
    414 int main (int argc, char **argv) 
     435#endif 
     436 
     437static void uh_dispatch_request( 
     438        struct client *cl, struct http_request *req, struct path_info *pin 
     439) { 
     440#ifdef HAVE_CGI 
     441        struct interpreter *ipr = NULL; 
     442 
     443        if( uh_path_match(cl->server->conf->cgi_prefix, pin->name) || 
     444                (ipr = uh_interpreter_lookup(pin->phys)) ) 
     445        { 
     446                uh_cgi_request(cl, req, pin, ipr); 
     447        } 
     448        else 
     449#endif 
     450        { 
     451                uh_file_request(cl, req, pin); 
     452        } 
     453} 
     454 
     455static void uh_mainloop(struct config *conf, fd_set serv_fds, int max_fd) 
    415456{ 
    416 #ifdef HAVE_LUA 
    417         /* Lua runtime */ 
    418         lua_State *L = NULL; 
    419 #endif 
    420  
    421457        /* master file descriptor list */ 
    422         fd_set used_fds, serv_fds, read_fds; 
     458        fd_set used_fds, read_fds; 
    423459 
    424460        /* working structs */ 
    425         struct addrinfo hints; 
    426461        struct http_request *req; 
    427462        struct path_info *pin; 
    428463        struct client *cl; 
     464 
     465        /* maximum file descriptor number */ 
     466        int new_fd, cur_fd = 0; 
     467 
     468        /* clear the master and temp sets */ 
     469        FD_ZERO(&used_fds); 
     470        FD_ZERO(&read_fds); 
     471 
     472        /* backup server descriptor set */ 
     473        used_fds = serv_fds; 
     474 
     475        /* loop */ 
     476        while(run) 
     477        { 
     478                /* create a working copy of the used fd set */ 
     479                read_fds = used_fds; 
     480 
     481                /* sleep until socket activity */ 
     482                if( select(max_fd + 1, &read_fds, NULL, NULL, NULL) == -1 ) 
     483                { 
     484                        perror("select()"); 
     485                        exit(1); 
     486                } 
     487 
     488                /* run through the existing connections looking for data to be read */ 
     489                for( cur_fd = 0; cur_fd <= max_fd; cur_fd++ ) 
     490                { 
     491                        /* is a socket managed by us */ 
     492                        if( FD_ISSET(cur_fd, &read_fds) ) 
     493                        { 
     494                                /* is one of our listen sockets */ 
     495                                if( FD_ISSET(cur_fd, &serv_fds) ) 
     496                                { 
     497                                        /* handle new connections */ 
     498                                        if( (new_fd = accept(cur_fd, NULL, 0)) != -1 ) 
     499                                        { 
     500                                                /* add to global client list */ 
     501                                                if( (cl = uh_client_add(new_fd, uh_listener_lookup(cur_fd))) != NULL ) 
     502                                                { 
     503#ifdef HAVE_TLS 
     504                                                        /* setup client tls context */ 
     505                                                        if( conf->tls ) 
     506                                                                conf->tls_accept(cl); 
     507#endif 
     508 
     509                                                        /* add client socket to global fdset */ 
     510                                                        FD_SET(new_fd, &used_fds); 
     511                                                        fd_cloexec(new_fd); 
     512                                                        max_fd = max(max_fd, new_fd); 
     513                                                } 
     514 
     515                                                /* insufficient resources */ 
     516                                                else 
     517                                                { 
     518                                                        fprintf(stderr, 
     519                                                                "uh_client_add(): Cannot allocate memory\n"); 
     520 
     521                                                        close(new_fd); 
     522                                                } 
     523                                        } 
     524                                } 
     525 
     526                                /* is a client socket */ 
     527                                else 
     528                                { 
     529                                        if( ! (cl = uh_client_lookup(cur_fd)) ) 
     530                                        { 
     531                                                /* this should not happen! */ 
     532                                                fprintf(stderr, 
     533                                                        "uh_client_lookup(): No entry for fd %i!\n", 
     534                                                        cur_fd); 
     535 
     536                                                goto cleanup; 
     537                                        } 
     538 
     539                                        /* parse message header */ 
     540                                        if( (req = uh_http_header_recv(cl)) != NULL ) 
     541                                        { 
     542                                                /* RFC1918 filtering required? */ 
     543                                                if( conf->rfc1918_filter && 
     544                                                    sa_rfc1918(&cl->peeraddr) && 
     545                                                    !sa_rfc1918(&cl->servaddr) ) 
     546                                                { 
     547                                                        uh_http_sendhf(cl, 403, "Forbidden", 
     548                                                                "Rejected request from RFC1918 IP " 
     549                                                                "to public server address"); 
     550                                                } 
     551                                                else 
     552#ifdef HAVE_LUA 
     553                                                /* Lua request? */ 
     554                                                if( conf->lua_state && 
     555                                                    uh_path_match(conf->lua_prefix, req->url) ) 
     556                                                { 
     557                                                        conf->lua_request(cl, req, conf->lua_state); 
     558                                                } 
     559                                                else 
     560#endif 
     561                                                /* dispatch request */ 
     562                                                if( (pin = uh_path_lookup(cl, req->url)) != NULL ) 
     563                                                { 
     564                                                        /* auth ok? */ 
     565                                                        if( uh_auth_check(cl, req, pin) ) 
     566                                                                uh_dispatch_request(cl, req, pin); 
     567                                                } 
     568 
     569                                                /* 404 */ 
     570                                                else 
     571                                                { 
     572                                                        /* Try to invoke an error handler */ 
     573                                                        pin = uh_path_lookup(cl, conf->error_handler); 
     574 
     575                                                        if( pin && uh_auth_check(cl, req, pin) ) 
     576                                                        { 
     577                                                                req->redirect_status = 404; 
     578                                                                uh_dispatch_request(cl, req, pin); 
     579                                                        } 
     580                                                        else 
     581                                                        { 
     582                                                                uh_http_sendhf(cl, 404, "Not Found", 
     583                                                                        "No such file or directory"); 
     584                                                        } 
     585                                                } 
     586                                        } 
     587 
     588#ifdef HAVE_TLS 
     589                                        /* free client tls context */ 
     590                                        if( conf->tls ) 
     591                                                conf->tls_close(cl); 
     592#endif 
     593 
     594                                        cleanup: 
     595 
     596                                        /* close client socket */ 
     597                                        close(cur_fd); 
     598                                        FD_CLR(cur_fd, &used_fds); 
     599 
     600                                        /* remove from global client list */ 
     601                                        uh_client_remove(cur_fd); 
     602                                } 
     603                        } 
     604                } 
     605        } 
     606 
     607#ifdef HAVE_LUA 
     608        /* destroy the Lua state */ 
     609        if( conf->lua_state != NULL ) 
     610                conf->lua_close(conf->lua_state); 
     611#endif 
     612} 
     613 
     614 
     615int main (int argc, char **argv) 
     616{ 
     617        /* master file descriptor list */ 
     618        fd_set used_fds, serv_fds, read_fds; 
     619 
     620        /* working structs */ 
     621        struct addrinfo hints; 
    429622        struct sigaction sa; 
    430623        struct config conf; 
     
    434627 
    435628        /* maximum file descriptor number */ 
    436         int new_fd, cur_fd, max_fd = 0; 
     629        int cur_fd, max_fd = 0; 
    437630 
    438631#ifdef HAVE_TLS 
     
    526719 
    527720        while( (opt = getopt(argc, argv, 
    528                 "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0 
     721                "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:i:t:T:")) > 0 
    529722        ) { 
    530723                switch(opt) 
     
    658851                        case 'x': 
    659852                                conf.cgi_prefix = optarg; 
     853                                break; 
     854 
     855                        /* interpreter */ 
     856                        case 'i': 
     857                                if( (optarg[0] == '.') && (port = strchr(optarg, '=')) ) 
     858                                { 
     859                                        *port++ = 0; 
     860                                        uh_interpreter_add(optarg, port); 
     861                                } 
     862                                else 
     863                                { 
     864                                        fprintf(stderr, "Error: Invalid interpreter: %s\n", 
     865                                                optarg); 
     866                                        exit(1); 
     867                                } 
    660868                                break; 
    661869#endif 
     
    741949#ifdef HAVE_CGI 
    742950                                        "       -x string       URL prefix for CGI handler, default is '/cgi-bin'\n" 
     951                                        "       -i .ext=path    Use interpreter at path for files with the given extension\n" 
    743952#endif 
    744953#if defined(HAVE_CGI) || defined(HAVE_LUA) 
     
    8311040                                conf.lua_prefix = "/lua"; 
    8321041 
    833                         L = conf.lua_init(conf.lua_handler); 
     1042                        conf.lua_state = conf.lua_init(conf.lua_handler); 
    8341043                } 
    8351044        } 
     
    8661075        } 
    8671076 
    868         /* backup server descriptor set */ 
    869         used_fds = serv_fds; 
    870  
    871         /* loop */ 
    872         while(run) 
    873         { 
    874                 /* create a working copy of the used fd set */ 
    875                 read_fds = used_fds; 
    876  
    877                 /* sleep until socket activity */ 
    878                 if( select(max_fd + 1, &read_fds, NULL, NULL, NULL) == -1 ) 
    879                 { 
    880                         perror("select()"); 
    881                         exit(1); 
    882                 } 
    883  
    884                 /* run through the existing connections looking for data to be read */ 
    885                 for( cur_fd = 0; cur_fd <= max_fd; cur_fd++ ) 
    886                 { 
    887                         /* is a socket managed by us */ 
    888                         if( FD_ISSET(cur_fd, &read_fds) ) 
    889                         { 
    890                                 /* is one of our listen sockets */ 
    891                                 if( FD_ISSET(cur_fd, &serv_fds) ) 
    892                                 { 
    893                                         /* handle new connections */ 
    894                                         if( (new_fd = accept(cur_fd, NULL, 0)) != -1 ) 
    895                                         { 
    896                                                 /* add to global client list */ 
    897                                                 if( (cl = uh_client_add(new_fd, uh_listener_lookup(cur_fd))) != NULL ) 
    898                                                 { 
    899 #ifdef HAVE_TLS 
    900                                                         /* setup client tls context */ 
    901                                                         if( conf.tls ) 
    902                                                                 conf.tls_accept(cl); 
    903 #endif 
    904  
    905                                                         /* add client socket to global fdset */ 
    906                                                         FD_SET(new_fd, &used_fds); 
    907                                                         fd_cloexec(new_fd); 
    908                                                         max_fd = max(max_fd, new_fd); 
    909                                                 } 
    910  
    911                                                 /* insufficient resources */ 
    912                                                 else 
    913                                                 { 
    914                                                         fprintf(stderr, 
    915                                                                 "uh_client_add(): Can not manage more than " 
    916                                                                 "%i client sockets, connection dropped\n", 
    917                                                                 UH_LIMIT_CLIENTS 
    918                                                         ); 
    919  
    920                                                         close(new_fd); 
    921                                                 } 
    922                                         } 
    923                                 } 
    924  
    925                                 /* is a client socket */ 
    926                                 else 
    927                                 { 
    928                                         if( ! (cl = uh_client_lookup(cur_fd)) ) 
    929                                         { 
    930                                                 /* this should not happen! */ 
    931                                                 fprintf(stderr, 
    932                                                         "uh_client_lookup(): No entry for fd %i!\n", 
    933                                                         cur_fd); 
    934  
    935                                                 goto cleanup; 
    936                                         } 
    937  
    938                                         /* parse message header */ 
    939                                         if( (req = uh_http_header_recv(cl)) != NULL ) 
    940                                         { 
    941                                                 /* RFC1918 filtering required? */ 
    942                                                 if( conf.rfc1918_filter && sa_rfc1918(&cl->peeraddr) && 
    943                                                     !sa_rfc1918(&cl->servaddr) ) 
    944                                                 { 
    945                                                         uh_http_sendhf(cl, 403, "Forbidden", 
    946                                                                 "Rejected request from RFC1918 IP to public server address"); 
    947                                                 } 
    948                                                 else 
    949 #ifdef HAVE_LUA 
    950                                                 /* Lua request? */ 
    951                                                 if( L && uh_path_match(conf.lua_prefix, req->url) ) 
    952                                                 { 
    953                                                         conf.lua_request(cl, req, L); 
    954                                                 } 
    955                                                 else 
    956 #endif 
    957                                                 /* dispatch request */ 
    958                                                 if( (pin = uh_path_lookup(cl, req->url)) != NULL ) 
    959                                                 { 
    960                                                         /* auth ok? */ 
    961                                                         if( uh_auth_check(cl, req, pin) ) 
    962                                                         { 
    963 #ifdef HAVE_CGI 
    964                                                                 if( uh_path_match(conf.cgi_prefix, pin->name) ) 
    965                                                                 { 
    966                                                                         uh_cgi_request(cl, req, pin); 
    967                                                                 } 
    968                                                                 else 
    969 #endif 
    970                                                                 { 
    971                                                                         uh_file_request(cl, req, pin); 
    972                                                                 } 
    973                                                         } 
    974                                                 } 
    975  
    976                                                 /* 404 */ 
    977                                                 else 
    978                                                 { 
    979                                                         /* Try to invoke an error handler */ 
    980                                                         pin = uh_path_lookup(cl, conf.error_handler); 
    981  
    982                                                         if( pin && uh_auth_check(cl, req, pin) ) 
    983                                                         { 
    984                                                                 req->redirect_status = 404; 
    985  
    986 #ifdef HAVE_CGI 
    987                                                                 if( uh_path_match(conf.cgi_prefix, pin->name) ) 
    988                                                                 { 
    989                                                                         uh_cgi_request(cl, req, pin); 
    990                                                                 } 
    991                                                                 else 
    992 #endif 
    993                                                                 { 
    994                                                                         uh_file_request(cl, req, pin); 
    995                                                                 } 
    996                                                         } 
    997                                                         else 
    998                                                         { 
    999                                                                 uh_http_sendhf(cl, 404, "Not Found", 
    1000                                                                         "No such file or directory"); 
    1001                                                         } 
    1002                                                 } 
    1003                                         } 
    1004  
    1005 #ifdef HAVE_TLS 
    1006                                         /* free client tls context */ 
    1007                                         if( conf.tls ) 
    1008                                                 conf.tls_close(cl); 
    1009 #endif 
    1010  
    1011                                         cleanup: 
    1012  
    1013                                         /* close client socket */ 
    1014                                         close(cur_fd); 
    1015                                         FD_CLR(cur_fd, &used_fds); 
    1016  
    1017                                         /* remove from global client list */ 
    1018                                         uh_client_remove(cur_fd); 
    1019                                 } 
    1020                         } 
    1021                 } 
    1022         } 
     1077        /* server main loop */ 
     1078        uh_mainloop(&conf, serv_fds, max_fd); 
    10231079 
    10241080#ifdef HAVE_LUA 
    10251081        /* destroy the Lua state */ 
    1026         if( L != NULL ) 
    1027                 conf.lua_close(L); 
     1082        if( conf.lua_state != NULL ) 
     1083                conf.lua_close(conf.lua_state); 
    10281084#endif 
    10291085 
  • branches/backfire/package/uhttpd/src/uhttpd.h

    r22590 r22962  
    2929#include <sys/wait.h> 
    3030#include <netinet/in.h> 
     31#include <netinet/tcp.h> 
    3132#include <arpa/inet.h> 
    3233#include <linux/limits.h> 
     
    4546#endif 
    4647 
     48/* uClibc... */ 
     49#ifndef SOL_TCP 
     50#define SOL_TCP 6 
     51#endif 
     52 
    4753 
    4854#define UH_LIMIT_MSGHEAD        4096 
    4955#define UH_LIMIT_HEADERS        64 
    5056 
    51 #define UH_LIMIT_LISTENERS      16 
    5257#define UH_LIMIT_CLIENTS        64 
    53 #define UH_LIMIT_AUTHREALMS     8 
    5458 
    5559#define UH_HTTP_MSG_GET         0 
     
    5963struct listener; 
    6064struct client; 
     65struct interpreter; 
    6166struct http_request; 
    6267 
     
    7782        char *lua_prefix; 
    7883        char *lua_handler; 
     84        lua_State *lua_state; 
    7985        lua_State * (*lua_init) (const char *handler); 
    8086        void (*lua_close) (lua_State *L); 
     
    106112        SSL_CTX *tls; 
    107113#endif 
     114        struct listener *next; 
    108115}; 
    109116 
     
    118125        SSL *tls; 
    119126#endif 
     127        struct client *next; 
    120128}; 
    121129 
     
    124132        char user[32]; 
    125133        char pass[128]; 
     134        struct auth_realm *next; 
    126135}; 
    127136 
     
    141150}; 
    142151 
     152#ifdef HAVE_CGI 
     153struct interpreter { 
     154        char path[PATH_MAX]; 
     155        char extn[32]; 
     156        struct interpreter *next; 
     157}; 
    143158#endif 
    144159 
     160#endif 
     161 
Note: See TracChangeset for help on using the changeset viewer.