A stack which works with or without an Mbed os library. Provides IPv4 or IPv6 with a full 1500 byte buffer.
Dependents: oldheating gps motorhome heating
tcp/http.cpp@10:f0854784e960, 2017-04-16 (annotated)
- Committer:
- andrewboyson
- Date:
- Sun Apr 16 14:21:55 2017 +0000
- Revision:
- 10:f0854784e960
- Parent:
- http.cpp@4:31fa7d50722c
- Child:
- 21:02c82594c8c0
MDNS and LLMNR now working.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
andrewboyson | 2:849103b5a16d | 1 | #include "mbed.h" |
andrewboyson | 3:ab6fd66d172c | 2 | #include "http.h" |
andrewboyson | 2:849103b5a16d | 3 | #include "time.h" |
andrewboyson | 4:31fa7d50722c | 4 | |
andrewboyson | 4:31fa7d50722c | 5 | |
andrewboyson | 4:31fa7d50722c | 6 | int (*HttpRequestFunction)(char *pPath, char *pLastModified); //Plumb into this from your html server |
andrewboyson | 4:31fa7d50722c | 7 | int (*HttpResponseFunction)(int position, int mss, char *pData, int todo); //Plumb into this from your html server |
andrewboyson | 2:849103b5a16d | 8 | |
andrewboyson | 2:849103b5a16d | 9 | static void dateHeaderFromTm(struct tm* ptm, char* ptext) |
andrewboyson | 2:849103b5a16d | 10 | { |
andrewboyson | 2:849103b5a16d | 11 | size_t size = strftime(ptext, HTTP_DATE_LENGTH, "%a, %d %b %Y %H:%M:%S GMT", ptm);//Sun, 06 Nov 1994 08:49:37 GMT ; RFC 822, updated by RFC 1123 |
andrewboyson | 2:849103b5a16d | 12 | } |
andrewboyson | 3:ab6fd66d172c | 13 | void HttpDateHeaderFromNow(char* pText) |
andrewboyson | 2:849103b5a16d | 14 | { |
andrewboyson | 2:849103b5a16d | 15 | struct tm tm; |
andrewboyson | 2:849103b5a16d | 16 | TimeToTmUtc(time(NULL), &tm); |
andrewboyson | 2:849103b5a16d | 17 | dateHeaderFromTm(&tm, pText); |
andrewboyson | 2:849103b5a16d | 18 | } |
andrewboyson | 3:ab6fd66d172c | 19 | void HttpDateHeaderFromDateTime(const char* date, const char *ptime, char* ptext) |
andrewboyson | 2:849103b5a16d | 20 | { |
andrewboyson | 2:849103b5a16d | 21 | struct tm tm; |
andrewboyson | 2:849103b5a16d | 22 | TimeAsciiDateTimeToTm(date, ptime, &tm); |
andrewboyson | 2:849103b5a16d | 23 | dateHeaderFromTm(&tm, ptext); |
andrewboyson | 2:849103b5a16d | 24 | } |
andrewboyson | 2:849103b5a16d | 25 | |
andrewboyson | 3:ab6fd66d172c | 26 | static char* getNextLine(char* p, char* pE) //Terminates this line and returns the start of the next line or NULL if none |
andrewboyson | 3:ab6fd66d172c | 27 | { |
andrewboyson | 3:ab6fd66d172c | 28 | while (true) |
andrewboyson | 3:ab6fd66d172c | 29 | { |
andrewboyson | 3:ab6fd66d172c | 30 | if (p == pE) //There are no more lines |
andrewboyson | 3:ab6fd66d172c | 31 | { |
andrewboyson | 3:ab6fd66d172c | 32 | *p = 0; //terminate the line |
andrewboyson | 3:ab6fd66d172c | 33 | return NULL; |
andrewboyson | 3:ab6fd66d172c | 34 | } |
andrewboyson | 3:ab6fd66d172c | 35 | if (*p == 0) return NULL;//There are no more lines |
andrewboyson | 3:ab6fd66d172c | 36 | if (*p == '\n') |
andrewboyson | 3:ab6fd66d172c | 37 | { |
andrewboyson | 3:ab6fd66d172c | 38 | *p = 0; //make the line a c string |
andrewboyson | 3:ab6fd66d172c | 39 | return p + 1; //return the start of the next line |
andrewboyson | 3:ab6fd66d172c | 40 | } |
andrewboyson | 3:ab6fd66d172c | 41 | if (*p < ' ') *p = 0; //terminate the line at any invalid characters |
andrewboyson | 3:ab6fd66d172c | 42 | if (*p >= 0x7f) *p = 0; //terminate the line at any invalid characters |
andrewboyson | 3:ab6fd66d172c | 43 | p++; |
andrewboyson | 3:ab6fd66d172c | 44 | } |
andrewboyson | 3:ab6fd66d172c | 45 | } |
andrewboyson | 1:5f70c361db20 | 46 | |
andrewboyson | 2:849103b5a16d | 47 | static void splitRequest(char* p, char** ppMethod, char** ppPath, char** ppQuery) |
andrewboyson | 2:849103b5a16d | 48 | { |
andrewboyson | 2:849103b5a16d | 49 | *ppMethod = NULL; |
andrewboyson | 2:849103b5a16d | 50 | *ppPath = NULL; |
andrewboyson | 2:849103b5a16d | 51 | *ppQuery = NULL; |
andrewboyson | 2:849103b5a16d | 52 | |
andrewboyson | 2:849103b5a16d | 53 | while (*p == ' ') //Move past any leading spaces |
andrewboyson | 2:849103b5a16d | 54 | { |
andrewboyson | 2:849103b5a16d | 55 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 56 | p++; |
andrewboyson | 2:849103b5a16d | 57 | } |
andrewboyson | 2:849103b5a16d | 58 | *ppMethod = p; //Record the start of the method (GET or POST) |
andrewboyson | 2:849103b5a16d | 59 | |
andrewboyson | 2:849103b5a16d | 60 | while (*p != ' ') //Move past the method |
andrewboyson | 2:849103b5a16d | 61 | { |
andrewboyson | 2:849103b5a16d | 62 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 63 | p++; |
andrewboyson | 2:849103b5a16d | 64 | } |
andrewboyson | 2:849103b5a16d | 65 | *p = 0; //Terminate the method |
andrewboyson | 2:849103b5a16d | 66 | p++; //Start at next character |
andrewboyson | 2:849103b5a16d | 67 | |
andrewboyson | 2:849103b5a16d | 68 | while (*p == ' ') //Move past any spaces |
andrewboyson | 2:849103b5a16d | 69 | { |
andrewboyson | 2:849103b5a16d | 70 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 71 | p++; |
andrewboyson | 2:849103b5a16d | 72 | } |
andrewboyson | 2:849103b5a16d | 73 | *ppPath = p; //Record the start of the path |
andrewboyson | 2:849103b5a16d | 74 | |
andrewboyson | 2:849103b5a16d | 75 | while (*p != ' ') //Move past the path and query |
andrewboyson | 2:849103b5a16d | 76 | { |
andrewboyson | 2:849103b5a16d | 77 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 78 | if (*p == '?') |
andrewboyson | 2:849103b5a16d | 79 | { |
andrewboyson | 2:849103b5a16d | 80 | *p = 0; //Terminate the path |
andrewboyson | 2:849103b5a16d | 81 | *ppQuery = p + 1; //Record the start of the query |
andrewboyson | 2:849103b5a16d | 82 | } |
andrewboyson | 2:849103b5a16d | 83 | p++; |
andrewboyson | 2:849103b5a16d | 84 | } |
andrewboyson | 2:849103b5a16d | 85 | *p = 0; //Terminate the path or query |
andrewboyson | 2:849103b5a16d | 86 | } |
andrewboyson | 3:ab6fd66d172c | 87 | static void splitHeader(char* p, char** ppName, char** ppValue) |
andrewboyson | 3:ab6fd66d172c | 88 | { |
andrewboyson | 3:ab6fd66d172c | 89 | *ppName = p; //Record the start of the name |
andrewboyson | 3:ab6fd66d172c | 90 | *ppValue = NULL; |
andrewboyson | 2:849103b5a16d | 91 | |
andrewboyson | 3:ab6fd66d172c | 92 | while (*p != ':') //Loop to an ':' |
andrewboyson | 3:ab6fd66d172c | 93 | { |
andrewboyson | 3:ab6fd66d172c | 94 | if (!*p) return; |
andrewboyson | 3:ab6fd66d172c | 95 | p++; |
andrewboyson | 3:ab6fd66d172c | 96 | } |
andrewboyson | 3:ab6fd66d172c | 97 | *p = 0; //Terminate the name by replacing the ':' with a NUL char |
andrewboyson | 3:ab6fd66d172c | 98 | p++; |
andrewboyson | 3:ab6fd66d172c | 99 | while (*p == ' ') //Move past any spaces |
andrewboyson | 3:ab6fd66d172c | 100 | { |
andrewboyson | 3:ab6fd66d172c | 101 | if (*p == 0) return; |
andrewboyson | 3:ab6fd66d172c | 102 | p++; |
andrewboyson | 3:ab6fd66d172c | 103 | } |
andrewboyson | 3:ab6fd66d172c | 104 | *ppValue = p; //Record the start of the value |
andrewboyson | 3:ab6fd66d172c | 105 | } |
andrewboyson | 4:31fa7d50722c | 106 | |
andrewboyson | 2:849103b5a16d | 107 | int HttpRequest(int position, int len, char *pData) |
andrewboyson | 3:ab6fd66d172c | 108 | { |
andrewboyson | 2:849103b5a16d | 109 | char* pMethod; |
andrewboyson | 2:849103b5a16d | 110 | char* pPath; |
andrewboyson | 2:849103b5a16d | 111 | char* pQuery; |
andrewboyson | 2:849103b5a16d | 112 | |
andrewboyson | 3:ab6fd66d172c | 113 | char* pEnd = pData + len; |
andrewboyson | 3:ab6fd66d172c | 114 | char* pThis = pData; |
andrewboyson | 3:ab6fd66d172c | 115 | char* pNext = getNextLine(pThis, pEnd); |
andrewboyson | 3:ab6fd66d172c | 116 | splitRequest(pThis, &pMethod, &pPath, &pQuery); |
andrewboyson | 2:849103b5a16d | 117 | |
andrewboyson | 3:ab6fd66d172c | 118 | char* pLastModified; |
andrewboyson | 3:ab6fd66d172c | 119 | while(pNext) |
andrewboyson | 2:849103b5a16d | 120 | { |
andrewboyson | 3:ab6fd66d172c | 121 | pThis = pNext; |
andrewboyson | 3:ab6fd66d172c | 122 | pNext = getNextLine(pThis, pEnd); |
andrewboyson | 3:ab6fd66d172c | 123 | if (*pThis == 0) break; //This line is empty ie no more headers |
andrewboyson | 3:ab6fd66d172c | 124 | char* pName; |
andrewboyson | 3:ab6fd66d172c | 125 | char* pValue; |
andrewboyson | 3:ab6fd66d172c | 126 | splitHeader(pThis, &pName, &pValue); |
andrewboyson | 3:ab6fd66d172c | 127 | if (strcmp(pName, "If-Modified-Since") == 0) pLastModified = pValue; |
andrewboyson | 2:849103b5a16d | 128 | } |
andrewboyson | 2:849103b5a16d | 129 | |
andrewboyson | 4:31fa7d50722c | 130 | return HttpRequestFunction(pPath, pLastModified); |
andrewboyson | 2:849103b5a16d | 131 | } |
andrewboyson | 2:849103b5a16d | 132 | int HttpResponse(int position, int mss, char *pData, int todo) |
andrewboyson | 2:849103b5a16d | 133 | { |
andrewboyson | 4:31fa7d50722c | 134 | return HttpResponseFunction(position, mss, pData, todo); |
andrewboyson | 2:849103b5a16d | 135 | } |
andrewboyson | 3:ab6fd66d172c | 136 |