Webserver using AXCEL 2 Library

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 this 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

server.cpp

#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


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}
};

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: