зеркало из https://github.com/mozilla/pjs.git
bug 153691: some HTTP 1.1 support; also, view.cgi now shows HTTP request
This commit is contained in:
Родитель
bc3a3c68a0
Коммит
87af4e04dc
|
@ -47,11 +47,11 @@ PURIFY =
|
|||
OBJS = \
|
||||
addurl.$(OBJ) \
|
||||
app.$(OBJ) \
|
||||
buf.$(OBJ) \
|
||||
file.$(OBJ) \
|
||||
hash.$(OBJ) \
|
||||
html.$(OBJ) \
|
||||
http.$(OBJ) \
|
||||
io.$(OBJ) \
|
||||
mime.$(OBJ) \
|
||||
net.$(OBJ) \
|
||||
thread.$(OBJ) \
|
||||
|
@ -60,13 +60,9 @@ OBJS = \
|
|||
view.$(OBJ)
|
||||
|
||||
EXES = \
|
||||
dnstest$(EXE) \
|
||||
ftp$(EXE) \
|
||||
grab$(EXE) \
|
||||
httpd$(EXE) \
|
||||
link$(EXE) \
|
||||
pop$(EXE) \
|
||||
proxy$(EXE) \
|
||||
robot$(EXE) \
|
||||
urltest$(EXE) \
|
||||
view.cgi$(EXE)
|
||||
|
|
|
@ -47,11 +47,11 @@ PURIFY =
|
|||
OBJS = \
|
||||
addurl.$(OBJ) \
|
||||
app.$(OBJ) \
|
||||
buf.$(OBJ) \
|
||||
file.$(OBJ) \
|
||||
hash.$(OBJ) \
|
||||
html.$(OBJ) \
|
||||
http.$(OBJ) \
|
||||
io.$(OBJ) \
|
||||
mime.$(OBJ) \
|
||||
net.$(OBJ) \
|
||||
thread.$(OBJ) \
|
||||
|
@ -60,13 +60,9 @@ OBJS = \
|
|||
view.$(OBJ)
|
||||
|
||||
EXES = \
|
||||
dnstest$(EXE) \
|
||||
ftp$(EXE) \
|
||||
grab$(EXE) \
|
||||
httpd$(EXE) \
|
||||
link$(EXE) \
|
||||
pop$(EXE) \
|
||||
proxy$(EXE) \
|
||||
robot$(EXE) \
|
||||
urltest$(EXE) \
|
||||
view.cgi$(EXE)
|
||||
|
|
|
@ -58,6 +58,7 @@ Description of Files
|
|||
|
||||
addurl.c, addurl.h: adds URLs to a list
|
||||
all.h: header that includes all the required headers
|
||||
buf.c, buf.h: I/O routines
|
||||
cgiview.c: the view.cgi tool
|
||||
config*: autoconf-related files
|
||||
dns.c: experimental DNS toy
|
||||
|
@ -71,7 +72,6 @@ Description of Files
|
|||
http.c, http.h: simple HTTP implementation
|
||||
index.html: used with view.cgi tool
|
||||
INSTALL: see this file for build instructions
|
||||
io.c, io.h: I/O routines
|
||||
link.c: the "link" tool
|
||||
main.h: very simple callbacks, could be more object-oriented
|
||||
Makefile, Makefile.in: to build everything
|
||||
|
|
|
@ -70,11 +70,11 @@ typedef struct App App;
|
|||
|
||||
#include "addurl.h"
|
||||
#include "app.h"
|
||||
#include "buf.h"
|
||||
#include "file.h"
|
||||
#include "hash.h"
|
||||
#include "html.h"
|
||||
#include "http.h"
|
||||
#include "io.h"
|
||||
#include "mime.h"
|
||||
#include "net.h"
|
||||
#include "thread.h"
|
||||
|
|
|
@ -30,52 +30,67 @@ appContentType(App *app, unsigned char *contentType)
|
|||
}
|
||||
|
||||
static void
|
||||
appHTML(App *app, Input *input)
|
||||
appHTML(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTMLAttributeName(App *app, HTML *html, Input *input)
|
||||
appHTMLAttributeName(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTMLAttributeValue(App *app, HTML *html, Input *input)
|
||||
appHTMLAttributeValue(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTMLTag(App *app, HTML *html, Input *input)
|
||||
appHTMLTag(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTMLText(App *app, Input *input)
|
||||
appHTMLText(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTP(App *app, Input *input)
|
||||
appHTTPRequest(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPBody(App *app, Input *input)
|
||||
appHTTPRequestHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPCharSet(App *app, unsigned char *charset)
|
||||
appHTTPRequestHeaderValue(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPHeaderName(App *app, Input *input)
|
||||
appHTTPResponse(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPHeaderValue(App *app, Input *input, unsigned char *url)
|
||||
appHTTPResponseBody(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPResponseCharSet(App *app, unsigned char *charset)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPResponseHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
appHTTPResponseHeaderValue(App *app, Buf *buf, unsigned char *url)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -97,11 +112,14 @@ App appDefault =
|
|||
appHTMLAttributeValue,
|
||||
appHTMLTag,
|
||||
appHTMLText,
|
||||
appHTTP,
|
||||
appHTTPBody,
|
||||
appHTTPCharSet,
|
||||
appHTTPHeaderName,
|
||||
appHTTPHeaderValue,
|
||||
appHTTPRequest,
|
||||
appHTTPRequestHeaderName,
|
||||
appHTTPRequestHeaderValue,
|
||||
appHTTPResponse,
|
||||
appHTTPResponseBody,
|
||||
appHTTPResponseCharSet,
|
||||
appHTTPResponseHeaderName,
|
||||
appHTTPResponseHeaderValue,
|
||||
appStatus,
|
||||
appTime
|
||||
};
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "html.h"
|
||||
#include "io.h"
|
||||
#include "view.h"
|
||||
|
||||
enum {
|
||||
|
@ -40,16 +39,28 @@ enum {
|
|||
struct App
|
||||
{
|
||||
void (*contentType)(App *app, unsigned char *contentType);
|
||||
void (*html)(App *app, Input *input);
|
||||
void (*htmlAttributeName)(App *app, HTML *html, Input *input);
|
||||
void (*htmlAttributeValue)(App *app, HTML *html, Input *input);
|
||||
void (*htmlTag)(App *app, HTML *html, Input *input);
|
||||
void (*htmlText)(App *app, Input *input);
|
||||
void (*http)(App *app, Input *input);
|
||||
void (*httpBody)(App *app, Input *input);
|
||||
void (*httpCharSet)(App *app, unsigned char *charset);
|
||||
void (*httpHeaderName)(App *app, Input *input);
|
||||
void (*httpHeaderValue)(App *app, Input *input, unsigned char *url);
|
||||
|
||||
void (*html)(App *app, Buf *buf);
|
||||
void (*htmlAttributeName)(App *app, HTML *html, Buf *buf);
|
||||
void (*htmlAttributeValue)(App *app, HTML *html, Buf *buf);
|
||||
void (*htmlTag)(App *app, HTML *html, Buf *buf);
|
||||
void (*htmlText)(App *app, Buf *buf);
|
||||
|
||||
void (*httpRequest)(App *app, Buf *buf);
|
||||
void (*httpRequestHeaderName)(App *app, Buf *buf);
|
||||
void (*httpRequestHeaderValue)(App *app, Buf *buf);
|
||||
|
||||
/* pieces of http response other than header names and values */
|
||||
void (*httpResponse)(App *app, Buf *buf);
|
||||
|
||||
/* called when Content-Type != text/html or Content-Type missing */
|
||||
void (*httpResponseBody)(App *app, Buf *buf);
|
||||
|
||||
void (*httpResponseCharSet)(App *app, unsigned char *charset);
|
||||
void (*httpResponseHeaderName)(App *app, Buf *buf);
|
||||
void (*httpResponseHeaderValue)(App *app, Buf *buf,
|
||||
unsigned char *url);
|
||||
|
||||
void (*status)(App *app, char *message, char *file, int line);
|
||||
void (*time)(App *app, int task, struct timeval *theTime);
|
||||
|
||||
|
|
|
@ -0,0 +1,256 @@
|
|||
#include "all.h"
|
||||
|
||||
#define bufBlock 2048
|
||||
|
||||
struct Buf
|
||||
{
|
||||
unsigned char *buf;
|
||||
unsigned long alloc;
|
||||
unsigned long curr;
|
||||
unsigned long endData;
|
||||
unsigned long markBegin;
|
||||
unsigned long markEnd;
|
||||
int fd;
|
||||
int error;
|
||||
};
|
||||
|
||||
static int bufGrow(Buf *buf, int size);
|
||||
|
||||
Buf *
|
||||
bufAlloc(int fd)
|
||||
{
|
||||
Buf *buf;
|
||||
|
||||
buf = calloc(1, sizeof(Buf));
|
||||
if (!buf)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
buf->alloc = 1;
|
||||
buf->buf = malloc(buf->alloc);
|
||||
if (!buf->buf)
|
||||
{
|
||||
free(buf);
|
||||
return NULL;
|
||||
}
|
||||
buf->fd = fd;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
bufCopy(Buf *buf)
|
||||
{
|
||||
return copySizedString(&buf->buf[buf->markBegin],
|
||||
buf->markEnd - buf->markBegin);
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
bufCopyLower(Buf *buf)
|
||||
{
|
||||
return lowerCase(copySizedString(&buf->buf[buf->markBegin],
|
||||
buf->markEnd - buf->markBegin));
|
||||
}
|
||||
|
||||
unsigned char *
|
||||
bufCopyMemory(Buf *buf, unsigned long *len)
|
||||
{
|
||||
unsigned char *ret;
|
||||
|
||||
*len = buf->markEnd - buf->markBegin;
|
||||
ret = malloc(*len);
|
||||
if (!ret)
|
||||
{
|
||||
fprintf(stderr, "cannot calloc block\n");
|
||||
exit(0);
|
||||
}
|
||||
memcpy(ret, &buf->buf[buf->markBegin], *len);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
unsigned long
|
||||
bufCurrent(Buf *buf)
|
||||
{
|
||||
return buf->curr;
|
||||
}
|
||||
|
||||
int
|
||||
bufError(Buf *buf)
|
||||
{
|
||||
return buf->error;
|
||||
}
|
||||
|
||||
void
|
||||
bufFree(Buf *buf)
|
||||
{
|
||||
free(buf->buf);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
unsigned short
|
||||
bufGetByte(Buf *buf)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (buf->curr < buf->endData)
|
||||
{
|
||||
return buf->buf[buf->curr++];
|
||||
}
|
||||
if (!bufGrow(buf, bufBlock))
|
||||
{
|
||||
buf->curr++;
|
||||
return 256;
|
||||
}
|
||||
n = recv(buf->fd, &buf->buf[buf->endData], bufBlock, 0);
|
||||
if (n < 0)
|
||||
{
|
||||
buf->curr++;
|
||||
return 256;
|
||||
}
|
||||
else if (n == 0)
|
||||
{
|
||||
buf->curr++;
|
||||
return 256;
|
||||
}
|
||||
buf->endData += n;
|
||||
|
||||
return buf->buf[buf->curr++];
|
||||
}
|
||||
|
||||
static int
|
||||
bufGrow(Buf *buf, int size)
|
||||
{
|
||||
int need;
|
||||
|
||||
need = buf->curr + size;
|
||||
if (buf->alloc >= need)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
while (buf->alloc < need)
|
||||
{
|
||||
buf->alloc *= 2;
|
||||
}
|
||||
buf->buf = realloc(buf->buf, buf->alloc);
|
||||
if (!buf->buf)
|
||||
{
|
||||
buf->error = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
bufMark(Buf *buf, int offset)
|
||||
{
|
||||
buf->markBegin = buf->markEnd;
|
||||
buf->markEnd = buf->curr + offset;
|
||||
}
|
||||
|
||||
void
|
||||
bufPutChar(Buf *buf, unsigned char c)
|
||||
{
|
||||
if (buf->error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (buf->curr >= buf->alloc)
|
||||
{
|
||||
if (!bufGrow(buf, 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
buf->buf[buf->curr++] = c;
|
||||
buf->endData = buf->curr;
|
||||
}
|
||||
|
||||
void
|
||||
bufPutString(Buf *buf, unsigned char *str)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (buf->error)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
len = strlen((char *) str);
|
||||
if (buf->curr + len >= buf->alloc)
|
||||
{
|
||||
if (!bufGrow(buf, len))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
while (*str)
|
||||
{
|
||||
buf->buf[buf->curr++] = *str++;
|
||||
}
|
||||
buf->endData = buf->curr;
|
||||
}
|
||||
|
||||
void
|
||||
bufSend(Buf *buf)
|
||||
{
|
||||
if (buf->error)
|
||||
{
|
||||
fprintf(stderr, "bufSend error\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send(buf->fd, buf->buf, buf->curr, 0);
|
||||
}
|
||||
|
||||
void
|
||||
bufSet(Buf *buf, unsigned long offset)
|
||||
{
|
||||
buf->curr = offset;
|
||||
}
|
||||
|
||||
void
|
||||
bufSetFD(Buf *buf, int fd)
|
||||
{
|
||||
buf->fd = fd;
|
||||
}
|
||||
|
||||
unsigned short
|
||||
bufTrimTrailingWhiteSpace(Buf *buf)
|
||||
{
|
||||
unsigned char c;
|
||||
|
||||
buf->curr -= 2;
|
||||
do
|
||||
{
|
||||
c = buf->buf[buf->curr--];
|
||||
} while
|
||||
(
|
||||
(c == ' ') ||
|
||||
(c == '\t') ||
|
||||
(c == '\r') ||
|
||||
(c == '\n')
|
||||
);
|
||||
buf->curr += 2;
|
||||
|
||||
return buf->buf[buf->curr++];
|
||||
}
|
||||
|
||||
void
|
||||
bufUnGetByte(Buf *buf)
|
||||
{
|
||||
if (buf->curr > 0)
|
||||
{
|
||||
buf->curr--;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
bufWrite(Buf *buf)
|
||||
{
|
||||
write(buf->fd, &buf->buf[buf->curr], buf->endData - buf->curr);
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
#ifndef _BUF_H_
|
||||
#define _BUF_H_
|
||||
|
||||
typedef struct Buf Buf;
|
||||
|
||||
Buf *bufAlloc(int fd);
|
||||
unsigned char *bufCopy(Buf *buf);
|
||||
unsigned char *bufCopyLower(Buf *buf);
|
||||
unsigned char *bufCopyMemory(Buf *buf, unsigned long *len);
|
||||
unsigned long bufCurrent(Buf *buf);
|
||||
int bufError(Buf *buf);
|
||||
void bufFree(Buf *buf);
|
||||
unsigned short bufGetByte(Buf *buf);
|
||||
void bufMark(Buf *buf, int offset);
|
||||
void bufPutChar(Buf *buf, unsigned char c);
|
||||
void bufPutString(Buf *buf, unsigned char *str);
|
||||
void bufSend(Buf *buf);
|
||||
void bufSet(Buf *buf, unsigned long offset);
|
||||
void bufSetFD(Buf *buf, int fd);
|
||||
unsigned short bufTrimTrailingWhiteSpace(Buf *buf);
|
||||
void bufUnGetByte(Buf *buf);
|
||||
void bufWrite(Buf *buf);
|
||||
|
||||
#endif /* _BUF_H_ */
|
|
@ -28,27 +28,36 @@ static char *me = NULL;
|
|||
|
||||
static char *passThese[] =
|
||||
{
|
||||
"HTTP_USER_AGENT=",
|
||||
"HTTP_ACCEPT=",
|
||||
"HTTP_ACCEPT_CHARSET=",
|
||||
"HTTP_ACCEPT_LANGUAGE=",
|
||||
"HTTP_ACCEPT",
|
||||
"HTTP_ACCEPT_CHARSET",
|
||||
"HTTP_ACCEPT_LANGUAGE",
|
||||
"HTTP_USER_AGENT",
|
||||
|
||||
/*
|
||||
"HTTP_ACCEPT_ENCODING",
|
||||
"HTTP_CONNECTION",
|
||||
"HTTP_HOST",
|
||||
"HTTP_KEEP_ALIVE",
|
||||
"HTTP_REFERER",
|
||||
*/
|
||||
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
cgiviewHTML(App *app, Input *input)
|
||||
cgiviewHTML(App *app, Buf *buf)
|
||||
{
|
||||
viewHTML(app, input);
|
||||
viewHTML(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTMLAttributeName(App *app, HTML *html, Input *input)
|
||||
cgiviewHTMLAttributeName(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
viewHTMLAttributeName(app, input);
|
||||
viewHTMLAttributeName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTMLAttributeValue(App *app, HTML *html, Input *input)
|
||||
cgiviewHTMLAttributeValue(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
unsigned char *referer;
|
||||
URL *url;
|
||||
|
@ -68,7 +77,7 @@ cgiviewHTMLAttributeValue(App *app, HTML *html, Input *input)
|
|||
free(referer);
|
||||
urlFree(url);
|
||||
}
|
||||
viewHTMLAttributeValue(app, input);
|
||||
viewHTMLAttributeValue(app, buf);
|
||||
if (html->currentAttributeIsURL)
|
||||
{
|
||||
fprintf(view->out, "</a>");
|
||||
|
@ -76,37 +85,55 @@ cgiviewHTMLAttributeValue(App *app, HTML *html, Input *input)
|
|||
}
|
||||
|
||||
static void
|
||||
cgiviewHTMLTag(App *app, HTML *html, Input *input)
|
||||
cgiviewHTMLTag(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
viewHTMLTag(app, input);
|
||||
viewHTMLTag(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTMLText(App *app, Input *input)
|
||||
cgiviewHTMLText(App *app, Buf *buf)
|
||||
{
|
||||
viewHTMLText(app, input);
|
||||
viewHTMLText(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTP(App *app, Input *input)
|
||||
cgiviewHTTPRequest(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTP(app, input);
|
||||
viewHTTP(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTPBody(App *app, Input *input)
|
||||
cgiviewHTTPRequestHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTP(app, input);
|
||||
viewHTTPHeaderName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTPHeaderName(App *app, Input *input)
|
||||
cgiviewHTTPRequestHeaderValue(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTPHeaderName(app, input);
|
||||
viewHTTPHeaderValue(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTPHeaderValue(App *app, Input *input, unsigned char *url)
|
||||
cgiviewHTTPResponse(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTP(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTPResponseBody(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTP(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTPResponseHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTPHeaderName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
cgiviewHTTPResponseHeaderValue(App *app, Buf *buf, unsigned char *url)
|
||||
{
|
||||
unsigned char *urlstring;
|
||||
View *view;
|
||||
|
@ -119,34 +146,29 @@ cgiviewHTTPHeaderValue(App *app, Input *input, unsigned char *url)
|
|||
fprintf(view->out, "<a href=\"%s%s\">", me, urlstring);
|
||||
free(urlstring);
|
||||
}
|
||||
viewHTTPHeaderValue(app, input);
|
||||
viewHTTPHeaderValue(app, buf);
|
||||
if (url)
|
||||
{
|
||||
fprintf(view->out, "</a>");
|
||||
}
|
||||
}
|
||||
|
||||
unsigned char **
|
||||
getHTTPRequestHeaders(App *app, char *host, char *referer, char *verbose)
|
||||
static HTTPNameValue *
|
||||
cgiviewGetEnv(App *app, char *referer, char *verbose, char **version)
|
||||
{
|
||||
char **e;
|
||||
extern char **environ;
|
||||
char *equals;
|
||||
int firstLetter;
|
||||
char **h;
|
||||
char *p;
|
||||
char *q;
|
||||
char **r;
|
||||
char **ret;
|
||||
HTTPNameValue *r;
|
||||
HTTPNameValue *ret;
|
||||
char *scriptName;
|
||||
char *str;
|
||||
|
||||
scriptName = "view.cgi";
|
||||
e = environ;
|
||||
while (*e)
|
||||
{
|
||||
e++;
|
||||
}
|
||||
ret = malloc((e - environ + 2) * sizeof(*e));
|
||||
ret = malloc((NELEMS(passThese) + 1) * sizeof(HTTPNameValue));
|
||||
if (!ret)
|
||||
{
|
||||
return NULL;
|
||||
|
@ -161,13 +183,20 @@ getHTTPRequestHeaders(App *app, char *host, char *referer, char *verbose)
|
|||
|
||||
e = environ;
|
||||
r = ret;
|
||||
viewReport(app, "will send these HTTP Request headers:");
|
||||
viewReport(app, "will ignore these:");
|
||||
while (*e)
|
||||
{
|
||||
equals = strchr(*e, '=');
|
||||
if (!equals)
|
||||
{
|
||||
e++;
|
||||
continue;
|
||||
}
|
||||
*equals = 0;
|
||||
h = passThese;
|
||||
while (*h)
|
||||
{
|
||||
if (!strncmp(*e, *h, strlen(*h)))
|
||||
if (!strcmp(*e, *h))
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
@ -175,14 +204,14 @@ getHTTPRequestHeaders(App *app, char *host, char *referer, char *verbose)
|
|||
}
|
||||
if (*h)
|
||||
{
|
||||
str = malloc(strlen(*e) - 5 + 1 + 1);
|
||||
if (!str)
|
||||
r->name = malloc(strlen(*e) - 5 + 1);
|
||||
if (!r->name)
|
||||
{
|
||||
continue;
|
||||
return NULL;
|
||||
}
|
||||
p = *e + 5;
|
||||
q = str;
|
||||
while (*p && (*p != '='))
|
||||
q = (char *) r->name;
|
||||
while (*p)
|
||||
{
|
||||
firstLetter = 1;
|
||||
while (*p && (*p != '=') && (*p != '_'))
|
||||
|
@ -204,45 +233,42 @@ getHTTPRequestHeaders(App *app, char *host, char *referer, char *verbose)
|
|||
p++;
|
||||
}
|
||||
}
|
||||
if (*p == '=')
|
||||
*q = 0;
|
||||
r->value = (unsigned char *) strdup(equals + 1);
|
||||
if (!r->value)
|
||||
{
|
||||
p++;
|
||||
*q++ = ':';
|
||||
*q++ = ' ';
|
||||
while (*p)
|
||||
{
|
||||
*q++ = *p++;
|
||||
}
|
||||
*q = 0;
|
||||
*r++ = str;
|
||||
viewReport(app, str);
|
||||
return NULL;
|
||||
}
|
||||
r++;
|
||||
}
|
||||
else if (!strncmp(*e, "HTTP_", 5))
|
||||
{
|
||||
viewReport(app, *e);
|
||||
}
|
||||
else if (!strcmp(*e, "SERVER_PROTOCOL"))
|
||||
{
|
||||
*version = strdup(equals + 1);
|
||||
}
|
||||
e++;
|
||||
}
|
||||
str = malloc(6 + strlen(host) + 1);
|
||||
if (str)
|
||||
{
|
||||
strcpy(str, "Host: ");
|
||||
strcat(str, host);
|
||||
/* *r++ = str; */ /* http.c will do Host header */
|
||||
viewReport(app, str);
|
||||
}
|
||||
if (referer)
|
||||
{
|
||||
str = malloc(9 + strlen(referer) + 1);
|
||||
if (str)
|
||||
r->name = (unsigned char *) strdup("Referer");
|
||||
if (!r->name)
|
||||
{
|
||||
strcpy(str, "Referer: ");
|
||||
strcat(str, referer);
|
||||
*r++ = str;
|
||||
viewReport(app, str);
|
||||
return NULL;
|
||||
}
|
||||
r->value = (unsigned char *) strdup(referer);
|
||||
if (!r->value)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
r++;
|
||||
}
|
||||
r->name = NULL;
|
||||
viewReportHTML(app, "<hr>");
|
||||
*r = NULL;
|
||||
|
||||
return (unsigned char **) ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -251,6 +277,7 @@ main(int argc, char *argv[])
|
|||
char *ampersand;
|
||||
App *app;
|
||||
unsigned char *equals;
|
||||
HTTPNameValue *headers;
|
||||
char *name;
|
||||
unsigned char *newURL;
|
||||
char *p;
|
||||
|
@ -259,6 +286,7 @@ main(int argc, char *argv[])
|
|||
URL *u;
|
||||
unsigned char *url;
|
||||
char *verbose;
|
||||
char *version;
|
||||
View *view;
|
||||
|
||||
if (!netInit())
|
||||
|
@ -282,10 +310,13 @@ main(int argc, char *argv[])
|
|||
app->htmlAttributeValue = cgiviewHTMLAttributeValue;
|
||||
app->htmlTag = cgiviewHTMLTag;
|
||||
app->htmlText = cgiviewHTMLText;
|
||||
app->http = cgiviewHTTP;
|
||||
app->httpBody = cgiviewHTTPBody;
|
||||
app->httpHeaderName = cgiviewHTTPHeaderName;
|
||||
app->httpHeaderValue = cgiviewHTTPHeaderValue;
|
||||
app->httpRequest = cgiviewHTTPRequest;
|
||||
app->httpRequestHeaderName = cgiviewHTTPRequestHeaderName;
|
||||
app->httpRequestHeaderValue = cgiviewHTTPRequestHeaderValue;
|
||||
app->httpResponse = cgiviewHTTPResponse;
|
||||
app->httpResponseBody = cgiviewHTTPResponseBody;
|
||||
app->httpResponseHeaderName = cgiviewHTTPResponseHeaderName;
|
||||
app->httpResponseHeaderValue = cgiviewHTTPResponseHeaderValue;
|
||||
view = &app->view;
|
||||
view->out = stdout;
|
||||
freopen("/dev/null", "w", stderr);
|
||||
|
@ -337,12 +368,9 @@ main(int argc, char *argv[])
|
|||
}
|
||||
if (url && (*url))
|
||||
{
|
||||
fprintf
|
||||
(
|
||||
view->out,
|
||||
"<html><head><title>View %s</title></head><body><pre>",
|
||||
url
|
||||
);
|
||||
fprintf(view->out,
|
||||
"<html><head><title>View %s</title></head><body>\n"
|
||||
"<pre>", url);
|
||||
viewReport(app, "input url:");
|
||||
viewReport(app, (char *) url);
|
||||
viewReportHTML(app, "<hr>");
|
||||
|
@ -399,9 +427,14 @@ main(int argc, char *argv[])
|
|||
viewReportHTML(app, "<hr>");
|
||||
if (!strcmp((char *) u->scheme, "http"))
|
||||
{
|
||||
httpProcess(app, u,
|
||||
getHTTPRequestHeaders(app, (char *) u->host,
|
||||
(char *) referer, verbose));
|
||||
version = NULL;
|
||||
headers = cgiviewGetEnv(app, (char *) referer,
|
||||
verbose, &version);
|
||||
if (!headers)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
httpFree(httpProcess(app, u, version, headers));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ fileProcess(void *a, URL *url)
|
|||
{
|
||||
char *dot;
|
||||
FILE *file;
|
||||
Input *input;
|
||||
Buf *buf;
|
||||
|
||||
/* XXX temporary? */
|
||||
if (!url->file)
|
||||
|
@ -55,7 +55,12 @@ fileProcess(void *a, URL *url)
|
|||
fprintf(stderr, "cannot open file %s\n", url->path);
|
||||
return;
|
||||
}
|
||||
input = readStream(fileno(file), url->url);
|
||||
htmlRead(a, input, url->url);
|
||||
inputFree(input);
|
||||
buf = bufAlloc(fileno(file));
|
||||
if (!buf)
|
||||
{
|
||||
fprintf(stderr, "cannot alloc buf\n");
|
||||
return;
|
||||
}
|
||||
htmlRead(a, buf, url->url);
|
||||
bufFree(buf);
|
||||
}
|
||||
|
|
|
@ -107,11 +107,9 @@ grab(char *dir, unsigned char *url, HTTP *http)
|
|||
fprintf(stderr, "cannot open file %s for writing\n", str);
|
||||
exit(0);
|
||||
}
|
||||
if (fwrite(http->body, 1, http->bodyLen, file) != http->bodyLen)
|
||||
{
|
||||
fprintf(stderr, "did not write %ld bytes\n", http->bodyLen);
|
||||
exit(0);
|
||||
}
|
||||
bufSetFD(http->in, fileno(file));
|
||||
bufSet(http->in, http->body);
|
||||
bufWrite(http->in);
|
||||
fclose(file);
|
||||
free(str);
|
||||
}
|
||||
|
@ -198,7 +196,7 @@ main(int argc, char *argv[])
|
|||
while (url)
|
||||
{
|
||||
appDefault.data = url;
|
||||
http = httpProcess(&appDefault, url, NULL);
|
||||
http = httpProcess(&appDefault, url, NULL, NULL);
|
||||
if (http)
|
||||
{
|
||||
switch (http->status)
|
||||
|
|
|
@ -332,7 +332,7 @@ htmlRegisterTagHandler(HTMLHandler handler)
|
|||
}
|
||||
|
||||
static unsigned short
|
||||
htmlGetByte(Input *input, HTMLState *state)
|
||||
htmlGetByte(Buf *buf, HTMLState *state)
|
||||
{
|
||||
unsigned short c;
|
||||
unsigned short ret;
|
||||
|
@ -345,21 +345,21 @@ htmlGetByte(Input *input, HTMLState *state)
|
|||
return tmp;
|
||||
}
|
||||
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
if (c == 256)
|
||||
{
|
||||
ret = c;
|
||||
}
|
||||
else if (c == 0x1b)
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
if (c == 256)
|
||||
{
|
||||
ret = c;
|
||||
}
|
||||
else if (c == '$')
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
if (c == 256)
|
||||
{
|
||||
ret = c;
|
||||
|
@ -367,9 +367,9 @@ htmlGetByte(Input *input, HTMLState *state)
|
|||
else if (c == '(')
|
||||
{
|
||||
/* throw away 4th byte in ESC sequence */
|
||||
getByte(input);
|
||||
bufGetByte(buf);
|
||||
state->mask = 0x80;
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
if (c == 256)
|
||||
{
|
||||
ret = c;
|
||||
|
@ -382,7 +382,7 @@ htmlGetByte(Input *input, HTMLState *state)
|
|||
else
|
||||
{
|
||||
state->mask = 0x80;
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
if (c == 256)
|
||||
{
|
||||
ret = c;
|
||||
|
@ -397,12 +397,12 @@ htmlGetByte(Input *input, HTMLState *state)
|
|||
{
|
||||
state->mask = 0;
|
||||
/* throw away 3rd byte in ESC sequence */
|
||||
getByte(input);
|
||||
ret = getByte(input);
|
||||
bufGetByte(buf);
|
||||
ret = bufGetByte(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
unGetByte(input);
|
||||
bufUnGetByte(buf);
|
||||
ret = 0x1b;
|
||||
}
|
||||
}
|
||||
|
@ -423,7 +423,7 @@ htmlUnGetByte(HTMLState *state)
|
|||
}
|
||||
|
||||
static unsigned short
|
||||
eatWhiteSpace(Input *input, HTMLState *state, unsigned short c)
|
||||
eatWhiteSpace(Buf *buf, HTMLState *state, unsigned short c)
|
||||
{
|
||||
while
|
||||
(
|
||||
|
@ -433,7 +433,7 @@ eatWhiteSpace(Input *input, HTMLState *state, unsigned short c)
|
|||
(c == '\n')
|
||||
)
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
}
|
||||
|
||||
return c;
|
||||
|
@ -458,13 +458,13 @@ htmlFreeAttributes(HTMLState *state)
|
|||
}
|
||||
|
||||
static unsigned short
|
||||
readAttribute(App *app, Input *input, HTMLState *state, unsigned short c)
|
||||
readAttribute(App *app, Buf *buf, HTMLState *state, unsigned short c)
|
||||
{
|
||||
HTMLAttribute *attr;
|
||||
unsigned short quote;
|
||||
|
||||
mark(input, -1);
|
||||
app->html(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->html(app, buf);
|
||||
while
|
||||
(
|
||||
(c != 256) &&
|
||||
|
@ -476,9 +476,9 @@ readAttribute(App *app, Input *input, HTMLState *state, unsigned short c)
|
|||
(c != '\n')
|
||||
)
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
}
|
||||
mark(input, -1);
|
||||
bufMark(buf, -1);
|
||||
attr = calloc(sizeof(HTMLAttribute), 1);
|
||||
if (!attr)
|
||||
{
|
||||
|
@ -498,15 +498,15 @@ readAttribute(App *app, Input *input, HTMLState *state, unsigned short c)
|
|||
state->html->attributes = attr;
|
||||
}
|
||||
state->html->currentAttribute = attr;
|
||||
attr->name = copyLower(input);
|
||||
app->htmlAttributeName(app, state->html, input);
|
||||
attr->name = bufCopyLower(buf);
|
||||
app->htmlAttributeName(app, state->html, buf);
|
||||
if ((c == 256) || (c == '>'))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
if (c != '=')
|
||||
{
|
||||
c = eatWhiteSpace(input, state, c);
|
||||
c = eatWhiteSpace(buf, state, c);
|
||||
}
|
||||
if ((c == 256) || (c == '>'))
|
||||
{
|
||||
|
@ -514,30 +514,30 @@ readAttribute(App *app, Input *input, HTMLState *state, unsigned short c)
|
|||
}
|
||||
if (c == '=')
|
||||
{
|
||||
c = eatWhiteSpace(input, state, htmlGetByte(input, state));
|
||||
c = eatWhiteSpace(buf, state, htmlGetByte(buf, state));
|
||||
if ((c == '"') || (c == '\''))
|
||||
{
|
||||
quote = c;
|
||||
mark(input, 0);
|
||||
app->html(app, input);
|
||||
bufMark(buf, 0);
|
||||
app->html(app, buf);
|
||||
do
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
} while ((c != 256) && (c != quote));
|
||||
if (c == 256)
|
||||
{
|
||||
diag(__LINE__, state, c);
|
||||
}
|
||||
mark(input, -1);
|
||||
attr->value = copy(input);
|
||||
bufMark(buf, -1);
|
||||
attr->value = bufCopy(buf);
|
||||
htmlCheckAttribute(state->html);
|
||||
app->htmlAttributeValue(app, state->html, input);
|
||||
c = htmlGetByte(input, state);
|
||||
app->htmlAttributeValue(app, state->html, buf);
|
||||
c = htmlGetByte(buf, state);
|
||||
}
|
||||
else
|
||||
{
|
||||
mark(input, -1);
|
||||
app->html(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->html(app, buf);
|
||||
while
|
||||
(
|
||||
(c != 256) &&
|
||||
|
@ -552,12 +552,12 @@ readAttribute(App *app, Input *input, HTMLState *state, unsigned short c)
|
|||
{
|
||||
diag(__LINE__, state, c);
|
||||
}
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
}
|
||||
mark(input, -1);
|
||||
attr->value = copy(input);
|
||||
bufMark(buf, -1);
|
||||
attr->value = bufCopy(buf);
|
||||
htmlCheckAttribute(state->html);
|
||||
app->htmlAttributeValue(app, state->html, input);
|
||||
app->htmlAttributeValue(app, state->html, buf);
|
||||
}
|
||||
callHandler(app, state->html);
|
||||
if (c == '>')
|
||||
|
@ -565,112 +565,114 @@ readAttribute(App *app, Input *input, HTMLState *state, unsigned short c)
|
|||
return c;
|
||||
}
|
||||
}
|
||||
return eatWhiteSpace(input, state, c);
|
||||
return eatWhiteSpace(buf, state, c);
|
||||
}
|
||||
|
||||
static int
|
||||
caseCompare(char *str, Input *input, HTMLState *state, unsigned short *ret)
|
||||
caseCompare(char *str, Buf *buf, HTMLState *state, unsigned short *ret)
|
||||
{
|
||||
unsigned short c;
|
||||
int i;
|
||||
|
||||
for (i = 0; str[i]; i++)
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (tolower(c) != tolower(str[i]))
|
||||
{
|
||||
*ret = c;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
*ret = c;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
endTag(App *app, Input *input, HTMLState *state)
|
||||
endTag(App *app, Buf *buf, HTMLState *state)
|
||||
{
|
||||
unsigned short c;
|
||||
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == 256)
|
||||
{
|
||||
mark(input, -1);
|
||||
app->html(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->html(app, buf);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
readTag(App *app, Input *input, HTMLState *state)
|
||||
readTag(App *app, Buf *buf, HTMLState *state)
|
||||
{
|
||||
unsigned short c;
|
||||
|
||||
mark(input, -1);
|
||||
app->html(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->html(app, buf);
|
||||
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == '!')
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == '-')
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == '-')
|
||||
{
|
||||
const unsigned char *beginningOfComment =
|
||||
current(input);
|
||||
unsigned long beginningOfComment =
|
||||
bufCurrent(buf);
|
||||
while (1)
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == '-')
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == '-')
|
||||
{
|
||||
c = htmlGetByte(input,
|
||||
c = htmlGetByte(buf,
|
||||
state);
|
||||
if (c == '>')
|
||||
{
|
||||
return endTag(app, input, state);
|
||||
return endTag(app,
|
||||
buf, state);
|
||||
}
|
||||
else if (c == '-')
|
||||
{
|
||||
do
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
} while (c == '-');
|
||||
if (c == '>')
|
||||
{
|
||||
return endTag(app, input, state);
|
||||
return endTag(app,
|
||||
buf, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (c == 256)
|
||||
{
|
||||
set(input, beginningOfComment);
|
||||
bufSet(buf, beginningOfComment);
|
||||
while (1)
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
if (c == '>')
|
||||
{
|
||||
return endTag(app, input, state);
|
||||
return endTag(app, buf, state);
|
||||
}
|
||||
else if (c == 256)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"bad comment\n");
|
||||
mark(input, -1);
|
||||
bufMark(buf, -1);
|
||||
FREE(state->html->tag);
|
||||
state->html->tag =
|
||||
copyString((unsigned
|
||||
char *) "!--");
|
||||
state->html->tagIsKnown = 1;
|
||||
app->htmlTag(app,
|
||||
state->html, input);
|
||||
state->html, buf);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
@ -694,7 +696,7 @@ readTag(App *app, Input *input, HTMLState *state)
|
|||
|
||||
do
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
}
|
||||
while
|
||||
(
|
||||
|
@ -705,9 +707,9 @@ readTag(App *app, Input *input, HTMLState *state)
|
|||
(c != '\r') &&
|
||||
(c != '\n')
|
||||
);
|
||||
mark(input, -1);
|
||||
bufMark(buf, -1);
|
||||
FREE(state->html->tag);
|
||||
state->html->tag = copyLower(input);
|
||||
state->html->tag = bufCopyLower(buf);
|
||||
if (hashLookup(knownTagTable, (*state->html->tag == '/') ?
|
||||
state->html->tag + 1 : state->html->tag))
|
||||
{
|
||||
|
@ -717,27 +719,27 @@ readTag(App *app, Input *input, HTMLState *state)
|
|||
{
|
||||
state->html->tagIsKnown = 0;
|
||||
}
|
||||
app->htmlTag(app, state->html, input);
|
||||
app->htmlTag(app, state->html, buf);
|
||||
if (c == 256)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
else if (c == '>')
|
||||
{
|
||||
return endTag(app, input, state);
|
||||
return endTag(app, buf, state);
|
||||
}
|
||||
c = eatWhiteSpace(input, state, c);
|
||||
c = eatWhiteSpace(buf, state, c);
|
||||
if (c == 256)
|
||||
{
|
||||
return c;
|
||||
}
|
||||
else if (c == '>')
|
||||
{
|
||||
return endTag(app, input, state);
|
||||
return endTag(app, buf, state);
|
||||
}
|
||||
do
|
||||
{
|
||||
c = readAttribute(app, input, state, c);
|
||||
c = readAttribute(app, buf, state, c);
|
||||
} while ((c != 256) && (c != '>'));
|
||||
state->html->currentAttribute = NULL;
|
||||
if (tagHandler)
|
||||
|
@ -746,31 +748,31 @@ readTag(App *app, Input *input, HTMLState *state)
|
|||
}
|
||||
if (c == '>')
|
||||
{
|
||||
return endTag(app, input, state);
|
||||
return endTag(app, buf, state);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
readText(App *app, Input *input, HTMLState *state)
|
||||
readText(App *app, Buf *buf, HTMLState *state)
|
||||
{
|
||||
unsigned short c;
|
||||
|
||||
mark(input, -1);
|
||||
app->html(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->html(app, buf);
|
||||
do
|
||||
{
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
} while ((c != 256) && (c != '<'));
|
||||
mark(input, -1);
|
||||
app->htmlText(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->htmlText(app, buf);
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
dealWithScript(Input *input, HTMLState *state, unsigned short c)
|
||||
dealWithScript(Buf *buf, HTMLState *state, unsigned short c)
|
||||
{
|
||||
if (state->html->tag &&
|
||||
(!strcasecmp((char *) state->html->tag, "script")))
|
||||
|
@ -783,13 +785,13 @@ dealWithScript(Input *input, HTMLState *state, unsigned short c)
|
|||
}
|
||||
if (c == '<')
|
||||
{
|
||||
if (caseCompare("/script>", input, state, &c))
|
||||
if (caseCompare("/script>", buf, state, &c))
|
||||
{
|
||||
FREE(state->html->tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
c = htmlGetByte(input, state);
|
||||
c = htmlGetByte(buf, state);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -797,7 +799,7 @@ dealWithScript(Input *input, HTMLState *state, unsigned short c)
|
|||
}
|
||||
|
||||
void
|
||||
htmlRead(App *app, Input *input, unsigned char *base)
|
||||
htmlRead(App *app, Buf *buf, unsigned char *base)
|
||||
{
|
||||
unsigned short c;
|
||||
HTML html;
|
||||
|
@ -819,12 +821,12 @@ htmlRead(App *app, Input *input, unsigned char *base)
|
|||
state.unGotten = 256;
|
||||
state.html = &html;
|
||||
|
||||
c = htmlGetByte(input, &state);
|
||||
c = htmlGetByte(buf, &state);
|
||||
while (c != 256)
|
||||
{
|
||||
if (c == '<')
|
||||
{
|
||||
c = htmlGetByte(input, &state);
|
||||
c = htmlGetByte(buf, &state);
|
||||
htmlUnGetByte(&state);
|
||||
if
|
||||
(
|
||||
|
@ -834,22 +836,23 @@ htmlRead(App *app, Input *input, unsigned char *base)
|
|||
(c == '!')
|
||||
)
|
||||
{
|
||||
c = readTag(app, input, &state);
|
||||
c = dealWithScript(input, &state, c);
|
||||
c = readTag(app, buf, &state);
|
||||
c = dealWithScript(buf, &state, c);
|
||||
}
|
||||
else
|
||||
{
|
||||
diag(__LINE__, &state, c);
|
||||
c = readText(app, input, &state);
|
||||
c = readText(app, buf, &state);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
c = readText(app, input, &state);
|
||||
c = readText(app, buf, &state);
|
||||
}
|
||||
}
|
||||
|
||||
FREE(html.base);
|
||||
FREE(html.url);
|
||||
FREE(html.tag);
|
||||
htmlFreeAttributes(&state);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef _HTML_H_
|
||||
#define _HTML_H_
|
||||
|
||||
#include "io.h"
|
||||
#include "buf.h"
|
||||
|
||||
typedef struct HTMLAttribute
|
||||
{
|
||||
|
@ -47,7 +47,7 @@ typedef struct HTML
|
|||
|
||||
typedef void (*HTMLHandler)(App *app, HTML *html);
|
||||
|
||||
void htmlRead(App *app, Input *input, unsigned char *base);
|
||||
void htmlRead(App *app, Buf *buf, unsigned char *base);
|
||||
void htmlRegister(char *tag, char *attributeName, HTMLHandler handler);
|
||||
void htmlRegisterTagHandler(HTMLHandler handler);
|
||||
void htmlRegisterURLHandler(HTMLHandler handler);
|
||||
|
|
|
@ -33,41 +33,57 @@ static int nonEmptyHTTPResponseCount = 0;
|
|||
static int http10OrGreaterCount = 0;
|
||||
|
||||
static unsigned short
|
||||
readLine(Input *input, unsigned short c)
|
||||
readLine(Buf *buf, unsigned short c)
|
||||
{
|
||||
while ((c != 256) && (c != '\r') && (c != '\n'))
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
if (c == '\r')
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
if (c == '\n')
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
}
|
||||
else if (c == '\n')
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
readSpaceTab(Input *input, unsigned short c)
|
||||
readNumber(Buf *buf, unsigned short c, int *num)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = 0;
|
||||
while ((c != 256) && (c >= '0') && (c <= '9'))
|
||||
{
|
||||
n = ((n * 10) + (c - '0'));
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
*num = n;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
readSpaceTab(Buf *buf, unsigned short c)
|
||||
{
|
||||
while ((c == ' ') || (c == '\t'))
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned short
|
||||
readNonWhiteSpace(Input *input, unsigned short c)
|
||||
readNonWhiteSpace(Buf *buf, unsigned short c)
|
||||
{
|
||||
while
|
||||
(
|
||||
|
@ -78,14 +94,15 @@ readNonWhiteSpace(Input *input, unsigned short c)
|
|||
(c != '\n')
|
||||
)
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static unsigned char *
|
||||
httpReadHeaders(HTTP *http, App *app, Input *input, unsigned char *url)
|
||||
static unsigned short
|
||||
httpReadHeaders(HTTP *http, App *app, Buf *buf, unsigned char *url,
|
||||
unsigned char **ct, int *chunked)
|
||||
{
|
||||
unsigned short c;
|
||||
unsigned char *charset;
|
||||
|
@ -95,42 +112,59 @@ httpReadHeaders(HTTP *http, App *app, Input *input, unsigned char *url)
|
|||
URL *rel;
|
||||
ContentType *type;
|
||||
unsigned char *value;
|
||||
char *version;
|
||||
|
||||
contentType = NULL;
|
||||
locationFound = 0;
|
||||
|
||||
if (!*current(input))
|
||||
bufMark(buf, 0);
|
||||
c = bufGetByte(buf);
|
||||
if (c == 256)
|
||||
{
|
||||
return emptyHTTPResponse;
|
||||
*ct = emptyHTTPResponse;
|
||||
return c;
|
||||
}
|
||||
nonEmptyHTTPResponseCount++;
|
||||
if (strncmp((char *) current(input), "HTTP/", 5))
|
||||
c = readNonWhiteSpace(buf, c);
|
||||
bufMark(buf, -1);
|
||||
app->httpResponse(app, buf);
|
||||
version = (char *) bufCopy(buf);
|
||||
if (!strcmp(version, "HTTP/1.0"))
|
||||
{
|
||||
}
|
||||
else if (!strcmp(version, "HTTP/1.1"))
|
||||
{
|
||||
}
|
||||
else if (!strncmp(version, "HTTP/", 5))
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
/* XXX deal with HTTP/0.9? */
|
||||
return http09Response;
|
||||
*ct = http09Response;
|
||||
return c;
|
||||
}
|
||||
free(version);
|
||||
http10OrGreaterCount++;
|
||||
mark(input, 0);
|
||||
c = readNonWhiteSpace(input, getByte(input));
|
||||
c = readSpaceTab(input, c);
|
||||
sscanf((char *) current(input) - 1, "%d", &http->status);
|
||||
c = readLine(input, c);
|
||||
c = readSpaceTab(buf, c);
|
||||
c = readNumber(buf, c, &http->status);
|
||||
c = readLine(buf, c);
|
||||
while (1)
|
||||
{
|
||||
if (c == 256)
|
||||
{
|
||||
mark(input, 0);
|
||||
app->http(app, input);
|
||||
bufMark(buf, 0);
|
||||
app->httpResponse(app, buf);
|
||||
break;
|
||||
}
|
||||
mark(input, -1);
|
||||
app->http(app, input);
|
||||
bufMark(buf, -1);
|
||||
app->httpResponse(app, buf);
|
||||
if ((c == '\r') || (c == '\n'))
|
||||
{
|
||||
readLine(input, c);
|
||||
unGetByte(input);
|
||||
mark(input, 0);
|
||||
app->http(app, input);
|
||||
readLine(buf, c);
|
||||
bufUnGetByte(buf);
|
||||
bufMark(buf, 0);
|
||||
app->httpResponse(app, buf);
|
||||
break;
|
||||
}
|
||||
while
|
||||
|
@ -141,73 +175,86 @@ httpReadHeaders(HTTP *http, App *app, Input *input, unsigned char *url)
|
|||
(c != ':')
|
||||
)
|
||||
{
|
||||
c = getByte(input);
|
||||
c = bufGetByte(buf);
|
||||
}
|
||||
if (c != ':')
|
||||
{
|
||||
mark(input, -1);
|
||||
bufMark(buf, -1);
|
||||
fprintf(stderr, "no colon in HTTP header \"%s\": %s\n",
|
||||
copy(input), url);
|
||||
return NULL;
|
||||
bufCopy(buf), url);
|
||||
*ct = NULL;
|
||||
return c;
|
||||
}
|
||||
mark(input, -1);
|
||||
app->httpHeaderName(app, input);
|
||||
name = copyLower(input);
|
||||
c = readSpaceTab(input, getByte(input));
|
||||
mark(input, -1);
|
||||
app->http(app, input);
|
||||
c = readLine(input, c);
|
||||
bufMark(buf, -1);
|
||||
app->httpResponseHeaderName(app, buf);
|
||||
name = bufCopyLower(buf);
|
||||
c = readSpaceTab(buf, bufGetByte(buf));
|
||||
bufMark(buf, -1);
|
||||
app->httpResponse(app, buf);
|
||||
c = readLine(buf, c);
|
||||
if ((c == ' ') || (c == '\t'))
|
||||
{
|
||||
do
|
||||
{
|
||||
c = readLine(input, c);
|
||||
c = readLine(buf, c);
|
||||
} while ((c == ' ') || (c == '\t'));
|
||||
}
|
||||
c = trimTrailingWhiteSpace(input);
|
||||
mark(input, -1);
|
||||
value = copy(input);
|
||||
c = bufTrimTrailingWhiteSpace(buf);
|
||||
bufMark(buf, -1);
|
||||
value = bufCopy(buf);
|
||||
if (!strcasecmp((char *) name, "content-type"))
|
||||
{
|
||||
app->httpHeaderValue(app, input, NULL);
|
||||
app->httpResponseHeaderValue(app, buf, NULL);
|
||||
type = mimeParseContentType(value);
|
||||
contentType = mimeGetContentType(type);
|
||||
charset = mimeGetContentTypeParameter(type, "charset");
|
||||
if (charset)
|
||||
{
|
||||
app->httpCharSet(app, charset);
|
||||
app->httpResponseCharSet(app, charset);
|
||||
free(charset);
|
||||
}
|
||||
mimeFreeContentType(type);
|
||||
}
|
||||
else if (!strcasecmp((char *) name, "location"))
|
||||
{
|
||||
app->httpHeaderValue(app, input, value);
|
||||
app->httpResponseHeaderValue(app, buf, value);
|
||||
/* XXX supposed to be absolute URL */
|
||||
rel = urlRelative(url, value);
|
||||
addURL(app, rel->url);
|
||||
urlFree(rel);
|
||||
locationFound = 1;
|
||||
}
|
||||
else if (!strcasecmp((char *) name, "transfer-encoding"))
|
||||
{
|
||||
app->httpResponseHeaderValue(app, buf, NULL);
|
||||
if (!strcasecmp((char *) value, "chunked"))
|
||||
{
|
||||
*chunked = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
app->httpHeaderValue(app, input, NULL);
|
||||
app->httpResponseHeaderValue(app, buf, NULL);
|
||||
}
|
||||
free(name);
|
||||
free(value);
|
||||
c = readLine(input, c);
|
||||
mark(input, -1);
|
||||
app->http(app, input);
|
||||
c = readLine(buf, c);
|
||||
bufMark(buf, -1);
|
||||
app->httpResponse(app, buf);
|
||||
}
|
||||
|
||||
if (!contentType)
|
||||
{
|
||||
if (locationFound)
|
||||
{
|
||||
return locationURLWasAdded;
|
||||
*ct = locationURLWasAdded;
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
return contentType;
|
||||
*ct = contentType;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -215,13 +262,13 @@ httpParseRequest(HTTP *http, App *app, char *url)
|
|||
{
|
||||
unsigned short c;
|
||||
|
||||
mark(http->input, 0);
|
||||
bufMark(http->in, 0);
|
||||
do
|
||||
{
|
||||
c = getByte(http->input);
|
||||
c = bufGetByte(http->in);
|
||||
} while (c != 256);
|
||||
mark(http->input, -1);
|
||||
app->http(app, http->input);
|
||||
bufMark(http->in, -1);
|
||||
app->httpResponse(app, http->in);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -231,23 +278,77 @@ httpDefaultType(HTTP *http, App *app)
|
|||
|
||||
do
|
||||
{
|
||||
c = getByte(http->input);
|
||||
c = bufGetByte(http->in);
|
||||
}
|
||||
while (c != 256);
|
||||
mark(http->input, -1);
|
||||
app->httpBody(app, http->input);
|
||||
bufMark(http->in, -1);
|
||||
app->httpResponseBody(app, http->in);
|
||||
}
|
||||
|
||||
void
|
||||
httpParseStream(HTTP *http, App *app, unsigned char *url)
|
||||
{
|
||||
const unsigned char *begin;
|
||||
unsigned char *contentType;
|
||||
Buf *buf;
|
||||
unsigned short c;
|
||||
unsigned char *contentType;
|
||||
int chunked;
|
||||
int i;
|
||||
unsigned char *line;
|
||||
unsigned int size;
|
||||
|
||||
chunked = 0;
|
||||
c = httpReadHeaders(http, app, http->in, url, &contentType, &chunked);
|
||||
|
||||
if (chunked)
|
||||
{
|
||||
buf = bufAlloc(-1);
|
||||
while (1)
|
||||
{
|
||||
bufMark(http->in, 0);
|
||||
c = bufGetByte(http->in);
|
||||
c = readLine(http->in, c);
|
||||
bufMark(http->in, -1);
|
||||
line = bufCopy(http->in);
|
||||
size = 0;
|
||||
sscanf((char *) line, "%x", &size);
|
||||
free(line);
|
||||
if (!size)
|
||||
{
|
||||
break;
|
||||
}
|
||||
bufUnGetByte(http->in);
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
c = bufGetByte(http->in);
|
||||
if (c == 256)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
bufPutChar(buf, c);
|
||||
}
|
||||
}
|
||||
c = bufGetByte(http->in);
|
||||
if (c != '\r')
|
||||
{
|
||||
break;
|
||||
}
|
||||
c = bufGetByte(http->in);
|
||||
if (c != '\n')
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
bufSet(buf, 0);
|
||||
bufMark(buf, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = http->in;
|
||||
}
|
||||
http->body = bufCurrent(buf);
|
||||
|
||||
begin = current(http->input);
|
||||
contentType = httpReadHeaders(http, app, http->input, url);
|
||||
http->body = current(http->input);
|
||||
http->bodyLen = inputLength(http->input) - (http->body - begin);
|
||||
if (contentType)
|
||||
{
|
||||
if
|
||||
|
@ -260,7 +361,7 @@ httpParseStream(HTTP *http, App *app, unsigned char *url)
|
|||
app->contentType(app, contentType);
|
||||
if (!strcasecmp((char *) contentType, "text/html"))
|
||||
{
|
||||
htmlRead(app, http->input, url);
|
||||
htmlRead(app, buf, url);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -273,95 +374,100 @@ httpParseStream(HTTP *http, App *app, unsigned char *url)
|
|||
{
|
||||
httpDefaultType(http, app);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
httpRead(HTTP *http, App *app, int sock, unsigned char *url)
|
||||
{
|
||||
struct timeval theTime;
|
||||
|
||||
app->status(app, "readStream", __FILE__, __LINE__);
|
||||
gettimeofday(&theTime, NULL);
|
||||
http->input = readStream(sock, url);
|
||||
app->time(app, appTimeReadStream, &theTime);
|
||||
app->status(app, "readStream done", __FILE__, __LINE__);
|
||||
httpParseStream(http, app, url);
|
||||
}
|
||||
|
||||
static int
|
||||
countOrCopy(char **p, char *str)
|
||||
{
|
||||
char *orig;
|
||||
char *q;
|
||||
|
||||
orig = str;
|
||||
if (*p)
|
||||
if (chunked)
|
||||
{
|
||||
q = *p;
|
||||
while ((*q++ = *str++));
|
||||
*p = --q;
|
||||
bufFree(buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (*str++);
|
||||
}
|
||||
|
||||
return --str - orig;
|
||||
}
|
||||
|
||||
static void
|
||||
httpGetObject(HTTP *http, App *app, int sock, URL *url, unsigned char **headers)
|
||||
httpRead(App *app, HTTP *http, int sock)
|
||||
{
|
||||
unsigned char **h;
|
||||
char *p;
|
||||
int len;
|
||||
int i;
|
||||
char *buf;
|
||||
struct timeval theTime;
|
||||
|
||||
p = NULL;
|
||||
buf = NULL;
|
||||
for (i = 0; i < 2; i++)
|
||||
app->status(app, "httpRead", __FILE__, __LINE__);
|
||||
gettimeofday(&theTime, NULL);
|
||||
http->in = bufAlloc(sock);
|
||||
httpParseStream(http, app, http->url->url);
|
||||
app->time(app, appTimeReadStream, &theTime);
|
||||
app->status(app, "httpRead done", __FILE__, __LINE__);
|
||||
}
|
||||
|
||||
static void
|
||||
httpPutHeader(App *app, Buf *buf, char *name, char *value)
|
||||
{
|
||||
bufPutString(buf, (unsigned char *) name);
|
||||
bufMark(buf, 0);
|
||||
app->httpRequestHeaderName(app, buf);
|
||||
bufPutString(buf, (unsigned char *) ": ");
|
||||
bufMark(buf, 0);
|
||||
app->httpRequest(app, buf);
|
||||
bufPutString(buf, (unsigned char *) value);
|
||||
bufMark(buf, 0);
|
||||
app->httpRequestHeaderValue(app, buf);
|
||||
bufPutString(buf, (unsigned char *) "\r\n");
|
||||
bufMark(buf, 0);
|
||||
app->httpRequest(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
httpGetObject(App *app, HTTP *http, int sock)
|
||||
{
|
||||
Buf *buf;
|
||||
HTTPNameValue *h;
|
||||
|
||||
buf = bufAlloc(sock);
|
||||
|
||||
bufMark(buf, 0);
|
||||
bufPutString(buf, (unsigned char *) "GET ");
|
||||
if (http->url->path)
|
||||
{
|
||||
len = countOrCopy(&p, "GET ");
|
||||
if (url->path)
|
||||
bufPutString(buf, http->url->path);
|
||||
}
|
||||
if (http->url->params)
|
||||
{
|
||||
bufPutString(buf, http->url->params);
|
||||
}
|
||||
if (http->url->query)
|
||||
{
|
||||
bufPutString(buf, http->url->query);
|
||||
}
|
||||
bufPutChar(buf, ' ');
|
||||
bufPutString(buf, http->version);
|
||||
bufPutString(buf, (unsigned char *) "\r\n");
|
||||
bufMark(buf, 0);
|
||||
app->httpRequest(app, buf);
|
||||
|
||||
h = http->headers;
|
||||
if (h)
|
||||
{
|
||||
while (h->name)
|
||||
{
|
||||
len += countOrCopy(&p, (char *) url->path);
|
||||
}
|
||||
if (url->params)
|
||||
{
|
||||
len += countOrCopy(&p, (char *) url->params);
|
||||
}
|
||||
if (url->query)
|
||||
{
|
||||
len += countOrCopy(&p, (char *) url->query);
|
||||
}
|
||||
len += countOrCopy(&p, " HTTP/1.0\n");
|
||||
h = headers;
|
||||
if (h)
|
||||
{
|
||||
while (*h)
|
||||
{
|
||||
len += countOrCopy(&p, (char *) *h);
|
||||
len += countOrCopy(&p, "\n");
|
||||
h++;
|
||||
}
|
||||
}
|
||||
len += countOrCopy(&p, "Host: ");
|
||||
len += countOrCopy(&p, (char *) url->host);
|
||||
len += countOrCopy(&p, "\n\n");
|
||||
if (!buf)
|
||||
{
|
||||
buf = malloc(len + 1);
|
||||
if (!buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
p = buf;
|
||||
httpPutHeader(app, buf, (char *) h->name,
|
||||
(char *) h->value);
|
||||
h++;
|
||||
}
|
||||
}
|
||||
send(sock, buf, len, 0);
|
||||
|
||||
httpRead(http, app, sock, url->url);
|
||||
httpPutHeader(app, buf, "Connection", "close");
|
||||
|
||||
httpPutHeader(app, buf, "Host", (char *) http->url->host);
|
||||
|
||||
bufPutString(buf, (unsigned char *) "\r\n");
|
||||
bufMark(buf, 0);
|
||||
app->httpRequest(app, buf);
|
||||
|
||||
if (bufError(buf))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
bufSend(buf);
|
||||
|
||||
bufFree(buf);
|
||||
|
||||
httpRead(app, http, sock);
|
||||
}
|
||||
|
||||
HTTP *
|
||||
|
@ -384,13 +490,13 @@ httpFree(HTTP *http)
|
|||
{
|
||||
if (http)
|
||||
{
|
||||
inputFree(http->input);
|
||||
bufFree(http->in);
|
||||
free(http);
|
||||
}
|
||||
}
|
||||
|
||||
HTTP *
|
||||
httpProcess(App *app, URL *url, unsigned char **headers)
|
||||
httpProcess(App *app, URL *url, char *version, HTTPNameValue *headers)
|
||||
{
|
||||
HTTP *http;
|
||||
int port;
|
||||
|
@ -418,8 +524,18 @@ httpProcess(App *app, URL *url, unsigned char **headers)
|
|||
}
|
||||
|
||||
http = httpAlloc();
|
||||
http->url = url;
|
||||
if (version)
|
||||
{
|
||||
http->version = (unsigned char *) version;
|
||||
}
|
||||
else
|
||||
{
|
||||
http->version = (unsigned char *) "HTTP/1.0";
|
||||
}
|
||||
http->headers = headers;
|
||||
|
||||
httpGetObject(http, app, sock, url, headers);
|
||||
httpGetObject(app, http, sock);
|
||||
|
||||
close(sock);
|
||||
|
||||
|
|
|
@ -25,24 +25,32 @@
|
|||
#ifndef _HTTP_H_
|
||||
#define _HTTP_H_
|
||||
|
||||
#include "io.h"
|
||||
#include "url.h"
|
||||
|
||||
typedef struct HTTPNameValue HTTPNameValue;
|
||||
|
||||
typedef struct HTTP
|
||||
{
|
||||
const unsigned char *body;
|
||||
unsigned long bodyLen;
|
||||
Input *input;
|
||||
int status;
|
||||
unsigned long body;
|
||||
HTTPNameValue *headers;
|
||||
Buf *in;
|
||||
int status;
|
||||
URL *url;
|
||||
unsigned char *version;
|
||||
} HTTP;
|
||||
|
||||
struct HTTPNameValue
|
||||
{
|
||||
unsigned char *name;
|
||||
unsigned char *value;
|
||||
};
|
||||
|
||||
HTTP *httpAlloc(void);
|
||||
void httpFree(HTTP *http);
|
||||
int httpGetHTTP10OrGreaterCount(void);
|
||||
int httpGetNonEmptyHTTPResponseCount(void);
|
||||
void httpParseRequest(HTTP *http, App *app, char *url);
|
||||
void httpParseStream(HTTP *http, App *app, unsigned char *url);
|
||||
HTTP *httpProcess(App *app, URL *url, unsigned char **headers);
|
||||
void httpRead(HTTP *http, App *app, int fd, unsigned char *url);
|
||||
HTTP *httpProcess(App *app, URL *url, char *version, HTTPNameValue *headers);
|
||||
|
||||
#endif /* _HTTP_H_ */
|
||||
|
|
|
@ -68,7 +68,7 @@ main(int argc, char *argv[])
|
|||
while (url)
|
||||
{
|
||||
appDefault.data = url;
|
||||
http = httpProcess(&appDefault, url, NULL);
|
||||
http = httpProcess(&appDefault, url, NULL, NULL);
|
||||
if (http)
|
||||
{
|
||||
switch (http->status)
|
||||
|
|
|
@ -46,15 +46,15 @@ typedef struct Arg
|
|||
View *view;
|
||||
} Arg;
|
||||
|
||||
static void proxyHTML(App *app, Input *input);
|
||||
static void proxyHTMLAttributeName(App *app, HTML *html, Input *input);
|
||||
static void proxyHTMLAttributeValue(App *app, HTML *html, Input *input);
|
||||
static void proxyHTMLTag(App *app, HTML *html, Input *input);
|
||||
static void proxyHTMLText(App *app, Input *input);
|
||||
static void proxyHTTP(App *app, Input *input);
|
||||
static void proxyHTTPBody(App *app, Input *input);
|
||||
static void proxyHTTPHeaderName(App *app, Input *input);
|
||||
static void proxyHTTPHeaderValue(App *app, Input *input, unsigned char *url);
|
||||
static void proxyHTML(App *app, Buf *buf);
|
||||
static void proxyHTMLAttributeName(App *app, HTML *html, Buf *buf);
|
||||
static void proxyHTMLAttributeValue(App *app, HTML *html, Buf *buf);
|
||||
static void proxyHTMLTag(App *app, HTML *html, Buf *buf);
|
||||
static void proxyHTMLText(App *app, Buf *buf);
|
||||
static void proxyHTTP(App *app, Buf *buf);
|
||||
static void proxyHTTPBody(App *app, Buf *buf);
|
||||
static void proxyHTTPHeaderName(App *app, Buf *buf);
|
||||
static void proxyHTTPHeaderValue(App *app, Buf *buf, unsigned char *url);
|
||||
|
||||
static fd_set fdSet;
|
||||
static int id = 0;
|
||||
|
@ -193,10 +193,10 @@ proxyApp(FD *f)
|
|||
app->htmlAttributeValue = proxyHTMLAttributeValue;
|
||||
app->htmlTag = proxyHTMLTag;
|
||||
app->htmlText = proxyHTMLText;
|
||||
app->http = proxyHTTP;
|
||||
app->httpBody = proxyHTTPBody;
|
||||
app->httpHeaderName = proxyHTTPHeaderName;
|
||||
app->httpHeaderValue = proxyHTTPHeaderValue;
|
||||
app->httpResponse = proxyHTTP;
|
||||
app->httpResponseBody = proxyHTTPBody;
|
||||
app->httpResponseHeaderName = proxyHTTPHeaderName;
|
||||
app->httpResponseHeaderValue = proxyHTTPHeaderValue;
|
||||
app->view.backslash = 1;
|
||||
app->view.out = f->logFile;
|
||||
|
||||
|
@ -204,7 +204,7 @@ proxyApp(FD *f)
|
|||
}
|
||||
|
||||
static int
|
||||
logRequest(FD *f, Input *input)
|
||||
logRequest(FD *f, Buf *buf)
|
||||
{
|
||||
App *app;
|
||||
HTTP *http;
|
||||
|
@ -212,7 +212,7 @@ logRequest(FD *f, Input *input)
|
|||
if
|
||||
(
|
||||
(table[fileno(f->logFile)]->suspend) ||
|
||||
(strstr((char *) current(input), suspendStr))
|
||||
(strstr((char *) current(buf), suspendStr))
|
||||
)
|
||||
{
|
||||
table[f->writeFD]->suspend = 1;
|
||||
|
@ -232,7 +232,7 @@ logRequest(FD *f, Input *input)
|
|||
f->id
|
||||
);
|
||||
http = httpAlloc();
|
||||
http->input = input;
|
||||
http->in = buf;
|
||||
app = proxyApp(f);
|
||||
httpParseRequest(http, app, "logRequest");
|
||||
free(app);
|
||||
|
@ -247,21 +247,21 @@ static int
|
|||
readClientRequest(int fd)
|
||||
{
|
||||
FD *f;
|
||||
Input *input;
|
||||
Buf *buf;
|
||||
|
||||
f = table[fd];
|
||||
input = readAvailableBytes(fd);
|
||||
send(f->writeFD, current(input), inputLength(input), 0);
|
||||
if (!logRequest(f, input))
|
||||
buf = readAvailableBytes(fd);
|
||||
send(f->writeFD, current(buf), inputLength(buf), 0);
|
||||
if (!logRequest(f, buf))
|
||||
{
|
||||
inputFree(input);
|
||||
bufFree(buf);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
logResponse(FD *f, Input *input)
|
||||
logResponse(FD *f, Buf *buf)
|
||||
{
|
||||
App *app;
|
||||
HTTP *http;
|
||||
|
@ -280,7 +280,7 @@ logResponse(FD *f, Input *input)
|
|||
f->id
|
||||
);
|
||||
http = httpAlloc();
|
||||
http->input = input;
|
||||
http->in = buf;
|
||||
app = proxyApp(f);
|
||||
httpParseStream(http, app, (unsigned char *) "readProxyResponse");
|
||||
free(app);
|
||||
|
@ -295,14 +295,14 @@ static int
|
|||
readProxyResponse(int fd)
|
||||
{
|
||||
FD *f;
|
||||
Input *input;
|
||||
Buf *buf;
|
||||
|
||||
f = table[fd];
|
||||
input = readStream(fd, (unsigned char *) "readProxyResponse");
|
||||
send(f->writeFD, current(input), inputLength(input), 0);
|
||||
if (!logResponse(f, input))
|
||||
buf = readStream(fd, (unsigned char *) "readProxyResponse");
|
||||
send(f->writeFD, current(buf), inputLength(buf), 0);
|
||||
if (!logResponse(f, buf))
|
||||
{
|
||||
inputFree(input);
|
||||
bufFree(buf);
|
||||
}
|
||||
removeFD(f->writeFD);
|
||||
removeFD(fd);
|
||||
|
@ -365,7 +365,7 @@ acceptNewClient(int fd)
|
|||
static int
|
||||
readLoggerRequest(int fd)
|
||||
{
|
||||
char buf[10240];
|
||||
char b[10240];
|
||||
int bytesRead;
|
||||
int doSuspend;
|
||||
FD *f;
|
||||
|
@ -380,7 +380,7 @@ readLoggerRequest(int fd)
|
|||
char *suspend;
|
||||
int suspendPort;
|
||||
|
||||
bytesRead = recv(fd, buf, sizeof(buf) - 1, 0);
|
||||
bytesRead = recv(fd, b, sizeof(b) - 1, 0);
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
if (errno != ECONNRESET)
|
||||
|
@ -395,11 +395,11 @@ readLoggerRequest(int fd)
|
|||
removeFD(fd);
|
||||
return 0;
|
||||
}
|
||||
buf[bytesRead] = 0;
|
||||
b[bytesRead] = 0;
|
||||
|
||||
resume = "/resume";
|
||||
suspend = "/suspend";
|
||||
if (strstr(buf, "/exit"))
|
||||
if (strstr(b, "/exit"))
|
||||
{
|
||||
char *goodbye =
|
||||
"HTTP/1.0 200 OK\n"
|
||||
|
@ -411,9 +411,9 @@ readLoggerRequest(int fd)
|
|||
removeFD(fd);
|
||||
return 1;
|
||||
}
|
||||
else if ((strstr(buf, resume)) || (strstr(buf, suspend)))
|
||||
else if ((strstr(b, resume)) || (strstr(b, suspend)))
|
||||
{
|
||||
if (strstr(buf, resume))
|
||||
if (strstr(b, resume))
|
||||
{
|
||||
str = resume;
|
||||
doSuspend = 0;
|
||||
|
@ -423,7 +423,7 @@ readLoggerRequest(int fd)
|
|||
str = suspend;
|
||||
doSuspend = 1;
|
||||
}
|
||||
p = strstr(buf, str);
|
||||
p = strstr(b, str);
|
||||
p += strlen(str);
|
||||
if (*p != '/')
|
||||
{
|
||||
|
@ -470,7 +470,7 @@ readLoggerRequest(int fd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* XXX send(1, buf, bytesRead, 0); */
|
||||
/* XXX send(1, b, bytesRead, 0); */
|
||||
|
||||
file = fdopen(fd, "w");
|
||||
if (!file)
|
||||
|
@ -537,57 +537,57 @@ acceptNewLogger(int fd)
|
|||
}
|
||||
|
||||
static void
|
||||
proxyHTML(App *app, Input *input)
|
||||
proxyHTML(App *app, Buf *buf)
|
||||
{
|
||||
viewHTML(app, input);
|
||||
viewHTML(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTMLAttributeName(App *app, HTML *html, Input *input)
|
||||
proxyHTMLAttributeName(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
viewHTMLAttributeName(app, input);
|
||||
viewHTMLAttributeName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTMLAttributeValue(App *app, HTML *html, Input *input)
|
||||
proxyHTMLAttributeValue(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
viewHTMLAttributeValue(app, input);
|
||||
viewHTMLAttributeValue(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTMLTag(App *app, HTML *html, Input *input)
|
||||
proxyHTMLTag(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
viewHTMLTag(app, input);
|
||||
viewHTMLTag(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTMLText(App *app, Input *input)
|
||||
proxyHTMLText(App *app, Buf *buf)
|
||||
{
|
||||
viewHTMLText(app, input);
|
||||
viewHTMLText(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTTP(App *app, Input *input)
|
||||
proxyHTTP(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTP(app, input);
|
||||
viewHTTP(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTTPBody(App *app, Input *input)
|
||||
proxyHTTPBody(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTP(app, input);
|
||||
viewHTTP(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTTPHeaderName(App *app, Input *input)
|
||||
proxyHTTPHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
viewHTTPHeaderName(app, input);
|
||||
viewHTTPHeaderName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
proxyHTTPHeaderValue(App *app, Input *input, unsigned char *url)
|
||||
proxyHTTPHeaderValue(App *app, Buf *buf, unsigned char *url)
|
||||
{
|
||||
viewHTTPHeaderValue(app, input);
|
||||
viewHTTPHeaderValue(app, buf);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -263,57 +263,57 @@ addURLFunc(App *app, URL *url)
|
|||
}
|
||||
|
||||
static void
|
||||
robotHTTP(App *app, Input *input)
|
||||
robotHTTP(App *app, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
|
||||
robot = app->data;
|
||||
|
||||
viewHTTP(app, input);
|
||||
viewHTTP(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTTPBody(App *app, Input *input)
|
||||
robotHTTPBody(App *app, Buf *buf)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTTPHeaderName(App *app, Input *input)
|
||||
robotHTTPHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
unsigned char *name;
|
||||
|
||||
robot = app->data;
|
||||
|
||||
name = copyLower(input);
|
||||
name = bufCopyLower(buf);
|
||||
addEntry(httpHeaderTable, robot, robot->url->url, name);
|
||||
free(name);
|
||||
|
||||
viewHTTPHeaderName(app, input);
|
||||
viewHTTPHeaderName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTTPHeaderValue(App *app, Input *input, unsigned char *url)
|
||||
robotHTTPHeaderValue(App *app, Buf *buf, unsigned char *url)
|
||||
{
|
||||
Robot *robot;
|
||||
|
||||
robot = app->data;
|
||||
|
||||
viewHTTPHeaderValue(app, input);
|
||||
viewHTTPHeaderValue(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTML(App *app, Input *input)
|
||||
robotHTML(App *app, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
|
||||
robot = app->data;
|
||||
|
||||
viewHTML(app, input);
|
||||
viewHTML(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTMLText(App *app, Input *input)
|
||||
robotHTMLText(App *app, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
unsigned char *p;
|
||||
|
@ -321,9 +321,9 @@ robotHTMLText(App *app, Input *input)
|
|||
|
||||
robot = app->data;
|
||||
|
||||
viewHTMLText(app, input);
|
||||
viewHTMLText(app, buf);
|
||||
|
||||
str = copy(input);
|
||||
str = bufCopy(buf);
|
||||
p = str;
|
||||
while (*p)
|
||||
{
|
||||
|
@ -352,7 +352,7 @@ robotHTMLText(App *app, Input *input)
|
|||
}
|
||||
|
||||
static void
|
||||
robotHTMLTag(App *app, HTML *html, Input *input)
|
||||
robotHTMLTag(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
HashEntry *tagEntry;
|
||||
|
@ -375,11 +375,11 @@ robotHTMLTag(App *app, HTML *html, Input *input)
|
|||
}
|
||||
}
|
||||
|
||||
viewHTMLTag(app, input);
|
||||
viewHTMLTag(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTMLAttributeName(App *app, HTML *html, Input *input)
|
||||
robotHTMLAttributeName(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
|
||||
|
@ -391,17 +391,17 @@ robotHTMLAttributeName(App *app, HTML *html, Input *input)
|
|||
html->currentAttribute->name);
|
||||
#endif
|
||||
}
|
||||
viewHTMLAttributeName(app, input);
|
||||
viewHTMLAttributeName(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
robotHTMLAttributeValue(App *app, HTML *html, Input *input)
|
||||
robotHTMLAttributeValue(App *app, HTML *html, Buf *buf)
|
||||
{
|
||||
Robot *robot;
|
||||
|
||||
robot = app->data;
|
||||
|
||||
viewHTMLAttributeValue(app, input);
|
||||
viewHTMLAttributeValue(app, buf);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -669,7 +669,7 @@ processURL(App *app)
|
|||
app->status(app, "processURL", __FILE__, __LINE__);
|
||||
|
||||
openViewFile(app);
|
||||
httpFree(httpProcess(app, robot->url, NULL));
|
||||
httpFree(httpProcess(app, robot->url, NULL, NULL));
|
||||
closeViewFile(app);
|
||||
|
||||
app->status(app, "processURL done", __FILE__, __LINE__);
|
||||
|
@ -688,17 +688,17 @@ startHere(void *a)
|
|||
app = appAlloc();
|
||||
app->status = robotStatus;
|
||||
app->time = robotTime;
|
||||
app->http = robotHTTP;
|
||||
app->httpBody = robotHTTPBody;
|
||||
app->httpHeaderName = robotHTTPHeaderName;
|
||||
app->httpHeaderValue = robotHTTPHeaderValue;
|
||||
app->httpResponse = robotHTTP;
|
||||
app->httpResponseBody = robotHTTPBody;
|
||||
app->httpResponseHeaderName = robotHTTPHeaderName;
|
||||
app->httpResponseHeaderValue = robotHTTPHeaderValue;
|
||||
app->html = robotHTML;
|
||||
app->htmlText = robotHTMLText;
|
||||
app->htmlTag = robotHTMLTag;
|
||||
app->htmlAttributeName = robotHTMLAttributeName;
|
||||
app->htmlAttributeValue = robotHTMLAttributeValue;
|
||||
app->contentType = robotContentType;
|
||||
app->httpCharSet = robotHTTPCharSet;
|
||||
app->httpResponseCharSet = robotHTTPCharSet;
|
||||
app->data = &robot;
|
||||
|
||||
while (1)
|
||||
|
@ -841,12 +841,12 @@ compareStatusEntries(const void *e1, const void *e2)
|
|||
static void
|
||||
readClientRequest(int fd)
|
||||
{
|
||||
unsigned char buf[10240];
|
||||
unsigned char b[10240];
|
||||
int bytesRead;
|
||||
FILE *file;
|
||||
int i;
|
||||
|
||||
bytesRead = recv(fd, buf, sizeof(buf) - 1, 0);
|
||||
bytesRead = recv(fd, b, sizeof(b) - 1, 0);
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
if (errno != ECONNRESET)
|
||||
|
@ -861,7 +861,7 @@ readClientRequest(int fd)
|
|||
removeFD(fd);
|
||||
return;
|
||||
}
|
||||
buf[bytesRead] = 0;
|
||||
b[bytesRead] = 0;
|
||||
|
||||
file = fdopen(fd, "w");
|
||||
if (!file)
|
||||
|
@ -874,7 +874,7 @@ readClientRequest(int fd)
|
|||
|
||||
table[fd]->file = file;
|
||||
|
||||
if (strstr((char *) buf, "/exit"))
|
||||
if (strstr((char *) b, "/exit"))
|
||||
{
|
||||
char *goodbye =
|
||||
"HTTP/1.0 200 OK\n"
|
||||
|
@ -886,7 +886,7 @@ readClientRequest(int fd)
|
|||
removeFD(fd);
|
||||
exit(0);
|
||||
}
|
||||
else if (strstr((char *) buf, "/times"))
|
||||
else if (strstr((char *) b, "/times"))
|
||||
{
|
||||
char *begin =
|
||||
"HTTP/1.0 200 OK\n"
|
||||
|
|
|
@ -30,6 +30,8 @@
|
|||
#endif
|
||||
#define FREE(p) do { if (p) { free(p); (p) = NULL; } } while (0)
|
||||
|
||||
#define NELEMS(array) (sizeof(array) / sizeof((array)[0]))
|
||||
|
||||
unsigned char *appendString(const unsigned char *str1,
|
||||
const unsigned char *str2);
|
||||
unsigned char *copySizedString(const unsigned char *str, int size);
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
static int verbose = 0;
|
||||
|
||||
static void
|
||||
print(View *view, Input *input)
|
||||
print(View *view, Buf *b)
|
||||
{
|
||||
char buf[1024];
|
||||
char *hex;
|
||||
|
@ -47,7 +47,7 @@ print(View *view, Input *input)
|
|||
unsigned char *str;
|
||||
|
||||
hex = "0123456789ABCDEF";
|
||||
str = copyMemory(input, &inLen);
|
||||
str = bufCopyMemory(b, &inLen);
|
||||
|
||||
buf[1] = 0;
|
||||
len = 0;
|
||||
|
@ -61,7 +61,7 @@ print(View *view, Input *input)
|
|||
switch (str[j])
|
||||
{
|
||||
case '\r':
|
||||
if (str[j + 1] == '\n')
|
||||
if (((j + 1) < inLen) && (str[j + 1] == '\n'))
|
||||
{
|
||||
j++;
|
||||
replacement = CONTROL("CRLF") NL;
|
||||
|
@ -154,62 +154,62 @@ print(View *view, Input *input)
|
|||
}
|
||||
|
||||
void
|
||||
viewHTML(App *app, Input *input)
|
||||
viewHTML(App *app, Buf *buf)
|
||||
{
|
||||
fprintf(app->view.out, "<font color=#009900>");
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
fprintf(app->view.out, "</font>");
|
||||
}
|
||||
|
||||
void
|
||||
viewHTMLAttributeName(App *app, Input *input)
|
||||
viewHTMLAttributeName(App *app, Buf *buf)
|
||||
{
|
||||
fprintf(app->view.out, "<font color=#FF6600>");
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
fprintf(app->view.out, "</font>");
|
||||
}
|
||||
|
||||
void
|
||||
viewHTMLAttributeValue(App *app, Input *input)
|
||||
viewHTMLAttributeValue(App *app, Buf *buf)
|
||||
{
|
||||
fprintf(app->view.out, "<font color=#3333FF>");
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
fprintf(app->view.out, "</font>");
|
||||
}
|
||||
|
||||
void
|
||||
viewHTMLTag(App *app, Input *input)
|
||||
viewHTMLTag(App *app, Buf *buf)
|
||||
{
|
||||
fprintf(app->view.out, "<font color=#CC33CC>");
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
fprintf(app->view.out, "</font>");
|
||||
}
|
||||
|
||||
void
|
||||
viewHTMLText(App *app, Input *input)
|
||||
viewHTMLText(App *app, Buf *buf)
|
||||
{
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
}
|
||||
|
||||
void
|
||||
viewHTTP(App *app, Input *input)
|
||||
viewHTTP(App *app, Buf *buf)
|
||||
{
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
}
|
||||
|
||||
void
|
||||
viewHTTPHeaderName(App *app, Input *input)
|
||||
viewHTTPHeaderName(App *app, Buf *buf)
|
||||
{
|
||||
fprintf(app->view.out, "<font color=#FF6600>");
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
fprintf(app->view.out, "</font>");
|
||||
}
|
||||
|
||||
void
|
||||
viewHTTPHeaderValue(App *app, Input *input)
|
||||
viewHTTPHeaderValue(App *app, Buf *buf)
|
||||
{
|
||||
fprintf(app->view.out, "<font color=#3333FF>");
|
||||
print(&app->view, input);
|
||||
print(&app->view, buf);
|
||||
fprintf(app->view.out, "</font>");
|
||||
}
|
||||
|
||||
|
@ -222,10 +222,13 @@ viewVerbose(void)
|
|||
void
|
||||
viewReport(App *app, char *str)
|
||||
{
|
||||
unsigned char *esc;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
fprintf(app->view.out, (char *) escapeHTML((unsigned char *) str));
|
||||
fprintf(app->view.out, "<br>");
|
||||
esc = escapeHTML((unsigned char *) str);
|
||||
fprintf(app->view.out, "%s\n", (char *) esc);
|
||||
free(esc);
|
||||
fflush(app->view.out);
|
||||
}
|
||||
}
|
||||
|
@ -235,8 +238,7 @@ viewReportHTML(App *app, char *str)
|
|||
{
|
||||
if (verbose)
|
||||
{
|
||||
fprintf(app->view.out, str);
|
||||
fprintf(app->view.out, "<br>");
|
||||
fprintf(app->view.out, "%s\n", str);
|
||||
fflush(app->view.out);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
#ifndef _VIEW_H_
|
||||
#define _VIEW_H_
|
||||
|
||||
#include "io.h"
|
||||
#include "buf.h"
|
||||
|
||||
typedef struct View
|
||||
{
|
||||
|
@ -33,14 +33,14 @@ typedef struct View
|
|||
FILE *out;
|
||||
} View;
|
||||
|
||||
void viewHTML(App *app, Input *input);
|
||||
void viewHTMLAttributeName(App *app, Input *input);
|
||||
void viewHTMLAttributeValue(App *app, Input *input);
|
||||
void viewHTMLTag(App *app, Input *input);
|
||||
void viewHTMLText(App *app, Input *input);
|
||||
void viewHTTP(App *app, Input *input);
|
||||
void viewHTTPHeaderName(App *app, Input *input);
|
||||
void viewHTTPHeaderValue(App *app, Input *input);
|
||||
void viewHTML(App *app, Buf *buf);
|
||||
void viewHTMLAttributeName(App *app, Buf *buf);
|
||||
void viewHTMLAttributeValue(App *app, Buf *buf);
|
||||
void viewHTMLTag(App *app, Buf *buf);
|
||||
void viewHTMLText(App *app, Buf *buf);
|
||||
void viewHTTP(App *app, Buf *buf);
|
||||
void viewHTTPHeaderName(App *app, Buf *buf);
|
||||
void viewHTTPHeaderValue(App *app, Buf *buf);
|
||||
void viewReport(App *app, char *str);
|
||||
void viewReportHTML(App *app, char *str);
|
||||
void viewVerbose(void);
|
||||
|
|
Загрузка…
Ссылка в новой задаче