25FLASHMEM Response::Response(net::EthernetClient *client, uint8_t *writeBuffer,
int writeBufferLength)
26 : m_stream(client), m_headers(), m_contentLenghtSet(false), m_contentTypeSet(false), m_keepAlive(false),
27 m_statusSent(0), m_headersSent(false), m_sendingStatus(false), m_sendingHeaders(false),
28 m_headersCount(0), m_bytesSent(0), m_ended(false), m_buffer(writeBuffer),
29 m_bufferLength(writeBufferLength), m_bufFill(0) {}
31FLASHMEM
int Response::availableForWrite() {
return SERVER_OUTPUT_BUFFER_SIZE - m_bufFill - 1; }
33FLASHMEM
void Response::beginHeaders() {
38 m_sendingHeaders =
true;
40 P(headerSeprator) =
": ";
41 for (
int i = 0; i < m_headersCount; i++) {
42 print(m_headers[i].name);
43 printP(headerSeprator);
44 print(m_headers[i].value);
49FLASHMEM
int Response::bytesSent() {
return m_bytesSent; }
51FLASHMEM
void Response::end() { m_ended =
true; }
53FLASHMEM
void Response::endHeaders() {
56 m_sendingHeaders =
false;
60FLASHMEM
bool Response::ended() {
return m_ended; }
62FLASHMEM
void Response::flush() {
68FLASHMEM
const char *Response::get(
const char *name) {
69 for (
int i = 0; i < m_headersCount; i++) {
70 if (Application::strcmpi(name, m_headers[i].name) == 0) {
71 return m_headers[m_headersCount].value;
78FLASHMEM
bool Response::headersSent() {
return m_headersSent; }
80FLASHMEM
void Response::printP(
const unsigned char *
string) {
81 if (m_shouldPrintHeaders()) {
85 while (uint8_t value = pgm_read_byte(
string++)) {
90FLASHMEM
void Response::printP(
const char *
string) { printP((
unsigned char *)
string); }
92FLASHMEM
void Response::sendStatus(
int code) {
97 if (code != 204 && code != 304) {
102FLASHMEM
void Response::set(
const char *name,
const char *value) {
103 if (m_headersCount >= SERVER_MAX_HEADERS) {
107 m_headers[m_headersCount].name = name;
108 m_headers[m_headersCount].value = value;
111 P(contentType) =
"Content-Type";
112 if (Application::strcmpiP(name, contentType) == 0) {
113 m_contentTypeSet =
true;
116 P(contentLength) =
"Content-Length";
117 if (Application::strcmpiP(name, contentLength) == 0) {
118 m_contentLenghtSet =
true;
121 P(connection) =
"Connection";
122 if (Application::strcmpiP(name, connection) == 0) {
123 P(keepAlive) =
"keep-alive";
124 m_keepAlive = Application::strcmpiP(value, keepAlive) == 0;
128FLASHMEM
void Response::setDefaults() {
129 if (!m_contentTypeSet) {
130 set(
"Content-Type",
"text/plain");
133 if (m_keepAlive && !m_contentLenghtSet) {
134 set(
"Transfer-Encoding",
"chunked");
138 m_contentLenghtSet =
true;
139 set(
"Connection",
"close");
143FLASHMEM
void Response::status(
int code) {
150 m_sendingStatus =
true;
151 P(httpVersion) =
"HTTP/1.1 ";
164 }
else if (code == 204 || code == 304) {
165 m_contentLenghtSet =
true;
166 m_contentTypeSet =
true;
169 m_sendingStatus =
false;
172FLASHMEM
int Response::statusSent() {
return m_statusSent; }
174FLASHMEM
size_t Response::write(uint8_t data) {
175 if (m_shouldPrintHeaders()) {
179 m_buffer[m_bufFill++] = data;
181 if (m_bufFill == SERVER_OUTPUT_BUFFER_SIZE) {
182 if (m_headersSent && !m_contentLenghtSet) {
187 m_stream->writeFully(m_buffer, SERVER_OUTPUT_BUFFER_SIZE);
189 if (m_headersSent && !m_contentLenghtSet) {
190 m_stream->print(CRLF);
196 size_t bytesSent =
sizeof(data);
197 m_bytesSent += bytesSent;
201FLASHMEM
size_t Response::write(uint8_t *buffer,
size_t bufferLength) {
202 if (m_shouldPrintHeaders()) {
208 if (m_headersSent && !m_contentLenghtSet) {
213 m_stream->writeFully(buffer, bufferLength);
215 if (m_headersSent && !m_contentLenghtSet) {
216 m_stream->print(CRLF);
219 m_bytesSent += bufferLength;
223FLASHMEM
void Response::writeP(
const unsigned char *data,
size_t length) {
224 if (m_shouldPrintHeaders()) {
229 write(pgm_read_byte(data++));
233FLASHMEM
void Response::m_printStatus(
int code) {
235#ifndef LOW_MEMORY_MCU
237 P(Continue) =
"Continue";
242 P(SwitchingProtocols) =
"Switching Protocols";
243 printP(SwitchingProtocols);
247 P(Processing) =
"Processing";
252 P(EarlyHints) =
"Early Hints";
262 P(Created) =
"Created";
267 P(Accepted) =
"Accepted";
272 P(NonAuthoritativeInformation) =
"Non-Authoritative Information";
273 printP(NonAuthoritativeInformation);
277 P(NoContent) =
"No Content";
282 P(ResetContent) =
"Reset Content";
283 printP(ResetContent);
287 P(PartialContent) =
"Partial Content";
288 printP(PartialContent);
292 P(MultiStatus) =
"Multi-Status";
297 P(AlreadyReported) =
"Already Reported";
298 printP(AlreadyReported);
302 P(IMUsed) =
"IM Used";
307 P(MultipleChoices) =
"Multiple Choices";
308 printP(MultipleChoices);
312 P(MovedPermanently) =
"Moved Permanently";
313 printP(MovedPermanently);
322 P(SeeOther) =
"See Other";
327 P(NotModified) =
"Not Modified";
332 P(UseProxy) =
"Use Proxy";
337 P(Unused) =
"(Unused)";
342 P(TemporaryRedirect) =
"Temporary Redirect";
343 printP(TemporaryRedirect);
347 P(PermanentRedirect) =
"Permanent Redirect";
348 printP(PermanentRedirect);
352 P(BadRequest) =
"Bad Request";
357 P(Unauthorized) =
"Unauthorized";
358 printP(Unauthorized);
362 P(PaymentRequired) =
"Payment Required";
363 printP(PaymentRequired);
367 P(Forbidden) =
"Forbidden";
372 P(NotFound) =
"Not Found";
377 P(MethodNotAllowed) =
"Method Not Allowed";
378 printP(MethodNotAllowed);
382 P(NotAcceptable) =
"Not Acceptable";
383 printP(NotAcceptable);
387 P(ProxyAuthenticationRequired) =
"Proxy Authentication Required";
388 printP(ProxyAuthenticationRequired);
392 P(RequestTimeout) =
"Request Timeout";
393 printP(RequestTimeout);
397 P(Conflict) =
"Conflict";
407 P(LengthRequired) =
"Length Required";
408 printP(LengthRequired);
412 P(PreconditionFailed) =
"Precondition Failed";
413 printP(PreconditionFailed);
417 P(PayloadTooLarge) =
"Payload Too Large";
418 printP(PayloadTooLarge);
422 P(URITooLong) =
"URI Too Long";
427 P(UnsupportedMediaType) =
"Unsupported Media Type";
428 printP(UnsupportedMediaType);
432 P(RangeNotSatisfiable) =
"Range Not Satisfiable";
433 printP(RangeNotSatisfiable);
437 P(ExpectationFailed) =
"Expectation Failed";
438 printP(ExpectationFailed);
442 P(MisdirectedRequest) =
"Misdirected Request";
443 printP(MisdirectedRequest);
447 P(UnprocessableEntity) =
"Unprocessable Entity";
448 printP(UnprocessableEntity);
452 P(Locked) =
"Locked";
457 P(FailedDependency) =
"Failed Dependency";
458 printP(FailedDependency);
462 P(TooEarly) =
"Too Early";
467 P(UpgradeRequired) =
"Upgrade Required";
468 printP(UpgradeRequired);
472 P(PreconditionRequired) =
"Precondition Required";
473 printP(PreconditionRequired);
477 P(TooManyRequests) =
"Too Many Requests";
478 printP(TooManyRequests);
482 P(RequestHeaderFieldsTooLarge) =
"Request Header Fields Too Large";
483 printP(RequestHeaderFieldsTooLarge);
487 P(UnavailableForLegalReasons) =
"Unavailable For Legal Reasons";
488 printP(UnavailableForLegalReasons);
492 P(InternalServerError) =
"Internal Server Error";
493 printP(InternalServerError);
497 P(NotImplemented) =
"Not Implemented";
498 printP(NotImplemented);
502 P(BadGateway) =
"Bad Gateway";
507 P(ServiceUnavailable) =
"Service Unavailable";
508 printP(ServiceUnavailable);
512 P(GatewayTimeout) =
"Gateway Timeout";
513 printP(GatewayTimeout);
517 P(HTTPVersionNotSupported) =
"HTTP Version Not Supported";
518 printP(HTTPVersionNotSupported);
522 P(VariantAlsoNegotiates) =
"Variant Also Negotiates";
523 printP(VariantAlsoNegotiates);
527 P(InsufficientStorage) =
"Insufficient Storage";
528 printP(InsufficientStorage);
532 P(LoopDetected) =
"Loop Detected";
533 printP(LoopDetected);
537 P(NotExtended) =
"Not Extended";
542 P(NetworkAuthenticationRequired) =
"Network Authentication Required";
543 printP(NetworkAuthenticationRequired);
553 P(Created) =
"Created";
558 P(Accepted) =
"Accepted";
563 P(NoContent) =
"No Content";
568 P(SeeOther) =
"See Other";
573 P(NotModified) =
"Not Modified";
578 P(BadRequest) =
"Bad Request";
583 P(Unauthorized) =
"Unauthorized";
584 printP(Unauthorized);
588 P(PaymentRequired) =
"Payment Required";
589 printP(PaymentRequired);
593 P(Forbidden) =
"Forbidden";
598 P(NotFound) =
"Not Found";
603 P(MethodNotAllowed) =
"Method Not Allowed";
604 printP(MethodNotAllowed);
608 P(NotAcceptable) =
"Not Acceptable";
609 printP(NotAcceptable);
613 P(ProxyAuthenticationRequired) =
"Proxy Authentication Required";
614 printP(ProxyAuthenticationRequired);
618 P(RequestTimeout) =
"Request Timeout";
619 printP(RequestTimeout);
624 P(RequestHeaderFieldsTooLarge) =
"Request Header Fields Too Large";
625 printP(RequestHeaderFieldsTooLarge);
629 P(InternalServerError) =
"Internal Server Error";
630 printP(InternalServerError);
634 P(HTTPVersionNotSupported) =
"HTTP Version Not Supported";
635 printP(HTTPVersionNotSupported);
646FLASHMEM
bool Response::m_shouldPrintHeaders() {
647 return (!m_headersSent && !m_sendingHeaders && !m_sendingStatus);
650FLASHMEM
void Response::m_printHeaders() {
656FLASHMEM
void Response::m_printCRLF() { print(CRLF); }
658FLASHMEM
void Response::m_flushBuf() {
660 if (m_headersSent && !m_contentLenghtSet) {
665 m_stream->writeFully(m_buffer, m_bufFill);
667 if (m_headersSent && !m_contentLenghtSet) {
668 m_stream->print(CRLF);
675FLASHMEM
void Response::m_finalize() {
678 if (m_headersSent && !m_contentLenghtSet) {
685FLASHMEM Request::Request(net::EthernetClient *client, Response *m_response, HeaderNode *headerTail,
686 char *urlBuffer,
int urlBufferLength,
unsigned long timeout,
void *context)
687 : context(context), m_stream(client), m_response(m_response), m_method(UNKNOWN), m_minorVersion(-1),
688 m_pushback(), m_pushbackDepth(0), m_readingContent(false), m_left(0), m_bytesRead(0),
689 m_headerTail(headerTail), m_query(NULL), m_queryLength(0), m_readTimedout(false), m_path(urlBuffer),
690 m_pathLength(urlBufferLength - 1), m_pattern(NULL), m_route(NULL) {
694FLASHMEM
int Request::availableForWrite() {
return m_response->availableForWrite(); }
696FLASHMEM
int Request::available() {
return std::min(m_stream->available(), m_left + m_pushbackDepth); }
698FLASHMEM
int Request::bytesRead() {
return m_bytesRead; }
700FLASHMEM Stream *Request::stream() {
return m_stream; }
702FLASHMEM
char *Request::get(
const char *name) {
703 HeaderNode *headerNode = m_headerTail;
705 while (headerNode != NULL) {
706 if (Application::strcmpi(headerNode->name, name) == 0) {
707 return headerNode->buffer;
710 headerNode = headerNode->next;
716FLASHMEM
void Request::flush() {
return m_response->flush(); }
718FLASHMEM
bool Request::form(
char *name,
int nameLength,
char *value,
int valueLength) {
720 bool foundSomething =
false;
721 bool readingName =
true;
723 memset(name, 0, nameLength);
724 memset(value, 0, valueLength);
726 while ((ch = m_timedRead()) != -1) {
727 foundSomething =
true;
730 }
else if (ch ==
'=') {
733 }
else if (ch ==
'&') {
734 return nameLength > 0 && valueLength > 0;
735 }
else if (ch ==
'%') {
736 int high = m_timedRead();
741 int low = m_timedRead();
758 ch = (high << 4) | low;
761 if (readingName && --nameLength) {
763 }
else if (!readingName && --valueLength) {
768 return foundSomething && nameLength > 0 && valueLength > 0;
771FLASHMEM
int Request::left() {
return m_left + m_pushbackDepth; }
773FLASHMEM Request::MethodType Request::method() {
return m_method; }
775FLASHMEM
char *Request::path() {
return m_path; }
777FLASHMEM
int Request::peek() {
787FLASHMEM
void Request::push(uint8_t ch) {
788 m_pushback[m_pushbackDepth++] =
ch;
791 if (m_pushbackDepth == SERVER_PUSHBACK_BUFFER_SIZE) {
792 m_pushbackDepth = SERVER_PUSHBACK_BUFFER_SIZE - 1;
796FLASHMEM
char *Request::query() {
return m_query; }
798FLASHMEM
bool Request::query(
const char *name,
char *buffer,
int bufferLength) {
799 memset(buffer, 0, bufferLength);
801 char *position = m_query;
802 int nameLength = strlen(name);
804 while ((position = strstr(position, name))) {
805 char previous = *(position - 1);
807 if ((previous ==
'\0' || previous ==
'&') && *(position + nameLength) ==
'=') {
808 position = position + nameLength + 1;
809 while (*position && *position !=
'&' && --bufferLength) {
810 *buffer++ = *position++;
813 return bufferLength > 0;
823 if (m_pushbackDepth > 0) {
824 return m_pushback[--m_pushbackDepth];
827 if (m_readingContent && !m_left) {
832 int ch = m_stream->read();
837 if (m_readingContent) {
845int Request::read(uint8_t *buf,
size_t size) {
848 while (m_pushbackDepth > 0) {
849 *buf++ = m_pushback[--m_pushbackDepth];
854 int read = m_stream->read(buf, (
size < (
unsigned)m_left ?
size : m_left));
870FLASHMEM
bool Request::route(
const char *name,
char *buffer,
int bufferLength) {
874 while (m_pattern[i]) {
875 if (m_pattern[i] ==
'/') {
879 if (m_pattern[i++] ==
':') {
882 while ((m_pattern[i] && name[j]) && m_pattern[i] == name[j]) {
887 if (!name[j] && (m_pattern[i] ==
'/' || !m_pattern[i])) {
888 return route(part, buffer, bufferLength);
896FLASHMEM
bool Request::route(
int number,
char *buffer,
int bufferLength) {
897 memset(buffer, 0, bufferLength);
899 const char *routeStart = m_route;
901 while (*routeStart) {
902 if (*routeStart++ ==
'/') {
905 if (part == number) {
906 while (*routeStart && *routeStart !=
'/' && --bufferLength) {
907 *buffer++ = *routeStart++;
910 return bufferLength > 0;
918FLASHMEM
int Request::minorVersion() {
return m_minorVersion; }
920FLASHMEM
size_t Request::write(uint8_t data) {
return m_response->write(data); }
922FLASHMEM
size_t Request::write(uint8_t *buffer,
size_t bufferLength) {
923 return m_response->write(buffer, bufferLength);
926FLASHMEM
bool Request::m_processMethod() {
927 P(GET_VERB) =
"GET ";
928 P(HEAD_VERB) =
"HEAD ";
929 P(POST_VERB) =
"POST ";
930 P(PUT_VERB) =
"PUT ";
931 P(DELETE_VERB) =
"DELETE ";
932 P(PATCH_VERB) =
"PATCH ";
933 P(OPTIONS_VERB) =
"OPTIONS ";
935 if (m_expectP(GET_VERB)) {
937 }
else if (m_expectP(HEAD_VERB)) {
939 }
else if (m_expectP(POST_VERB)) {
941 }
else if (m_expectP(PUT_VERB)) {
943 }
else if (m_expectP(DELETE_VERB)) {
945 }
else if (m_expectP(PATCH_VERB)) {
947 }
else if (m_expectP(OPTIONS_VERB)) {
956FLASHMEM
bool Request::m_readURL() {
957 char *request = m_path;
958 int bufferLeft = m_pathLength;
961 while ((ch = m_timedRead()) != -1 && ch !=
' ' && ch !=
'\n' && ch !=
'\r' && --bufferLeft) {
963 int high = m_timedRead();
968 int low = m_timedRead();
985 ch = (high << 4) | low;
993 return bufferLeft > 0;
996FLASHMEM
bool Request::m_readVersion() {
997 while (!m_expect(CRLF)) {
1001 if (m_expectP(HTTP_10)) {
1003 }
else if (m_expectP(HTTP_11)) {
1005 }
else if (m_timedRead() == -1) {
1013FLASHMEM
void Request::m_processURL() {
1014 char *qmLocation = strchr(m_path,
'?');
1015 int qmOffset = (qmLocation == NULL) ? 0 : 1;
1017 m_pathLength = (qmLocation == NULL) ? strlen(m_path) : (qmLocation - m_path);
1018 m_query = m_path + m_pathLength + qmOffset;
1019 m_queryLength = strlen(m_query);
1026FLASHMEM
bool Request::m_processHeaders() {
1029 while (!(canEnd && m_expect(CRLF))) {
1031 P(ContentLength) =
"Content-Length:";
1032 if (m_expectP(ContentLength)) {
1033 if (!m_readInt(m_left) || !m_expect(CRLF)) {
1039 HeaderNode *headerNode = m_headerTail;
1041 while (headerNode != NULL) {
1042 P(headerSeparator) =
":";
1043 if (m_expect(headerNode->name) && m_expectP(headerSeparator)) {
1044 if (!m_headerValue(headerNode->buffer, headerNode->bufferLength)) {
1052 headerNode = headerNode->next;
1057 while (!m_expect(CRLF)) {
1058 if (m_timedRead() == -1) {
1067 m_readingContent =
true;
1072FLASHMEM
bool Request::m_headerValue(
char *buffer,
int bufferLength) {
1075 if (buffer[0] !=
'\0') {
1076 int length = strlen(buffer);
1077 buffer[length] =
',';
1078 buffer = buffer + length + 1;
1079 bufferLength = bufferLength - (length + 1);
1082 if (!m_skipSpace()) {
1086 while ((ch = m_timedRead()) != -1) {
1087 if (--bufferLength > 0) {
1091 if (m_expect(CRLF)) {
1093 return bufferLength > 0;
1100FLASHMEM
bool Request::m_readInt(
int &number) {
1101 bool negate =
false;
1102 bool gotNumber =
false;
1104 if (!m_skipSpace()) {
1108 int ch = m_timedRead();
1123 while (ch >=
'0' && ch <=
'9') {
1125 number = number * 10 +
ch -
'0';
1141FLASHMEM
void Request::m_setRoute(
const char *route,
const char *pattern) {
1143 m_pattern = pattern;
1146FLASHMEM
int Request::m_getUrlPathLength() {
return m_pathLength; }
1148FLASHMEM
bool Request::m_expect(
const char *expected) {
1149 const char *candidate = expected;
1151 while (*candidate != 0) {
1152 int ch = m_timedRead();
1157 if (tolower(ch) != tolower(*candidate++)) {
1160 while (--candidate != expected) {
1161 push(candidate[-1]);
1171FLASHMEM
bool Request::m_expectP(
const unsigned char *expected) {
1172 const unsigned char *candidate = expected;
1174 while (pgm_read_byte(candidate) != 0) {
1175 int ch = m_timedRead();
1180 if (tolower(ch) != tolower(pgm_read_byte(candidate++))) {
1183 while (--candidate != expected) {
1184 push(pgm_read_byte(candidate - 1));
1194FLASHMEM
bool Request::m_skipSpace() {
1197 while ((ch = m_timedRead()) != -1 && (ch ==
' ' || ch ==
'\t'))
1209FLASHMEM
void Request::m_reset() {
1210 HeaderNode *headerNode = m_headerTail;
1211 while (headerNode != NULL) {
1212 headerNode->buffer[0] =
'\0';
1213 headerNode = headerNode->next;
1217FLASHMEM
bool Request::m_timedout() {
return m_readTimedout; }
1219FLASHMEM
int Request::m_timedRead() {
1223 m_readTimedout =
true;
1229FLASHMEM Router::Router() : m_head(NULL) {}
1231FLASHMEM Router::~Router() {
1232 MiddlewareNode *current = m_head;
1233 MiddlewareNode *next;
1235 while (current != NULL) {
1236 next = current->next;
1245FLASHMEM
void Router::del(
const char *path, MIDDLEWARE_PARAM middleware) {
1246 m_addMiddleware(Request::DELETE, path, middleware);
1249FLASHMEM
void Router::del(MIDDLEWARE_PARAM middleware) { del(NULL, middleware); }
1251FLASHMEM
void Router::get(
const char *path, MIDDLEWARE_PARAM middleware) {
1252 m_addMiddleware(Request::GET, path, middleware);
1255FLASHMEM
void Router::get(MIDDLEWARE_PARAM middleware) { get(NULL, middleware); }
1257FLASHMEM
void Router::head(
const char *path, MIDDLEWARE_PARAM middleware) {
1258 m_addMiddleware(Request::HEAD, path, middleware);
1261FLASHMEM
void Router::head(MIDDLEWARE_PARAM middleware) { head(NULL, middleware); }
1263FLASHMEM
void Router::options(
const char *path, MIDDLEWARE_PARAM middleware) {
1264 m_addMiddleware(Request::OPTIONS, path, middleware);
1267FLASHMEM
void Router::options(MIDDLEWARE_PARAM middleware) { options(NULL, middleware); }
1269FLASHMEM
void Router::post(
const char *path, MIDDLEWARE_PARAM middleware) {
1270 m_addMiddleware(Request::POST, path, middleware);
1273FLASHMEM
void Router::post(MIDDLEWARE_PARAM middleware) { post(NULL, middleware); }
1275FLASHMEM
void Router::put(
const char *path, MIDDLEWARE_PARAM middleware) {
1276 m_addMiddleware(Request::PUT, path, middleware);
1279FLASHMEM
void Router::put(MIDDLEWARE_PARAM middleware) { put(NULL, middleware); }
1281FLASHMEM
void Router::patch(
const char *path, MIDDLEWARE_PARAM middleware) {
1282 m_addMiddleware(Request::PATCH, path, middleware);
1285FLASHMEM
void Router::patch(MIDDLEWARE_PARAM middleware) { patch(NULL, middleware); }
1287FLASHMEM
void Router::use(
const char *path, MIDDLEWARE_PARAM middleware) {
1288 m_addMiddleware(Request::ALL, path, middleware);
1291FLASHMEM
void Router::use(MIDDLEWARE_PARAM middleware) { use(NULL, middleware); }
1293FLASHMEM
void Router::use(
const char *path, Router *router) {
1294 MiddlewareNode *tail =
new MiddlewareNode();
1296 tail->middleware = NULL;
1297 tail->router = router;
1299 m_mountMiddleware(tail);
1302FLASHMEM
void Router::use(Router *router) { use(NULL, router); }
1304FLASHMEM
void Router::m_addMiddleware(Request::MethodType type,
const char *path,
1305 MIDDLEWARE_PARAM middleware) {
1306 MiddlewareNode *tail =
new MiddlewareNode();
1308 tail->middleware = middleware;
1309 tail->router = NULL;
1313 m_mountMiddleware(tail);
1316FLASHMEM
void Router::m_mountMiddleware(MiddlewareNode *tail) {
1317 if (m_head == NULL) {
1320 MiddlewareNode *current = m_head;
1322 while (current->next != NULL) {
1323 current = current->next;
1326 current->next = tail;
1330FLASHMEM
void Router::m_dispatchMiddleware(Request &request, Response &response,
int urlShift) {
1331 MiddlewareNode *middleware = m_head;
1333 while (middleware != NULL && !response.ended()) {
1334 if (middleware->router != NULL) {
1335 int prefixLength = middleware->path ? strlen(middleware->path) : 0;
1336 int shift = urlShift + prefixLength;
1338 if (middleware->path == NULL ||
1339 strncmp(middleware->path, request.path() + urlShift, prefixLength) == 0) {
1340 middleware->router->m_dispatchMiddleware(request, response, shift);
1342 }
else if (middleware->type == request.method() || middleware->type == Request::ALL) {
1343 if (middleware->path == NULL || m_routeMatch(request.path() + urlShift, middleware->path)) {
1344 request.m_setRoute(request.path() + urlShift, middleware->path);
1345 middleware->middleware(request, response);
1349 middleware = middleware->next;
1353FLASHMEM
bool Router::m_routeMatch(
const char *route,
const char *pattern) {
1354 if (pattern[0] ==
'\0' && route[0] ==
'\0') {
1362 while (pattern[i] && route[j]) {
1363 if (pattern[i] ==
':') {
1364 while (pattern[i] && pattern[i] !=
'/') {
1368 while (route[j] && route[j] !=
'/') {
1373 }
else if (pattern[i] == route[j]) {
1383 if (match && !pattern[i] && route[j] ==
'/' && !route[i]) {
1385 }
else if (pattern[i] || route[j]) {
1392FLASHMEM Application::Application() : m_final(NULL), m_notFound(NULL), m_headerTail(NULL), m_timeout(1000) {}
1394FLASHMEM
int Application::strcmpi(
const char *s1,
const char *s2) {
1397 for (i = 0; s1[i] && s2[i]; ++i) {
1398 if (s1[i] == s2[i] || (s1[i] ^ 32) == s2[i]) {
1405 if (s1[i] == s2[i]) {
1409 if ((s1[i] | 32) < (s2[i] | 32)) {
1416FLASHMEM
int Application::strcmpiP(
const char *s1,
const unsigned char *s2) {
1419 for (i = 0; s1[i] && pgm_read_byte(s2 + i); ++i) {
1420 if (s1[i] == pgm_read_byte(s2 + i) || (s1[i] ^ 32) == pgm_read_byte(s2 + i)) {
1427 if (s1[i] == pgm_read_byte(s2 + i)) {
1431 if ((s1[i] | 32) < (pgm_read_byte(s2 + i) | 32)) {
1438FLASHMEM Application::~Application() {
1439 Request::HeaderNode *current = m_headerTail;
1440 Request::HeaderNode *next;
1442 while (current != NULL) {
1443 next = current->next;
1448 m_headerTail = NULL;
1451FLASHMEM
void Application::del(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1452 m_defaultRouter.m_addMiddleware(Request::DELETE, path, middleware);
1455FLASHMEM
void Application::del(Router::MIDDLEWARE_PARAM middleware) { del(NULL, middleware); }
1457FLASHMEM
void Application::finally(Router::MIDDLEWARE_PARAM
final) { m_final =
final; }
1459FLASHMEM
void Application::get(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1460 m_defaultRouter.m_addMiddleware(Request::GET, path, middleware);
1463FLASHMEM
void Application::get(Router::MIDDLEWARE_PARAM middleware) { get(NULL, middleware); }
1465FLASHMEM
void Application::head(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1466 m_defaultRouter.m_addMiddleware(Request::HEAD, path, middleware);
1469FLASHMEM
void Application::head(Router::MIDDLEWARE_PARAM middleware) { head(NULL, middleware); }
1471FLASHMEM
void Application::notFound(Router::MIDDLEWARE_PARAM notFound) { m_notFound = notFound; }
1473FLASHMEM
void Application::options(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1474 m_defaultRouter.m_addMiddleware(Request::OPTIONS, path, middleware);
1477FLASHMEM
void Application::options(Router::MIDDLEWARE_PARAM middleware) { options(NULL, middleware); }
1479FLASHMEM
void Application::patch(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1480 m_defaultRouter.m_addMiddleware(Request::PATCH, path, middleware);
1483FLASHMEM
void Application::patch(Router::MIDDLEWARE_PARAM middleware) { patch(NULL, middleware); }
1485FLASHMEM
void Application::post(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1486 m_defaultRouter.m_addMiddleware(Request::POST, path, middleware);
1489FLASHMEM
void Application::post(Router::MIDDLEWARE_PARAM middleware) { post(NULL, middleware); }
1491FLASHMEM
void Application::put(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1492 m_defaultRouter.m_addMiddleware(Request::PUT, path, middleware);
1495FLASHMEM
void Application::put(Router::MIDDLEWARE_PARAM middleware) { put(NULL, middleware); }
1497FLASHMEM
void Application::process(net::EthernetClient *client,
void *context) {
1502 char urlBuffer[SERVER_URL_BUFFER_SIZE];
1503 process(client, urlBuffer, SERVER_URL_BUFFER_SIZE, context);
1506FLASHMEM
void Application::process(net::EthernetClient *client,
char *urlBuffer,
int urlBufferLength,
1512 uint8_t writeBuffer[SERVER_OUTPUT_BUFFER_SIZE];
1513 process(client, urlBuffer, urlBufferLength, writeBuffer, SERVER_OUTPUT_BUFFER_SIZE, context);
1516FLASHMEM
void Application::process(net::EthernetClient *client,
char *urlBuffer,
int urlBufferLength,
1517 uint8_t *writeBuffer,
int writeBufferLength,
void *context) {
1522 Response response(client, writeBuffer, writeBufferLength);
1523 Request request(client, &response, m_headerTail, urlBuffer, urlBufferLength, m_timeout, context);
1525 m_process(request, response);
1527 if (m_final != NULL) {
1528 m_final(request, response);
1531 response.m_finalize();
1533 Request::HeaderNode *headerNode = m_headerTail;
1534 while (headerNode != NULL) {
1535 headerNode->buffer[0] =
'\0';
1536 headerNode = headerNode->next;
1540FLASHMEM
void Application::process(Stream *stream,
void *context) {
1545 StreamClient client(stream);
1546 process(&client, context);
1549FLASHMEM
void Application::process(Stream *stream,
char *buffer,
int bufferLength,
void *context) {
1554 StreamClient client(stream);
1555 process(&client, buffer, bufferLength, context);
1558FLASHMEM
void Application::process(Stream *stream,
char *urlBuffer,
int urlBufferLength, uint8_t *writeBuffer,
1559 int writeBufferLength,
void *context) {
1564 StreamClient client(stream);
1565 process(&client, urlBuffer, urlBufferLength, writeBuffer, writeBufferLength, context);
1568FLASHMEM
void Application::use(
const char *path, Router::MIDDLEWARE_PARAM middleware) {
1569 m_defaultRouter.m_addMiddleware(Request::ALL, path, middleware);
1572FLASHMEM
void Application::use(Router::MIDDLEWARE_PARAM middleware) { use(NULL, middleware); }
1574FLASHMEM
void Application::setTimeout(
unsigned long timeoutMillis) { m_timeout = timeoutMillis; }
1576FLASHMEM
void Application::use(
const char *path, Router *router) { m_defaultRouter.use(path, router); }
1578FLASHMEM
void Application::use(Router *router) { use(NULL, router); }
1580FLASHMEM
void Application::m_process(Request &request, Response &response) {
1581 if (!request.m_processMethod()) {
1582 if (request.m_timedout()) {
1583 return response.sendStatus(408);
1586 return response.sendStatus(400);
1589 if (!request.m_readURL()) {
1590 if (request.m_timedout()) {
1591 return response.sendStatus(408);
1594 return response.sendStatus(414);
1597 request.m_processURL();
1599 if (!request.m_readVersion()) {
1600 if (request.m_timedout()) {
1601 return response.sendStatus(408);
1604 return response.sendStatus(505);
1607 if (!request.m_processHeaders()) {
1608 if (request.m_timedout()) {
1609 return response.sendStatus(408);
1612 return response.sendStatus(431);
1615 m_defaultRouter.m_dispatchMiddleware(request, response);
1617 if (!response.statusSent() && !response.ended()) {
1618 if (m_notFound != NULL) {
1619 response.status(404);
1620 return m_notFound(request, response);
1623 return response.sendStatus(404);
1626 if (!response.headersSent()) {
1627 response.m_printHeaders();
1631FLASHMEM
void Application::header(
const char *name,
char *buffer,
int bufferLength) {
1632 Request::HeaderNode *newNode =
new Request::HeaderNode();
1636 newNode->name = name;
1637 newNode->buffer = buffer;
1638 newNode->bufferLength = bufferLength;
1639 newNode->next = NULL;
1641 if (m_headerTail == NULL) {
1642 m_headerTail = newNode;
1644 Request::HeaderNode *headerNode = m_headerTail;
1646 while (headerNode->next != NULL) {
1647 headerNode = headerNode->next;
1650 headerNode->next = newNode;
uint32_t ch(uint32_t x, uint32_t y, uint32_t z)