Apply PIE to nghttpx
[platform/upstream/nghttp2.git] / third-party / llhttp / src / api.c
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4
5 #include "llhttp.h"
6
7 #define CALLBACK_MAYBE(PARSER, NAME, ...)                                     \
8   do {                                                                        \
9     llhttp_settings_t* settings;                                              \
10     settings = (llhttp_settings_t*) (PARSER)->settings;                       \
11     if (settings == NULL || settings->NAME == NULL) {                         \
12       err = 0;                                                                \
13       break;                                                                  \
14     }                                                                         \
15     err = settings->NAME(__VA_ARGS__);                                        \
16   } while (0)
17
18 void llhttp_init(llhttp_t* parser, llhttp_type_t type,
19                  const llhttp_settings_t* settings) {
20   llhttp__internal_init(parser);
21
22   parser->type = type;
23   parser->settings = (void*) settings;
24 }
25
26
27 llhttp_errno_t llhttp_execute(llhttp_t* parser, const char* data, size_t len) {
28   return llhttp__internal_execute(parser, data, data + len);
29 }
30
31
32 void llhttp_settings_init(llhttp_settings_t* settings) {
33   memset(settings, 0, sizeof(*settings));
34 }
35
36
37 llhttp_errno_t llhttp_finish(llhttp_t* parser) {
38   int err;
39
40   /* We're in an error state. Don't bother doing anything. */
41   if (parser->error != 0) {
42     return 0;
43   }
44
45   switch (parser->finish) {
46     case HTTP_FINISH_SAFE_WITH_CB:
47       CALLBACK_MAYBE(parser, on_message_complete, parser);
48       if (err != HPE_OK) return err;
49
50     /* FALLTHROUGH */
51     case HTTP_FINISH_SAFE:
52       return HPE_OK;
53     case HTTP_FINISH_UNSAFE:
54       parser->reason = "Invalid EOF state";
55       return HPE_INVALID_EOF_STATE;
56     default:
57       abort();
58   }
59 }
60
61
62 void llhttp_pause(llhttp_t* parser) {
63   if (parser->error != HPE_OK) {
64     return;
65   }
66
67   parser->error = HPE_PAUSED;
68   parser->reason = "Paused";
69 }
70
71
72 void llhttp_resume(llhttp_t* parser) {
73   if (parser->error != HPE_PAUSED) {
74     return;
75   }
76
77   parser->error = 0;
78 }
79
80
81 void llhttp_resume_after_upgrade(llhttp_t* parser) {
82   if (parser->error != HPE_PAUSED_UPGRADE) {
83     return;
84   }
85
86   parser->error = 0;
87 }
88
89
90 llhttp_errno_t llhttp_get_errno(const llhttp_t* parser) {
91   return parser->error;
92 }
93
94
95 const char* llhttp_get_error_reason(const llhttp_t* parser) {
96   return parser->reason;
97 }
98
99
100 void llhttp_set_error_reason(llhttp_t* parser, const char* reason) {
101   parser->reason = reason;
102 }
103
104
105 const char* llhttp_get_error_pos(const llhttp_t* parser) {
106   return parser->error_pos;
107 }
108
109
110 const char* llhttp_errno_name(llhttp_errno_t err) {
111 #define HTTP_ERRNO_GEN(CODE, NAME, _) case HPE_##NAME: return "HPE_" #NAME;
112   switch (err) {
113     HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
114     default: abort();
115   }
116 #undef HTTP_ERRNO_GEN
117 }
118
119
120 const char* llhttp_method_name(llhttp_method_t method) {
121 #define HTTP_METHOD_GEN(NUM, NAME, STRING) case HTTP_##NAME: return #STRING;
122   switch (method) {
123     HTTP_METHOD_MAP(HTTP_METHOD_GEN)
124     default: abort();
125   }
126 #undef HTTP_METHOD_GEN
127 }
128
129
130 void llhttp_set_lenient(llhttp_t* parser, int enabled) {
131   if (enabled) {
132     parser->flags |= F_LENIENT;
133   } else {
134     parser->flags &= ~F_LENIENT;
135   }
136 }
137
138
139 /* Callbacks */
140
141
142 int llhttp__on_message_begin(llhttp_t* s, const char* p, const char* endp) {
143   int err;
144   CALLBACK_MAYBE(s, on_message_begin, s);
145   return err;
146 }
147
148
149 int llhttp__on_url(llhttp_t* s, const char* p, const char* endp) {
150   int err;
151   CALLBACK_MAYBE(s, on_url, s, p, endp - p);
152   return err;
153 }
154
155
156 int llhttp__on_status(llhttp_t* s, const char* p, const char* endp) {
157   int err;
158   CALLBACK_MAYBE(s, on_status, s, p, endp - p);
159   return err;
160 }
161
162
163 int llhttp__on_header_field(llhttp_t* s, const char* p, const char* endp) {
164   int err;
165   CALLBACK_MAYBE(s, on_header_field, s, p, endp - p);
166   return err;
167 }
168
169
170 int llhttp__on_header_value(llhttp_t* s, const char* p, const char* endp) {
171   int err;
172   CALLBACK_MAYBE(s, on_header_value, s, p, endp - p);
173   return err;
174 }
175
176
177 int llhttp__on_headers_complete(llhttp_t* s, const char* p, const char* endp) {
178   int err;
179   CALLBACK_MAYBE(s, on_headers_complete, s);
180   return err;
181 }
182
183
184 int llhttp__on_message_complete(llhttp_t* s, const char* p, const char* endp) {
185   int err;
186   CALLBACK_MAYBE(s, on_message_complete, s);
187   return err;
188 }
189
190
191 int llhttp__on_body(llhttp_t* s, const char* p, const char* endp) {
192   int err;
193   CALLBACK_MAYBE(s, on_body, s, p, endp - p);
194   return err;
195 }
196
197
198 int llhttp__on_chunk_header(llhttp_t* s, const char* p, const char* endp) {
199   int err;
200   CALLBACK_MAYBE(s, on_chunk_header, s);
201   return err;
202 }
203
204
205 int llhttp__on_chunk_complete(llhttp_t* s, const char* p, const char* endp) {
206   int err;
207   CALLBACK_MAYBE(s, on_chunk_complete, s);
208   return err;
209 }
210
211
212 /* Private */
213
214
215 void llhttp__debug(llhttp_t* s, const char* p, const char* endp,
216                    const char* msg) {
217   if (p == endp) {
218     fprintf(stderr, "p=%p type=%d flags=%02x next=null debug=%s\n", s, s->type,
219             s->flags, msg);
220   } else {
221     fprintf(stderr, "p=%p type=%d flags=%02x next=%02x   debug=%s\n", s,
222             s->type, s->flags, *p, msg);
223   }
224 }