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

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?

UserRevisionLine numberNew 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