mirror of
https://github.com/ksherlock/gopher.git
synced 2024-12-26 21:30:12 +00:00
http parsing
This commit is contained in:
parent
b17f0fa448
commit
3f65a4ed2e
56
htest.c
Normal file
56
htest.c
Normal 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
156
http.utils.c
Normal 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
11
http.utils.h
Normal 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
|
Loading…
Reference in New Issue
Block a user