1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
|
Index: src/mod_staticfile.c
===================================================================
--- src/mod_staticfile.c (revision 2802)
+++ src/mod_staticfile.c (revision 2803)
@@ -26,6 +26,7 @@
typedef struct {
array *exclude_ext;
unsigned short etags_used;
+ unsigned short disable_pathinfo;
} plugin_config;
typedef struct {
@@ -84,6 +85,7 @@
config_values_t cv[] = {
{ "static-file.exclude-extensions", NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION }, /* 0 */
{ "static-file.etags", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 1 */
+ { "static-file.disable-pathinfo", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 2 */
{ NULL, NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET }
};
@@ -97,9 +99,11 @@
s = calloc(1, sizeof(plugin_config));
s->exclude_ext = array_init();
s->etags_used = 1;
+ s->disable_pathinfo = 0;
cv[0].destination = s->exclude_ext;
cv[1].destination = &(s->etags_used);
+ cv[2].destination = &(s->disable_pathinfo);
p->config_storage[i] = s;
@@ -119,6 +123,7 @@
PATCH(exclude_ext);
PATCH(etags_used);
+ PATCH(disable_pathinfo);
/* skip the first, the global context */
for (i = 1; i < srv->config_context->used; i++) {
@@ -136,7 +141,9 @@
PATCH(exclude_ext);
} else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.etags"))) {
PATCH(etags_used);
- }
+ } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("static-file.disable-pathinfo"))) {
+ PATCH(disable_pathinfo);
+ }
}
}
@@ -375,6 +382,13 @@
mod_staticfile_patch_connection(srv, con, p);
+ if (p->conf.disable_pathinfo && 0 != con->request.pathinfo->used) {
+ if (con->conf.log_request_handling) {
+ log_error_write(srv, __FILE__, __LINE__, "s", "-- NOT handling file as static file, pathinfo forbidden");
+ }
+ return HANDLER_GO_ON;
+ }
+
/* ignore certain extensions */
for (k = 0; k < p->conf.exclude_ext->used; k++) {
ds = (data_string *)p->conf.exclude_ext->data[k];
Index: tests/request.t
===================================================================
--- tests/request.t (revision 2802)
+++ tests/request.t (revision 2803)
@@ -8,7 +8,7 @@
use strict;
use IO::Socket;
-use Test::More tests => 44;
+use Test::More tests => 46;
use LightyTest;
my $tf = LightyTest->new();
@@ -413,5 +413,21 @@
$t->{SLOWREQUEST} = 1;
ok($tf->handle_http($t) == 0, 'GET, slow \\r\\n\\r\\n (#2105)');
+print "\nPathinfo for static files\n";
+$t->{REQUEST} = ( <<EOF
+GET /image.jpg/index.php HTTP/1.0
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 200, 'Content-Type' => 'image/jpeg' } ];
+ok($tf->handle_http($t) == 0, 'static file accepting pathinfo by default');
+
+$t->{REQUEST} = ( <<EOF
+GET /image.jpg/index.php HTTP/1.0
+Host: zzz.example.org
+EOF
+ );
+$t->{RESPONSE} = [ { 'HTTP-Protocol' => 'HTTP/1.0', 'HTTP-Status' => 403 } ];
+ok($tf->handle_http($t) == 0, 'static file with forbidden pathinfo');
+
ok($tf->stop_proc == 0, "Stopping lighttpd");
Index: tests/wrapper.sh
===================================================================
--- tests/wrapper.sh (revision 2802)
+++ tests/wrapper.sh (revision 2803)
@@ -6,4 +6,4 @@
top_builddir=$2
export SHELL srcdir top_builddir
-$3
+exec $3
Index: tests/lighttpd.conf
===================================================================
--- tests/lighttpd.conf (revision 2802)
+++ tests/lighttpd.conf (revision 2803)
@@ -149,6 +149,7 @@
$HTTP["host"] == "zzz.example.org" {
server.document-root = env.SRCDIR + "/tmp/lighttpd/servers/www.example.org/pages/"
server.name = "zzz.example.org"
+ static-file.disable-pathinfo = "enable"
}
$HTTP["host"] == "symlink.example.org" {
|