Date:2010-08-11 02:23:13 (2 years 9 months ago)
Author:jow
Commit:952efd6fee0aa14e964d419dfe758c5b385dbe47
Message:[backfire] merge r22589

git-svn-id: svn://svn.openwrt.org/openwrt/branches/backfire@22590 3c298f89-4303-0410-b956-a3cf2f4a3e73
Files: package/uhttpd/Makefile (1 diff)
package/uhttpd/files/uhttpd.config (1 diff)
package/uhttpd/files/uhttpd.init (2 diffs)
package/uhttpd/src/uhttpd-cgi.c (1 diff)
package/uhttpd/src/uhttpd-file.c (4 diffs)
package/uhttpd/src/uhttpd-utils.c (3 diffs)
package/uhttpd/src/uhttpd-utils.h (1 diff)
package/uhttpd/src/uhttpd.c (10 diffs)
package/uhttpd/src/uhttpd.h (2 diffs)

Change Details

package/uhttpd/Makefile
88include $(TOPDIR)/rules.mk
99
1010PKG_NAME:=uhttpd
11PKG_RELEASE:=11
11PKG_RELEASE:=13
1212
1313PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
14PKG_BUILD_DEPENDS := libcyassl liblua
1415
1516include $(INCLUDE_DIR)/package.mk
1617
package/uhttpd/files/uhttpd.config
1212    # Server document root
1313    option home /www
1414
15    # Reject requests from RFC1918 IP addresses
16    # directed to the servers public IP(s).
17    # This is a DNS rebinding countermeasure.
18    option rfc1918_filter 1
19
1520    # Certificate and private key for HTTPS.
1621    # If no listen_https addresses are given,
1722    # the key options are ignored.
package/uhttpd/files/uhttpd.init
1717    [ -n "$val" -o -n "$def" ] && append UHTTPD_ARGS "$opt ${val:-$def}"
1818}
1919
20append_bool() {
21    local cfg="$1"
22    local var="$2"
23    local opt="$3"
24    local def="$4"
25    local val
26
27    config_get_bool val "$cfg" "$var" "$def"
28    [ "$val" = 1 ] && append UHTTPD_ARGS "$opt"
29}
30
2031generate_keys() {
2132    local cfg="$1"
2233    local key="$2"
...... 
5970    append_arg "$cfg" lua_handler "-L"
6071    append_arg "$cfg" script_timeout "-t"
6172    append_arg "$cfg" network_timeout "-T"
73    append_arg "$cfg" error_page "-E"
74    append_arg "$cfg" index_page "-I"
75
76    append_bool "$cfg" no_symlinks "-S" 0
77    append_bool "$cfg" no_dirlists "-D" 0
78    append_bool "$cfg" rfc1918_filter "-R" 0
6279
6380    config_get http "$cfg" listen_http
6481    for listen in $http; do
package/uhttpd/src/uhttpd-cgi.c
234234                if( pi->info )
235235                    setenv("PATH_INFO", pi->info, 1);
236236
237                /* REDIRECT_STATUS, php-cgi wants it */
238                switch( req->redirect_status )
239                {
240                    case 404:
241                        setenv("REDIRECT_STATUS", "404", 1);
242                        break;
243
244                    default:
245                        setenv("REDIRECT_STATUS", "200", 1);
246                        break;
247                }
237248
238249                /* http version */
239250                if( req->version > 1.0 )
package/uhttpd/src/uhttpd-file.c
2929static const char * uh_file_mime_lookup(const char *path)
3030{
3131    struct mimetype *m = &uh_mime_types[0];
32    char *e;
32    const char *e;
3333
3434    while( m->extn )
3535    {
...... 
275275            strncat(filename, files[i]->d_name,
276276                sizeof(filename) - strlen(files[i]->d_name));
277277
278            if( !stat(filename, &s) && (s.st_mode & S_IFDIR) )
278            if( !stat(filename, &s) &&
279                (s.st_mode & S_IFDIR) && (s.st_mode & S_IXOTH)
280            )
279281                uh_http_sendf(cl, req,
280282                    "<li><strong><a href='%s%s'>%s</a>/</strong><br />"
281283                    "<small>modified: %s<br />directory - %.02f kbyte"
...... 
293295            strncat(filename, files[i]->d_name,
294296                sizeof(filename) - strlen(files[i]->d_name));
295297
296            if( !stat(filename, &s) && !(s.st_mode & S_IFDIR) )
298            if( !stat(filename, &s) &&
299                !(s.st_mode & S_IFDIR) && (s.st_mode & S_IROTH)
300            )
297301                uh_http_sendf(cl, req,
298302                    "<li><strong><a href='%s%s'>%s</a></strong><br />"
299303                    "<small>modified: %s<br />%s - %.02f kbyte<br />"
...... 
369373    }
370374
371375    /* directory */
372    else if( pi->stat.st_mode & S_IFDIR )
376    else if( (pi->stat.st_mode & S_IFDIR) && !cl->server->conf->no_dirlists )
373377    {
374378        /* write status */
375379        uh_file_response_200(cl, req, NULL);
package/uhttpd/src/uhttpd-utils.c
5959    return ntohs(((struct sockaddr_in6 *)sa)->sin6_port);
6060}
6161
62int sa_rfc1918(void *sa)
63{
64    struct sockaddr_in *v4 = (struct sockaddr_in *)sa;
65    unsigned long a = htonl(v4->sin_addr.s_addr);
66
67    if( v4->sin_family == AF_INET )
68    {
69        return ((a >= 0x0A000000) && (a <= 0x0AFFFFFF)) ||
70               ((a >= 0xAC100000) && (a <= 0xAC1FFFFF)) ||
71               ((a >= 0xC0A80000) && (a <= 0xC0A8FFFF));
72    }
73
74    return 0;
75}
76
6277/* Simple strstr() like function that takes len arguments for both haystack and needle. */
6378char *strfind(char *haystack, int hslen, const char *needle, int ndlen)
6479{
...... 
464479    int i = 0;
465480    struct stat s;
466481
482    /* back out early if url is undefined */
483    if ( url == NULL )
484        return NULL;
467485
468486    memset(path_phys, 0, sizeof(path_phys));
469487    memset(path_info, 0, sizeof(path_info));
...... 
550568            memcpy(buffer, path_phys, sizeof(buffer));
551569            pathptr = &buffer[strlen(buffer)];
552570
553            for( i = 0; i < array_size(uh_index_files); i++ )
571            if( cl->server->conf->index_file )
554572            {
555                strncat(buffer, uh_index_files[i], sizeof(buffer));
573                strncat(buffer, cl->server->conf->index_file, sizeof(buffer));
556574
557575                if( !stat(buffer, &s) && (s.st_mode & S_IFREG) )
558576                {
559577                    memcpy(path_phys, buffer, sizeof(path_phys));
560578                    memcpy(&p.stat, &s, sizeof(p.stat));
561                    break;
562579                }
580            }
581            else
582            {
583                for( i = 0; i < array_size(uh_index_files); i++ )
584                {
585                    strncat(buffer, uh_index_files[i], sizeof(buffer));
563586
564                *pathptr = 0;
587                    if( !stat(buffer, &s) && (s.st_mode & S_IFREG) )
588                    {
589                        memcpy(path_phys, buffer, sizeof(path_phys));
590                        memcpy(&p.stat, &s, sizeof(p.stat));
591                        break;
592                    }
593
594                    *pathptr = 0;
595                }
565596            }
566597
567598            p.root = docroot;
package/uhttpd/src/uhttpd-utils.h
4949const char * sa_straddr(void *sa);
5050const char * sa_strport(void *sa);
5151int sa_port(void *sa);
52int sa_rfc1918(void *sa);
5253
5354char *strfind(char *haystack, int hslen, const char *needle, int ndlen);
5455
package/uhttpd/src/uhttpd.c
4747    while( waitpid(-1, NULL, WNOHANG) > 0 ) { }
4848}
4949
50static void uh_config_parse(const char *path)
50static void uh_config_parse(struct config *conf)
5151{
5252    FILE *c;
5353    char line[512];
...... 
5555    char *pass = NULL;
5656    char *eol = NULL;
5757
58    if( (c = fopen(path ? path : "/etc/httpd.conf", "r")) != NULL )
58    const char *path = conf->file ? conf->file : "/etc/httpd.conf";
59
60
61    if( (c = fopen(path, "r")) != NULL )
5962    {
6063        memset(line, 0, sizeof(line));
6164
...... 
7477                        "Notice: No password set for user %s, ignoring "
7578                        "authentication on %s\n", user, line
7679                    );
80                }
81            }
82            else if( !strncmp(line, "I:", 2) )
83            {
84                if( !(user = strchr(line, ':')) || (*user++ = 0) ||
85                    !(eol = strchr(user, '\n')) || (*eol++ = 0) )
86                        continue;
7787
78                    break;
79                }
88                conf->index_file = strdup(user);
89            }
90            else if( !strncmp(line, "E404:", 5) )
91            {
92                if( !(user = strchr(line, ':')) || (*user++ = 0) ||
93                    !(eol = strchr(user, '\n')) || (*eol++ = 0) )
94                        continue;
95
96                conf->error_handler = strdup(user);
8097            }
8198        }
8299
...... 
302319        }
303320
304321        /* valid enough */
322        req.redirect_status = 200;
305323        return &req;
306324    }
307325
...... 
505523    }
506524#endif
507525
508    while( (opt = getopt(argc, argv, "fSC:K:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0 )
509    {
526    while( (opt = getopt(argc, argv,
527        "fSDRC:K:E:I:p:s:h:c:l:L:d:r:m:x:t:T:")) > 0
528    ) {
510529        switch(opt)
511530        {
512531            /* [addr:]port */
...... 
597616                }
598617                break;
599618
619            /* error handler */
620            case 'E':
621                if( (strlen(optarg) == 0) || (optarg[0] != '/') )
622                {
623                    fprintf(stderr, "Error: Invalid error handler: %s\n",
624                        optarg);
625                    exit(1);
626                }
627                conf.error_handler = optarg;
628                break;
629
630            /* index file */
631            case 'I':
632                if( (strlen(optarg) == 0) || (optarg[0] == '/') )
633                {
634                    fprintf(stderr, "Error: Invalid index page: %s\n",
635                        optarg);
636                    exit(1);
637                }
638                conf.index_file = optarg;
639                break;
640
600641            /* don't follow symlinks */
601642            case 'S':
602643                conf.no_symlinks = 1;
603644                break;
604645
646            /* don't list directories */
647            case 'D':
648                conf.no_dirlists = 1;
649                break;
650
651            case 'R':
652                conf.rfc1918_filter = 1;
653                break;
654
605655#ifdef HAVE_CGI
606656            /* cgi prefix */
607657            case 'x':
...... 
678728                    " -K file ASN.1 server private key file\n"
679729#endif
680730                    " -h directory Specify the document root, default is '.'\n"
731                    " -E string Use given virtual URL as 404 error handler\n"
732                    " -I string Use given filename as index page for directories\n"
681733                    " -S Do not follow symbolic links outside of the docroot\n"
734                    " -D Do not allow directory listings, send 403 instead\n"
735                    " -R Enable RFC1918 filter\n"
682736#ifdef HAVE_LUA
683737                    " -l string URL prefix for Lua handler, default is '/lua'\n"
684738                    " -L file Lua handler script, omit to disable Lua\n"
...... 
727781        conf.realm = "Protected Area";
728782
729783    /* config file */
730    uh_config_parse(conf.file);
784    uh_config_parse(&conf);
731785
732786    /* default network timeout */
733787    if( conf.network_timeout <= 0 )
...... 
883937                    /* parse message header */
884938                    if( (req = uh_http_header_recv(cl)) != NULL )
885939                    {
940                        /* RFC1918 filtering required? */
941                        if( conf.rfc1918_filter && sa_rfc1918(&cl->peeraddr) &&
942                            !sa_rfc1918(&cl->servaddr) )
943                        {
944                            uh_http_sendhf(cl, 403, "Forbidden",
945                                "Rejected request from RFC1918 IP to public server address");
946                        }
947                        else
886948#ifdef HAVE_LUA
887949                        /* Lua request? */
888950                        if( L && uh_path_match(conf.lua_prefix, req->url) )
...... 
913975                        /* 404 */
914976                        else
915977                        {
916                            uh_http_sendhf(cl, 404, "Not Found",
917                                "No such file or directory");
978                            /* Try to invoke an error handler */
979                            pin = uh_path_lookup(cl, conf.error_handler);
980
981                            if( pin && uh_auth_check(cl, req, pin) )
982                            {
983                                req->redirect_status = 404;
984
985#ifdef HAVE_CGI
986                                if( uh_path_match(conf.cgi_prefix, pin->name) )
987                                {
988                                    uh_cgi_request(cl, req, pin);
989                                }
990                                else
991#endif
992                                {
993                                    uh_file_request(cl, req, pin);
994                                }
995                            }
996                            else
997                            {
998                                uh_http_sendhf(cl, 404, "Not Found",
999                                    "No such file or directory");
1000                            }
9181001                        }
9191002                    }
9201003
package/uhttpd/src/uhttpd.h
6464    char docroot[PATH_MAX];
6565    char *realm;
6666    char *file;
67    char *index_file;
68    char *error_handler;
6769    int no_symlinks;
70    int no_dirlists;
6871    int network_timeout;
72    int rfc1918_filter;
6973#ifdef HAVE_CGI
7074    char *cgi_prefix;
7175#endif
...... 
124128struct http_request {
125129    int method;
126130    float version;
131    int redirect_status;
127132    char *url;
128133    char *headers[UH_LIMIT_HEADERS];
129134    struct auth_realm *realm;

Archive Download the corresponding diff file



interactive