📄 test_http.c
字号:
/* * This file is part of the Sofia-SIP package * * Copyright (C) 2005 Nokia Corporation. * * Contact: Pekka Pessi <pekka.pessi@nokia.com> * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA * *//**@CFILE test_http.c * * Testing functions for HTTP parser. * * @author Pekka Pessi <Pekka.Pessi@nokia.com> * * @date Created: Tue Mar 6 18:33:42 2001 ppessi */#include "config.h"#include <stdio.h>#include <string.h>#include <stddef.h>#include <assert.h>#include <sofia-sip/su.h>#include <sofia-sip/su_types.h>#include <sofia-sip/su_tag.h>#include <sofia-sip/su_tag_class.h>#include <sofia-sip/su_tag_io.h>#include <sofia-sip/http_parser.h>#include <sofia-sip/http_tag.h>#include <sofia-sip/url_tag.h>#include <sofia-sip/http_header.h>#include <sofia-sip/msg_addr.h>#define TSTFLAGS tstflags#include <sofia-sip/tstdef.h>char const *name = "test_http";static int tag_test(void);static int tag_test2(void);static int http_header_handling_test(void);static int http_header_test(void);static int http_parser_test(void);static int test_http_encoding(void);static int http_chunk_test(void);static int http_tag_test(void);static int test_query_parser(void);static msg_t *read_message(char const string[]);msg_mclass_t *test_mclass = NULL;void usage(void){ fprintf(stderr, "usage: %s [-v]\n", name);}char *lastpart(char *path){ if (strchr(path, '/')) return strrchr(path, '/') + 1; else return path;}int tstflags;int main(int argc, char *argv[]){ int retval = 0; int i; name = lastpart(argv[0]); /* Set our name */ for (i = 1; argv[i]; i++) { if (strcmp(argv[i], "-v") == 0) tstflags |= tst_verbatim; else usage(); } if (!test_mclass) test_mclass = http_default_mclass(); retval |= tag_test(); fflush(stdout); retval |= tag_test2(); fflush(stdout); retval |= http_header_handling_test(); fflush(stdout); retval |= http_header_test(); fflush(stdout); retval |= http_tag_test(); fflush(stdout); retval |= http_parser_test(); fflush(stdout); retval |= test_http_encoding(); fflush(stdout); retval |= http_chunk_test(); fflush(stdout); retval |= test_query_parser(); fflush(stdout); return retval;}msg_t *read_message(char const buffer[]){ int i, n, m; msg_t *msg; msg_iovec_t iovec[2]; n = strlen(buffer); if (n == 0) return NULL; msg = msg_create(test_mclass, MSG_DO_EXTRACT_COPY); for (i = 0; i < n;) { if (msg_recv_iovec(msg, iovec, 2, 10, 0) < 0) { perror("msg_recv_iovec"); return NULL; } *(char *)(iovec->mv_base) = buffer[i++]; msg_recv_commit(msg, 1, i == n); m = msg_extract(msg); if (m < 0) { fprintf(stderr, "test_http: parsing error\n"); return NULL; } if (m > 0) break; } if (i != n) { fprintf(stderr, "test_http: parser error (len=%u, read=%u)\n", n, i); msg_destroy(msg), msg = NULL; } return msg;}/* Read message byte-by-byte */msg_t *read_message_byte_by_byte(char const buffer[]){ int i, n, m; msg_t *msg; msg_iovec_t iovec[msg_n_fragments]; n = strlen(buffer); if (n == 0) return NULL; msg = msg_create(test_mclass, MSG_DO_EXTRACT_COPY); for (i = 0; i < n;) { /* This prevent msg_recv_iovec() from allocating extra slack */ int msg_buf_exact(msg_t *, int); msg_buf_exact(msg, 10 + 1); if (msg_recv_iovec(msg, iovec, msg_n_fragments, 10, 0) < 0) { perror("msg_recv_iovec"); return NULL; } assert(iovec->mv_len > 0); *(char *)(iovec->mv_base) = buffer[i++]; msg_recv_commit(msg, 1, i == n); m = msg_extract(msg); if (m < 0) { fprintf(stderr, "test_http: parsing error\n"); return NULL; } if (m > 0) break; } if (i != n) { fprintf(stderr, "test_http: parser error (len=%u, read=%u)\n", n, i); msg_destroy(msg), msg = NULL; } return msg;}staticint header_size(http_header_t *h){ int offset = 0; for (; h; h = h->sh_next) { offset += SU_ALIGN(offset) + h->sh_class->hc_size; offset = h->sh_class->hc_dxtra(h, offset); } return offset;}#define XTRA(xtra, h) SU_ALIGN(xtra) + header_size((http_header_t*)h)/** Test header filtering and duplicating */static int tag_test(void){ su_home_t *home = su_home_new(sizeof *home); http_request_t *request = http_request_make(home, "GET /test/path HTTP/1.1"); http_via_t *via = http_via_make(home, "1.1 http.example.com, 1.0 fred"); http_host_t *host = http_host_make(home, "http.example.com:8080"); http_max_forwards_t *mf = http_max_forwards_make(home, "16"); url_t *url = url_hdup(home, (url_t *)"http://host:80/test/path"); tagi_t *lst, *dup; int xtra; BEGIN(); su_home_check(home); TEST_1(home); TEST_1(request); TEST_1(host); TEST_1(via); TEST_1(via->v_next); lst = tl_list(HTTPTAG_REQUEST(request), HTTPTAG_HOST(host), HTTPTAG_VIA(via), HTTPTAG_MAX_FORWARDS(mf), URLTAG_URL(url), TAG_NULL()); xtra = 0; xtra += XTRA(xtra, request); xtra += XTRA(xtra, host); xtra += XTRA(xtra, via); xtra += XTRA(xtra, mf); xtra += SU_ALIGN(xtra) + sizeof(*url) + url_xtra(url); TEST(tl_xtra(lst, 0), xtra); TEST(tl_len(lst), 6 * sizeof(tagi_t)); dup = tl_adup(NULL, lst); TEST(dup != NULL, 1); TEST(tl_len(dup), 6 * sizeof(tagi_t)); TEST(tl_xtra(dup, 0), xtra); if (tstflags & tst_verbatim) tl_print(stdout, "dup:\n", dup); su_free(NULL, dup); tl_vfree(lst); su_home_unref(home); END();}/** Test advanced tag features */static int tag_test2(void){ BEGIN();#if 0 tagi_t *lst, *dup, *filter1, *filter2, *filter3, *filter4, *b1, *b2, *b3, *b4; msg_t *msg; http_t *http; su_home_t *home; int xtra; home = su_home_new(sizeof *home); msg = read_message("HTTP/2.0 401 Unauthorized\r\n" "Content-Length: 0\r\n" "\r\n"); http = msg_object(msg); TEST_1(home && msg && http); TEST_1(http_status_p((http_header_t *)http->http_status)); TEST_1(http_content_length_p((http_header_t *)http->http_content_length)); lst = tl_list(HTTPTAG_VIA(http->http_via), HTTPTAG_RECORD_ROUTE(http->http_record_route), TAG_SKIP(2), HTTPTAG_CSEQ(http->http_cseq), HTTPTAG_PAYLOAD(http->http_payload), TAG_NULL()); filter1 = tl_list(HTTPTAG_VIA(0), TAG_NULL()); filter2 = tl_list(HTTPTAG_CALL_ID(0), HTTPTAG_FROM(0), HTTPTAG_ROUTE(0), HTTPTAG_CSEQ(0), TAG_NULL()); filter3 = tl_list(HTTPTAG_CSEQ(0), HTTPTAG_CONTENT_LENGTH(0), TAG_NULL()); filter4 = tl_list(HTTPTAG_STATUS(0), HTTPTAG_VIA(0), HTTPTAG_RECORD_ROUTE(0), HTTPTAG_FROM(0), HTTPTAG_TO(0), HTTPTAG_CALL_ID(0), HTTPTAG_CSEQ(0), HTTPTAG_WWW_AUTHENTICATE(0), HTTPTAG_PROXY_AUTHENTICATE(0), HTTPTAG_CONTENT_LENGTH(0), TAG_NULL()); TEST_1(lst && filter1 && filter2 && filter3 && filter4); b1 = tl_afilter(home, filter1, lst); TEST(tl_len(b1), 2 * sizeof(tagi_t)); TEST_1(((http_via_t *)b1->t_value)->v_next); xtra = http_header_size((http_header_t *)http->http_via); xtra += SU_ALIGN(xtra); xtra += http_header_size((http_header_t *)http->http_via->v_next); TEST(tl_xtra(b1, 0), xtra); dup = tl_adup(home, lst); TEST(tl_len(dup), tl_len(lst)); TEST(tl_xtra(dup, 0), tl_xtra(lst, 0)); tl_vfree(lst); lst = tl_list(HTTPTAG_HTTP(http), TAG_NULL()); b2 = tl_afilter(home, filter2, lst); TEST(tl_len(b2), 4 * sizeof(tagi_t)); xtra = 0; xtra += XTRA(xtra, http->http_call_id); xtra += XTRA(xtra, http->http_from); xtra += XTRA(xtra, http->http_cseq); TEST(tl_xtra(b2, 0), xtra); b3 = tl_afilter(home, filter3, lst); TEST(tl_len(b3), 3 * sizeof(tagi_t)); TEST(tl_xtra(b3, 0), sizeof(http_content_length_t) + sizeof(http_cseq_t)); b4 = tl_afilter(home, filter4, lst); TEST(tl_len(b4), 11 * sizeof(tagi_t)); xtra = 0; xtra += XTRA(xtra, http->http_status); xtra += XTRA(xtra, http->http_via); xtra += XTRA(xtra, http->http_via->v_next); xtra += XTRA(xtra, http->http_record_route); xtra += XTRA(xtra, http->http_from); xtra += XTRA(xtra, http->http_to); xtra += XTRA(xtra, http->http_call_id); xtra += XTRA(xtra, http->http_cseq); xtra += XTRA(xtra, http->http_www_authenticate); xtra += XTRA(xtra, http->http_proxy_authenticate); xtra += XTRA(xtra, http->http_content_length); TEST(tl_xtra(b4, 0), xtra); tl_vfree(filter1); tl_vfree(filter2); tl_vfree(filter3); tl_vfree(filter4); tl_vfree(lst); su_home_check(home); su_free(home, b4); su_free(home, b3); su_free(home, b2); su_free(home, dup); su_free(home, b1); su_home_check(home); su_home_unref(home);#endif END();}/** Test parser and header manipulation */static int http_header_handling_test(void){ msg_t *msg; http_t *http; su_home_t *home; http_request_t http_request[1]; http_status_t http_status[1]; http_unknown_t http_unknown[1]; http_separator_t http_separator[1]; http_payload_t http_payload[1]; http_via_t http_via[1]; http_host_t http_host[1]; http_from_t http_from[1]; http_referer_t http_referer[1]; http_connection_t http_connection[1]; http_accept_t http_accept[1]; http_accept_charset_t http_accept_charset[1]; http_accept_encoding_t http_accept_encoding[1]; http_accept_language_t http_accept_language[1]; http_accept_ranges_t http_accept_ranges[1]; http_allow_t http_allow[1]; http_te_t http_te[1]; http_authorization_t http_authorization[1]; http_www_authenticate_t http_www_authenticate[1]; http_proxy_authenticate_t http_proxy_authenticate[1]; http_proxy_authorization_t http_proxy_authorization[1]; http_age_t http_age[1]; http_cache_control_t http_cache_control[1]; http_date_t http_date[1]; http_expires_t http_expires[1]; http_if_match_t http_if_match[1]; http_if_modified_since_t http_if_modified_since[1]; http_if_none_match_t http_if_none_match[1]; http_if_range_t http_if_range[1]; http_if_unmodified_since_t http_if_unmodified_since[1]; http_etag_t http_etag[1]; http_expect_t http_expect[1]; http_last_modified_t http_last_modified[1]; http_location_t http_location[1]; http_max_forwards_t http_max_forwards[1]; http_pragma_t http_pragma[1]; http_range_t http_range[1]; http_retry_after_t http_retry_after[1]; http_trailer_t http_trailer[1]; http_upgrade_t http_upgrade[1]; http_vary_t http_vary[1]; http_warning_t http_warning[1]; http_user_agent_t http_user_agent[1]; http_server_t http_server[1]; http_mime_version_t http_mime_version[1]; http_content_language_t http_content_language[1]; http_content_location_t http_content_location[1]; http_content_md5_t http_content_md5[1]; http_content_range_t http_content_range[1]; http_content_encoding_t http_content_encoding[1]; http_transfer_encoding_t http_transfer_encoding[1]; http_content_type_t http_content_type[1]; http_content_length_t http_content_length[1]; BEGIN(); http_request_init(http_request); http_status_init(http_status); http_unknown_init(http_unknown); http_separator_init(http_separator); http_payload_init(http_payload); http_via_init(http_via); http_host_init(http_host); http_from_init(http_from); http_referer_init(http_referer); http_connection_init(http_connection); http_accept_init(http_accept); http_accept_charset_init(http_accept_charset); http_accept_encoding_init(http_accept_encoding); http_accept_language_init(http_accept_language); http_accept_ranges_init(http_accept_ranges); http_allow_init(http_allow); http_te_init(http_te); http_authorization_init(http_authorization); http_www_authenticate_init(http_www_authenticate); http_proxy_authenticate_init(http_proxy_authenticate); http_proxy_authorization_init(http_proxy_authorization); http_age_init(http_age); http_cache_control_init(http_cache_control); http_date_init(http_date); http_expires_init(http_expires); http_if_match_init(http_if_match); http_if_modified_since_init(http_if_modified_since); http_if_none_match_init(http_if_none_match); http_if_range_init(http_if_range); http_if_unmodified_since_init(http_if_unmodified_since); http_etag_init(http_etag); http_expect_init(http_expect); http_last_modified_init(http_last_modified); http_location_init(http_location); http_max_forwards_init(http_max_forwards); http_pragma_init(http_pragma); http_range_init(http_range); http_retry_after_init(http_retry_after); http_trailer_init(http_trailer);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -