summaryrefslogtreecommitdiff
path: root/src/t/test_keyvalue.c
blob: 0c63e437b6158ec2b14d758849bd50d0f865e361 (plain)
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
123
124
125
126
127
128
129
130
131
132
133
134
#include "first.h"

#undef NDEBUG
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>

#include "keyvalue.c"

#include "base.h"   /* struct server */
#include "plugin_config.h" /* struct cond_match_t */
#include "fdlog.h"  /* struct fdlog_st */

#ifdef HAVE_PCRE_H
static pcre_keyvalue_buffer * test_keyvalue_test_kvb_init (void) {
    pcre_keyvalue_buffer *kvb = pcre_keyvalue_buffer_init();

    fdlog_st * const errh = fdlog_init(NULL, -1, FDLOG_FD);

    /* strings must be persistent for pcre_keyvalue_buffer_append() */
    static const buffer kvstr[] = {
      { "^/foo($|\\?.+)",          sizeof("^/foo($|\\?.+)"), 0 },
      { "/foo/$1",                 sizeof("/foo/$1"), 0 },
      { "^/bar(?:$|\\?(.+))",      sizeof("^/bar(?:$|\\?(.+))"), 0 },
      { "/?bar&$1",                sizeof("/?bar&$1"), 0 },
      { "^/redirect(?:\\?(.*))?$", sizeof("^/redirect(?:\\?(.*))?$"), 0 },
      { "/?seg=%1&$1",             sizeof("/?seg=%1&$1"), 0 },
      { "^(/[^?]*)(?:\\?(.*))?$",  sizeof("^(/[^?]*)(?:\\?(.*))?$"), 0 },
      { "/?file=$1&$2",            sizeof("/?file=$1&$2"), 0 }
    };

    assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+0, kvstr+1, 1));
    assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+2, kvstr+3, 1));
    assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+4, kvstr+5, 1));
    assert(pcre_keyvalue_buffer_append(errh, kvb, kvstr+6, kvstr+7, 1));

    fdlog_free(errh);

    return kvb;
}

static void test_keyvalue_pcre_keyvalue_buffer_process (void) {
    pcre_keyvalue_buffer *kvb = test_keyvalue_test_kvb_init();
    buffer *url = buffer_init();
    buffer *result = buffer_init();
    struct burl_parts_t burl;
    cond_match_t cache;
    pcre_keyvalue_ctx ctx;
    handler_t rc;
    buffer *scheme    = buffer_init();
    buffer *authority = buffer_init();
    buffer *path      = buffer_init();
    buffer *query     = buffer_init();

    ctx.burl = &burl;
    burl.scheme    = scheme;
    burl.authority = authority;
    burl.port      = 80;
    burl.path      = path;
    burl.query     = query;
    buffer_copy_string_len(scheme, CONST_STR_LEN("http"));
    buffer_copy_string_len(authority, CONST_STR_LEN("www.example.com"));
    /* model outer conditional match of $HTTP["host"] =~ "^(www).example.com$" */
    ctx.cache = &cache;
    memset(&cache, 0, sizeof(cache));
    cache.comp_value = authority;
    cache.captures = 2;
  #ifdef HAVE_PCRE2_H
    PCRE2_SIZE matches[4];
  #else /* HAVE_PCRE_H */
    int matches[4];
  #endif
    matches[0] = 0;
    matches[1] = 15;
    matches[2] = 0;
    matches[3] = 3;
    cache.matches = matches;

    /* converted from prior sparse tests/mod-redirect.t and tests/mod-rewrite.t
     * (real-world use should prefer ${url.path} and ${qsa} in substitutions)
     */

    buffer_copy_string_len(url, CONST_STR_LEN("/foo"));
    buffer_copy_string_len(path, CONST_STR_LEN("/foo"));
    buffer_clear(query);
    rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
    assert(HANDLER_FINISHED == rc);
    assert(buffer_eq_slen(result, CONST_STR_LEN("/foo/")));

    buffer_copy_string_len(url, CONST_STR_LEN("/foo?a=b"));
    buffer_copy_string_len(path, CONST_STR_LEN("/foo"));
    buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
    rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
    assert(HANDLER_FINISHED == rc);
    assert(buffer_eq_slen(result, CONST_STR_LEN("/foo/?a=b")));

    buffer_copy_string_len(url, CONST_STR_LEN("/bar?a=b"));
    buffer_copy_string_len(path, CONST_STR_LEN("/bar"));
    buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
    rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
    assert(HANDLER_FINISHED == rc);
    assert(buffer_eq_slen(result, CONST_STR_LEN("/?bar&a=b")));

    buffer_copy_string_len(url, CONST_STR_LEN("/nofile?a=b"));
    buffer_copy_string_len(path, CONST_STR_LEN("/nofile"));
    buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
    rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
    assert(HANDLER_FINISHED == rc);
    assert(buffer_eq_slen(result, CONST_STR_LEN("/?file=/nofile&a=b")));

    buffer_copy_string_len(url, CONST_STR_LEN("/redirect?a=b"));
    buffer_copy_string_len(path, CONST_STR_LEN("/redirect"));
    buffer_copy_string_len(query, CONST_STR_LEN("a=b"));
    rc = pcre_keyvalue_buffer_process(kvb, &ctx, url, result);
    assert(HANDLER_FINISHED == rc);
    assert(buffer_eq_slen(result, CONST_STR_LEN("/?seg=www&a=b")));

    buffer_free(url);
    buffer_free(result);
    buffer_free(scheme);
    buffer_free(authority);
    buffer_free(path);
    buffer_free(query);
    pcre_keyvalue_buffer_free(kvb);
}
#endif

void test_keyvalue (void);
void test_keyvalue (void)
{
  #ifdef HAVE_PCRE_H
    test_keyvalue_pcre_keyvalue_buffer_process();
  #endif
}