#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" "" "