57
57
#define WEBDUINO_READ_TIMEOUT_IN_MS 1000
58
58
#endif
59
59
60
+ #ifndef WEBDUINO_URL_PATH_COMMAND_LENGTH
61
+ #define WEBDUINO_URL_PATH_COMMAND_LENGTH 8
62
+ #endif
63
+
60
64
#ifndef WEBDUINO_FAIL_MESSAGE
61
65
#define WEBDUINO_FAIL_MESSAGE " <h1>EPIC FAIL</h1>"
62
66
#endif
@@ -158,6 +162,13 @@ class WebServer: public Print
158
162
typedef void Command (WebServer &server, ConnectionType type,
159
163
char *url_tail, bool tail_complete);
160
164
165
+ // Prototype for the optional function which consumes the URL path itself.
166
+ // url_path contains pointers to the seperate parts of the URL path where '/'
167
+ // was used as the delimiter.
168
+ typedef void UrlPathCommand (WebServer &server, ConnectionType type,
169
+ char **url_path, char *url_tail,
170
+ bool tail_complete);
171
+
161
172
// constructor for webserver object
162
173
WebServer (const char *urlPrefix = " " , int port = 80 );
163
174
@@ -184,6 +195,11 @@ class WebServer: public Print
184
195
// add a new command to be run at the URL specified by verb
185
196
void addCommand (const char *verb, Command *cmd);
186
197
198
+ // Set command that's run if default command or URL specified commands do
199
+ // not run, uses extra url_path parameter to allow resolving the URL in the
200
+ // function.
201
+ void setUrlPathCommand (UrlPathCommand *cmd);
202
+
187
203
// utility function to output CRLF pair
188
204
void printCRLF ();
189
205
@@ -296,6 +312,7 @@ class WebServer: public Print
296
312
Command *cmd;
297
313
} m_commands[8 ];
298
314
char m_cmdCount;
315
+ UrlPathCommand *m_urlPathCmd;
299
316
300
317
void reset ();
301
318
void getRequest (WebServer::ConnectionType &type, char *request, int *length);
@@ -329,7 +346,8 @@ WebServer::WebServer(const char *urlPrefix, int port) :
329
346
m_cmdCount(0 ),
330
347
m_contentLength(0 ),
331
348
m_failureCmd(&defaultFailCmd),
332
- m_defaultCmd(&defaultFailCmd)
349
+ m_defaultCmd(&defaultFailCmd),
350
+ m_urlPathCmd(NULL )
333
351
{
334
352
}
335
353
@@ -357,6 +375,11 @@ void WebServer::addCommand(const char *verb, Command *cmd)
357
375
}
358
376
}
359
377
378
+ void WebServer::setUrlPathCommand (UrlPathCommand *cmd)
379
+ {
380
+ m_urlPathCmd = cmd;
381
+ }
382
+
360
383
size_t WebServer::write (uint8_t ch)
361
384
{
362
385
return m_client.write (ch);
@@ -472,6 +495,36 @@ bool WebServer::dispatchCommand(ConnectionType requestType, char *verb,
472
495
return true ;
473
496
}
474
497
}
498
+ // Check if UrlPathCommand is assigned.
499
+ if (m_urlPathCmd != NULL )
500
+ {
501
+ // Initialize with null bytes, so number of parts can be determined.
502
+ char *url_path[WEBDUINO_URL_PATH_COMMAND_LENGTH] = {0 };
503
+ int part = 0 ;
504
+
505
+ // URL path should be terminated with null byte.
506
+ *(verb + verb_len) = 0 ;
507
+
508
+ // First URL path part is at the start of verb.
509
+ url_path[part++] = verb;
510
+ // Replace all slashes ('/') with a null byte so every part of the URL
511
+ // path is a seperate string. Add every char following a '/' as a new
512
+ // part of the URL, even if that char is a '/' (which will be replaced
513
+ // with a null byte).
514
+ for (char * p = verb; p < verb + verb_len; p++)
515
+ {
516
+ if (*p == ' /' )
517
+ {
518
+ *p = 0 ;
519
+ url_path[part++] = p + 1 ;
520
+ // Don't try to assign out of array bounds.
521
+ if (part == WEBDUINO_URL_PATH_COMMAND_LENGTH) break ;
522
+ }
523
+ }
524
+ m_urlPathCmd (*this , requestType, url_path,
525
+ verb + verb_len + qm_offset, tail_complete);
526
+ return true ;
527
+ }
475
528
}
476
529
return false ;
477
530
}
0 commit comments