Common stuff for all my devices' web server pages: css, login, log, ipv4, ipv6, firmware update, clock, reset info etc.

Dependents:   oldheating gps motorhome heating

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers httprequest.c Source File

httprequest.c

00001 #include <stdbool.h>
00002 #include <stdio.h>
00003 #include <string.h>
00004 #include <stdlib.h>
00005 
00006 #include "http.h"
00007 #include "log.h"
00008 
00009 static char* terminateThisAndGetNextLine(char* p, char* pE) //Terminates this line and returns the start of the next line or NULL if none
00010 {
00011     while (true)
00012     {
00013         if ( p == pE)   { *p = 0; return NULL;  } //no more buffer - relies on having designed the buffer to be bigger than an ethernet packet
00014         if (*p == 0)              return NULL;    //there are no more lines
00015         if (*p == '\n') { *p = 0; return p + 1; } //return the start of the next line
00016         if (*p < ' ')     *p = 0;                 //terminate the line at any invalid characters but keep going to find the start of the next line
00017         if (*p >= 0x7f)   *p = 0;                 //terminate the line at any invalid characters but keep going to find the start of the next line
00018         p++;
00019     }
00020 }
00021 
00022 static void splitRequest(char* p, char** ppMethod, char** ppPath, char** ppQuery)
00023 {        
00024     *ppMethod   = NULL;
00025     *ppPath     = NULL;
00026     *ppQuery    = NULL;
00027 
00028     while (*p == ' ')         //Move past any leading spaces
00029     {
00030         if (*p == 0) return;
00031         p++;
00032     }
00033     *ppMethod = p;            //Record the start of the method (GET or POST)
00034  
00035     while (*p != ' ')         //Move past the method
00036     {
00037         if (*p == 0) return;
00038         p++;
00039     } 
00040     *p = 0;                   //Terminate the method
00041     p++;                      //Start at next character
00042 
00043     while (*p == ' ')         //Move past any spaces
00044     {
00045         if (*p == 0) return;
00046         p++;
00047     } 
00048     *ppPath = p;              //Record the start of the path
00049     
00050     while (*p != ' ')         //Move past the path and query
00051     {
00052         if (*p == 0) return;
00053         if (*p == '?')
00054         {
00055             *p = 0;           //Terminate the path
00056             *ppQuery = p + 1; //Record the start of the query
00057         }
00058         p++;
00059     }
00060     *p = 0;                   //Terminate the path or query
00061 }
00062 static void splitHeader(char* p, char** ppName, char** ppValue)
00063 {
00064     *ppName    = p;                     //Record the start of the name
00065     *ppValue   = NULL;
00066 
00067     while (*p != ':')                   //Loop to an ':'
00068     {
00069         if (!*p) return;
00070         p++;
00071     }
00072     *p = 0;                             //Terminate the name by replacing the ':' with a NUL char
00073     p++;
00074     while (*p == ' ')                   //Move past any spaces
00075     {
00076         if (*p == 0) return;
00077         p++;
00078     }
00079     *ppValue = p;                       //Record the start of the value
00080 }
00081 int HttpRequestRead(char *pData, int len, char** ppMethod, char** ppPath, char** ppQuery, char** ppLastModified, char** ppCookies, int* pContentLength)
00082 {
00083     char* pEnd = pData + len;
00084     char* pThis = pData;
00085     char* pNext = terminateThisAndGetNextLine(pThis, pEnd);
00086     splitRequest(pThis, ppMethod, ppPath, ppQuery);
00087 
00088     *ppLastModified = NULL; //Return NULL if no 'If-Modified-Since' line
00089     *ppCookies      = NULL; //Return NULL if no 'Cookie'            line
00090     *pContentLength = 0;    //Return 0    if no 'Content-Length'    line
00091     while(pNext)
00092     {
00093         pThis = pNext;
00094         pNext = terminateThisAndGetNextLine(pThis, pEnd);
00095         if (*pThis == 0) break;     //This line is empty ie no more headers
00096         char* pName;
00097         char* pValue;
00098         splitHeader(pThis, &pName, &pValue);
00099         if (HttpSameStrCaseInsensitive(pName, "If-Modified-Since")) *ppLastModified = pValue;
00100         if (HttpSameStrCaseInsensitive(pName, "Cookie"           )) *ppCookies      = pValue;
00101         if (HttpSameStrCaseInsensitive(pName, "Content-Length"   )) *pContentLength = atoi(pValue);
00102     }
00103     if (pNext) return pNext - pData;
00104     else       return len;
00105 }