http parsing

This commit is contained in:
Kelvin Sherlock 2012-04-29 22:46:22 -04:00
parent b17f0fa448
commit 3f65a4ed2e
3 changed files with 223 additions and 0 deletions

56
htest.c Normal file
View File

@ -0,0 +1,56 @@
#include <stdio.h>
#include <string.h>
#include "http.utils.h"
int main(int argc, char **argv)
{
int version;
int status;
int ok;
char *cp;
URLRange k, v;
cp = "HTTP/1.0 200 OK";
ok = parseStatusLine(cp, strlen(cp), &version, &status);
if (!ok || version != 0x0100 || status != 200)
{
fprintf(stderr, "%s: %x %d\n", cp, version, status);
}
cp = "HTTP/1.1 404 bleh";
ok = parseStatusLine(cp, strlen(cp), &version, &status);
if (!ok || version != 0x0101 || status != 404)
{
fprintf(stderr, "%s: %x %d\n", cp, version, status);
}
cp = "http/1.10 200 asdasd as dsad asd";
ok = parseStatusLine(cp, strlen(cp), &version, &status);
if (!ok || version != 0x010a || status != 200)
{
fprintf(stderr, "%s: %x %d\n", cp, version, status);
}
cp = "key: value";
ok = parseHeaderLine(cp, strlen(cp), &k, &v);
if (!ok
|| k.location != 0
|| k.length != 3
|| v.location != 5
|| v.length != 5)
{
fprintf(stderr, "%s: %.*s, %.*s\n", cp,
k.length, cp + k.location,
v.length, cp + v.location);
}
return 0;
}

156
http.utils.c Normal file
View File

@ -0,0 +1,156 @@
#ifdef __ORCAC__
#pragma optimize 79
#pragma noroot
#endif
#include <ctype.h>
#include "url.h"
int parseHeaderLine(const char *cp, unsigned length, URLRange *key, URLRange *value)
{
unsigned i, l;
key->location = 0;
key->length = 0;
value->location = 0;
value->length = 0;
// trim any trailing whitespace.
while (length)
{
if (isspace(cp[length - 1]))
--length;
else break;
}
if (!length) return 0;
/* format:
* key: value
* /^([^:]+):\s+(.*)$/
* -or-
* value [continuation of previous line]
* /^\s+(.*)$/
*/
for (i = 0; i < length; ++i)
{
if (cp[i] == ':') break;
}
if (i == length)
{
// try as value only
i = 0;
}
else
{
key->length = i;
i = i + 1;
}
// now gobble up all the whitespace...
for ( ; i < length; ++i)
{
if (!isspace(cp[i])) break;
}
// no value? no problem!
if (i == length) return 1;
value->location = i;
value->length = length - i;
return 1;
}
int parseStatusLine(const char *cp, unsigned length, int *version, int *status)
{
/*
* HTTP/1.1 200 OK etc.
*
*/
unsigned short *wp;
int i;
char c;
int x;
*version = 0;
*status = 0;
wp = (unsigned short *)cp;
// HTTP/
if (length <= 5) return 0;
if ((wp[0] | 0x2020) != 0x7468) return 0; // 'ht'
if ((wp[1] | 0x2020) != 0x7074) return 0; // 'tp'
if (cp[4] != '/') return 0;
// version string.
// \d+ . \d+
i = 5;
c = cp[i];
if (!isdigit(c)) return 0;
x = c - '0';
for (i = i + 1; i < length; ++i)
{
c = cp[i];
if (!isdigit(c)) break;
x = (x << 1) + (x << 3) + (c - '0');
}
*version = x << 8;
if (i == length) return 0;
if (cp[i++] != '.') return 0;
c = cp[i];
if (!isdigit(c)) return 0;
x = c - '0';
for (i = i + 1; i < length; ++i)
{
c = cp[i];
if (!isdigit(c)) break;
x = (x << 1) + (x << 3) + (c - '0');
}
*version |= x;
// 1+ space
if (i == length) return 0;
c = cp[i];
if (!isspace(c)) return 0;
for (i = i + 1; i < length; ++i)
{
c = cp[i];
if (!isspace(c)) break;
}
if (i == length) return 0;
c = cp[i];
if (!isdigit(c)) return 0;
x = c - '0';
for (i = i + 1; i < length; ++i)
{
c = cp[i];
if (!isdigit(c)) break;
x = (x << 1) + (x << 3) + (c - '0');
}
*status = x;
// rest of status line unimportant.
return 1;
}

11
http.utils.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef __HTTP_UTILS_H__
#define __HTTP_UTILS_H__
#include "url.h"
int parseHeaderLine(const char *line, unsigned length, URLRange *key, URLRange *value);
int parseStatusLine(const char *cp, unsigned length, int *version, int *status);
#endif