mirror of
https://github.com/ksherlock/gopher.git
synced 2025-01-21 07:30:52 +00:00
parse http headers, handle content-length
This commit is contained in:
parent
a8779193d6
commit
b7420ca623
166
http.c
166
http.c
@ -20,6 +20,7 @@
|
|||||||
#include <TCPIP.h>
|
#include <TCPIP.h>
|
||||||
#include <MiscTool.h>
|
#include <MiscTool.h>
|
||||||
#include <Memory.h>
|
#include <Memory.h>
|
||||||
|
#include <IntMath.h>
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -34,6 +35,7 @@
|
|||||||
#include "flags.h"
|
#include "flags.h"
|
||||||
#include "readline2.h"
|
#include "readline2.h"
|
||||||
#include "http.utils.h"
|
#include "http.utils.h"
|
||||||
|
#include "s16debug.h"
|
||||||
|
|
||||||
static int do_http_0_9(
|
static int do_http_0_9(
|
||||||
const char *url,
|
const char *url,
|
||||||
@ -124,6 +126,12 @@ static int parseHeaders(Word ipid, FILE *file, Handle dict)
|
|||||||
// need to yank it later.
|
// need to yank it later.
|
||||||
// if rb.terminater == '\r' && term == TERMINATOR_CR_LF ...
|
// if rb.terminater == '\r' && term == TERMINATOR_CR_LF ...
|
||||||
|
|
||||||
|
if (rb.terminator)
|
||||||
|
{
|
||||||
|
if (flags._i || flags._I)
|
||||||
|
fputc('\r', file);
|
||||||
|
}
|
||||||
|
|
||||||
if (line == 0) return -1;
|
if (line == 0) return -1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -192,6 +200,149 @@ static int parseHeaders(Word ipid, FILE *file, Handle dict)
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum {
|
||||||
|
TE_unknown = -1,
|
||||||
|
TE_identity = 0,
|
||||||
|
TE_chunked
|
||||||
|
};
|
||||||
|
|
||||||
|
int read_response(Word ipid, FILE *file, Handle dict)
|
||||||
|
{
|
||||||
|
// get the file size and content encoding
|
||||||
|
// from the dict.
|
||||||
|
// todo -- check for text/* ?
|
||||||
|
// -m <mimetype>?
|
||||||
|
|
||||||
|
|
||||||
|
char *value;
|
||||||
|
Word valueSize;
|
||||||
|
int transferEncoding;
|
||||||
|
|
||||||
|
LongWord contentSize;
|
||||||
|
|
||||||
|
|
||||||
|
contentSize = 0;
|
||||||
|
transferEncoding = -1;
|
||||||
|
value = DictionaryGet(dict, "Content-Length", 14, &valueSize);
|
||||||
|
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
contentSize = Dec2Long(value, valueSize, 0);
|
||||||
|
transferEncoding = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
value = DictionaryGet(dict, "Transfer-Encoding", 17, &valueSize);
|
||||||
|
if (value)
|
||||||
|
{
|
||||||
|
Word *wp = (Word *)value;
|
||||||
|
// id en ti ty ?
|
||||||
|
// ch un ke d ?
|
||||||
|
if (valueSize == 8
|
||||||
|
&& (wp[0] | 0x2020) == 0x6469
|
||||||
|
&& (wp[1] | 0x2020) == 0x6e65
|
||||||
|
&& (wp[2] | 0x2020) == 0x6974
|
||||||
|
&& (wp[3] | 0x2020) == 0x7974
|
||||||
|
)
|
||||||
|
{
|
||||||
|
transferEncoding = 0;
|
||||||
|
}
|
||||||
|
else if (valueSize == 7
|
||||||
|
&& (wp[0] | 0x2020) == 0x6863
|
||||||
|
&& (wp[1] | 0x2020) == 0x6e75
|
||||||
|
&& (wp[2] | 0x2020) == 0x656b
|
||||||
|
&& (value[6] | 0x20) == 0x64
|
||||||
|
)
|
||||||
|
{
|
||||||
|
transferEncoding = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Unsupported Transfer Encoding: %.*s\n",
|
||||||
|
valueSize, value);
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ?
|
||||||
|
if (transferEncoding == -1)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Content Size not provided.\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (transferEncoding == 0)
|
||||||
|
{
|
||||||
|
// identity.
|
||||||
|
// just read contentLength bytes.
|
||||||
|
|
||||||
|
static srBuff sr;
|
||||||
|
static rrBuff rr;
|
||||||
|
|
||||||
|
int terr;
|
||||||
|
|
||||||
|
// todo -- time out if no data for 30 seconds?
|
||||||
|
|
||||||
|
while (contentSize)
|
||||||
|
{
|
||||||
|
LongWord count = 256;
|
||||||
|
|
||||||
|
|
||||||
|
TCPIPPoll();
|
||||||
|
TCPIPStatusTCP(ipid, &sr);
|
||||||
|
|
||||||
|
count = sr.srRcvQueued;
|
||||||
|
if (count > contentSize) count = contentSize;
|
||||||
|
|
||||||
|
if (count == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
terr = TCPIPReadTCP(ipid, 2, (Ref)0, count, &rr);
|
||||||
|
|
||||||
|
if (_toolErr) break;
|
||||||
|
|
||||||
|
if (rr.rrBuffCount)
|
||||||
|
{
|
||||||
|
Handle h = rr.rrBuffHandle;
|
||||||
|
HLock(h);
|
||||||
|
|
||||||
|
fwrite(*(char **)h, 1, count, file);
|
||||||
|
contentSize -= rr.rrBuffCount;
|
||||||
|
|
||||||
|
DisposeHandle(h);
|
||||||
|
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (terr && !rr.rrMoreFlag)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "read error\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transferEncoding == 1)
|
||||||
|
{
|
||||||
|
// chunked..
|
||||||
|
// format = hex <CRLF>
|
||||||
|
// data .. <CRLF>
|
||||||
|
/// 0 <CRLF>
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int do_http_1_1(
|
static int do_http_1_1(
|
||||||
const char *url,
|
const char *url,
|
||||||
URLComponents *components,
|
URLComponents *components,
|
||||||
@ -275,9 +426,22 @@ static int do_http_1_1(
|
|||||||
// todo -- check the headers for content length, transfer-encoding.
|
// todo -- check the headers for content length, transfer-encoding.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
cookie = 0;
|
||||||
|
while ((cookie = DictionaryEnumerate(dict, &e, cookie)))
|
||||||
|
{
|
||||||
|
s16_debug_printf("%.*s -> %.*s",
|
||||||
|
e.keySize, e.key, e.valueSize, e.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ok == 200)
|
||||||
|
{
|
||||||
|
if (!flags._I)
|
||||||
|
read_response(ipid, file, dict);
|
||||||
|
}
|
||||||
|
DisposeHandle(dict);
|
||||||
|
|
||||||
|
|
||||||
ok = read_binary(ipid, file);
|
//ok = read_binary(ipid, file);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user