Date:2010-08-12 01:44:30 (2 years 9 months ago)
Author:jow
Commit:01658f6e25197d603a1fcd0c14eda097316bf5a2
Message:[package] uhttpd:

- abort file serving if client connection is lost (#7742)
- don't send bad request headers twice


git-svn-id: svn://svn.openwrt.org/openwrt/trunk@22602 3c298f89-4303-0410-b956-a3cf2f4a3e73
Files: package/uhttpd/Makefile (1 diff)
package/uhttpd/src/uhttpd-file.c (8 diffs)
package/uhttpd/src/uhttpd.c (1 diff)

Change Details

package/uhttpd/Makefile
88include $(TOPDIR)/rules.mk
99
1010PKG_NAME:=uhttpd
11PKG_RELEASE:=13
11PKG_RELEASE:=14
1212
1313PKG_BUILD_DIR := $(BUILD_DIR)/$(PKG_NAME)
1414PKG_BUILD_DEPENDS := libcyassl liblua
package/uhttpd/src/uhttpd-file.c
9797    return NULL;
9898}
9999
100#define ensure_ret(x) \
101    do { if( x < 0 ) return; } while(0)
102
100103static void uh_file_response_ok_hdrs(struct client *cl, struct http_request *req, struct stat *s)
101104{
102    uh_http_sendf(cl, NULL, "Connection: close\r\n");
105    ensure_ret(uh_http_sendf(cl, NULL, "Connection: close\r\n"));
103106
104107    if( s )
105108    {
106        uh_http_sendf(cl, NULL, "ETag: %s\r\n", uh_file_mktag(s));
107        uh_http_sendf(cl, NULL, "Last-Modified: %s\r\n", uh_file_unix2date(s->st_mtime));
109        ensure_ret(uh_http_sendf(cl, NULL, "ETag: %s\r\n", uh_file_mktag(s)));
110        ensure_ret(uh_http_sendf(cl, NULL, "Last-Modified: %s\r\n", uh_file_unix2date(s->st_mtime)));
108111    }
109112
110    uh_http_sendf(cl, NULL, "Date: %s\r\n", uh_file_unix2date(time(NULL)));
113    ensure_ret(uh_http_sendf(cl, NULL, "Date: %s\r\n", uh_file_unix2date(time(NULL))));
111114}
112115
113116static void uh_file_response_200(struct client *cl, struct http_request *req, struct stat *s)
114117{
115    uh_http_sendf(cl, NULL, "HTTP/%.1f 200 OK\r\n", req->version);
118    ensure_ret(uh_http_sendf(cl, NULL, "HTTP/%.1f 200 OK\r\n", req->version));
116119    uh_file_response_ok_hdrs(cl, req, s);
117120}
118121
119122static void uh_file_response_304(struct client *cl, struct http_request *req, struct stat *s)
120123{
121    uh_http_sendf(cl, NULL, "HTTP/%.1f 304 Not Modified\r\n", req->version);
124    ensure_ret(uh_http_sendf(cl, NULL, "HTTP/%.1f 304 Not Modified\r\n", req->version));
122125    uh_file_response_ok_hdrs(cl, req, s);
123126}
124127
125128static void uh_file_response_412(struct client *cl, struct http_request *req)
126129{
127    uh_http_sendf(cl, NULL,
130    ensure_ret(uh_http_sendf(cl, NULL,
128131        "HTTP/%.1f 412 Precondition Failed\r\n"
129        "Connection: close\r\n", req->version);
132        "Connection: close\r\n", req->version));
130133}
131134
132135static int uh_file_if_match(struct client *cl, struct http_request *req, struct stat *s)
...... 
244247}
245248
246249
250#define ensure_out(x) \
251    do { if( x < 0 ) goto out; } while(0)
252
247253static int uh_file_scandir_filter_dir(const struct dirent *e)
248254{
249255    return strcmp(e->d_name, ".") ? 1 : 0;
...... 
251257
252258static void uh_file_dirlist(struct client *cl, struct http_request *req, struct path_info *pi)
253259{
254    int i, count;
260    int i;
261    int count = 0;
255262    char filename[PATH_MAX];
256263    char *pathptr;
257264    struct dirent **files = NULL;
258265    struct stat s;
259266
260    uh_http_sendf(cl, req,
267    ensure_out(uh_http_sendf(cl, req,
261268        "<html><head><title>Index of %s</title></head>"
262269        "<body><h1>Index of %s</h1><hr /><ol>",
263270            pi->name, pi->name
264    );
271    ));
265272
266273    if( (count = scandir(pi->phys, &files, uh_file_scandir_filter_dir, alphasort)) > 0 )
267274    {
...... 
278285            if( !stat(filename, &s) &&
279286                (s.st_mode & S_IFDIR) && (s.st_mode & S_IXOTH)
280287            )
281                uh_http_sendf(cl, req,
288                ensure_out(uh_http_sendf(cl, req,
282289                    "<li><strong><a href='%s%s'>%s</a>/</strong><br />"
283290                    "<small>modified: %s<br />directory - %.02f kbyte"
284291                    "<br /><br /></small></li>",
285292                        pi->name, files[i]->d_name, files[i]->d_name,
286293                        uh_file_unix2date(s.st_mtime), s.st_size / 1024.0
287                );
294                ));
288295
289296            *pathptr = 0;
290297        }
...... 
298305            if( !stat(filename, &s) &&
299306                !(s.st_mode & S_IFDIR) && (s.st_mode & S_IROTH)
300307            )
301                uh_http_sendf(cl, req,
308                ensure_out(uh_http_sendf(cl, req,
302309                    "<li><strong><a href='%s%s'>%s</a></strong><br />"
303310                    "<small>modified: %s<br />%s - %.02f kbyte<br />"
304311                    "<br /></small></li>",
305312                        pi->name, files[i]->d_name, files[i]->d_name,
306313                        uh_file_unix2date(s.st_mtime),
307314                        uh_file_mime_lookup(filename), s.st_size / 1024.0
308                );
315                ));
309316
310317            *pathptr = 0;
311            free(files[i]);
312318        }
313319    }
314320
315    free(files);
321    ensure_out(uh_http_sendf(cl, req, "</ol><hr /></body></html>"));
322    ensure_out(uh_http_sendf(cl, req, ""));
323
324out:
325    if( files )
326    {
327        for( i = 0; i < count; i++ )
328            free(files[i]);
316329
317    uh_http_sendf(cl, req, "</ol><hr /></body></html>");
318    uh_http_sendf(cl, req, "");
330        free(files);
331    }
319332}
320333
321334
322335void uh_file_request(struct client *cl, struct http_request *req, struct path_info *pi)
323336{
324    int fd, rlen;
337    int rlen;
338    int fd = -1;
325339    char buf[UH_LIMIT_MSGHEAD];
326340
327341    /* we have a file */
...... 
338352            /* write status */
339353            uh_file_response_200(cl, req, &pi->stat);
340354
341            uh_http_sendf(cl, NULL, "Content-Type: %s\r\n", uh_file_mime_lookup(pi->name));
342            uh_http_sendf(cl, NULL, "Content-Length: %i\r\n", pi->stat.st_size);
355            ensure_out(uh_http_sendf(cl, NULL, "Content-Type: %s\r\n", uh_file_mime_lookup(pi->name)));
356            ensure_out(uh_http_sendf(cl, NULL, "Content-Length: %i\r\n", pi->stat.st_size));
343357
344358            /* if request was HTTP 1.1 we'll respond chunked */
345359            if( (req->version > 1.0) && (req->method != UH_HTTP_MSG_HEAD) )
346                uh_http_send(cl, NULL, "Transfer-Encoding: chunked\r\n", -1);
360                ensure_out(uh_http_send(cl, NULL, "Transfer-Encoding: chunked\r\n", -1));
347361
348362            /* close header */
349            uh_http_send(cl, NULL, "\r\n", -1);
363            ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
350364
351365            /* send body */
352366            if( req->method != UH_HTTP_MSG_HEAD )
353367            {
354368                /* pump file data */
355369                while( (rlen = read(fd, buf, sizeof(buf))) > 0 )
356                {
357                    if( uh_http_send(cl, req, buf, rlen) < 0 )
358                        break;
359                }
370                    ensure_out(uh_http_send(cl, req, buf, rlen));
360371
361372                /* send trailer in chunked mode */
362                uh_http_send(cl, req, "", 0);
373                ensure_out(uh_http_send(cl, req, "", 0));
363374            }
364375        }
365376
366377        /* one of the preconditions failed, terminate opened header and exit */
367378        else
368379        {
369            uh_http_send(cl, NULL, "\r\n", -1);
380            ensure_out(uh_http_send(cl, NULL, "\r\n", -1));
370381        }
371
372        close(fd);
373382    }
374383
375384    /* directory */
...... 
379388        uh_file_response_200(cl, req, NULL);
380389
381390        if( req->version > 1.0 )
382            uh_http_send(cl, NULL, "Transfer-Encoding: chunked\r\n", -1);
391            ensure_out(uh_http_send(cl, NULL, "Transfer-Encoding: chunked\r\n", -1));
383392
384        uh_http_send(cl, NULL, "Content-Type: text/html\r\n\r\n", -1);
393        ensure_out(uh_http_send(cl, NULL, "Content-Type: text/html\r\n\r\n", -1));
385394
386395        /* content */
387396        uh_file_dirlist(cl, req, pi);
...... 
390399    /* 403 */
391400    else
392401    {
393        uh_http_sendhf(cl, 403, "Forbidden",
394            "Access to this resource is forbidden");
402        ensure_out(uh_http_sendhf(cl, 403, "Forbidden",
403            "Access to this resource is forbidden"));
395404    }
405
406out:
407    if( fd > -1 )
408        close(fd);
396409}
397410
package/uhttpd/src/uhttpd.c
10011001                        }
10021002                    }
10031003
1004                    /* 400 */
1005                    else
1006                    {
1007                        uh_http_sendhf(cl, 400, "Bad Request",
1008                            "Malformed request received");
1009                    }
1010
10111004#ifdef HAVE_TLS
10121005                    /* free client tls context */
10131006                    if( conf.tls )

Archive Download the corresponding diff file



interactive