UByte bufRdUByte(Buffer buf) { UByte result; result = bufGetByte(buf); return result; }
static unsigned short readSpaceTab(Buf *buf, unsigned short c) { while ((c == ' ') || (c == '\t')) { c = bufGetByte(buf); } return c; }
static unsigned short readLine(Buf *buf, unsigned short c) { while ((c != 256) && (c != '\r') && (c != '\n')) { c = bufGetByte(buf); } if (c == '\r') { c = bufGetByte(buf); if (c == '\n') { c = bufGetByte(buf); } } else if (c == '\n') { c = bufGetByte(buf); } return c; }
static void httpDefaultType(HTTP *http, App *app) { unsigned short c; do { c = bufGetByte(http->in); } while (c != 256); bufMark(http->in, -1); app->httpResponseBody(app, http->in); }
void httpParseRequest(HTTP *http, App *app, char *url) { unsigned short c; bufMark(http->in, 0); do { c = bufGetByte(http->in); } while (c != 256); bufMark(http->in, -1); app->httpResponse(app, http->in); }
static unsigned short 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 readNonWhiteSpace(Buf *buf, unsigned short c) { while ( (c != 256) && (c != ' ') && (c != '\t') && (c != '\r') && (c != '\n') ) { c = bufGetByte(buf); } return c; }
void httpParseStream(HTTP *http, App *app, unsigned char *url) { 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); if (contentType) { if ( (contentType != emptyHTTPResponse) && (contentType != http09Response) && (contentType != locationURLWasAdded) ) { app->contentType(app, contentType); if (!strcasecmp((char *) contentType, "text/html")) { htmlRead(app, buf, url); } else { httpDefaultType(http, app); } free(contentType); } } else { httpDefaultType(http, app); } if (chunked) { bufFree(buf); } app->printHTML(app, "</pre>"); }
static unsigned short httpReadHeaders(HTTP *http, App *app, Buf *buf, unsigned char *url, unsigned char **ct, int *chunked) { unsigned short c; unsigned char *charset; unsigned char *contentType; int locationFound; unsigned char *name; URL *rel; ContentType *type; unsigned char *value; char *version; app->printHTML(app, "<h4>Response</h4>"); app->printHTML(app, "<pre>"); contentType = NULL; locationFound = 0; bufMark(buf, 0); c = bufGetByte(buf); if (c == 256) { *ct = emptyHTTPResponse; return c; } nonEmptyHTTPResponseCount++; 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? */ *ct = http09Response; return c; } free(version); http10OrGreaterCount++; c = readSpaceTab(buf, c); c = readNumber(buf, c, &http->status); c = readLine(buf, c); while (1) { if (c == 256) { bufMark(buf, 0); app->httpResponse(app, buf); break; } bufMark(buf, -1); app->httpResponse(app, buf); if ((c == '\r') || (c == '\n')) { readLine(buf, c); bufUnGetByte(buf); bufMark(buf, 0); app->httpResponse(app, buf); break; } while ( (c != 256) && (c != '\r') && (c != '\n') && (c != ':') ) { c = bufGetByte(buf); } if (c != ':') { bufMark(buf, -1); fprintf(stderr, "no colon in HTTP header \"%s\": %s\n", bufCopy(buf), url); *ct = NULL; return 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(buf, c); } while ((c == ' ') || (c == '\t')); } c = bufTrimTrailingWhiteSpace(buf); bufMark(buf, -1); value = bufCopy(buf); if (!strcasecmp((char *) name, "content-type")) { app->httpResponseHeaderValue(app, buf, NULL); type = mimeParseContentType(value); contentType = mimeGetContentType(type); charset = mimeGetContentTypeParameter(type, "charset"); if (charset) { app->httpResponseCharSet(app, charset); free(charset); } mimeFreeContentType(type); } else if (!strcasecmp((char *) name, "location")) { /* XXX supposed to be absolute URL? */ rel = urlRelative(url, value); addURL(app, rel->url); app->httpResponseHeaderValue(app, buf, 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->httpResponseHeaderValue(app, buf, NULL); } free(name); free(value); c = readLine(buf, c); bufMark(buf, -1); app->httpResponse(app, buf); } if (!contentType) { if (locationFound) { *ct = locationURLWasAdded; return c; } } *ct = contentType; return c; }