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
http.cpp@3:ab6fd66d172c, 2017-01-28 (annotated)
- Committer:
- andrewboyson
- Date:
- Sat Jan 28 19:10:30 2017 +0000
- Revision:
- 3:ab6fd66d172c
- Parent:
- 2:849103b5a16d
- Child:
- 4:31fa7d50722c
Pulled out server part to make it closer to an independant library
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 | 3:ab6fd66d172c | 4 | #include "server.h" |
andrewboyson | 2:849103b5a16d | 5 | |
andrewboyson | 2:849103b5a16d | 6 | static void dateHeaderFromTm(struct tm* ptm, char* ptext) |
andrewboyson | 2:849103b5a16d | 7 | { |
andrewboyson | 2:849103b5a16d | 8 | 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 | 9 | } |
andrewboyson | 3:ab6fd66d172c | 10 | void HttpDateHeaderFromNow(char* pText) |
andrewboyson | 2:849103b5a16d | 11 | { |
andrewboyson | 2:849103b5a16d | 12 | struct tm tm; |
andrewboyson | 2:849103b5a16d | 13 | TimeToTmUtc(time(NULL), &tm); |
andrewboyson | 2:849103b5a16d | 14 | dateHeaderFromTm(&tm, pText); |
andrewboyson | 2:849103b5a16d | 15 | } |
andrewboyson | 3:ab6fd66d172c | 16 | void HttpDateHeaderFromDateTime(const char* date, const char *ptime, char* ptext) |
andrewboyson | 2:849103b5a16d | 17 | { |
andrewboyson | 2:849103b5a16d | 18 | struct tm tm; |
andrewboyson | 2:849103b5a16d | 19 | TimeAsciiDateTimeToTm(date, ptime, &tm); |
andrewboyson | 2:849103b5a16d | 20 | dateHeaderFromTm(&tm, ptext); |
andrewboyson | 2:849103b5a16d | 21 | } |
andrewboyson | 2:849103b5a16d | 22 | |
andrewboyson | 3:ab6fd66d172c | 23 | 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 | 24 | { |
andrewboyson | 3:ab6fd66d172c | 25 | while (true) |
andrewboyson | 3:ab6fd66d172c | 26 | { |
andrewboyson | 3:ab6fd66d172c | 27 | if (p == pE) //There are no more lines |
andrewboyson | 3:ab6fd66d172c | 28 | { |
andrewboyson | 3:ab6fd66d172c | 29 | *p = 0; //terminate the line |
andrewboyson | 3:ab6fd66d172c | 30 | return NULL; |
andrewboyson | 3:ab6fd66d172c | 31 | } |
andrewboyson | 3:ab6fd66d172c | 32 | if (*p == 0) return NULL;//There are no more lines |
andrewboyson | 3:ab6fd66d172c | 33 | if (*p == '\n') |
andrewboyson | 3:ab6fd66d172c | 34 | { |
andrewboyson | 3:ab6fd66d172c | 35 | *p = 0; //make the line a c string |
andrewboyson | 3:ab6fd66d172c | 36 | return p + 1; //return the start of the next line |
andrewboyson | 3:ab6fd66d172c | 37 | } |
andrewboyson | 3:ab6fd66d172c | 38 | if (*p < ' ') *p = 0; //terminate the line at any invalid characters |
andrewboyson | 3:ab6fd66d172c | 39 | if (*p >= 0x7f) *p = 0; //terminate the line at any invalid characters |
andrewboyson | 3:ab6fd66d172c | 40 | p++; |
andrewboyson | 3:ab6fd66d172c | 41 | } |
andrewboyson | 3:ab6fd66d172c | 42 | } |
andrewboyson | 1:5f70c361db20 | 43 | |
andrewboyson | 2:849103b5a16d | 44 | static void splitRequest(char* p, char** ppMethod, char** ppPath, char** ppQuery) |
andrewboyson | 2:849103b5a16d | 45 | { |
andrewboyson | 2:849103b5a16d | 46 | *ppMethod = NULL; |
andrewboyson | 2:849103b5a16d | 47 | *ppPath = NULL; |
andrewboyson | 2:849103b5a16d | 48 | *ppQuery = NULL; |
andrewboyson | 2:849103b5a16d | 49 | |
andrewboyson | 2:849103b5a16d | 50 | while (*p == ' ') //Move past any leading spaces |
andrewboyson | 2:849103b5a16d | 51 | { |
andrewboyson | 2:849103b5a16d | 52 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 53 | p++; |
andrewboyson | 2:849103b5a16d | 54 | } |
andrewboyson | 2:849103b5a16d | 55 | *ppMethod = p; //Record the start of the method (GET or POST) |
andrewboyson | 2:849103b5a16d | 56 | |
andrewboyson | 2:849103b5a16d | 57 | while (*p != ' ') //Move past the method |
andrewboyson | 2:849103b5a16d | 58 | { |
andrewboyson | 2:849103b5a16d | 59 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 60 | p++; |
andrewboyson | 2:849103b5a16d | 61 | } |
andrewboyson | 2:849103b5a16d | 62 | *p = 0; //Terminate the method |
andrewboyson | 2:849103b5a16d | 63 | p++; //Start at next character |
andrewboyson | 2:849103b5a16d | 64 | |
andrewboyson | 2:849103b5a16d | 65 | while (*p == ' ') //Move past any spaces |
andrewboyson | 2:849103b5a16d | 66 | { |
andrewboyson | 2:849103b5a16d | 67 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 68 | p++; |
andrewboyson | 2:849103b5a16d | 69 | } |
andrewboyson | 2:849103b5a16d | 70 | *ppPath = p; //Record the start of the path |
andrewboyson | 2:849103b5a16d | 71 | |
andrewboyson | 2:849103b5a16d | 72 | while (*p != ' ') //Move past the path and query |
andrewboyson | 2:849103b5a16d | 73 | { |
andrewboyson | 2:849103b5a16d | 74 | if (*p == 0) return; |
andrewboyson | 2:849103b5a16d | 75 | if (*p == '?') |
andrewboyson | 2:849103b5a16d | 76 | { |
andrewboyson | 2:849103b5a16d | 77 | *p = 0; //Terminate the path |
andrewboyson | 2:849103b5a16d | 78 | *ppQuery = p + 1; //Record the start of the query |
andrewboyson | 2:849103b5a16d | 79 | } |
andrewboyson | 2:849103b5a16d | 80 | p++; |
andrewboyson | 2:849103b5a16d | 81 | } |
andrewboyson | 2:849103b5a16d | 82 | *p = 0; //Terminate the path or query |
andrewboyson | 2:849103b5a16d | 83 | } |
andrewboyson | 3:ab6fd66d172c | 84 | static void splitHeader(char* p, char** ppName, char** ppValue) |
andrewboyson | 3:ab6fd66d172c | 85 | { |
andrewboyson | 3:ab6fd66d172c | 86 | *ppName = p; //Record the start of the name |
andrewboyson | 3:ab6fd66d172c | 87 | *ppValue = NULL; |
andrewboyson | 2:849103b5a16d | 88 | |
andrewboyson | 3:ab6fd66d172c | 89 | while (*p != ':') //Loop to an ':' |
andrewboyson | 3:ab6fd66d172c | 90 | { |
andrewboyson | 3:ab6fd66d172c | 91 | if (!*p) return; |
andrewboyson | 3:ab6fd66d172c | 92 | p++; |
andrewboyson | 3:ab6fd66d172c | 93 | } |
andrewboyson | 3:ab6fd66d172c | 94 | *p = 0; //Terminate the name by replacing the ':' with a NUL char |
andrewboyson | 3:ab6fd66d172c | 95 | p++; |
andrewboyson | 3:ab6fd66d172c | 96 | while (*p == ' ') //Move past any spaces |
andrewboyson | 3:ab6fd66d172c | 97 | { |
andrewboyson | 3:ab6fd66d172c | 98 | if (*p == 0) return; |
andrewboyson | 3:ab6fd66d172c | 99 | p++; |
andrewboyson | 3:ab6fd66d172c | 100 | } |
andrewboyson | 3:ab6fd66d172c | 101 | *ppValue = p; //Record the start of the value |
andrewboyson | 3:ab6fd66d172c | 102 | } |
andrewboyson | 2:849103b5a16d | 103 | int HttpRequest(int position, int len, char *pData) |
andrewboyson | 3:ab6fd66d172c | 104 | { |
andrewboyson | 2:849103b5a16d | 105 | char* pMethod; |
andrewboyson | 2:849103b5a16d | 106 | char* pPath; |
andrewboyson | 2:849103b5a16d | 107 | char* pQuery; |
andrewboyson | 2:849103b5a16d | 108 | |
andrewboyson | 3:ab6fd66d172c | 109 | char* pEnd = pData + len; |
andrewboyson | 3:ab6fd66d172c | 110 | char* pThis = pData; |
andrewboyson | 3:ab6fd66d172c | 111 | char* pNext = getNextLine(pThis, pEnd); |
andrewboyson | 3:ab6fd66d172c | 112 | splitRequest(pThis, &pMethod, &pPath, &pQuery); |
andrewboyson | 2:849103b5a16d | 113 | |
andrewboyson | 3:ab6fd66d172c | 114 | char* pLastModified; |
andrewboyson | 3:ab6fd66d172c | 115 | while(pNext) |
andrewboyson | 2:849103b5a16d | 116 | { |
andrewboyson | 3:ab6fd66d172c | 117 | pThis = pNext; |
andrewboyson | 3:ab6fd66d172c | 118 | pNext = getNextLine(pThis, pEnd); |
andrewboyson | 3:ab6fd66d172c | 119 | if (*pThis == 0) break; //This line is empty ie no more headers |
andrewboyson | 3:ab6fd66d172c | 120 | char* pName; |
andrewboyson | 3:ab6fd66d172c | 121 | char* pValue; |
andrewboyson | 3:ab6fd66d172c | 122 | splitHeader(pThis, &pName, &pValue); |
andrewboyson | 3:ab6fd66d172c | 123 | if (strcmp(pName, "If-Modified-Since") == 0) pLastModified = pValue; |
andrewboyson | 2:849103b5a16d | 124 | } |
andrewboyson | 2:849103b5a16d | 125 | |
andrewboyson | 3:ab6fd66d172c | 126 | return ServerRequest(pPath, pLastModified); |
andrewboyson | 2:849103b5a16d | 127 | } |
andrewboyson | 2:849103b5a16d | 128 | int HttpResponse(int position, int mss, char *pData, int todo) |
andrewboyson | 2:849103b5a16d | 129 | { |
andrewboyson | 3:ab6fd66d172c | 130 | return ServerResponse(position, mss, pData, todo); |
andrewboyson | 2:849103b5a16d | 131 | } |
andrewboyson | 3:ab6fd66d172c | 132 |