#include "common.h" class Object { public: char *name; char *value; Object *next; Object(char *iname = 0, char *ivalue = 0) { next = 0; if (iname && ivalue) { set(iname, ivalue); } else { name = 0; value = 0; } } ~Object() { if (name) free(name); if (value) free(value); } void set(char *iname, char *ivalue) { int len_name = strlen(iname); int len_value = strlen(ivalue); name = new char[len_name + 1]; value = new char[len_value + 1]; strcpy(name, iname); strcpy(value, ivalue); } void setLower(char *iname, char *ivalue) { set(iname, ivalue); char c, *p = name; while (c = *p) { if (c >= 'A' && c <= 'Z') { *p += 0x20; } p++; } } void setNext(Object *np) { next = np; } }; class Hash { public: Object *top, *cp; Hash() { top = cp = 0; } ~Hash() { cp = top; while (cp) { Object *np = cp->next; delete cp; cp = np; } } int set(char *name, char *value) { Object *np = new Object(name, value); if (!top) { cp = top = np; } else { cp->setNext(np); cp = np; } } char *get(char *name) { Object *sp = top; while (sp) { if (!strcasecmp(name, sp->name)) return sp->value; sp = sp->next; } return 0; } int delete(char *name) { Object *bp, *sp = top; bp = 0; while (sp) { Object *np = sp->next; if (!strcasecmp(name, sp->name)) { if (!bp) { top = np; } else { bp->setNext(np); } if (cp == sp) { cp = bp; } delete sp; return 1; } bp = sp; sp = np; } return 0; } }; class Socket { char rbuf[1024]; char *readp; char *writep; int rlen; public: SOCKET s; SSL *ssl; Socket() { readp = writep = rbuf; rlen = 1024; s = -1; ssl = 0; } int read(char *buf, int len) { int ret; int total = 0; char *p = buf; if (writep - readp > 0) { int slen = writep - readp; memcpy(p, readp, slen); p += slen; len -= slen; readp = writep = rbuf; rlen = 1024; } while (len) { if (ssl) { ret = SSL_read(ssl, p, len); } else { ret = recv(s, p, len, 0); } if (ret < 0) { return -1; } if (!ret) { return 0; } p += ret; len -= ret; } return (p - buf); } int read() { int ret; if (ssl) { ret = SSL_read(ssl, writep, rlen); } else { ret = recv(s, writep, rlen, 0); } if (ret < 0) { return -1; } if (!ret) { return 0; } rlen -= ret; writep += ret; return ret; } int strcpyln(char *dest, int len, int flag) { char c, *p = readp; while(p <= writep) { c = *p; len--; if (!len) { readp = p; *dest = 0; return 1; } if (flag) { if (c == '\r' || c == '\n') { while (*p == '\r' || *p == '\n') p++; readp = p; *dest = 0; return 2; } } *dest++ = *p++; if (c == '\n') { *dest = 0; readp = p; return 2; } } readp = writep = rbuf; rlen = 1024; return FALSE; } int readText(char *buf, int len, flag) { int ret = 0; while (!ret) { ret = read(); if (ret <= 0) return ret; ret = strcpyln(buf, len, flag); } return 1; } int readBinary(char *buf, int len) { int ret = 0; return read(buf, len); } int write(char *buf, int len = 0) { if (!len) len = strlen(buf); int ret; if (ssl) { ret = SSL_write(ssl, buf, len); } else { ret = send(s, buf, len, 0); } return ret; } }; class HTTP_Response { public: Hash header; int response; char msgResponse[256]; HTTP_Response() { header.set("Server", "Bjorb/0.0.0"); } void set(char *name, char *value) { header.set(name, value); } void setDate(); void setResponse(int res, char *buf) { response = res; strcpy(msgResponse, buf); } int writeSocket(Socket *s) { Hash *cp = header.top; char buf[1024]; sprintf(buf, "HTTP/1.0 %d %s\r\n", response, msgResponse); s->write(buf); while (cp) { sprintf(buf, "%s: %s\r\n", cp->name, cp->value); s->write(buf); cp = cp->next; } } }; int HTTP_relay_auth(Socket *s, Socket *s_server) { char buf[1024]; int ret; char c, *p, *q; Hash header; char first_line[1024]; char name[1024]; char value[1024]; int len; ret = s->readText(first_line, 1024, FALSE); if (ret <= 0) return FALSE; while ((ret = s->readText(buf, 1024, TRUE)) > 0) { p = buf; if (!*p) break; q = name; while (c = *p, c && c != ':') { *q++ = *p++; } *q = 0; if (c != ':') { /* format error */ continue; } p++; skipSpace(&p); q = value; if (*p == '"') { p++; while (c = *p, c && c != '"') { *q++ = *p++; } if (c == '"') p++; else { /* warning: '"' is not closed. */ } } else { while (c = *p, c) { *q++ = *p++; } } *q = 0; header.set(name, value); } HTTP_Response hres; char *authorization = header.get("Authorization"); if (!authorization) { hres.setResponse(401, "Authorization Required"); hres.set("WWW-Authenticate", "Basic realm=\"ByPassword\""); hres.set("Connection", "close"); hres.writeSocket(s); s->writeSocketLine("\r\n" "401 Authorization Required\r\n" "\r\n" "

Authorization Required

\r\n" "This server could not verify that you" "are authorized to access the document you" "requiested. Either you supplied the wrong" "credentials (e.g., bad password), or your" "browser doesn't understand how to suppy" "the credentials required.

" "\r\n"); return FALSE; } hres.delete("Authorization"); hres.setDate(); hres.set("Content-Type", "text/html"); hres.writeSocket(s_server); while ((ret = s_server->readBinary(buf, 1024)) >= 0) { ret = s->writeBinary(buf, ret); if (ret <= 0) return FALSE; } return TRUE; }