Andrew Boyson / net

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Jan 11 17:38:21 2018 +0000
Revision:
61:aad055f1b0d1
Parent:
tcp/http/httprequest.cpp@54:84ef2b29cf7e
Child:
110:67c96c143c2a
Removed dependence on Mbed OS

Who changed what in which revision?

UserRevisionLine numberNew 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 54:84ef2b29cf7e 5 char* HttpGetNextLine(char* p, char* pE) //Terminates this line and returns the start of the next line or NULL if none
andrewboyson 54:84ef2b29cf7e 6 {
andrewboyson 54:84ef2b29cf7e 7 while (true)
andrewboyson 54:84ef2b29cf7e 8 {
andrewboyson 54:84ef2b29cf7e 9 if (p == pE) //There are no more lines
andrewboyson 54:84ef2b29cf7e 10 {
andrewboyson 54:84ef2b29cf7e 11 *p = 0; //terminate the line
andrewboyson 54:84ef2b29cf7e 12 return NULL;
andrewboyson 54:84ef2b29cf7e 13 }
andrewboyson 54:84ef2b29cf7e 14 if (*p == 0) return NULL;//There are no more lines
andrewboyson 54:84ef2b29cf7e 15 if (*p == '\n')
andrewboyson 54:84ef2b29cf7e 16 {
andrewboyson 54:84ef2b29cf7e 17 *p = 0; //make the line a c string
andrewboyson 54:84ef2b29cf7e 18 return p + 1; //return the start of the next line
andrewboyson 54:84ef2b29cf7e 19 }
andrewboyson 54:84ef2b29cf7e 20 if (*p < ' ') *p = 0; //terminate the line at any invalid characters
andrewboyson 54:84ef2b29cf7e 21 if (*p >= 0x7f) *p = 0; //terminate the line at any invalid characters
andrewboyson 54:84ef2b29cf7e 22 p++;
andrewboyson 54:84ef2b29cf7e 23 }
andrewboyson 54:84ef2b29cf7e 24 }
andrewboyson 54:84ef2b29cf7e 25
andrewboyson 54:84ef2b29cf7e 26 void HttpSplitRequest(char* p, char** ppMethod, char** ppPath, char** ppQuery)
andrewboyson 54:84ef2b29cf7e 27 {
andrewboyson 54:84ef2b29cf7e 28 *ppMethod = NULL;
andrewboyson 54:84ef2b29cf7e 29 *ppPath = NULL;
andrewboyson 54:84ef2b29cf7e 30 *ppQuery = NULL;
andrewboyson 54:84ef2b29cf7e 31
andrewboyson 54:84ef2b29cf7e 32 while (*p == ' ') //Move past any leading spaces
andrewboyson 54:84ef2b29cf7e 33 {
andrewboyson 54:84ef2b29cf7e 34 if (*p == 0) return;
andrewboyson 54:84ef2b29cf7e 35 p++;
andrewboyson 54:84ef2b29cf7e 36 }
andrewboyson 54:84ef2b29cf7e 37 *ppMethod = p; //Record the start of the method (GET or POST)
andrewboyson 54:84ef2b29cf7e 38
andrewboyson 54:84ef2b29cf7e 39 while (*p != ' ') //Move past the method
andrewboyson 54:84ef2b29cf7e 40 {
andrewboyson 54:84ef2b29cf7e 41 if (*p == 0) return;
andrewboyson 54:84ef2b29cf7e 42 p++;
andrewboyson 54:84ef2b29cf7e 43 }
andrewboyson 54:84ef2b29cf7e 44 *p = 0; //Terminate the method
andrewboyson 54:84ef2b29cf7e 45 p++; //Start at next character
andrewboyson 54:84ef2b29cf7e 46
andrewboyson 54:84ef2b29cf7e 47 while (*p == ' ') //Move past any spaces
andrewboyson 54:84ef2b29cf7e 48 {
andrewboyson 54:84ef2b29cf7e 49 if (*p == 0) return;
andrewboyson 54:84ef2b29cf7e 50 p++;
andrewboyson 54:84ef2b29cf7e 51 }
andrewboyson 54:84ef2b29cf7e 52 *ppPath = p; //Record the start of the path
andrewboyson 54:84ef2b29cf7e 53
andrewboyson 54:84ef2b29cf7e 54 while (*p != ' ') //Move past the path and query
andrewboyson 54:84ef2b29cf7e 55 {
andrewboyson 54:84ef2b29cf7e 56 if (*p == 0) return;
andrewboyson 54:84ef2b29cf7e 57 if (*p == '?')
andrewboyson 54:84ef2b29cf7e 58 {
andrewboyson 54:84ef2b29cf7e 59 *p = 0; //Terminate the path
andrewboyson 54:84ef2b29cf7e 60 *ppQuery = p + 1; //Record the start of the query
andrewboyson 54:84ef2b29cf7e 61 }
andrewboyson 54:84ef2b29cf7e 62 p++;
andrewboyson 54:84ef2b29cf7e 63 }
andrewboyson 54:84ef2b29cf7e 64 *p = 0; //Terminate the path or query
andrewboyson 54:84ef2b29cf7e 65 }
andrewboyson 54:84ef2b29cf7e 66 void HttpSplitHeader(char* p, char** ppName, char** ppValue)
andrewboyson 54:84ef2b29cf7e 67 {
andrewboyson 54:84ef2b29cf7e 68 *ppName = p; //Record the start of the name
andrewboyson 54:84ef2b29cf7e 69 *ppValue = NULL;
andrewboyson 54:84ef2b29cf7e 70
andrewboyson 54:84ef2b29cf7e 71 while (*p != ':') //Loop to an ':'
andrewboyson 54:84ef2b29cf7e 72 {
andrewboyson 54:84ef2b29cf7e 73 if (!*p) return;
andrewboyson 54:84ef2b29cf7e 74 p++;
andrewboyson 54:84ef2b29cf7e 75 }
andrewboyson 54:84ef2b29cf7e 76 *p = 0; //Terminate the name by replacing the ':' with a NUL char
andrewboyson 54:84ef2b29cf7e 77 p++;
andrewboyson 54:84ef2b29cf7e 78 while (*p == ' ') //Move past any spaces
andrewboyson 54:84ef2b29cf7e 79 {
andrewboyson 54:84ef2b29cf7e 80 if (*p == 0) return;
andrewboyson 54:84ef2b29cf7e 81 p++;
andrewboyson 54:84ef2b29cf7e 82 }
andrewboyson 54:84ef2b29cf7e 83 *ppValue = p; //Record the start of the value
andrewboyson 54:84ef2b29cf7e 84 }
andrewboyson 54:84ef2b29cf7e 85
andrewboyson 54:84ef2b29cf7e 86 char* HttpSplitQuery(char* p, char** ppName, char** ppValue) //returns the start of the next name value pair
andrewboyson 54:84ef2b29cf7e 87 {
andrewboyson 54:84ef2b29cf7e 88 *ppName = p; //Record the start of the name
andrewboyson 54:84ef2b29cf7e 89 *ppValue = NULL;
andrewboyson 54:84ef2b29cf7e 90
andrewboyson 54:84ef2b29cf7e 91 while (*p != '=') //Loop to an '='
andrewboyson 54:84ef2b29cf7e 92 {
andrewboyson 54:84ef2b29cf7e 93 if (*p == 0) return 0;
andrewboyson 54:84ef2b29cf7e 94 p++;
andrewboyson 54:84ef2b29cf7e 95 }
andrewboyson 54:84ef2b29cf7e 96 *p = 0; //Terminate the name by replacing the '=' with a NUL char
andrewboyson 54:84ef2b29cf7e 97 p++; //Move on to the start of the value
andrewboyson 54:84ef2b29cf7e 98 *ppValue = p; //Record the start of the value
andrewboyson 54:84ef2b29cf7e 99 while (*p != '&') //Loop to a '&'
andrewboyson 54:84ef2b29cf7e 100 {
andrewboyson 54:84ef2b29cf7e 101 if (*p == 0) return 0;
andrewboyson 54:84ef2b29cf7e 102 p++;
andrewboyson 54:84ef2b29cf7e 103 }
andrewboyson 54:84ef2b29cf7e 104 *p = 0; //Terminate the value by replacing the '&' with a NULL
andrewboyson 54:84ef2b29cf7e 105 return p + 1;
andrewboyson 54:84ef2b29cf7e 106 }
andrewboyson 54:84ef2b29cf7e 107 static int hexToInt(char c)
andrewboyson 54:84ef2b29cf7e 108 {
andrewboyson 54:84ef2b29cf7e 109 int nibble;
andrewboyson 54:84ef2b29cf7e 110 if (c >= '0' && c <= '9') nibble = c - '0';
andrewboyson 54:84ef2b29cf7e 111 if (c >= 'A' && c <= 'F') nibble = c - 'A' + 0xA;
andrewboyson 54:84ef2b29cf7e 112 if (c >= 'a' && c <= 'f') nibble = c - 'a' + 0xA;
andrewboyson 54:84ef2b29cf7e 113 return nibble;
andrewboyson 54:84ef2b29cf7e 114 }
andrewboyson 54:84ef2b29cf7e 115 void HttpDecodeValue(char* value)
andrewboyson 54:84ef2b29cf7e 116 {
andrewboyson 54:84ef2b29cf7e 117 char* pDst = value;
andrewboyson 61:aad055f1b0d1 118 int a;
andrewboyson 54:84ef2b29cf7e 119 for (char* pSrc = value; *pSrc; pSrc++)
andrewboyson 54:84ef2b29cf7e 120 {
andrewboyson 54:84ef2b29cf7e 121 char c = *pSrc;
andrewboyson 54:84ef2b29cf7e 122 switch (c)
andrewboyson 54:84ef2b29cf7e 123 {
andrewboyson 54:84ef2b29cf7e 124 case '+':
andrewboyson 54:84ef2b29cf7e 125 c = ' ';
andrewboyson 54:84ef2b29cf7e 126 break;
andrewboyson 54:84ef2b29cf7e 127 case '%':
andrewboyson 54:84ef2b29cf7e 128 c = *++pSrc;
andrewboyson 54:84ef2b29cf7e 129 if (c == 0) break;
andrewboyson 54:84ef2b29cf7e 130 a = hexToInt(c);
andrewboyson 54:84ef2b29cf7e 131 a <<= 4;
andrewboyson 54:84ef2b29cf7e 132 c = *++pSrc;
andrewboyson 54:84ef2b29cf7e 133 if (c == 0) break;
andrewboyson 54:84ef2b29cf7e 134 a += hexToInt(c);
andrewboyson 54:84ef2b29cf7e 135 c = a;
andrewboyson 54:84ef2b29cf7e 136 break;
andrewboyson 54:84ef2b29cf7e 137 default:
andrewboyson 54:84ef2b29cf7e 138 c = *pSrc;
andrewboyson 54:84ef2b29cf7e 139 break;
andrewboyson 54:84ef2b29cf7e 140 }
andrewboyson 54:84ef2b29cf7e 141 *pDst++ = c;
andrewboyson 54:84ef2b29cf7e 142 }
andrewboyson 54:84ef2b29cf7e 143 *pDst = 0;
andrewboyson 54:84ef2b29cf7e 144 }
andrewboyson 54:84ef2b29cf7e 145
andrewboyson 54:84ef2b29cf7e 146 void HttpReadRequest(char *pData, int len, char** ppMethod, char** ppPath, char** ppQuery, char** ppLastModified)
andrewboyson 54:84ef2b29cf7e 147 {
andrewboyson 54:84ef2b29cf7e 148 char* pEnd = pData + len;
andrewboyson 54:84ef2b29cf7e 149 char* pThis = pData;
andrewboyson 54:84ef2b29cf7e 150 char* pNext = HttpGetNextLine(pThis, pEnd);
andrewboyson 54:84ef2b29cf7e 151 HttpSplitRequest(pThis, ppMethod, ppPath, ppQuery);
andrewboyson 54:84ef2b29cf7e 152
andrewboyson 54:84ef2b29cf7e 153 while(pNext)
andrewboyson 54:84ef2b29cf7e 154 {
andrewboyson 54:84ef2b29cf7e 155 pThis = pNext;
andrewboyson 54:84ef2b29cf7e 156 pNext = HttpGetNextLine(pThis, pEnd);
andrewboyson 54:84ef2b29cf7e 157 if (*pThis == 0) break; //This line is empty ie no more headers
andrewboyson 54:84ef2b29cf7e 158 char* pName;
andrewboyson 54:84ef2b29cf7e 159 char* pValue;
andrewboyson 54:84ef2b29cf7e 160 HttpSplitHeader(pThis, &pName, &pValue);
andrewboyson 54:84ef2b29cf7e 161 if (strcmp(pName, "If-Modified-Since") == 0) *ppLastModified = pValue;
andrewboyson 54:84ef2b29cf7e 162 }
andrewboyson 54:84ef2b29cf7e 163 }