bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2013-2018 Dovecot authors, see the included COPYING file */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#include "test-lib.h"
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch#include "str-sanitize.h"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#include "istream.h"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#include "test-common.h"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch#include "http-response.h"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#include "http-header-parser.h"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch#include <time.h>
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstruct http_header_parse_result {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const char *name;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const char *value;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstruct http_header_parse_test {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const char *header;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch struct http_header_limits limits;
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch enum http_header_parse_flags flags;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const struct http_header_parse_result *fields;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch/* Valid header tests */
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result1[] = {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Date", "Sat, 06 Oct 2012 16:01:44 GMT" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Server", "Apache/2.2.16 (Debian)" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Last-Modified", "Mon, 30 Jul 2012 11:09:28 GMT" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Etag", "\"3d24677-3261-4c60a1863aa00\"" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Accept-Ranges", "bytes" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Vary", "Accept-Encoding" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Content-Encoding", "gzip" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Content-Length", "4092" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Keep-Alive", "timeout=15, max=100" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Connection", "Keep-Alive" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Content-Type", "text/html" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { NULL, NULL }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result2[] = {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Host", "p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Accept", "image/png,image/*;q=0.8,*/*;q=0.5" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Accept-Language", "en-us,en;q=0.5" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Accept-Encoding", "gzip, deflate" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "DNT", "1" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Connection", "keep-alive" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Referer", "http://www.example.nl/" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { NULL, NULL }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result3[] = {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Date", "Sat, 06 Oct 2012 17:12:37 GMT" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Server", "Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch " Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch " mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "WWW-Authenticate", "Basic realm=\"Munin\"" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Vary", "Accept-Encoding" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Content-Encoding", "gzip" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Content-Length", "445" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Keep-Alive", "timeout=15, max=98" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Connection", "Keep-Alive" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { "Content-Type", "text/html; charset=iso-8859-1" },
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { NULL, NULL }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result4[] = {
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Age", "58" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Date", "Sun, 04 Aug 2013 09:33:09 GMT" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Expires", "Sun, 04 Aug 2013 09:34:08 GMT" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Cache-Control", "max-age=60" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Content-Length", "17336" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Connection", "Keep-Alive" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Via", "NS-CACHE-9.3" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Server", "Apache" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Vary", "Host" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Last-Modified", "Sun, 04 Aug 2013 09:33:07 GMT" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Content-Type", "text/html; charset=utf-8" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { "Content-Encoding", "gzip" },
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen { NULL, NULL }
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen};
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result5[] = {
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch { NULL, NULL }
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch};
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result6[] = {
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch { "X-Frop", "This text\x80 contains obs-text\x81 characters" },
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch { NULL, NULL }
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch};
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const struct http_header_parse_result valid_header_parse_result7[] = {
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch { "X-Frop", "This text contains invalid characters" },
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch { NULL, NULL }
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch};
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic const struct http_header_parse_test valid_header_parse_tests[] = {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch { .header =
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Server: Apache/2.2.16 (Debian)\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Last-Modified: Mon, 30 Jul 2012 11:09:28 GMT\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Etag: \"3d24677-3261-4c60a1863aa00\"\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Accept-Ranges: bytes\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Vary: Accept-Encoding\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Content-Encoding: gzip\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Content-Length: 4092\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Keep-Alive: timeout=15, max=100\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Connection: Keep-Alive\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Content-Type: text/html\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "\r\n",
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch .fields = valid_header_parse_result1
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch },{
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch .header =
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Accept:\t\timage/png,image/*;q=0.8,*/*;q=0.5\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Accept-Language:\ten-us,en;q=0.5\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Accept-Encoding: \t\tgzip, deflate\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "DNT: 1\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Connection: \t\tkeep-alive\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Referer: http://www.example.nl/\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "\n",
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch .fields = valid_header_parse_result2
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch },{
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch .header =
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch " Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch " mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "WWW-Authenticate: Basic realm=\"Munin\"\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Vary: Accept-Encoding\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Content-Encoding: gzip\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Content-Length: 445\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Keep-Alive: timeout=15, max=98\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Connection: Keep-Alive\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "Content-Type: text/html; charset=iso-8859-1\r\n"
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch "\r\n",
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch .fields = valid_header_parse_result3
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch },{
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen .header =
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Age: 58 \r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Cache-Control: max-age=60 \r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Content-Length: 17336 \r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Connection: Keep-Alive\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Via: NS-CACHE-9.3\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Server: Apache\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Vary: Host\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Content-Type: text/html; charset=utf-8\r\n"
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "Content-Encoding: gzip\r\n"
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch "\r\n",
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .fields = valid_header_parse_result4,
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .limits = {
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .max_size = 340,
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .max_field_size = 46,
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .max_fields = 12
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch }
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen },{
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen .header =
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen "\r\n",
9a449fb205b61613586b905ce3ee537486d5bd7cTimo Sirainen .fields = valid_header_parse_result5
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch },{
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch .header =
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "X-Frop: This text\x80 contains obs-text\x81 characters\r\n"
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "\r\n",
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch .fields = valid_header_parse_result6
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch },{
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch .header =
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "X-Frop: This text\x01 contains invalid\x7f characters\r\n"
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "\r\n",
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch .fields = valid_header_parse_result7
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const unsigned int valid_header_parse_test_count = N_ELEMENTS(valid_header_parse_tests);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic void test_http_header_parse_valid(void)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch{
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch unsigned int i;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch for (i = 0; i < valid_header_parse_test_count; i++) T_BEGIN {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch struct istream *input;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch struct http_header_parser *parser;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch const struct http_header_limits *limits;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch const char *header, *field_name, *error = NULL;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const unsigned char *field_data;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch size_t field_size;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch int ret;
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen unsigned int j, pos, header_len;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch header = valid_header_parse_tests[i].header;
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen header_len = strlen(header);
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch limits = &valid_header_parse_tests[i].limits;
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen input = test_istream_create_data(header, header_len);
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch parser = http_header_parser_init(input, limits,
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch valid_header_parse_tests[i].flags);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_begin(t_strdup_printf("http header valid [%d]", i));
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen j = 0; pos = 0; test_istream_set_size(input, 0);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch while ((ret=http_header_parse_next_field
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen (parser, &field_name, &field_data, &field_size, &error)) >= 0) {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const struct http_header_parse_result *result;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const char *field_value;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen if (ret == 0) {
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen if (pos == header_len)
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen break;
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen test_istream_set_size(input, ++pos);
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen continue;
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen }
d1f1ad02d1ed5d83c62fba356259b7c9073608c6Timo Sirainen
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch if (field_name == NULL) break;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch result = &valid_header_parse_tests[i].fields[j];
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch field_value = t_strndup(field_data, field_size);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch if (result->name == NULL) {
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch test_out_reason("valid", FALSE, t_strdup_printf
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch ("%s: %s", field_name, str_sanitize(field_value, 100)));
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch break;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_out_reason("valid",
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch strcmp(result->name, field_name) == 0 &&
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch strcmp(result->value, field_value) == 0,
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch t_strdup_printf("%s: %s", field_name,
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch str_sanitize(field_value, 100)));
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch j++;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch test_out_reason("parse success", ret > 0, error);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_end();
5968fa8151eecd191b1973b44dd8bec9b75810a6Phil Carmody i_stream_unref(&input);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch http_header_parser_deinit(&parser);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch } T_END;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch}
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Boschstatic const struct http_header_parse_test invalid_header_parse_tests[] = {
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch {
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Date: Sat, 06 Oct 2012 16:01:44 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Server : Apache/2.2.16 (Debian)\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Last-Modified: Mon, 30 Jul 2012 11:09:28 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Date: Sat, 06 Oct 2012 17:18:22 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Server: Apache/2.2.3 (CentOS)\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "X Powered By: PHP/5.3.6\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Host: www.example.com\n\r"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Accept: image/png,image/*;q=0.8,*/*;q=0.5\n\r"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Accept-Language: en-us,en;q=0.5\n\r"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Accept-Encoding: gzip, deflate\n\r"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\n\r"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Host: p5-lrqzb4yavu4l7nagydw-428649-i2-v6exp3-ds.metric.example.com\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64; rv:15.0)\n"
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "Accept:\t\timage/png,image/*;q=0.8,*/\1;q=0.5\n"
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch "\n",
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch .flags = HTTP_HEADER_PARSE_FLAG_STRICT
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch },{
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch .header =
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "Date: Sat, 06 Oct 2012 17:18:22 GMT\r\n"
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "Server: Apache/2.2.3\177 (CentOS)\r\n"
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch "\r\n",
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch .flags = HTTP_HEADER_PARSE_FLAG_STRICT
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Server: Apache/2.2.16 (Debian) PHP/5.3.3-7+squeeze14 with\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Suhosin-Patch proxy_html/3.0.1 mod_python/3.3.1 Python/2.6.6\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "mod_ssl/2.2.16 OpenSSL/0.9.8o mod_perl/2.0.4 Perl/v5.10.1\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\r\n"
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch },{
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch .header =
e0cf44fb802a5e7aa4cbeee5e80ef8f3f6aecdbeStephan Bosch "Date: Sat, 06 Oct 2012 17:12:37 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Age: 58 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Cache-Control: max-age=60 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Length: 17336 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Connection: Keep-Alive\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Via: NS-CACHE-9.3\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Server: Apache\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Vary: Host\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Type: text/html; charset=utf-8\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Encoding: gzip\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\r\n",
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .limits = { .max_size = 339 }
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Age: 58 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Cache-Control: max-age=60 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Length: 17336 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Connection: Keep-Alive\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Via: NS-CACHE-9.3\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Server: Apache\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Vary: Host\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Type: text/html; charset=utf-8\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Encoding: gzip\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\r\n",
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .fields = valid_header_parse_result4,
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .limits = { .max_field_size = 45 }
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch },{
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .header =
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Age: 58 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Date: Sun, 04 Aug 2013 09:33:09 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Expires: Sun, 04 Aug 2013 09:34:08 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Cache-Control: max-age=60 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Length: 17336 \r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Connection: Keep-Alive\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Via: NS-CACHE-9.3\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Server: Apache\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Vary: Host\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Last-Modified: Sun, 04 Aug 2013 09:33:07 GMT\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Type: text/html; charset=utf-8\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "Content-Encoding: gzip\r\n"
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch "\r\n",
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .fields = valid_header_parse_result4,
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch .limits = { .max_fields = 11 }
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch};
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
ba592dc74a004ad47dfe58edcfc1ca7297551e39Phil Carmodystatic const unsigned int invalid_header_parse_test_count = N_ELEMENTS(invalid_header_parse_tests);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschstatic void test_http_header_parse_invalid(void)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch{
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch unsigned int i;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch for (i = 0; i < invalid_header_parse_test_count; i++) T_BEGIN {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch struct istream *input;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch struct http_header_parser *parser;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch const struct http_header_limits *limits;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch const char *header, *field_name, *error = NULL;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch const unsigned char *field_data;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch size_t field_size;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch int ret;
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch header = invalid_header_parse_tests[i].header;
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch limits = &invalid_header_parse_tests[i].limits;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch input = i_stream_create_from_data(header, strlen(header));
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch parser = http_header_parser_init(input, limits,
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch invalid_header_parse_tests[i].flags);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_begin(t_strdup_printf("http header invalid [%d]", i));
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch while ((ret=http_header_parse_next_field
7384b4e78eaab44693c985192276e31322155e32Stephan Bosch (parser, &field_name, &field_data, &field_size, &error)) > 0) {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch if (field_name == NULL) break;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch }
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch test_out_reason("parse failure", ret < 0, error);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_end();
5968fa8151eecd191b1973b44dd8bec9b75810a6Phil Carmody i_stream_unref(&input);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch http_header_parser_deinit(&parser);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch } T_END;
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch}
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Boschint main(void)
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch{
baf3e87e186453fda13bd21f7cbcb2efc8492e8bTimo Sirainen static void (*const test_functions[])(void) = {
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_http_header_parse_valid,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch test_http_header_parse_invalid,
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch NULL
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch };
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch return test_run(test_functions);
1bd20e2a575473f3d05499f05f1d72da59b34fd6Stephan Bosch}