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
- Committer:
- andrewboyson
- Date:
- 2018-01-11
- Revision:
- 61:aad055f1b0d1
- Parent:
- tcp/http/httprequest.cpp@ 54:84ef2b29cf7e
- Child:
- 110:67c96c143c2a
File content as of revision 61:aad055f1b0d1:
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
char* HttpGetNextLine(char* p, char* pE) //Terminates this line and returns the start of the next line or NULL if none
{
while (true)
{
if (p == pE) //There are no more lines
{
*p = 0; //terminate the line
return NULL;
}
if (*p == 0) return NULL;//There are no more lines
if (*p == '\n')
{
*p = 0; //make the line a c string
return p + 1; //return the start of the next line
}
if (*p < ' ') *p = 0; //terminate the line at any invalid characters
if (*p >= 0x7f) *p = 0; //terminate the line at any invalid characters
p++;
}
}
void HttpSplitRequest(char* p, char** ppMethod, char** ppPath, char** ppQuery)
{
*ppMethod = NULL;
*ppPath = NULL;
*ppQuery = NULL;
while (*p == ' ') //Move past any leading spaces
{
if (*p == 0) return;
p++;
}
*ppMethod = p; //Record the start of the method (GET or POST)
while (*p != ' ') //Move past the method
{
if (*p == 0) return;
p++;
}
*p = 0; //Terminate the method
p++; //Start at next character
while (*p == ' ') //Move past any spaces
{
if (*p == 0) return;
p++;
}
*ppPath = p; //Record the start of the path
while (*p != ' ') //Move past the path and query
{
if (*p == 0) return;
if (*p == '?')
{
*p = 0; //Terminate the path
*ppQuery = p + 1; //Record the start of the query
}
p++;
}
*p = 0; //Terminate the path or query
}
void HttpSplitHeader(char* p, char** ppName, char** ppValue)
{
*ppName = p; //Record the start of the name
*ppValue = NULL;
while (*p != ':') //Loop to an ':'
{
if (!*p) return;
p++;
}
*p = 0; //Terminate the name by replacing the ':' with a NUL char
p++;
while (*p == ' ') //Move past any spaces
{
if (*p == 0) return;
p++;
}
*ppValue = p; //Record the start of the value
}
char* HttpSplitQuery(char* p, char** ppName, char** ppValue) //returns the start of the next name value pair
{
*ppName = p; //Record the start of the name
*ppValue = NULL;
while (*p != '=') //Loop to an '='
{
if (*p == 0) return 0;
p++;
}
*p = 0; //Terminate the name by replacing the '=' with a NUL char
p++; //Move on to the start of the value
*ppValue = p; //Record the start of the value
while (*p != '&') //Loop to a '&'
{
if (*p == 0) return 0;
p++;
}
*p = 0; //Terminate the value by replacing the '&' with a NULL
return p + 1;
}
static int hexToInt(char c)
{
int nibble;
if (c >= '0' && c <= '9') nibble = c - '0';
if (c >= 'A' && c <= 'F') nibble = c - 'A' + 0xA;
if (c >= 'a' && c <= 'f') nibble = c - 'a' + 0xA;
return nibble;
}
void HttpDecodeValue(char* value)
{
char* pDst = value;
int a;
for (char* pSrc = value; *pSrc; pSrc++)
{
char c = *pSrc;
switch (c)
{
case '+':
c = ' ';
break;
case '%':
c = *++pSrc;
if (c == 0) break;
a = hexToInt(c);
a <<= 4;
c = *++pSrc;
if (c == 0) break;
a += hexToInt(c);
c = a;
break;
default:
c = *pSrc;
break;
}
*pDst++ = c;
}
*pDst = 0;
}
void HttpReadRequest(char *pData, int len, char** ppMethod, char** ppPath, char** ppQuery, char** ppLastModified)
{
char* pEnd = pData + len;
char* pThis = pData;
char* pNext = HttpGetNextLine(pThis, pEnd);
HttpSplitRequest(pThis, ppMethod, ppPath, ppQuery);
while(pNext)
{
pThis = pNext;
pNext = HttpGetNextLine(pThis, pEnd);
if (*pThis == 0) break; //This line is empty ie no more headers
char* pName;
char* pValue;
HttpSplitHeader(pThis, &pName, &pValue);
if (strcmp(pName, "If-Modified-Since") == 0) *ppLastModified = pValue;
}
}