1 /*
2 * Copyright (c) 2020, The OpenThread Authors.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. Neither the name of the copyright holder nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include "rest/parser.hpp"
30
31 #include <string>
32 #include <vector>
33
34 namespace otbr {
35 namespace rest {
36
OnUrl(http_parser * parser,const char * at,size_t len)37 static int OnUrl(http_parser *parser, const char *at, size_t len)
38 {
39 Request *request = reinterpret_cast<Request *>(parser->data);
40
41 if (len > 0)
42 {
43 request->SetUrl(at, len);
44 }
45
46 return 0;
47 }
48
OnBody(http_parser * parser,const char * at,size_t len)49 static int OnBody(http_parser *parser, const char *at, size_t len)
50 {
51 Request *request = reinterpret_cast<Request *>(parser->data);
52
53 if (len > 0)
54 {
55 request->SetBody(at, len);
56 }
57
58 return 0;
59 }
60
OnMessageComplete(http_parser * parser)61 static int OnMessageComplete(http_parser *parser)
62 {
63 Request *request = reinterpret_cast<Request *>(parser->data);
64
65 request->SetReadComplete();
66
67 return 0;
68 }
69
OnMessageBegin(http_parser * parser)70 static int OnMessageBegin(http_parser *parser)
71 {
72 Request *request = reinterpret_cast<Request *>(parser->data);
73 request->ResetReadComplete();
74
75 return 0;
76 }
77
OnHeaderComplete(http_parser * parser)78 static int OnHeaderComplete(http_parser *parser)
79 {
80 Request *request = reinterpret_cast<Request *>(parser->data);
81 request->SetMethod(parser->method);
82 return 0;
83 }
84
OnHandlerData(http_parser *,const char *,size_t)85 static int OnHandlerData(http_parser *, const char *, size_t)
86 {
87 return 0;
88 }
89
OnHeaderField(http_parser * parser,const char * at,size_t len)90 static int OnHeaderField(http_parser *parser, const char *at, size_t len)
91 {
92 Request *request = reinterpret_cast<Request *>(parser->data);
93
94 if (len > 0)
95 {
96 request->SetNextHeaderField(at, len);
97 }
98
99 return 0;
100 }
101
OnHeaderData(http_parser * parser,const char * at,size_t len)102 static int OnHeaderData(http_parser *parser, const char *at, size_t len)
103 {
104 Request *request = reinterpret_cast<Request *>(parser->data);
105
106 if (len > 0)
107 {
108 request->SetHeaderValue(at, len);
109 }
110
111 return 0;
112 }
113
Parser(Request * aRequest)114 Parser::Parser(Request *aRequest)
115 {
116 mParser.data = aRequest;
117 }
118
Init(void)119 void Parser::Init(void)
120 {
121 mSettings.on_message_begin = OnMessageBegin;
122 mSettings.on_url = OnUrl;
123 mSettings.on_status = OnHandlerData;
124 mSettings.on_header_field = OnHeaderField;
125 mSettings.on_header_value = OnHeaderData;
126 mSettings.on_body = OnBody;
127 mSettings.on_headers_complete = OnHeaderComplete;
128 mSettings.on_message_complete = OnMessageComplete;
129 http_parser_init(&mParser, HTTP_REQUEST);
130 }
131
Process(const char * aBuf,size_t aLength)132 void Parser::Process(const char *aBuf, size_t aLength)
133 {
134 http_parser_execute(&mParser, &mSettings, aBuf, aLength);
135 }
136
137 } // namespace rest
138 } // namespace otbr
139