Support Forums

Full Version: [C++][DOWNLOAD] Simple Webserver
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Even though I haven't provided a formal release of this library yet, I am offering you a download of a web server made from the AXCEL C++ Library that includes all the source code.

The compiled windows binary is there and the source can also be compiled on GNU/Linux. When compiling, keep in mind that there is usually a lot of .cpp file dependencies to compile your main file with, they are located in the src folder.

Download: http://www.mediafire.com/?li1f6vk6yl64ahj
Example usage:
Code:
server C:/Users/Bob 9000
Recommended but not necessary to have index.html in every folder and 404.html in the root folder.

server.cpp
Code:
#include "axcel/inc/Socket.h"
#include "axcel/inc/Thread.h"
#include "axcel/inc/Mutex.h"
#include "axcel/inc/String.h"
#include "axcel/inc/File.h"
#include "axcel/inc/console.h"
#include "mimes.cpp"
#include <vector>
#include <algorithm>
using namespace axcel;

const char* server = "Skynet";
const char* webroot;
std::vector<int> users;
Mutex m_users;

void urldecode(String& s) {
    size_t i;
    char hex[8];
    char byte[2];
    byte[1] = 0;
    for (i = 0; i < 0xff; i++) {
        sprintf(hex, "%%%02x", i);
        byte[0] = i;
        s = s.rep(hex, byte);
    }
}

String head(Socket& s, String buf) {
    size_t i;
    String file, stime;
    time_t t;
    time(&t);
    file = buf.tok(1, ' ').prep(webroot);
    urldecode(file);
    if (file.ends('/')) file = file.cat("index.html");
    unless(fexist(file)) {
        s << "HTTP/1.1 404 Not Found\r\n";
        file = file.cpy("/404.html").prep(webroot);
    } else s << "HTTP/1.1 200 OK\r\n";
    s << "Content-Length: " << fsize(file) << "\r\n";
    for (i = 0; mimes[i].ext != NULL; i++)
        if (file.rchshl('.') == mimes[i].ext) {
            s << "Content-Type: " << mimes[i].type << "\r\n";
            break;
        }
    if (mimes[i].ext == NULL)
        s << "Content-Type: application/octet-stream\r\n";
    stime = asctime(gmtime(&t));
    s <<
        "Server: " << server << "\r\n" <<
        "Date: " << stime.chomp('\n') << "\r\n" <<
        "X-Your-IP: " << s.ip() << "\r\n" <<
        "Connection: close\r\n\r\n";
    if (!fexist(file)) file.buf[0] = 0;
    return file;
}

bool get(Socket& s, String buf) {
    String fname;
    File f;
    char c;
    fname = head(s, buf);
    unless(fname.len()) return false;
    unless (f.open(fname, "rb")) return false;
    for (c = f.getc(); !f.eof; c = f.getc())
        s.putc(c);
    if (c != EOF) s.putc(c);
    f.close();
    return true;
}

void* session(void* param) {
    Socket s;
    String buf((1024 ^ 2) * 4);
    s.fd = (int)param;
    buf.fit = false;
    s.seteol("\r\n\r\n", 4);
    s.gets(buf, (1024 ^ 2) * 4);
    cout << s.ip() << " -> " << buf.tok(0, '\r').cat('\n');
    if (buf.begns("GET ")) get(s, buf);
    else if (buf.begns("HEAD ")) head(s, buf);
    s.close();
    m_users.lock();
    std::remove(users.begin(), users.end(), s.fd);
    m_users.unlock();
    return NULL;
}


int main(int argc, char** argv) {
    Thread t;
    Socket s, c;
    unless (argc == 3)
        die("Jakash3's webserver\nUsage: %s WEBDIR PORT\n", argv[0]);
    webroot = argv[1];
    t = session;
    s.listen(argv[2], 2);
    loop() {
        if (con::kbhit())
            if (con::getch() == 'q') break;
        s.accept(c);
        m_users.lock();
        users.push_back(c.fd);
        m_users.unlock();
        t.start((void*)c.fd);
    }
    std::vector<int>::iterator it;
    for (it = users.begin(); it < users.end(); it++) {
        c.fd = *it;
        c.close();
    }
    s.close();
}
mimes.cpp
Code:
struct mime { const char* ext; const char* type; };

struct mime mimes[] = {
    {"exe", "application/octet-stream"},
    {"pdf", "application/pdf"},
    {"zip", "application/zip"},
    {"gz", "application/x-gzip"},
    {"js", "application/javascript"},
    {"mp3", "audio/mpeg"},
    {"wma", "audio/x-ms-wma"},
    {"wav", "audio/vnd.wave"},
    {"gif", "image/gif"},
    {"jpg", "image/jpeg"},
    {"png", "image/png"},
    {"tiff", "image/tiff"},
    {"tif", "image/tiff"},
    {"ico", "image/vnd.microsoft.icon"},
    {"css", "text/css"},
    {"html", "text/html"},
    {"txt", "text/plain"},
    {"xml", "text/xml"},
    {"mpg", "video/mpeg"},
    {"mp4", "video/mp4"},
    {"wmv", "video/x-ms-wmv"},
    {"odt", "application/vnd.oasis.opendocument.text"},
    {"ods", "application/vnd.oasis.opendocument.spreadsheet"},
    {"odp", "application/vnd.oasis.opendocument.presentation"},
    {"odg", "application/vnd.oasis.opendocument.graphics"},
    {"xls", "application/vnd.ms-excel"},
    {"ppt", "application/vnd.ms-powerpoint"},
    {"doc", "application/msword"},
    {"docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
    {"ttf", "application/x-font-ttf"},
    {"rar", "application/x-rar-compressed"},
    {"tar", "application/x-tar"},
    {"c", "text/plain"},
    {"cpp", "text/plain"},
    {"asm", "text/plain"},
    {"bat", "text/plain"},
    {"vb", "text/plain"},
    {"cs", "text/plain"},
    {"pl", "text/plain"},
    {"py", "text/plain"},
    {"class", "text/plain"},
    {"vbs", "text/plain"},
    {NULL, NULL}
};
Thanks for this!
I was looking for exactly this!
thank you Smile!. very usefull for me