Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
tcp/http/httprequest.c@117:a725e5ad4fad, 2019-01-26 (annotated)
- Committer:
- andrewboyson
- Date:
- Sat Jan 26 15:44:59 2019 +0000
- Revision:
- 117:a725e5ad4fad
- Parent:
- 110:67c96c143c2a
- Child:
- 118:067cb5bce7e3
Found bug in function which retrieves the 'If-Last-Modified' line: the lastModified pointer is not initialised so could point anywhere if no line. Although checked for NULL it is not checked for other random values. Initialised to NULL.
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| andrewboyson | 61:aad055f1b0d1 | 1 | #include <stdbool.h> |
| andrewboyson | 61:aad055f1b0d1 | 2 | #include <stdio.h> |
| andrewboyson | 61:aad055f1b0d1 | 3 | #include <string.h> |
| andrewboyson | 54:84ef2b29cf7e | 4 | |
| andrewboyson | 110:67c96c143c2a | 5 | #include "http.h" |
| andrewboyson | 110:67c96c143c2a | 6 | |
| andrewboyson | 110:67c96c143c2a | 7 | static char* terminateThisAndGetNextLine(char* p, char* pE) //Terminates this line and returns the start of the next line or NULL if none |
| andrewboyson | 54:84ef2b29cf7e | 8 | { |
| andrewboyson | 54:84ef2b29cf7e | 9 | while (true) |
| andrewboyson | 54:84ef2b29cf7e | 10 | { |
| andrewboyson | 110:67c96c143c2a | 11 | if ( p == pE) { *p = 0; return NULL; } //No more buffer - relies on having designed the buffer to be bigger than an ethernet packet |
| andrewboyson | 110:67c96c143c2a | 12 | if (*p == 0) return NULL; //There are no more lines |
| andrewboyson | 110:67c96c143c2a | 13 | if (*p == '\n') { *p = 0; return p + 1; } //return the start of the next line |
| andrewboyson | 110:67c96c143c2a | 14 | if (*p < ' ') { *p = 0; return NULL; } //Invalid characters |
| andrewboyson | 110:67c96c143c2a | 15 | if (*p >= 0x7f) { *p = 0; return NULL; } //Invalid characters |
| andrewboyson | 54:84ef2b29cf7e | 16 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 17 | } |
| andrewboyson | 54:84ef2b29cf7e | 18 | } |
| andrewboyson | 54:84ef2b29cf7e | 19 | |
| andrewboyson | 110:67c96c143c2a | 20 | static void splitRequest(char* p, char** ppMethod, char** ppPath, char** ppQuery) |
| andrewboyson | 54:84ef2b29cf7e | 21 | { |
| andrewboyson | 54:84ef2b29cf7e | 22 | *ppMethod = NULL; |
| andrewboyson | 54:84ef2b29cf7e | 23 | *ppPath = NULL; |
| andrewboyson | 54:84ef2b29cf7e | 24 | *ppQuery = NULL; |
| andrewboyson | 54:84ef2b29cf7e | 25 | |
| andrewboyson | 54:84ef2b29cf7e | 26 | while (*p == ' ') //Move past any leading spaces |
| andrewboyson | 54:84ef2b29cf7e | 27 | { |
| andrewboyson | 54:84ef2b29cf7e | 28 | if (*p == 0) return; |
| andrewboyson | 54:84ef2b29cf7e | 29 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 30 | } |
| andrewboyson | 54:84ef2b29cf7e | 31 | *ppMethod = p; //Record the start of the method (GET or POST) |
| andrewboyson | 54:84ef2b29cf7e | 32 | |
| andrewboyson | 54:84ef2b29cf7e | 33 | while (*p != ' ') //Move past the method |
| andrewboyson | 54:84ef2b29cf7e | 34 | { |
| andrewboyson | 54:84ef2b29cf7e | 35 | if (*p == 0) return; |
| andrewboyson | 54:84ef2b29cf7e | 36 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 37 | } |
| andrewboyson | 54:84ef2b29cf7e | 38 | *p = 0; //Terminate the method |
| andrewboyson | 54:84ef2b29cf7e | 39 | p++; //Start at next character |
| andrewboyson | 54:84ef2b29cf7e | 40 | |
| andrewboyson | 54:84ef2b29cf7e | 41 | while (*p == ' ') //Move past any spaces |
| andrewboyson | 54:84ef2b29cf7e | 42 | { |
| andrewboyson | 54:84ef2b29cf7e | 43 | if (*p == 0) return; |
| andrewboyson | 54:84ef2b29cf7e | 44 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 45 | } |
| andrewboyson | 54:84ef2b29cf7e | 46 | *ppPath = p; //Record the start of the path |
| andrewboyson | 54:84ef2b29cf7e | 47 | |
| andrewboyson | 54:84ef2b29cf7e | 48 | while (*p != ' ') //Move past the path and query |
| andrewboyson | 54:84ef2b29cf7e | 49 | { |
| andrewboyson | 54:84ef2b29cf7e | 50 | if (*p == 0) return; |
| andrewboyson | 54:84ef2b29cf7e | 51 | if (*p == '?') |
| andrewboyson | 54:84ef2b29cf7e | 52 | { |
| andrewboyson | 54:84ef2b29cf7e | 53 | *p = 0; //Terminate the path |
| andrewboyson | 54:84ef2b29cf7e | 54 | *ppQuery = p + 1; //Record the start of the query |
| andrewboyson | 54:84ef2b29cf7e | 55 | } |
| andrewboyson | 54:84ef2b29cf7e | 56 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 57 | } |
| andrewboyson | 54:84ef2b29cf7e | 58 | *p = 0; //Terminate the path or query |
| andrewboyson | 54:84ef2b29cf7e | 59 | } |
| andrewboyson | 110:67c96c143c2a | 60 | static void splitHeader(char* p, char** ppName, char** ppValue) |
| andrewboyson | 54:84ef2b29cf7e | 61 | { |
| andrewboyson | 54:84ef2b29cf7e | 62 | *ppName = p; //Record the start of the name |
| andrewboyson | 54:84ef2b29cf7e | 63 | *ppValue = NULL; |
| andrewboyson | 54:84ef2b29cf7e | 64 | |
| andrewboyson | 54:84ef2b29cf7e | 65 | while (*p != ':') //Loop to an ':' |
| andrewboyson | 54:84ef2b29cf7e | 66 | { |
| andrewboyson | 54:84ef2b29cf7e | 67 | if (!*p) return; |
| andrewboyson | 54:84ef2b29cf7e | 68 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 69 | } |
| andrewboyson | 54:84ef2b29cf7e | 70 | *p = 0; //Terminate the name by replacing the ':' with a NUL char |
| andrewboyson | 54:84ef2b29cf7e | 71 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 72 | while (*p == ' ') //Move past any spaces |
| andrewboyson | 54:84ef2b29cf7e | 73 | { |
| andrewboyson | 54:84ef2b29cf7e | 74 | if (*p == 0) return; |
| andrewboyson | 54:84ef2b29cf7e | 75 | p++; |
| andrewboyson | 54:84ef2b29cf7e | 76 | } |
| andrewboyson | 54:84ef2b29cf7e | 77 | *ppValue = p; //Record the start of the value |
| andrewboyson | 54:84ef2b29cf7e | 78 | } |
| andrewboyson | 117:a725e5ad4fad | 79 | void HttpRequestRead(char *pData, int len, char** ppMethod, char** ppPath, char** ppQuery, char** ppLastModified) |
| andrewboyson | 54:84ef2b29cf7e | 80 | { |
| andrewboyson | 54:84ef2b29cf7e | 81 | char* pEnd = pData + len; |
| andrewboyson | 110:67c96c143c2a | 82 | char* pThis = pData; |
| andrewboyson | 110:67c96c143c2a | 83 | char* pNext = terminateThisAndGetNextLine(pThis, pEnd); |
| andrewboyson | 110:67c96c143c2a | 84 | splitRequest(pThis, ppMethod, ppPath, ppQuery); |
| andrewboyson | 54:84ef2b29cf7e | 85 | |
| andrewboyson | 117:a725e5ad4fad | 86 | *ppLastModified = NULL; //Return NULL if no 'If-Modified-Since' line |
| andrewboyson | 54:84ef2b29cf7e | 87 | while(pNext) |
| andrewboyson | 54:84ef2b29cf7e | 88 | { |
| andrewboyson | 54:84ef2b29cf7e | 89 | pThis = pNext; |
| andrewboyson | 110:67c96c143c2a | 90 | pNext = terminateThisAndGetNextLine(pThis, pEnd); |
| andrewboyson | 54:84ef2b29cf7e | 91 | if (*pThis == 0) break; //This line is empty ie no more headers |
| andrewboyson | 54:84ef2b29cf7e | 92 | char* pName; |
| andrewboyson | 54:84ef2b29cf7e | 93 | char* pValue; |
| andrewboyson | 110:67c96c143c2a | 94 | splitHeader(pThis, &pName, &pValue); |
| andrewboyson | 54:84ef2b29cf7e | 95 | if (strcmp(pName, "If-Modified-Since") == 0) *ppLastModified = pValue; |
| andrewboyson | 54:84ef2b29cf7e | 96 | } |
| andrewboyson | 54:84ef2b29cf7e | 97 | } |