⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wwwapi.cpp

📁 fastdb-2.92的源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//-< WWWAPI.CPP >----------------------------------------------------*--------*// FastDB                    Version 1.0         (c) 1999  GARRET    *     ?  *// (Main Memory Database Management System)                          *   /\|  *//                                                                   *  /  \  *//                          Created:     27-Mar-99    K.A. Knizhnik  * / [] \ *//                          Last update:  1-Jul-99    K.A. Knizhnik  * GARRET *//-------------------------------------------------------------------*--------*// Implementation of WWWapi class//-------------------------------------------------------------------*--------*#define INSIDE_FASTDB#include "wwwapi.h"#include <ctype.h>const size_t init_reply_buffer_size = 4*1024;inline unsigned string_hash_function(const char* name){     unsigned h = 0, g;    while(*name) {         h = (h << 4) + *name++;        if ((g = h & 0xF0000000) != 0) {             h ^= g >> 24;        }        h &= ~g;    }    return h;}#define ERROR_TEXT(x) \"HTTP/1.1 " x "\r\n\Connection: close\r\n\r\n\<HTML><HEAD><TITLE>Invalid request to the database</TITLE>\r\n\</HEAD><BODY>\n\r\<H1>" x "</H1>\n\r\</BODY></HTML>\r\n\r\n"WWWconnection::WWWconnection(){    memset(hash_table, 0, sizeof hash_table);    sock = NULL;    reply_buf = new char[init_reply_buffer_size];    reply_buf_size = init_reply_buffer_size;    free_pairs = NULL;    peer = NULL;    userData = NULL;    userDataDestructor = NULL;}WWWconnection::~WWWconnection(){    reset();    name_value_pair *nvp, *next;    for (nvp = free_pairs; nvp != NULL; nvp = next) {         next = nvp->next;        delete nvp;    }    delete[] reply_buf;    delete[] peer;    if (userDataDestructor != NULL && userData != NULL) {         userDataDestructor(userData);    }}inline char* WWWconnection::extendBuffer(size_t inc){    if (reply_buf_used + inc >= reply_buf_size) {         reply_buf_size = reply_buf_size*2 > reply_buf_used + inc            ? reply_buf_size*2 : reply_buf_used + inc;        char* new_buf = new char[reply_buf_size+1];        memcpy(new_buf, reply_buf, reply_buf_used);        delete[] reply_buf;        reply_buf = new_buf;    }         reply_buf_used += inc;    return reply_buf;}bool WWWconnection::terminatedBy(char const* str) const{    size_t len = strlen(str);    if (len > reply_buf_used - 4) {         return false;    }    return memcmp(reply_buf + reply_buf_used - len, str, len) == 0;}WWWconnection& WWWconnection::append(const void *buf, int len) {    int pos = reply_buf_used;    char *dst = extendBuffer(len);    memcpy(dst + pos, buf, len);    return *this;}WWWconnection& WWWconnection::append(char const* str) {    int pos = reply_buf_used;    char* dst = extendBuffer(strlen(str));    unsigned char ch;    switch (encoding) {      case TAG:        strcpy(dst + pos, str);        encoding = HTML;        break;      case HTML:        encoding = TAG;#if 1 // MS-Explorer handle "&nbsp;" in HTML string literals in very strange way        if (str[0] == ' ' && str[1] == '\0') {             strcpy(extendBuffer(5) + pos, "&nbsp;");            return *this;        }#endif                    while (true) {             switch(ch = *str++) {               case '<':                dst = extendBuffer(3);                dst[pos++] = '&';                dst[pos++] = 'l';                dst[pos++] = 't';                dst[pos++] = ';';                break;              case '>':                dst = extendBuffer(3);                dst[pos++] = '&';                dst[pos++] = 'g';                dst[pos++] = 't';                dst[pos++] = ';';                break;              case '&':                dst = extendBuffer(4);                dst[pos++] = '&';                dst[pos++] = 'a';                dst[pos++] = 'm';                dst[pos++] = 'p';                dst[pos++] = ';';                break;              case '"':                dst = extendBuffer(5);                dst[pos++] = '&';                dst[pos++] = 'q';                dst[pos++] = 'u';                dst[pos++] = 'o';                dst[pos++] = 't';                dst[pos++] = ';';                break;              case '\0':                dst[pos] = '\0';                return *this;#if 0 // MS-Explorer handle "&nbsp;" in HTML string literals in very strange way              case ' ':                dst = extendBuffer(5);                dst[pos++] = '&';                dst[pos++] = 'n';                dst[pos++] = 'b';                dst[pos++] = 's';                dst[pos++] = 'p';                dst[pos++] = ';';                break;                #endif              default:                dst[pos++] = ch;            }        }      case URL:        encoding = TAG;        while (true) {             ch = *str++;            if (ch == '\0') {                 dst[pos] = '\0';                return *this;            } else if (ch == ' ') {                 dst[pos++] = '+';            } else if (!isalnum(ch)) {                 dst = extendBuffer(2);                dst[pos++] = '%';                dst[pos++] = (ch >> 4) >= 10                     ? (ch >> 4) + 'A' - 10 : (ch >> 4) + '0';                dst[pos++] = (ch & 0xF) >= 10                    ? (ch & 0xF) + 'A' - 10 : (ch & 0xF) + '0';            } else {                 dst[pos++] = ch;            }        }    }    return *this;}void WWWconnection::reset(){    reply_buf_used = 0;    encoding = TAG;    for (int i = itemsof(hash_table); --i >= 0;) {         name_value_pair *nvp, *next;        for (nvp = hash_table[i]; nvp != NULL; nvp = next) {             next = nvp->next;            nvp->next = free_pairs;            free_pairs = nvp;        }        hash_table[i] = NULL;    }       }void WWWconnection::addPair(char const* name, char const* value){    name_value_pair* nvp;    if (free_pairs != NULL) {         nvp = free_pairs;        free_pairs = nvp->next;    } else {         nvp = new name_value_pair;    }    unsigned hash_code = string_hash_function(name);    nvp->hash_code = hash_code;    hash_code %= hash_table_size;    nvp->next = hash_table[hash_code];    hash_table[hash_code] = nvp;    nvp->value = value;    nvp->name = name;}#define HEX_DIGIT(ch) ((ch) >= 'a' ? ((ch) - 'a' + 10) : (ch) >= 'A' ? ((ch) - 'A' + 10) : ((ch) - '0'))char* WWWconnection::unpack(char* body, size_t length){    char *src = body, *end = body + length;    while (src < end) {         char* name = src;        char ch;         char* dst = src;        while (src < end && (ch = *src++) != '=') {             if (ch == '+') {                ch = ' ';            } else if (ch == '%') {                 ch = (HEX_DIGIT(src[0]) << 4) | HEX_DIGIT(src[1]);                src += 2;            }            *dst++ = ch;        }        *dst = '\0';        char* value = dst = src;        while (src < end && (ch = *src++) != '&') {             if (ch == '+') {                ch = ' ';            } else if (ch == '%') {                 ch = (HEX_DIGIT(src[0]) << 4) | HEX_DIGIT(src[1]);                src += 2;            }            *dst++ = ch;        }        *dst = '\0';        addPair(name, value);    }    stub = get("stub");    return get("page");}char* WWWconnection::get(char const* name, int n){    unsigned hash_code = string_hash_function(name);    name_value_pair* nvp;    for (nvp = hash_table[hash_code % hash_table_size];         nvp != NULL;          nvp = nvp->next)    {        if (nvp->hash_code == hash_code && strcmp(nvp->name, name) == 0) {             if (n == 0) {                 return (char*)nvp->value;            }            n -= 1;        }    }    return NULL;}    //--------------------------------------------------WWWapi::WWWapi(dbDatabase& dbase, int n_handlers, dispatcher* dispatch_table): db(dbase){    memset(hash_table, 0, sizeof hash_table);    sock = NULL;    address = NULL;    dispatcher* disp = dispatch_table;    while (--n_handlers >= 0) {         unsigned hash_code = string_hash_function(disp->page);        disp->hash_code = hash_code;        hash_code %= hash_table_size;        disp->collision_chain = hash_table[hash_code];        hash_table[hash_code] = disp;        disp += 1;    }}bool WWWapi::open(char const* socket_address,                   socket_t::socket_domain domain,                   int listen_queue){    if (sock != NULL) {         close();    }    address = new char[strlen(socket_address) + 1];    strcpy(address, socket_address);    sock = domain != socket_t::sock_global_domain         ? socket_t::create_local(socket_address, listen_queue)        : socket_t::create_global(socket_address, listen_queue);    canceled = false;    if (!sock->is_ok()) {         char buf[64];        sock->get_error_text(buf, sizeof buf);        fprintf(stderr, "WWWapi::open: create socket failed: %s\n", buf);        return false;    }    return true;        }bool WWWapi::connect(WWWconnection& con){    assert(sock != NULL);    con.reset();    delete con.sock;    con.sock = sock->accept();    con.address = address;    if (con.sock == NULL) {         if (!canceled) {             char buf[64];            sock->get_error_text(buf, sizeof buf);            fprintf(stderr, "WWWapi::connect: accept failed: %s\n", buf);        }        return false;    }    return true;}void WWWapi::cancel(){    canceled = true;    sock->cancel_accept();}void WWWapi::close(){    delete sock;    delete[] address;    sock = NULL;}bool WWWapi::dispatch(WWWconnection& con, char* page){    unsigned hash_code = string_hash_function(page);    for (dispatcher* disp = hash_table[hash_code % hash_table_size];         disp != NULL;          disp = disp->collision_chain)    {        if (disp->hash_code == hash_code && strcmp(disp->page, page) == 0)        {             bool result = disp->func(con);            db.commit();            return result;        }    }    return true;}void URL2ASCII(char* src){    char* dst = src;    char ch;    while ((ch = *src++) != '\0') {         if (ch == '%') {             *dst++ = ((src[0] - '0') << 8) | (src[1] - '0');        } else if (ch == '+') {            *dst++ = ' ';        } else if (ch == '.' && *src == '.') {            // for security reasons do not allow access to parent directory            break;        } else {             *dst++ = ch;        }    }    *dst = '\0';}bool CGIapi::serve(WWWconnection& con){    nat4 length;    con.reset();    if ((size_t)con.sock->read(&length, sizeof length, sizeof length)         != sizeof(length)) 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -