-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_response.h
182 lines (151 loc) · 3.66 KB
/
http_response.h
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
/*
================================================================================
DREAM core / HTTP package parser
--------------------------------------------------------------------------------
Class for parsing HTTP responses from server.
Parser gets all data from string of HTTP package.
--------------------------------------------------------------------------------
Copyright © 2019-2023 Dmytro Obukhov (DeLy Dreamer)
License: https://www.gnu.org/licenses/gpl-3.0.html
================================================================================
*/
#pragma once
#include <Arduino.h>
#include <vector>
#include "http_common.h"
namespace dream
{
class HTTPResponse
{
private: //-------------------------------------------------------------
// Buffer for package as string
String _buffer;
// HTTP response code
int _http_code;
// Headers
std::vector<HTTPHeader> _headers;
// Some common headers as values
int _content_length;
String _content_type;
String _location;
String _date;
// Body content
String _body;
// Parse package status code, headers and body
void parse()
{
bool first_line = true;
bool reading_body = false;
String current_line = "";
for (int i = 0; i < _buffer.length(); i++)
{
// Get current char
char c = _buffer[i];
if (reading_body)
{
// Add to the body
_body += c;
}
else
{
// Add to the buffer line
current_line += c;
if (c == '\n')
{
if (first_line)
{
// Parse response code
int code_pos = _buffer.indexOf(' ') + 1;
_http_code = _buffer.substring(code_pos, _buffer.indexOf(' ', code_pos)).toInt();
first_line = false;
}
else
{
// If separation line
if (current_line == "\r\n" || current_line == "\n")
{
reading_body = true;
}
else
{
// Parse header
String name = current_line.substring(0, current_line.indexOf(':'));
String value = current_line.substring(current_line.indexOf(':') + 1);
value.trim();
_headers.push_back({ name, value });
}
}
// Reset current line
current_line = "";
}
}
}
_body.trim();
}
// Fill fields from headers
void headersDataToValues()
{
for (const auto &h : _headers)
{
if (h.name.equalsIgnoreCase("Content-Length"))
{
_content_length = h.value.toInt();
}
else if (h.name.equalsIgnoreCase("Date"))
{
_date = h.value;
}
else if (h.name.equalsIgnoreCase("Content-Type"))
{
_content_type = h.value;
}
else if (h.name.equalsIgnoreCase("Location"))
{
_location = h.value;
}
}
}
public: //--------------------------------------------------------------
HTTPResponse(const String &package)
{
_buffer = package;
_buffer.trim();
parse();
headersDataToValues();
}
// Get some of most common headers
int getStatus() { return _http_code; }
int getContentLength() { return _content_length; }
String getContentType() { return _content_type; }
String getLocation() { return _location; }
String getDate() { return _date; }
// Get list of headers
std::vector<HTTPHeader> getHeaders()
{
return _headers;
}
// Check if package has header
bool hasHeader(const String &name)
{
for (const HTTPHeader &h : _headers)
{
if (h.name == name) return true;
}
return false;
}
// Get value of header
String getHeader(const String &name)
{
for (const HTTPHeader &h : _headers)
{
if (h.name == name) return h.value;
}
return "";
}
// Get body data
String getBody()
{
return _body;
}
};
}