/* ** Copyright 2003-2005 The Apache Software Foundation ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include "apreq_param.h" #include "apreq_util.h" #include "apreq_error.h" #include "apr_strings.h" #include "at.h" static const char query_string[] = "a=1;quux=foo+bar&a=2&plus=%2B;" "uplus=%U002b;okie=dokie;" "novalue1;novalue2="; static apr_table_t *args; static apr_pool_t *p; static void request_make(dAT) { apr_status_t s; args = apr_table_make(p, APREQ_DEFAULT_NELTS); AT_not_null(args); s = apreq_parse_query_string(p, args, query_string); AT_int_eq(s, APR_SUCCESS); AT_int_eq(apr_table_elts(args)->nelts, 8); } static void request_args_get(dAT) { const char *val; const apreq_param_t *param; AT_str_eq(apr_table_get(args,"a"), "1"); val = apr_table_get(args,"quux"); AT_str_eq(val, "foo bar"); param = apreq_value_to_param(val); AT_int_eq(param->v.dlen, 7); AT_str_eq(apr_table_get(args,"plus"), "+"); AT_str_eq(apr_table_get(args,"uplus"), "+"); AT_str_eq(apr_table_get(args,"okie"), "dokie"); AT_str_eq(apr_table_get(args,"novalue1"), ""); AT_str_eq(apr_table_get(args,"novalue2"),""); } static void params_as(dAT) { const char *val; apr_array_header_t *arr; arr = apreq_params_as_array(p,args,"a"); AT_int_eq(arr->nelts, 2); val = apreq_params_as_string(p,args,"a",APREQ_JOIN_AS_IS); AT_str_eq(val, "1, 2"); val = apreq_params_as_string(p,args,"does_not_exist",APREQ_JOIN_AS_IS); AT_str_eq(val, ""); } static void string_decoding_in_place(dAT) { char *s1 = apr_palloc(p,4096); char *s2 = apr_palloc(p,4096); char *s3; strcpy(s1, "bend it like beckham"); strcpy(s2, "dandy %3Edons"); AT_str_eq(s1,"bend it like beckham"); apreq_unescape(s1); AT_str_eq(s1, "bend it like beckham"); s3 = apreq_escape(p, s1, 20); AT_str_eq(s3, "bend+it+like+beckham"); apreq_unescape(s3); AT_str_eq(s3,"bend it like beckham"); AT_str_eq(s2,"dandy %3Edons"); apreq_unescape(s2); AT_str_eq(s2,"dandy >dons"); s3 = apreq_escape(p, s2, 11); AT_str_eq(s3,"dandy+%3Edons"); apreq_unescape(s3); AT_str_eq(s3,"dandy >dons"); } static void header_attributes(dAT) { const char *hdr = "text/plain; boundary=\"-foo-\", charset=ISO-8859-1"; const char *val; apr_size_t vlen; apr_status_t s; s = apreq_header_attribute(hdr, "none", 4, &val, &vlen); AT_int_eq(s, APREQ_ERROR_NOATTR); s = apreq_header_attribute(hdr, "set", 3, &val, &vlen); AT_int_eq(s, APREQ_ERROR_NOATTR); s = apreq_header_attribute(hdr, "boundary", 8, &val, &vlen); AT_int_eq(s, APR_SUCCESS); AT_int_eq(vlen, 5); AT_mem_eq(val, "-foo-", 5); s = apreq_header_attribute(hdr, "charset", 7, &val, &vlen); AT_int_eq(s, APR_SUCCESS); AT_int_eq(vlen, 10); AT_mem_eq(val, "ISO-8859-1", 10); hdr = "max-age=20; no-quote=\"..."; s = apreq_header_attribute(hdr, "max-age", 7, &val, &vlen); AT_int_eq(s, APR_SUCCESS); AT_int_eq(vlen, 2); AT_mem_eq(val, "20", 2); s = apreq_header_attribute(hdr, "age", 3, &val, &vlen); AT_int_eq(s, APREQ_ERROR_BADSEQ); s = apreq_header_attribute(hdr, "no-quote", 8, &val, &vlen); AT_int_eq(s, APREQ_ERROR_BADSEQ); } static void make_param(dAT) { apreq_param_t *param, *decode; apr_status_t s; apr_size_t nlen = 3, vlen = 11; char *name = apr_palloc(p,nlen+1); char *val = apr_palloc(p,vlen+1); char *encode; strcpy(name, "foo"); strcpy(val, "bar > alpha"); param = apreq_param_make(p, name, nlen, val, vlen); AT_str_eq(param->v.name, name); AT_int_eq(param->v.dlen, vlen); AT_str_eq(param->v.data, val); encode = apreq_param_encode(p, param); AT_str_eq(encode, "foo=bar+%3E+alpha"); s = apreq_param_decode(&decode, p, encode, nlen, vlen+2); AT_int_eq(s, APR_SUCCESS); AT_str_eq(decode->v.name, name); AT_int_eq(decode->v.dlen, vlen); AT_str_eq(decode->v.data, val); } static void quote_strings(dAT) { apr_size_t exp_len, res_len, res_quote_len; char *res = apr_palloc(p,24); char *res_quote = apr_palloc(p,24); const char *expr; int i; const char * arr[] = {"cest", "\"cest", "ce\"st", "\"cest\""}; const char * arr_quote[] = {"\"cest\"", "\"\\\"cest\"", "\"ce\\\"st\"", "\"\\\"cest\\\"\""}; apr_size_t arr_len[] = {4, 5, 5, 6}; apr_size_t arr_quote_len[] = {6, 8, 8, 10}; for (i=0; i<4; i++) { res_len = apreq_quote(res, arr[i], arr_len[i]); AT_int_eq(res_len, arr_quote_len[i]); AT_mem_eq(res, arr_quote[i], res_len); res_quote_len = apreq_quote_once(res_quote, res, res_len); AT_int_eq(res_quote_len, res_len); AT_mem_eq(res_quote, res, res_len); res_len = apreq_quote_once(res, arr[i], arr_len[i]); exp_len = (i == 3) ? arr_len[i] : arr_quote_len[i]; expr = (i == 3) ? arr[i] : arr_quote[i]; AT_int_eq(res_len, exp_len); AT_mem_eq(res, expr, exp_len); } } #define dT(func, plan) {#func, func, plan} int main(int argc, char *argv[]) { unsigned i, plan = 0; dAT; at_test_t test_list [] = { dT(request_make, 3), dT(request_args_get, 8), dT(params_as, 3), dT(string_decoding_in_place, 8), dT(header_attributes, 13), dT(make_param, 8), dT(quote_strings, 24), }; apr_initialize(); atexit(apr_terminate); apr_pool_create(&p, NULL); apreq_initialize(p); AT = at_create(p, 0, at_report_stdout_make(p)); AT_trace_on(); for (i = 0; i < sizeof(test_list) / sizeof(at_test_t); ++i) plan += test_list[i].plan; AT_begin(plan); for (i = 0; i < sizeof(test_list) / sizeof(at_test_t); ++i) AT_run(&test_list[i]); AT_end(); return 0; }