xref: /lighttpd1.4/src/t/test_mod_ssi.c (revision 96fd7e5d)
1 #include "first.h"
2 
3 #undef NDEBUG
4 #include <sys/types.h>
5 #include <assert.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <unistd.h>
9 
10 #include "mod_ssi.c"
11 #include "fdlog.h"
12 
test_mod_ssi_reset(request_st * const r,handler_ctx * const hctx)13 static void test_mod_ssi_reset (request_st * const r, handler_ctx * const hctx)
14 {
15     r->http_status = 0;
16     r->resp_htags = 0;
17     array_reset_data_strings(&r->resp_headers);
18     http_response_body_clear(r, 0);
19 
20     buffer_clear(hctx->timefmt);
21     array_reset_data_strings(hctx->ssi_vars);
22     array_reset_data_strings(hctx->ssi_cgi_env);
23 }
24 
test_mod_ssi_write_testfile(int fd,const char * buf,size_t len)25 static void test_mod_ssi_write_testfile (int fd, const char *buf, size_t len)
26 {
27     if (0 != lseek(fd, 0, SEEK_SET)
28         || (ssize_t)len != write(fd, buf, len)
29         || 0 != ftruncate(fd, (off_t)len)
30         || 0 != lseek(fd, 0, SEEK_SET)) {
31         perror("lseek(),ftruncate(),write()"); /*(unlikely: partial write)*/
32         exit(1);
33     }
34 }
35 
36 
37 static void
test_mod_ssi_read_fd(request_st * const r,handler_ctx * const hctx)38 test_mod_ssi_read_fd (request_st * const r, handler_ctx * const hctx)
39 {
40     /* TODO: add adjustments for _WIN32 */
41     char fn[] = "/tmp/lighttpd_mod_ssi_XXXXXX";
42     struct stat st;
43     chunkqueue * const cq = &r->write_queue;
44 
45     int fd = fdevent_mkostemp(fn, 0);
46     if (fd < 0) {
47         perror("mkstemp()");
48         exit(1);
49     }
50     if (0 != fstat(fd, &st)) {
51         perror("fstat()");
52         exit(1);
53     }
54     unlink(fn);
55 
56     const char ssi_simple[] =
57       "<!--#echo var=\"SCRIPT_NAME\" -->";
58     test_mod_ssi_write_testfile(fd, ssi_simple, sizeof(ssi_simple)-1);
59     test_mod_ssi_reset(r, hctx);
60     array_set_key_value(hctx->ssi_cgi_env,
61                         CONST_STR_LEN("SCRIPT_NAME"),
62                         CONST_STR_LEN("/ssi.shtml"));
63     mod_ssi_read_fd(r, hctx, &st, fd);
64     assert(cq->first);
65     assert(buffer_eq_slen(cq->first->mem,
66                           CONST_STR_LEN("/ssi.shtml")));
67 
68     hctx->conf.ssi_exec = 0; /* default */
69     const char ssi_exec[] =
70        "<!--#exec cmd=\"expr 1 + 1\"-->";
71     test_mod_ssi_write_testfile(fd, ssi_exec, sizeof(ssi_exec)-1);
72     test_mod_ssi_reset(r, hctx);
73     mod_ssi_read_fd(r, hctx, &st, fd);
74     assert(NULL == cq->first);
75 
76     hctx->conf.ssi_exec = 1;
77     test_mod_ssi_write_testfile(fd, ssi_exec, sizeof(ssi_exec)-1);
78     test_mod_ssi_reset(r, hctx);
79     mod_ssi_read_fd(r, hctx, &st, fd);
80     assert(cq->first);
81     assert(cq->first->type == FILE_CHUNK);
82     assert(2 == chunkqueue_length(cq));
83     char buf[80];
84     if (0 != lseek(cq->first->file.fd, 0, SEEK_SET)
85         || 2 != read(cq->first->file.fd, buf, sizeof(buf))) {
86         perror("lseek(),read()");
87         exit(1);
88     }
89     assert(0 == memcmp(buf, "2\n", 2));
90     hctx->conf.ssi_exec = 0;
91 
92     char fni[] = "/tmp/lighttpd_mod_ssi_inc_XXXXXX";
93     int fdi = fdevent_mkostemp(fni, 0);
94     if (fdi < 0) {
95         perror("mkstemp()");
96         exit(1);
97     }
98     const char ssi_include[] =
99        "ssi-include";
100     test_mod_ssi_write_testfile(fdi, ssi_include, sizeof(ssi_include)-1);
101     close(fdi);
102 
103     const char ssi_include_shtml[] =
104       "<!--#echo var=SCRIPT_NAME-->\n"
105       "<!--#echo var='SCRIPT_NAME'-->\n"
106       "<!--#echo var=\"SCRIPT_NAME\"-->\n";
107     buffer * const b = buffer_init();
108     buffer_copy_string_len(b, CONST_STR_LEN(ssi_include_shtml));
109     buffer_append_str3(b, CONST_STR_LEN("<!--#include virtual=\""),
110                           fni+5, strlen(fni)-5, /*(step over "/tmp/")*/
111                           CONST_STR_LEN("\" -->\n"));
112     buffer_append_str3(b, CONST_STR_LEN("<!--#include file=\""),
113                           fni+5, strlen(fni)-5, /*(step over "/tmp/")*/
114                           CONST_STR_LEN("\" -->\n"));
115     test_mod_ssi_write_testfile(fd, BUF_PTR_LEN(b));
116     buffer_free(b);
117     test_mod_ssi_reset(r, hctx);
118     array_set_key_value(hctx->ssi_cgi_env,
119                         CONST_STR_LEN("SCRIPT_NAME"),
120                         CONST_STR_LEN("/ssi-include.shtml"));
121     buffer_copy_string_len(&r->physical.doc_root, CONST_STR_LEN("/tmp"));
122     buffer_copy_string_len(&r->uri.path, CONST_STR_LEN("/ssi-include.shtml"));
123     buffer_copy_string_len(&r->physical.rel_path, CONST_STR_LEN("/ssi-include.shtml"));
124     buffer_copy_string_len(&r->physical.path, CONST_STR_LEN("/tmp/ssi-include.shtml"));
125     mod_ssi_read_fd(r, hctx, &st, fd);
126     chunkqueue_read_squash(cq, r->conf.errh);
127     assert(buffer_eq_slen(cq->first->mem,
128                           CONST_STR_LEN("/ssi-include.shtml\n"
129                                         "/ssi-include.shtml\n"
130                                         "/ssi-include.shtml\n"
131                                         "ssi-include\n"
132                                         "ssi-include\n")));
133 
134     unlink(fni);
135 
136     test_mod_ssi_reset(r, hctx);
137     close(fd);
138 }
139 
140 void test_mod_ssi (void);
test_mod_ssi(void)141 void test_mod_ssi (void)
142 {
143     plugin_data * const p = mod_ssi_init();
144     assert(NULL != p);
145 
146     request_st r;
147 
148     memset(&r, 0, sizeof(request_st));
149     r.tmp_buf                = buffer_init();
150     r.conf.errh              = fdlog_init(NULL, -1, FDLOG_FD);
151     r.conf.errh->fd          = -1; /* (disable) */
152     r.conf.follow_symlink    = 1;
153 
154     handler_ctx * const hctx = handler_ctx_init(p, r.conf.errh);
155     assert(NULL != hctx);
156 
157     test_mod_ssi_read_fd(&r, hctx);
158 
159     handler_ctx_free(hctx);
160 
161     fdlog_free(r.conf.errh);
162     buffer_free(r.tmp_buf);
163     chunkqueue_reset(&r.write_queue);
164 
165     free(r.uri.path.ptr);
166     free(r.physical.path.ptr);
167     free(r.physical.rel_path.ptr);
168     free(r.physical.doc_root.ptr);
169 
170     mod_ssi_free(p);
171     free(p);
172     stat_cache_free();
173 }
174