1 #include "first.h"
2
3 #undef NDEBUG
4 #include <assert.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7
8 #include "keyvalue.c"
9
10 #include "base.h" /* struct server */
11 #include "plugin_config.h" /* struct cond_match_t */
12 #include "fdlog.h" /* struct fdlog_st */
13
14 #ifdef HAVE_PCRE_H
test_keyvalue_test_kvb_init(void)15 static pcre_keyvalue_buffer * test_keyvalue_test_kvb_init (void) {
16 pcre_keyvalue_buffer *kvb = pcre_keyvalue_buffer_init();
17
18 fdlog_st * const errh = fdlog_init(NULL, -1, FDLOG_FD);
19
20 /* strings must be persistent for pcre_keyvalue_buffer_append() */
21 static const buffer kvstr[] = {
22 { "^/foo($|\\?.+)", sizeof("^/foo($|\\?.+)"), 0 },
23 { "/foo/$1", sizeof("/foo/$1"), 0 },
24 { "^/bar(?:$|\\?(.+))", sizeof("^/bar(?:$|\\?(.+))"), 0 },
25 { "/?bar&$1", sizeof("/?bar&$1"), 0 },
26 { "^/redirect(?:\\?(.*))?$", sizeof("^/redirect(?:\\?(.*))?$"), 0 },
27 { "/?seg=%1&$1", sizeof("/?seg=%1&$1"), 0 },
28 { "^(/[^?]*)(?:\\?(.*))?$", sizeof("^(/[^?]*)(?:\\?(.*))?$"), 0 },
29 { "/?file=$1&$2", sizeof("/?file=$1&$2"), 0 }
30 };
31
32 assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+0, kvstr+1, 1));
33 assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+2, kvstr+3, 1));
34 assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+4, kvstr+5, 1));
35 assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+6, kvstr+7, 1));
36
37 fdlog_free(errh);
38
39 return kvb;
40 }
41
test_keyvalue_pcre_keyvalue_buffer_process(void)42 static void test_keyvalue_pcre_keyvalue_buffer_process (void) {
43 pcre_keyvalue_buffer *kvb = test_keyvalue_test_kvb_init();
44 buffer *url = buffer_init();
45 buffer *result = buffer_init();
46 struct burl_parts_t burl;
47 cond_match_t cache;
48 pcre_keyvalue_ctx ctx;
49 handler_t rc;
50 buffer *scheme = buffer_init();
51 buffer *authority = buffer_init();
52 buffer *path = buffer_init();
53 buffer *query = buffer_init();
54
55 ctx.burl = &burl;
56 burl.scheme = scheme;
57 burl.authority = authority;
58 burl.port = 80;
59 burl.path = path;
60 burl.query = query;
61 buffer_copy_string_len(scheme, CONST_STR_LEN("http"));
62 buffer_copy_string_len(authority, CONST_STR_LEN("www.example.com"));
63 /* model outer conditional match of $HTTP["host"] =~ "^(www).example.com$" */
64 ctx.cache = &cache;
65 memset(&cache, 0, sizeof(cache));
66 cache.comp_value = authority;
67 cache.captures = 2;
68 #ifdef HAVE_PCRE2_H
69 PCRE2_SIZE matches[4];
70 #else /* HAVE_PCRE_H */
71 int matches[4];
72 #endif
73 matches[0] = 0;
74 matches[1] = 15;
75 matches[2] = 0;
76 matches[3] = 3;
77 cache.matches = matches;
78
79 /* converted from prior sparse tests/mod-redirect.t and tests/mod-rewrite.t
80 * (real-world use should prefer ${url.path} and ${qsa} in substitutions)
81 */
82
83 buffer_copy_string_len(url, CONST_STR_LEN("/foo"));
84 buffer_copy_string_len(path, CONST_STR_LEN("/foo"));
85 buffer_clear(query);
86 rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
87 assert(HANDLER_FINISHED == rc);
88 assert(buffer_eq_slen(result, CONST_STR_LEN("/foo/")));
89
90 buffer_copy_string_len(url, CONST_STR_LEN("/foo?a=b"));
91 buffer_copy_string_len(path, CONST_STR_LEN("/foo"));
92 buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
93 rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
94 assert(HANDLER_FINISHED == rc);
95 assert(buffer_eq_slen(result, CONST_STR_LEN("/foo/?a=b")));
96
97 buffer_copy_string_len(url, CONST_STR_LEN("/bar?a=b"));
98 buffer_copy_string_len(path, CONST_STR_LEN("/bar"));
99 buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
100 rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
101 assert(HANDLER_FINISHED == rc);
102 assert(buffer_eq_slen(result, CONST_STR_LEN("/?bar&a=b")));
103
104 buffer_copy_string_len(url, CONST_STR_LEN("/nofile?a=b"));
105 buffer_copy_string_len(path, CONST_STR_LEN("/nofile"));
106 buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
107 rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
108 assert(HANDLER_FINISHED == rc);
109 assert(buffer_eq_slen(result, CONST_STR_LEN("/?file=/nofile&a=b")));
110
111 buffer_copy_string_len(url, CONST_STR_LEN("/redirect?a=b"));
112 buffer_copy_string_len(path, CONST_STR_LEN("/redirect"));
113 buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
114 rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
115 assert(HANDLER_FINISHED == rc);
116 assert(buffer_eq_slen(result, CONST_STR_LEN("/?seg=www&a=b")));
117
118 buffer_free(url);
119 buffer_free(result);
120 buffer_free(scheme);
121 buffer_free(authority);
122 buffer_free(path);
123 buffer_free(query);
124 pcre_keyvalue_buffer_free(kvb);
125 }
126 #endif
127
128 void test_keyvalue (void);
test_keyvalue(void)129 void test_keyvalue (void)
130 {
131 #ifdef HAVE_PCRE_H
132 test_keyvalue_pcre_keyvalue_buffer_process();
133 #endif
134 }
135