summaryrefslogtreecommitdiffstats
path: root/tests/HTTP/HTTPResponseParser_file.cpp
blob: 48ff928bcba914f8e323bf409ca02d9d3a9cbcf0 (plain) (blame)
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

// HTTPResponseParser_file.cpp

// Implements a test that feeds file contents into a cHTTPResponseParser instance and prints all callbacks

#include "Globals.h"
#include "HTTP/HTTPResponseParser.h"





/** Maximum size of the input buffer, through which the file is read */
static const size_t MAX_BUF = 4096;





class cCallbacks:
	public cHTTPResponseParser::cCallbacks
{
	typedef cHTTPResponseParser::cCallbacks Super;
public:
	cCallbacks(void)
	{
		printf("cCallbacks created\n");
	}

	// cHTTPResponseParser::cCallbacks overrides:
	virtual void OnError(const AString & a_ErrorDescription) override
	{
		printf("Error: \"%s\"\n", a_ErrorDescription.c_str());
	}

	/** Called when the status line is fully parsed. */
	virtual void OnStatusLine(const AString & a_StatusLine) override
	{
		printf("Status line: \"%s\"\n", a_StatusLine.c_str());
	}

	/** Called when a single header line is parsed. */
	virtual void OnHeaderLine(const AString & a_Key, const AString & a_Value) override
	{
		printf("Header line: \"%s\": \"%s\"\n", a_Key.c_str(), a_Value.c_str());
	}

	/** Called when all the headers have been parsed. */
	virtual void OnHeadersFinished(void) override
	{
		printf("Headers finished\n");
	}

	/** Called for each chunk of the incoming body data. */
	virtual void OnBodyData(const void * a_Data, size_t a_Size) override
	{
		AString hexDump;
		CreateHexDump(hexDump, a_Data, a_Size, 16);
		printf("Body data: %u bytes\n%s", static_cast<unsigned>(a_Size), hexDump.c_str());
	}

	virtual void OnBodyFinished(void) override
	{
		printf("Body finished\n");
	}
};





int main(int argc, char * argv[])
{
	printf("HTTPResponseParser_file beginning\n");

	// Open the input file:
	if (argc <= 1)
	{
		printf("Usage: %s <filename> [<buffersize>]\n", argv[0]);
		return 1;
	}
	FILE * f;
	if (strcmp(argv[1], "-") == 0)
	{
		f = stdin;
	}
	else
	{
		f = fopen(argv[1], "rb");
		if (f == nullptr)
		{
			printf("Cannot open file \"%s\". Aborting.\n", argv[1]);
			return 2;
		}
	}

	// If a third param is present, use it as the buffer size
	size_t bufSize = MAX_BUF;
	if (argc >= 3)
	{
		if (!StringToInteger(argv[2], bufSize) || (bufSize == 0))
		{
			bufSize = MAX_BUF;
			printf("\"%s\" is not a valid buffer size, using the default of %u instead.\n", argv[2], static_cast<unsigned>(bufSize));
		}
		if (bufSize > MAX_BUF)
		{
			bufSize = MAX_BUF;
			printf("\"%s\" is too large, maximum buffer size is %u. Using the size %u instead.\n", argv[2], static_cast<unsigned>(bufSize), static_cast<unsigned>(bufSize));
		}
	}

	// Feed the file contents into the parser:
	cCallbacks callbacks;
	cHTTPResponseParser parser(callbacks);
	while (!feof(f))
	{
		char buf[MAX_BUF];
		auto numBytes = fread(buf, 1, bufSize, f);
		if (numBytes == 0)
		{
			printf("Read 0 bytes from file (EOF?), terminating\n");
			break;
		}
		auto numLeft = parser.Parse(buf, numBytes);
		if (numLeft == AString::npos)
		{
			printf("Parser indicates there was an error, terminating parsing.\n");
			break;
		}
		ASSERT(numLeft <= numBytes);
		if (numLeft > 0)
		{
			printf("Parser indicates stream end, but there's more data (at least %u bytes) in the file.\n", static_cast<unsigned>(numLeft));
		}
	}
	if (!parser.IsFinished())
	{
		printf("Parser indicates an incomplete stream.\n");
	}

	// Close the input file:
	if (f != stdin)
	{
		fclose(f);
	}

	return 0;
}