-
Notifications
You must be signed in to change notification settings - Fork 4
/
Request.h
executable file
·147 lines (123 loc) · 4.95 KB
/
Request.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
#ifndef OTF_REQUEST_H
#define OTF_REQUEST_H
#include "StringBuilder.hpp"
#if defined(ARDUINO)
#include <Arduino.h>
#endif
#include "LinkedMap.h"
#include <stddef.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdio.h>
// #define SERIAL_DEBUG
#ifdef SERIAL_DEBUG
#if defined(ARDUINO)
#define REQ_DEBUG(...) \
Serial.print("Request: "); \
Serial.printf(__VA_ARGS__)
#else
#define REQ_DEBUG(...) \
fprintf(stdout, "Request: "); \
fprintf(stdout, __VA_ARGS__)
#endif
#else
#define REQ_DEBUG(...)
#endif
namespace OTF {
enum HTTPMethod {
HTTP_ANY,
HTTP_GET,
HTTP_POST,
HTTP_PUT,
HTTP_PATCH,
HTTP_DELETE,
HTTP_OPTIONS
};
enum RequestType {
INVALID,
NORMAL
};
class Request {
friend class OpenThingsFramework;
private:
enum HTTPMethod httpMethod;
char *httpVersion = nullptr;
char *path = nullptr;
LinkedMap<char *> queryParams;
LinkedMap<char *> headers;
char *body = nullptr;
size_t bodyLength = 0;
RequestType requestType = INVALID;
bool cloudRequest;
/**
* Parses the query of the request.
* @param str The full request string.
* @param length The length of the full request.
* @param index The index of the first character after the '?' character that marks the start of the request.
* When the function terminates successfully, this will be updated to the index of the character that marked the
* end of the query. The character at this index may be changed, but its original value will be returned.
* @return The character that was originally at `index` in the string. Possible values are:
* '\0', indicating an error occurred.
* '#', indicating that the new value of `index` marks the first character in the URI fragment.
* ' ', indicating that the new value of `index` marks the first character in the HTTP version.
*/
char parseQuery(char *str, size_t length, size_t &index);
/**
* Parses a single header and adds it to `headers`.
* @param str The full request string.
* @param length The length of the full request.
* @param index The index of the first character in the header line. When the function terminates successfully,
* this will be updated to the index of the first character after the CRLF sequence at the end of the header.
* @param headers The set of headers to add the parsed header to.
* @return A boolean indicating if the header could be parsed successfully.
*/
bool parseHeader(char *str, size_t length, size_t &index, LinkedMap<char *> &headers);
/**
* Decodes the specified query string, updating and null-terminating the string in-place.
* @param value a null-terminated query value.
*/
static void decodeQueryParameter(char *value);
/**
* Parses an HTTP request. The parser makes some assumptions about the message format that may not hold if the
* message is improperly formatted, so the behavior of this constructor is undefined if it is passed an improperly
* formatted request.
*/
Request(char *str, size_t length, bool cloudRequest);
public:
/** Returns the path of the request (not including the query) as a null-terminated string. */
char *getPath() const;
/** Returns the decoded value of the specified query parameter as a null-terminated string, or NULL if the parameter was not set in the request. */
char *getQueryParameter(const char *key) const;
#if defined(ARDUINO)
/** Returns the decoded value of the specified query parameter as a null-terminated string, or NULL if the parameter was not set in the request. */
char *getQueryParameter(const __FlashStringHelper *key) const;
#endif
/**
* Returns the value of the specified header as a null-terminated string, or NULL if the header was not set in the request.
* @param key The lowercase header name.
*/
char *getHeader(const char *key) const;
#if defined(ARDUINO)
/**
* Returns the value of the specified header as a null-terminated string, or NULL if the header was not set in the request.
* @param key The lowercase header name.
*/
char *getHeader(const __FlashStringHelper *key) const;
#endif
/**
* Returns the body of the request. THIS STRING IS NOT NULL TERMINATED, AND IT MAY CONTAIN NULL CHARACTERS. If
* the request could not be parsed (as indicated by the getType() method), this method has undefined behavior.
*/
char *getBody() const;
/** Returns the length of the request body. */
size_t getBodyLength() const;
/** Indicates if this request is a multipart request, a non-multipart request, or an illegally formatted request. */
RequestType getType() const;
/**
* Indicates if the request came through the cloud rather than through the local server. If this returns `true`,
* it means that the request has already been authenticated by an OpenThings Cloud token.
*/
bool isCloudRequest() const;
};
}// namespace OTF
#endif