efl
156 строк · 4.2 Кб
1/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev
2*
3* Additional changes are licensed under the same terms as NGINX and
4* copyright Joyent, Inc. and other Node contributors. All rights reserved.
5*
6* Permission is hereby granted, free of charge, to any person obtaining a copy
7* of this software and associated documentation files (the "Software"), to
8* deal in the Software without restriction, including without limitation the
9* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10* sell copies of the Software, and to permit persons to whom the Software is
11* furnished to do so, subject to the following conditions:
12*
13* The above copyright notice and this permission notice shall be included in
14* all copies or substantial portions of the Software.
15*
16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22* IN THE SOFTWARE.
23*/
24
25/* Dump what the parser finds to stdout as it happen */
26
27#include "http_parser.h"
28#include <stdio.h>
29#include <stdlib.h>
30#include <string.h>
31
32int on_message_begin(http_parser* _) {
33(void)_;
34printf("\n***MESSAGE BEGIN***\n\n");
35return 0;
36}
37
38int on_headers_complete(http_parser* _) {
39(void)_;
40printf("\n***HEADERS COMPLETE***\n\n");
41return 0;
42}
43
44int on_message_complete(http_parser* _) {
45(void)_;
46printf("\n***MESSAGE COMPLETE***\n\n");
47return 0;
48}
49
50int on_url(http_parser* _, const char* at, size_t length) {
51(void)_;
52printf("Url: %.*s\n", (int)length, at);
53return 0;
54}
55
56int on_header_field(http_parser* _, const char* at, size_t length) {
57(void)_;
58printf("Header field: %.*s\n", (int)length, at);
59return 0;
60}
61
62int on_header_value(http_parser* _, const char* at, size_t length) {
63(void)_;
64printf("Header value: %.*s\n", (int)length, at);
65return 0;
66}
67
68int on_body(http_parser* _, const char* at, size_t length) {
69(void)_;
70printf("Body: %.*s\n", (int)length, at);
71return 0;
72}
73
74void usage(const char* name) {
75fprintf(stderr,
76"Usage: %s $type $filename\n"
77" type: -x, where x is one of {r,b,q}\n"
78" parses file as a Response, reQuest, or Both\n",
79name);
80exit(EXIT_FAILURE);
81}
82
83int main(int argc, char* argv[]) {
84enum http_parser_type file_type;
85
86if (argc != 3) {
87usage(argv[0]);
88}
89
90char* type = argv[1];
91if (type[0] != '-') {
92usage(argv[0]);
93}
94
95switch (type[1]) {
96/* in the case of "-", type[1] will be NUL */
97case 'r':
98file_type = HTTP_RESPONSE;
99break;
100case 'q':
101file_type = HTTP_REQUEST;
102break;
103case 'b':
104file_type = HTTP_BOTH;
105break;
106default:
107usage(argv[0]);
108}
109
110char* filename = argv[2];
111FILE* file = fopen(filename, "rb");
112if (file == NULL) {
113perror("fopen");
114return EXIT_FAILURE;
115}
116
117fseek(file, 0, SEEK_END);
118long file_length = ftell(file);
119if (file_length == -1) {
120perror("ftell");
121return EXIT_FAILURE;
122}
123fseek(file, 0, SEEK_SET);
124
125char* data = malloc(file_length);
126if (fread(data, 1, file_length, file) != (size_t)file_length) {
127fprintf(stderr, "couldn't read entire file\n");
128free(data);
129return EXIT_FAILURE;
130}
131
132http_parser_settings settings;
133memset(&settings, 0, sizeof(settings));
134settings.on_message_begin = on_message_begin;
135settings.on_url = on_url;
136settings.on_header_field = on_header_field;
137settings.on_header_value = on_header_value;
138settings.on_headers_complete = on_headers_complete;
139settings.on_body = on_body;
140settings.on_message_complete = on_message_complete;
141
142http_parser parser;
143http_parser_init(&parser, file_type);
144size_t nparsed = http_parser_execute(&parser, &settings, data, file_length);
145free(data);
146
147if (nparsed != (size_t)file_length) {
148fprintf(stderr,
149"Error: %s (%s)\n",
150http_errno_description(HTTP_PARSER_ERRNO(&parser)),
151http_errno_name(HTTP_PARSER_ERRNO(&parser)));
152return EXIT_FAILURE;
153}
154
155return EXIT_SUCCESS;
156}
157