Browse Source

HTTP::Server is now minimally functional.

release/0.19
JustinAJ 9 years ago
parent
commit
06d980666b
  1. 190
      Jupiter/HTTP_Server.cpp
  2. 11
      Jupiter/HTTP_Server.h
  3. BIN
      Release/Jupiter.lib

190
Jupiter/HTTP_Server.cpp

@ -66,7 +66,7 @@ Jupiter::ReadableString *Jupiter::HTTP::Server::Content::execute(const Jupiter::
Jupiter::HTTP::Server::Directory::Directory(const Jupiter::ReadableString &in_name) : name(in_name) Jupiter::HTTP::Server::Directory::Directory(const Jupiter::ReadableString &in_name) : name(in_name)
{ {
name_checksum = Jupiter::HTTP::Server::Directory::name.calcChecksumi(); name_checksum = Jupiter::HTTP::Server::Directory::name.calcChecksum();
} }
Jupiter::HTTP::Server::Directory::~Directory() Jupiter::HTTP::Server::Directory::~Directory()
@ -76,19 +76,24 @@ Jupiter::HTTP::Server::Directory::~Directory()
} }
// host/dir/content // host/dir/content
// .hook(host, "dir/content") // .hook("dir/subdir/", content)
void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_name, Content *in_content) void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_name, Content *in_content)
{ {
Jupiter::ReferenceString in_name_ref = in_name; Jupiter::ReferenceString in_name_ref = in_name;
in_name_ref.shiftRight(in_name_ref.span('/')); in_name_ref.shiftRight(in_name_ref.span('/'));
size_t index = in_name_ref.find('/'); if (in_name_ref.isEmpty()) // Hook content
if (index == Jupiter::INVALID_INDEX) // Hook content
Jupiter::HTTP::Server::Directory::content.add(in_content); Jupiter::HTTP::Server::Directory::content.add(in_content);
else else
{ {
Jupiter::ReferenceString dir_name(in_name_ref.ptr(), index); size_t index = in_name_ref.find('/');
Jupiter::ReferenceString dir_name;
if (index == Jupiter::INVALID_INDEX)
dir_name = in_name_ref;
else
dir_name = in_name_ref.substring(0U, index);
in_name_ref.shiftRight(dir_name.size()); in_name_ref.shiftRight(dir_name.size());
Jupiter::HTTP::Server::Directory *directory; Jupiter::HTTP::Server::Directory *directory;
unsigned int dir_name_checksum = dir_name.calcChecksum(); unsigned int dir_name_checksum = dir_name.calcChecksum();
@ -97,7 +102,10 @@ void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_na
{ {
directory = Jupiter::HTTP::Server::Directory::directories.get(--index); directory = Jupiter::HTTP::Server::Directory::directories.get(--index);
if (directory->name_checksum == dir_name_checksum && directory->name.equals(dir_name)) if (directory->name_checksum == dir_name_checksum && directory->name.equals(dir_name))
return directory->hook(dir_name, in_content); {
directory->hook(dir_name, in_content);
return;
}
} }
// create directories // create directories
@ -105,14 +113,22 @@ void Jupiter::HTTP::Server::Directory::hook(const Jupiter::ReadableString &in_na
Jupiter::HTTP::Server::Directory::directories.add(directory); Jupiter::HTTP::Server::Directory::directories.add(directory);
directory_add_loop: directory_add_loop:
index = in_name_ref.find('/'); in_name_ref.shiftRight(in_name_ref.span('/'));
if (index != Jupiter::INVALID_INDEX) if (in_name_ref.isNotEmpty())
{ {
// add directory // add directory
directory->directories.add(new Jupiter::HTTP::Server::Directory(in_name_ref.substring(0U, index))); index = in_name_ref.find('/');
if (index != Jupiter::INVALID_INDEX)
{
directory->directories.add(new Jupiter::HTTP::Server::Directory(in_name_ref.substring(0U, index)));
directory = directory->directories.get(directories.size() - 1);
in_name_ref.shiftRight(index + 1);
goto directory_add_loop;
}
directory->directories.add(new Jupiter::HTTP::Server::Directory(in_name_ref));
directory = directory->directories.get(directories.size() - 1); directory = directory->directories.get(directories.size() - 1);
goto directory_add_loop;
} }
// add content // add content
directory->content.add(in_content); directory->content.add(in_content);
} }
@ -125,7 +141,7 @@ bool Jupiter::HTTP::Server::Directory::remove(const Jupiter::ReadableString &in_
bool Jupiter::HTTP::Server::Directory::has(const Jupiter::ReadableString &in_name) bool Jupiter::HTTP::Server::Directory::has(const Jupiter::ReadableString &in_name)
{ {
return false; return this->find(in_name) != nullptr;
} }
Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Directory::find(const Jupiter::ReadableString &in_name) Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Directory::find(const Jupiter::ReadableString &in_name)
@ -149,10 +165,11 @@ Jupiter::HTTP::Server::Content *Jupiter::HTTP::Server::Directory::find(const Jup
} }
Jupiter::ReferenceString dir_name(in_name_ref.ptr(), index); Jupiter::ReferenceString dir_name(in_name_ref.ptr(), index);
in_name_ref.shiftRight(dir_name.size()); in_name_ref.shiftRight(dir_name.size() + 1);
Jupiter::HTTP::Server::Directory *directory; Jupiter::HTTP::Server::Directory *directory;
unsigned int dir_name_checksum = dir_name.calcChecksum(); unsigned int dir_name_checksum = dir_name.calcChecksum();
index = Jupiter::HTTP::Server::Directory::directories.size(); index = Jupiter::HTTP::Server::Directory::directories.size();
while (index != 0) while (index != 0)
{ {
directory = Jupiter::HTTP::Server::Directory::directories.get(--index); directory = Jupiter::HTTP::Server::Directory::directories.get(--index);
@ -261,7 +278,6 @@ void Jupiter::HTTP::Server::Data::hook(const Jupiter::ReadableString &hostname,
Jupiter::ReferenceString path = in_path; Jupiter::ReferenceString path = in_path;
Jupiter::ReferenceString dir_name; Jupiter::ReferenceString dir_name;
Jupiter::HTTP::Server::Host *host = Jupiter::HTTP::Server::Data::find_host(hostname); Jupiter::HTTP::Server::Host *host = Jupiter::HTTP::Server::Data::find_host(hostname);
Jupiter::HTTP::Server::Directory *dir;
if (host == nullptr) if (host == nullptr)
{ {
@ -270,43 +286,11 @@ void Jupiter::HTTP::Server::Data::hook(const Jupiter::ReadableString &hostname,
// OPTIMIZE: create directory tree and return. // OPTIMIZE: create directory tree and return.
} }
dir = host;
path.shiftRight(path.span('/')); path.shiftRight(path.span('/'));
if (path.isEmpty()) if (path.isEmpty())
host->content.add(in_content); host->content.add(in_content);
else
if (path.isNotEmpty()) host->hook(path, in_content);
{
dir_name = path.getToken(0, '/');
size_t index = dir->directories.size();
Jupiter::HTTP::Server::Directory *t_dir;
dir_search_loop:
if (index != 0)
{
t_dir = dir->directories.get(--index);
if (t_dir->name.equalsi(dir_name) == false)
goto dir_search_loop;
dir = t_dir;
}
else // directory doesn't exist
{
t_dir = new Jupiter::HTTP::Server::Directory(dir_name);
dir->directories.add(t_dir);
dir = t_dir;
// OPTIMIZE: create directory tree and return.
}
// end dir_search_loop
path.shiftRight(dir_name.size());
path.shiftRight(path.span('/'));
}
dir->hook(path, in_content);
//dir->content.add(in_content);
// path is empty -- insert content into dir
} }
bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname) bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname)
@ -329,30 +313,10 @@ bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname
// name: path/to/resource OR path/ // name: path/to/resource OR path/
bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name) bool Jupiter::HTTP::Server::Data::remove(const Jupiter::ReadableString &hostname, const Jupiter::ReadableString &name)
{ {
/*unsigned int name_checksum = hostname.calcChecksumi(); Jupiter::HTTP::Server::Host *host = Jupiter::HTTP::Server::Data::find_host(hostname);
size_t index = Jupiter::HTTP::Server::Data::hosts.size(); if (host == nullptr)
Jupiter::HTTP::Server::Host *host; return false;
while (index != 0) return host->remove(name);
{
host = Jupiter::HTTP::Server::Data::hosts.get(--index);
if (name_checksum == host->name_checksum && host->name.equalsi(hostname))
{
name_checksum = name.calcChecksum(); // switch to equalsi to make case-insensitive
index = host->functions.size();
Jupiter::HTTP::Server::Content *content;
while (index != 0)
{
content = host->functions.get(--index);
if (name_checksum == content->name_checksum && content->name.equals(name)) // switch to equalsi to make case-insensitive
{
delete host->functions.remove(index);
return true;
}
}
return false;
}
}*/
return false;
} }
bool Jupiter::HTTP::Server::Data::has(const Jupiter::ReadableString &hostname) bool Jupiter::HTTP::Server::Data::has(const Jupiter::ReadableString &hostname)
@ -482,17 +446,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
case HTTPCommand::HEAD: case HTTPCommand::HEAD:
if (content != nullptr) if (content != nullptr)
{ {
/* // 200 (success)
HTTP/1.1 200 OK
Date: Mon, 05 Oct 2015 01:50:08 GMT
Server: Apache/2.4.7 (Ubuntu)
Last-Modified: Tue, 18 Aug 2015 03:53:28 GMT
ETag: "0-51d8ddc61160f"
Accept-Ranges: bytes
Content-Length: 0
Connection: close
Content-Type: text/html
*/
Jupiter::ReadableString *content_result = content->execute(content_parameters); Jupiter::ReadableString *content_result = content->execute(content_parameters);
switch (session.version) switch (session.version)
@ -511,7 +465,7 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
result += time_header; result += time_header;
delete[] time_header; delete[] time_header;
result += "Server: " JUPITER_VERSION ENDL; result += "Server: "_jrs JUPITER_VERSION ENDL;
result += Jupiter::StringS::Format("Content-Length: %u" ENDL, content_result->size()); result += Jupiter::StringS::Format("Content-Length: %u" ENDL, content_result->size());
@ -554,16 +508,41 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
} }
else else
{ {
// 404 // 404 (not found)
/*
HTTP/1.1 404 Not Found switch (session.version)
Date: Mon, 05 Oct 2015 01:46:01 GMT {
Server: Apache/2.4.7 (Ubuntu) default:
Content-Length: 281 case HTTPVersion::HTTP_1_0:
Connection: close result = "HTTP/1.0 404 Not Found"_jrs ENDL;
Content-Type: text/html; charset=iso-8859-1 break;
*/ case HTTPVersion::HTTP_1_1:
result = "HTTP/1.1 404 Not Found"_jrs ENDL;
break;
}
char *time_header = html_time();
result += "Date: "_jrs ENDL;
result += time_header;
delete[] time_header;
result += "Server: "_jrs JUPITER_VERSION ENDL;
result += "Content-Length: 0"_jrs ENDL;
switch (session.version)
{
default:
case HTTPVersion::HTTP_1_0:
result += "Connection: close"_jrs ENDL;
break;
case HTTPVersion::HTTP_1_1:
result += "Connection: keep-alive"_jrs ENDL;
break;
}
result += ENDL ENDL;
session.sock.send(result);
} }
break; break;
default: default:
@ -607,13 +586,19 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
span = content_parameters.find('?'); // repurposing 'span' span = content_parameters.find('?'); // repurposing 'span'
if (span == Jupiter::INVALID_INDEX) if (span == Jupiter::INVALID_INDEX)
{ {
content = Jupiter::HTTP::Server::Data::find(content_parameters); if (session.host == nullptr)
content = Jupiter::HTTP::Server::Data::find(content_parameters);
else
content = session.host->find(content_parameters);
content_parameters.erase(); content_parameters.erase();
} }
else else
{ {
content = Jupiter::HTTP::Server::Data::find(content_parameters.substring(0U, span)); if (session.host == nullptr)
content_parameters.shiftRight(span + 1); content = Jupiter::HTTP::Server::Data::find(content_parameters.substring(0U, span));
else
content = session.host->find(content_parameters.substring(0U, span));
content_parameters.shiftRight(span);
// decode content_parameters here // decode content_parameters here
} }
@ -634,13 +619,20 @@ int Jupiter::HTTP::Server::Data::process_request(HTTPSession &session)
span = content_parameters.find('?'); // repurposing 'span' span = content_parameters.find('?'); // repurposing 'span'
if (span == Jupiter::INVALID_INDEX) if (span == Jupiter::INVALID_INDEX)
{ {
content = Jupiter::HTTP::Server::Data::find(content_parameters); if (session.host == nullptr)
content = Jupiter::HTTP::Server::Data::find(content_parameters);
else
content = session.host->find(content_parameters);
content_parameters.erase(); content_parameters.erase();
} }
else else
{ {
content = Jupiter::HTTP::Server::Data::find(content_parameters.substring(0U, span)); if (session.host == nullptr)
content_parameters.shiftRight(span + 1); content = Jupiter::HTTP::Server::Data::find(content_parameters.substring(0U, span));
else
content = session.host->find(content_parameters.substring(0U, span));
content_parameters.shiftRight(span);
// decode content_parameters here
} }
Jupiter::ReferenceString protocol_str = line.getWord(2, " "); Jupiter::ReferenceString protocol_str = line.getWord(2, " ");
@ -798,7 +790,7 @@ int Jupiter::HTTP::Server::think()
{ {
socket->setBlocking(false); socket->setBlocking(false);
session = new HTTPSession(std::move(*socket)); session = new HTTPSession(std::move(*socket));
if (session->sock.recv()) // data received if (session->sock.recv() > 0) // data received
{ {
const Jupiter::ReadableString &sock_buffer = session->sock.getBuffer(); const Jupiter::ReadableString &sock_buffer = session->sock.getBuffer();
if (sock_buffer.size() < Jupiter::HTTP::Server::data_->max_request_size) // accept if (sock_buffer.size() < Jupiter::HTTP::Server::data_->max_request_size) // accept

11
Jupiter/HTTP_Server.h

@ -29,6 +29,12 @@
#include "Readable_String.h" #include "Readable_String.h"
#include "ArrayList.h" #include "ArrayList.h"
/** DLL Linkage Nagging */
#if defined _MSC_VER
#pragma warning(push)
#pragma warning(disable: 4251)
#endif
namespace Jupiter namespace Jupiter
{ {
namespace HTTP namespace HTTP
@ -111,4 +117,9 @@ namespace Jupiter
} // Jupiter::HTTP namespace } // Jupiter::HTTP namespace
} // Jupiter namespace } // Jupiter namespace
/** Re-enable warnings */
#if defined _MSC_VER
#pragma warning(pop)
#endif
#endif // _HTTP_SERVER_H_HEADER #endif // _HTTP_SERVER_H_HEADER

BIN
Release/Jupiter.lib

Binary file not shown.
Loading…
Cancel
Save