CLOUD: Refactor LocalWebserver
Its handlers are now more compact. This commit moves Handler classes in handlers\ directory. ResourceHandler ignores "hidden" files in the archive, and these are used as markup templates in IndexPageHandler and FilesPageHandler.
This commit is contained in:
parent
627bda9d82
commit
48e3fff6bc
18 changed files with 665 additions and 358 deletions
|
@ -58,7 +58,11 @@ ifdef USE_SDL_NET
|
|||
MODULE_OBJS += \
|
||||
networking/sdl_net/client.o \
|
||||
networking/sdl_net/getclienthandler.o \
|
||||
networking/sdl_net/indexpagehandler.o \
|
||||
networking/sdl_net/handlers/basehandler.o \
|
||||
networking/sdl_net/handlers/filesbasehandler.o \
|
||||
networking/sdl_net/handlers/filespagehandler.o \
|
||||
networking/sdl_net/handlers/indexpagehandler.o \
|
||||
networking/sdl_net/handlers/resourcehandler.o \
|
||||
networking/sdl_net/localwebserver.o
|
||||
endif
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ def buildArchive(archiveName):
|
|||
filenames = os.listdir('.')
|
||||
filenames.sort()
|
||||
for filename in filenames:
|
||||
if os.path.isfile(filename) and not filename[0] == '.' and filename.endswith(ARCHIVE_FILE_EXTENSIONS):
|
||||
if os.path.isfile(filename) and filename.endswith(ARCHIVE_FILE_EXTENSIONS):
|
||||
zf.write(filename, './' + filename)
|
||||
print (" Adding file: " + filename)
|
||||
|
||||
|
|
100
backends/networking/sdl_net/handlers/basehandler.cpp
Normal file
100
backends/networking/sdl_net/handlers/basehandler.cpp
Normal file
|
@ -0,0 +1,100 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/basehandler.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/unzip.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
#define ARCHIVE_NAME "wwwroot.zip"
|
||||
|
||||
BaseHandler::BaseHandler() {}
|
||||
|
||||
BaseHandler::~BaseHandler() {}
|
||||
|
||||
/// utils
|
||||
|
||||
Common::Archive *BaseHandler::getZipArchive() const {
|
||||
// first search in themepath
|
||||
if (ConfMan.hasKey("themepath")) {
|
||||
const Common::FSNode &node = Common::FSNode(ConfMan.get("themepath"));
|
||||
if (!node.exists() || !node.isReadable() || !node.isDirectory())
|
||||
return nullptr;
|
||||
|
||||
Common::FSNode fileNode = node.getChild(ARCHIVE_NAME);
|
||||
if (fileNode.exists() && fileNode.isReadable() && !fileNode.isDirectory()) {
|
||||
Common::SeekableReadStream *const stream = fileNode.createReadStream();
|
||||
Common::Archive *zipArchive = Common::makeZipArchive(stream);
|
||||
if (zipArchive) return zipArchive;
|
||||
}
|
||||
}
|
||||
|
||||
// then use SearchMan to find it
|
||||
Common::ArchiveMemberList fileList;
|
||||
SearchMan.listMatchingMembers(fileList, ARCHIVE_NAME);
|
||||
for (Common::ArchiveMemberList::iterator it = fileList.begin(); it != fileList.end(); ++it) {
|
||||
Common::ArchiveMember const &m = **it;
|
||||
Common::SeekableReadStream *const stream = m.createReadStream();
|
||||
Common::Archive *zipArchive = Common::makeZipArchive(stream);
|
||||
if (zipArchive) return zipArchive;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Common::ArchiveMemberList BaseHandler::listArchive() const {
|
||||
Common::ArchiveMemberList resultList;
|
||||
Common::Archive *zipArchive = getZipArchive();
|
||||
if (zipArchive) {
|
||||
zipArchive->listMembers(resultList);
|
||||
delete zipArchive;
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *BaseHandler::getArchiveFile(Common::String name) const {
|
||||
Common::SeekableReadStream *result = nullptr;
|
||||
Common::Archive *zipArchive = getZipArchive();
|
||||
if (zipArchive) {
|
||||
const Common::ArchiveMemberPtr ptr = zipArchive->getMember(name);
|
||||
if (ptr.get() == nullptr) return nullptr;
|
||||
result = ptr->createReadStream();
|
||||
delete zipArchive;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Common::String BaseHandler::readEverythingFromStream(Common::SeekableReadStream *const stream) {
|
||||
Common::String result;
|
||||
char buf[1024];
|
||||
uint32 readBytes;
|
||||
while (!stream->eos()) {
|
||||
readBytes = stream->read(buf, 1024);
|
||||
result += Common::String(buf, readBytes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End of namespace Networking
|
50
backends/networking/sdl_net/handlers/basehandler.h
Normal file
50
backends/networking/sdl_net/handlers/basehandler.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDS_NETWORKING_SDL_NET_BASEHANDLER_H
|
||||
#define BACKENDS_NETWORKING_SDL_NET_BASEHANDLER_H
|
||||
|
||||
#include "backends/networking/sdl_net/client.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/callback.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
typedef Common::BaseCallback<Client &> *ClientHandlerCallback;
|
||||
|
||||
class BaseHandler {
|
||||
protected:
|
||||
Common::Archive *getZipArchive() const;
|
||||
Common::ArchiveMemberList listArchive() const;
|
||||
Common::SeekableReadStream *getArchiveFile(Common::String name) const;
|
||||
static Common::String readEverythingFromStream(Common::SeekableReadStream *const stream);
|
||||
|
||||
public:
|
||||
BaseHandler();
|
||||
virtual ~BaseHandler();
|
||||
|
||||
virtual ClientHandlerCallback getHandler() = 0;
|
||||
};
|
||||
|
||||
} // End of namespace Networking
|
||||
|
||||
#endif
|
79
backends/networking/sdl_net/handlers/filesbasehandler.cpp
Normal file
79
backends/networking/sdl_net/handlers/filesbasehandler.cpp
Normal file
|
@ -0,0 +1,79 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
FilesBaseHandler::FilesBaseHandler() {}
|
||||
|
||||
FilesBaseHandler::~FilesBaseHandler() {}
|
||||
|
||||
Common::String FilesBaseHandler::parentPath(Common::String path) {
|
||||
if (path.size() && (path.lastChar() == '/' || path.lastChar() == '\\')) path.deleteLastChar();
|
||||
if (!path.empty()) {
|
||||
for (int i = path.size() - 1; i >= 0; --i)
|
||||
if (i == 0 || path[i] == '/' || path[i] == '\\') {
|
||||
path.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (path.size() && path.lastChar() != '/' && path.lastChar() != '\\') path += '/';
|
||||
return path;
|
||||
}
|
||||
|
||||
bool FilesBaseHandler::transformPath(Common::String &path, Common::String &prefixToRemove, Common::String &prefixToAdd) {
|
||||
// <path> is not empty, but could lack the trailing slash
|
||||
if (path.lastChar() != '/' && path.lastChar() != '\\') path += '/';
|
||||
|
||||
if (path.hasPrefix("/root")) {
|
||||
prefixToAdd = "/root/";
|
||||
prefixToRemove = "";
|
||||
path.erase(0, 5);
|
||||
if (path == "") path = "/"; // absolute root is '/'
|
||||
if (path != "/") path.deleteChar(0); // if that was "/root/ab/c", it becomes "/ab/c", but we need "ab/c"
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path.hasPrefix("/saves")) {
|
||||
prefixToAdd = "/saves/";
|
||||
|
||||
// determine savepath (prefix to remove)
|
||||
DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager());
|
||||
prefixToRemove = (manager ? manager->concatWithSavesPath("") : ConfMan.get("savepath"));
|
||||
if (prefixToRemove.size() && prefixToRemove.lastChar() != '/' && prefixToRemove.lastChar() != '\\')
|
||||
prefixToRemove += '/';
|
||||
|
||||
path.erase(0, 6);
|
||||
if (path.size() && (path[0] == '/' || path[0] == '\\'))
|
||||
path.deleteChar(0);
|
||||
path = prefixToRemove + path;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
} // End of namespace Networking
|
50
backends/networking/sdl_net/handlers/filesbasehandler.h
Normal file
50
backends/networking/sdl_net/handlers/filesbasehandler.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDS_NETWORKING_SDL_NET_FILESBASEHANDLER_H
|
||||
#define BACKENDS_NETWORKING_SDL_NET_FILESBASEHANDLER_H
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/basehandler.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
class FilesBaseHandler: public BaseHandler {
|
||||
protected:
|
||||
Common::String parentPath(Common::String path);
|
||||
|
||||
/**
|
||||
* Transforms virtual <path> into actual file system path.
|
||||
*
|
||||
* Fills prefixes with actual file system prefix ("to remove")
|
||||
* and virtual path prefix ("to add").
|
||||
*
|
||||
* Returns true on success.
|
||||
*/
|
||||
bool transformPath(Common::String &path, Common::String &prefixToRemove, Common::String &prefixToAdd);
|
||||
public:
|
||||
FilesBaseHandler();
|
||||
virtual ~FilesBaseHandler();
|
||||
};
|
||||
|
||||
} // End of namespace Networking
|
||||
|
||||
#endif
|
146
backends/networking/sdl_net/handlers/filespagehandler.cpp
Normal file
146
backends/networking/sdl_net/handlers/filespagehandler.cpp
Normal file
|
@ -0,0 +1,146 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/filespagehandler.h"
|
||||
#include "backends/networking/sdl_net/localwebserver.h"
|
||||
#include "common/file.h"
|
||||
#include "common/translation.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
#define INDEX_PAGE_NAME ".index.html"
|
||||
#define FILES_PAGE_NAME ".files.html"
|
||||
|
||||
FilesPageHandler::FilesPageHandler() {}
|
||||
|
||||
FilesPageHandler::~FilesPageHandler() {}
|
||||
|
||||
void FilesPageHandler::handle(Client &client) {
|
||||
Common::String response = "<html><head><title>ScummVM</title></head><body><table>{content}</table></body></html>"; //TODO: add controls
|
||||
Common::String itemTemplate = "<tr><td><a href=\"{link}\">{name}</a></td><td>{size}</td></tr>\n"; //TODO: load this template too?
|
||||
|
||||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = getArchiveFile(FILES_PAGE_NAME);
|
||||
if (stream) response = readEverythingFromStream(stream);
|
||||
|
||||
Common::String path = client.queryParameter("path");
|
||||
Common::String content = "";
|
||||
|
||||
// show an error message if failed to list directory
|
||||
if (!listDirectory(path, content, itemTemplate)) {
|
||||
handleErrorMessage(
|
||||
client,
|
||||
Common::String::format(
|
||||
"%s<br/><a href=\"files?path=/\">%s</a>",
|
||||
_("ScummVM couldn't list the directory you specified."),
|
||||
_("Back to the files manager")
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
//these occur twice:
|
||||
replace(response, "{create_directory_button}", _("Create directory"));
|
||||
replace(response, "{create_directory_button}", _("Create directory"));
|
||||
replace(response, "{upload_files_button}", _("Upload files")); //tab
|
||||
replace(response, "{upload_file_button}", _("Upload files")); //button in the tab
|
||||
replace(response, "{create_directory_desc}", _("Type new directory name:"));
|
||||
replace(response, "{upload_file_desc}", _("Select a file to upload:"));
|
||||
replace(response, "{content}", content);
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
||||
void FilesPageHandler::handleErrorMessage(Client &client, Common::String message) {
|
||||
Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>";
|
||||
|
||||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME);
|
||||
if (stream) response = readEverythingFromStream(stream);
|
||||
|
||||
replace(response, "{message}", message);
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
||||
bool FilesPageHandler::listDirectory(Common::String path, Common::String &content, const Common::String &itemTemplate) {
|
||||
if (path == "" || path == "/") {
|
||||
addItem(content, itemTemplate, true, "/root/", _("File system root"));
|
||||
addItem(content, itemTemplate, true, "/saves/", _("Saved games"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::String prefixToRemove = "", prefixToAdd = "";
|
||||
if (!transformPath(path, prefixToRemove, prefixToAdd)) return false;
|
||||
|
||||
Common::FSNode node = Common::FSNode(path);
|
||||
if (path == "/") node = node.getParent(); // absolute root
|
||||
if (!node.isDirectory()) return false;
|
||||
|
||||
// list directory
|
||||
Common::FSList _nodeContent;
|
||||
if (!node.getChildren(_nodeContent, Common::FSNode::kListAll, false)) // do not show hidden files
|
||||
_nodeContent.clear();
|
||||
else
|
||||
Common::sort(_nodeContent.begin(), _nodeContent.end());
|
||||
|
||||
// add parent directory link
|
||||
{
|
||||
Common::String filePath = path;
|
||||
if (filePath.hasPrefix(prefixToRemove))
|
||||
filePath.erase(0, prefixToRemove.size());
|
||||
if (filePath == "" || filePath == "/" || filePath == "\\")
|
||||
filePath = "/";
|
||||
else
|
||||
filePath = parentPath(prefixToAdd + filePath);
|
||||
addItem(content, itemTemplate, true, filePath, _("Parent directory"));
|
||||
}
|
||||
|
||||
// fill the content
|
||||
for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
|
||||
Common::String name = i->getDisplayName();
|
||||
if (i->isDirectory()) name += "/";
|
||||
|
||||
Common::String filePath = i->getPath();
|
||||
if (filePath.hasPrefix(prefixToRemove))
|
||||
filePath.erase(0, prefixToRemove.size());
|
||||
filePath = prefixToAdd + filePath;
|
||||
|
||||
addItem(content, itemTemplate, i->isDirectory(), filePath, name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void FilesPageHandler::addItem(Common::String &content, const Common::String &itemTemplate, bool isDirectory, Common::String path, Common::String name, Common::String size) {
|
||||
Common::String item = itemTemplate;
|
||||
replace(item, "{link}", (isDirectory ? "files?path=" : "download?path=") + path);
|
||||
replace(item, "{name}", name);
|
||||
replace(item, "{size}", size);
|
||||
content += item;
|
||||
}
|
||||
|
||||
/// public
|
||||
|
||||
ClientHandlerCallback FilesPageHandler::getHandler() {
|
||||
return new Common::Callback<FilesPageHandler, Client &>(this, &FilesPageHandler::handle);
|
||||
}
|
||||
|
||||
} // End of namespace Networking
|
|
@ -20,30 +20,17 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDS_NETWORKING_SDL_NET_INDEXPAGEHANDLER_H
|
||||
#define BACKENDS_NETWORKING_SDL_NET_INDEXPAGEHANDLER_H
|
||||
#ifndef BACKENDS_NETWORKING_SDL_NET_FILESPAGEHANDLER_H
|
||||
#define BACKENDS_NETWORKING_SDL_NET_FILESPAGEHANDLER_H
|
||||
|
||||
#include "backends/networking/sdl_net/client.h"
|
||||
#include "common/archive.h"
|
||||
#include "gui/object.h"
|
||||
#include "backends/networking/sdl_net/handlers/filesbasehandler.h"
|
||||
|
||||
namespace Networking {
|
||||
class LocalWebserver;
|
||||
|
||||
class IndexPageHandler: public GUI::CommandSender {
|
||||
Common::String _code;
|
||||
|
||||
class FilesPageHandler: public FilesBaseHandler {
|
||||
void handle(Client &client);
|
||||
void handleFiles(Client &client);
|
||||
void handleResource(Client &client);
|
||||
void handleErrorMessage(Client &client, Common::String message);
|
||||
|
||||
// "files/"-related
|
||||
Common::String parentPath(Common::String path);
|
||||
|
||||
/** Helper method for adding items into the files list. */
|
||||
void addItem(Common::String &content, const Common::String &itemTemplate, bool isDirectory, Common::String path, Common::String name, Common::String size = "");
|
||||
|
||||
/**
|
||||
* Lists the directory <path>.
|
||||
*
|
||||
|
@ -51,27 +38,14 @@ class IndexPageHandler: public GUI::CommandSender {
|
|||
*/
|
||||
bool listDirectory(Common::String path, Common::String &content, const Common::String &itemTemplate);
|
||||
|
||||
/**
|
||||
* Transforms virtual <path> into actual file system path.
|
||||
*
|
||||
* Fills prefixes with actual file system prefix ("to remove")
|
||||
* and virtual path prefix ("to add").
|
||||
*
|
||||
* Returns true on success.
|
||||
*/
|
||||
bool transformPath(Common::String &path, Common::String &prefixToRemove, Common::String &prefixToAdd);
|
||||
|
||||
Common::Archive *getZipArchive();
|
||||
Common::ArchiveMemberList listArchive();
|
||||
Common::SeekableReadStream *getArchiveFile(Common::String name);
|
||||
Common::String readEverythingFromStream(Common::SeekableReadStream *const stream);
|
||||
/** Helper method for adding items into the files list. */
|
||||
void addItem(Common::String &content, const Common::String &itemTemplate, bool isDirectory, Common::String path, Common::String name, Common::String size = "");
|
||||
|
||||
public:
|
||||
IndexPageHandler();
|
||||
virtual ~IndexPageHandler();
|
||||
FilesPageHandler();
|
||||
virtual ~FilesPageHandler();
|
||||
|
||||
void addPathHandler(LocalWebserver &server);
|
||||
Common::String code();
|
||||
virtual ClientHandlerCallback getHandler();
|
||||
};
|
||||
|
||||
} // End of namespace Networking
|
70
backends/networking/sdl_net/handlers/indexpagehandler.cpp
Normal file
70
backends/networking/sdl_net/handlers/indexpagehandler.cpp
Normal file
|
@ -0,0 +1,70 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/indexpagehandler.h"
|
||||
#include "backends/networking/sdl_net/localwebserver.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/translation.h"
|
||||
#include "gui/storagewizarddialog.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
#define INDEX_PAGE_NAME ".index.html"
|
||||
|
||||
IndexPageHandler::IndexPageHandler(): CommandSender(nullptr) {}
|
||||
|
||||
IndexPageHandler::~IndexPageHandler() {}
|
||||
|
||||
void IndexPageHandler::handle(Client &client) {
|
||||
Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>";
|
||||
|
||||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME);
|
||||
if (stream) response = readEverythingFromStream(stream);
|
||||
|
||||
Common::String code = client.queryParameter("code");
|
||||
|
||||
if (code == "") {
|
||||
replace(response, "{message}", _("This is a local webserver index page."));
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
return;
|
||||
}
|
||||
|
||||
_code = code;
|
||||
sendCommand(GUI::kStorageCodePassedCmd, 0);
|
||||
replace(response, "{message}", _("ScummVM got the code and already connects to your cloud storage!"));
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
||||
/// public
|
||||
|
||||
Common::String IndexPageHandler::code() { return _code; }
|
||||
|
||||
ClientHandlerCallback IndexPageHandler::getHandler() {
|
||||
return new Common::Callback<IndexPageHandler, Client &>(this, &IndexPageHandler::handle);
|
||||
}
|
||||
|
||||
} // End of namespace Networking
|
46
backends/networking/sdl_net/handlers/indexpagehandler.h
Normal file
46
backends/networking/sdl_net/handlers/indexpagehandler.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDS_NETWORKING_SDL_NET_INDEXPAGEHANDLER_H
|
||||
#define BACKENDS_NETWORKING_SDL_NET_INDEXPAGEHANDLER_H
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/basehandler.h"
|
||||
#include "gui/object.h"
|
||||
|
||||
namespace Networking {
|
||||
class LocalWebserver;
|
||||
|
||||
class IndexPageHandler: public BaseHandler, public GUI::CommandSender {
|
||||
Common::String _code;
|
||||
|
||||
void handle(Client &client);
|
||||
public:
|
||||
IndexPageHandler();
|
||||
virtual ~IndexPageHandler();
|
||||
|
||||
Common::String code();
|
||||
virtual ClientHandlerCallback getHandler();
|
||||
};
|
||||
|
||||
} // End of namespace Networking
|
||||
|
||||
#endif
|
52
backends/networking/sdl_net/handlers/resourcehandler.cpp
Normal file
52
backends/networking/sdl_net/handlers/resourcehandler.cpp
Normal file
|
@ -0,0 +1,52 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/resourcehandler.h"
|
||||
#include "backends/networking/sdl_net/localwebserver.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
ResourceHandler::ResourceHandler() {}
|
||||
|
||||
ResourceHandler::~ResourceHandler() {}
|
||||
|
||||
void ResourceHandler::handle(Client &client) {
|
||||
Common::String filename = client.path();
|
||||
filename.deleteChar(0);
|
||||
|
||||
// if archive hidden file is requested, ignore
|
||||
if (filename.size() && filename[0] == '.') return;
|
||||
|
||||
// if file not found, don't set handler either
|
||||
Common::SeekableReadStream *file = getArchiveFile(filename);
|
||||
if (file == nullptr) return;
|
||||
|
||||
LocalWebserver::setClientGetHandler(client, file, 200, LocalWebserver::determineMimeType(filename));
|
||||
}
|
||||
|
||||
/// public
|
||||
|
||||
ClientHandlerCallback ResourceHandler::getHandler() {
|
||||
return new Common::Callback<ResourceHandler, Client &>(this, &ResourceHandler::handle);
|
||||
}
|
||||
|
||||
} // End of namespace Networking
|
41
backends/networking/sdl_net/handlers/resourcehandler.h
Normal file
41
backends/networking/sdl_net/handlers/resourcehandler.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BACKENDS_NETWORKING_SDL_NET_RESOURCEHANDLER_H
|
||||
#define BACKENDS_NETWORKING_SDL_NET_RESOURCEHANDLER_H
|
||||
|
||||
#include "backends/networking/sdl_net/handlers/basehandler.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
class ResourceHandler: public BaseHandler {
|
||||
void handle(Client &client);
|
||||
public:
|
||||
ResourceHandler();
|
||||
virtual ~ResourceHandler();
|
||||
|
||||
virtual ClientHandlerCallback getHandler();
|
||||
};
|
||||
|
||||
} // End of namespace Networking
|
||||
|
||||
#endif
|
|
@ -1,312 +0,0 @@
|
|||
/* ScummVM - Graphic Adventure Engine
|
||||
*
|
||||
* ScummVM is the legal property of its developers, whose names
|
||||
* are too numerous to list here. Please refer to the COPYRIGHT
|
||||
* file distributed with this source distribution.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "backends/networking/sdl_net/indexpagehandler.h"
|
||||
#include "backends/networking/sdl_net/localwebserver.h"
|
||||
#include "backends/saves/default/default-saves.h"
|
||||
#include "common/archive.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/file.h"
|
||||
#include "common/savefile.h"
|
||||
#include "common/translation.h"
|
||||
#include "common/unzip.h"
|
||||
#include "gui/storagewizarddialog.h"
|
||||
|
||||
namespace Networking {
|
||||
|
||||
#define ARCHIVE_NAME "wwwroot.zip"
|
||||
#define INDEX_PAGE_NAME "index.html"
|
||||
#define FILES_PAGE_NAME "files.html"
|
||||
|
||||
IndexPageHandler::IndexPageHandler(): CommandSender(nullptr) {}
|
||||
|
||||
IndexPageHandler::~IndexPageHandler() {
|
||||
LocalServer.removePathHandler("/");
|
||||
LocalServer.removePathHandler("/files/");
|
||||
|
||||
Common::ArchiveMemberList fileList = listArchive();
|
||||
for (Common::ArchiveMemberList::iterator it = fileList.begin(); it != fileList.end(); ++it) {
|
||||
Common::ArchiveMember const &m = **it;
|
||||
if (m.getName() == INDEX_PAGE_NAME) continue;
|
||||
LocalServer.removePathHandler("/" + m.getName());
|
||||
}
|
||||
}
|
||||
|
||||
void IndexPageHandler::handle(Client &client) {
|
||||
Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>";
|
||||
|
||||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME);
|
||||
if (stream) response = readEverythingFromStream(stream);
|
||||
|
||||
Common::String code = client.queryParameter("code");
|
||||
|
||||
if (code == "") {
|
||||
replace(response, "{message}", _("This is a local webserver index page."));
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
return;
|
||||
}
|
||||
|
||||
_code = code;
|
||||
sendCommand(GUI::kStorageCodePassedCmd, 0);
|
||||
replace(response, "{message}", _("ScummVM got the code and already connects to your cloud storage!"));
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
||||
void IndexPageHandler::handleFiles(Client &client) {
|
||||
Common::String response = "<html><head><title>ScummVM</title></head><body><table>{content}</table></body></html>"; //TODO: add controls
|
||||
Common::String itemTemplate = "<tr><td><a href=\"{link}\">{name}</a></td><td>{size}</td></tr>\n"; //TODO: load this template too?
|
||||
|
||||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = getArchiveFile(FILES_PAGE_NAME);
|
||||
if (stream) response = readEverythingFromStream(stream);
|
||||
|
||||
Common::String path = client.queryParameter("path");
|
||||
Common::String content = "";
|
||||
|
||||
// show an error message if failed to list directory
|
||||
if (!listDirectory(path, content, itemTemplate)) {
|
||||
handleErrorMessage(
|
||||
client,
|
||||
Common::String::format(
|
||||
"%s<br/><a href=\"files?path=/\">%s</a>",
|
||||
_("ScummVM couldn't list the directory you specified."),
|
||||
_("Back to the files manager")
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
//these occur twice:
|
||||
replace(response, "{create_directory_button}", _("Create directory"));
|
||||
replace(response, "{create_directory_button}", _("Create directory"));
|
||||
replace(response, "{upload_files_button}", _("Upload files")); //tab
|
||||
replace(response, "{upload_file_button}", _("Upload files")); //button in the tab
|
||||
replace(response, "{create_directory_desc}", _("Type new directory name:"));
|
||||
replace(response, "{upload_file_desc}", _("Select a file to upload:"));
|
||||
replace(response, "{content}", content);
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
||||
void IndexPageHandler::handleResource(Client &client) {
|
||||
Common::String filename = client.path();
|
||||
filename.deleteChar(0);
|
||||
LocalWebserver::setClientGetHandler(client, getArchiveFile(filename), 200, LocalWebserver::determineMimeType(filename));
|
||||
}
|
||||
|
||||
void IndexPageHandler::handleErrorMessage(Client &client, Common::String message) {
|
||||
Common::String response = "<html><head><title>ScummVM</title></head><body>{message}</body></html>";
|
||||
|
||||
// load stylish response page from the archive
|
||||
Common::SeekableReadStream *const stream = getArchiveFile(INDEX_PAGE_NAME);
|
||||
if (stream) response = readEverythingFromStream(stream);
|
||||
|
||||
replace(response, "{message}", message);
|
||||
LocalWebserver::setClientGetHandler(client, response);
|
||||
}
|
||||
|
||||
/// "files/"-related
|
||||
|
||||
Common::String IndexPageHandler::parentPath(Common::String path) {
|
||||
if (path.size() && (path.lastChar() == '/' || path.lastChar() == '\\')) path.deleteLastChar();
|
||||
if (!path.empty()) {
|
||||
for (int i = path.size() - 1; i >= 0; --i)
|
||||
if (i == 0 || path[i] == '/' || path[i] == '\\') {
|
||||
path.erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (path.size() && path.lastChar() != '/' && path.lastChar() != '\\') path += '/';
|
||||
return path;
|
||||
}
|
||||
|
||||
void IndexPageHandler::addItem(Common::String &content, const Common::String &itemTemplate, bool isDirectory, Common::String path, Common::String name, Common::String size) {
|
||||
Common::String item = itemTemplate;
|
||||
replace(item, "{link}", (isDirectory ? "files?path=" : "download?path=") + path);
|
||||
replace(item, "{name}", name);
|
||||
replace(item, "{size}", size);
|
||||
content += item;
|
||||
}
|
||||
|
||||
bool IndexPageHandler::listDirectory(Common::String path, Common::String &content, const Common::String &itemTemplate) {
|
||||
if (path == "" || path == "/") {
|
||||
addItem(content, itemTemplate, true, "/root/", _("File system root"));
|
||||
addItem(content, itemTemplate, true, "/saves/", _("Saved games"));
|
||||
return true;
|
||||
}
|
||||
|
||||
Common::String prefixToRemove = "", prefixToAdd = "";
|
||||
if (!transformPath(path, prefixToRemove, prefixToAdd)) return false;
|
||||
|
||||
Common::FSNode node = Common::FSNode(path);
|
||||
if (path == "/") node = node.getParent(); // absolute root
|
||||
if (!node.isDirectory()) return false;
|
||||
|
||||
// list directory
|
||||
Common::FSList _nodeContent;
|
||||
if (!node.getChildren(_nodeContent, Common::FSNode::kListAll, false)) // do not show hidden files
|
||||
_nodeContent.clear();
|
||||
else
|
||||
Common::sort(_nodeContent.begin(), _nodeContent.end());
|
||||
|
||||
// add parent directory link
|
||||
{
|
||||
Common::String filePath = path;
|
||||
if (filePath.hasPrefix(prefixToRemove))
|
||||
filePath.erase(0, prefixToRemove.size());
|
||||
if (filePath == "" || filePath == "/" || filePath == "\\")
|
||||
filePath = "/";
|
||||
else
|
||||
filePath = parentPath(prefixToAdd + filePath);
|
||||
addItem(content, itemTemplate, true, filePath, _("Parent directory"));
|
||||
}
|
||||
|
||||
// fill the content
|
||||
for (Common::FSList::iterator i = _nodeContent.begin(); i != _nodeContent.end(); ++i) {
|
||||
Common::String name = i->getDisplayName();
|
||||
if (i->isDirectory()) name += "/";
|
||||
|
||||
Common::String filePath = i->getPath();
|
||||
if (filePath.hasPrefix(prefixToRemove))
|
||||
filePath.erase(0, prefixToRemove.size());
|
||||
filePath = prefixToAdd + filePath;
|
||||
|
||||
addItem(content, itemTemplate, i->isDirectory(), filePath, name);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool IndexPageHandler::transformPath(Common::String &path, Common::String &prefixToRemove, Common::String &prefixToAdd) {
|
||||
// <path> is not empty, but could lack the trailing slash
|
||||
if (path.lastChar() != '/' && path.lastChar() != '\\') path += '/';
|
||||
|
||||
if (path.hasPrefix("/root")) {
|
||||
prefixToAdd = "/root/";
|
||||
prefixToRemove = "";
|
||||
path.erase(0, 5);
|
||||
if (path == "") path = "/"; // absolute root is '/'
|
||||
if (path != "/") path.deleteChar(0); // if that was "/root/ab/c", it becomes "/ab/c", but we need "ab/c"
|
||||
return true;
|
||||
}
|
||||
|
||||
if (path.hasPrefix("/saves")) {
|
||||
prefixToAdd = "/saves/";
|
||||
|
||||
// determine savepath (prefix to remove)
|
||||
DefaultSaveFileManager *manager = dynamic_cast<DefaultSaveFileManager *>(g_system->getSavefileManager());
|
||||
prefixToRemove = (manager ? manager->concatWithSavesPath("") : ConfMan.get("savepath"));
|
||||
if (prefixToRemove.size() && prefixToRemove.lastChar() != '/' && prefixToRemove.lastChar() != '\\')
|
||||
prefixToRemove += '/';
|
||||
|
||||
path.erase(0, 6);
|
||||
if (path.size() && (path[0] == '/' || path[0] == '\\'))
|
||||
path.deleteChar(0);
|
||||
path = prefixToRemove + path;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// public
|
||||
|
||||
void IndexPageHandler::addPathHandler(LocalWebserver &server) {
|
||||
// we can't use LocalServer yet, because IndexPageHandler is created while LocalWebserver is created
|
||||
// (thus no _instance is available and it causes stack overflow)
|
||||
server.addPathHandler("/", new Common::Callback<IndexPageHandler, Client &>(this, &IndexPageHandler::handle));
|
||||
server.addPathHandler("/files", new Common::Callback<IndexPageHandler, Client &>(this, &IndexPageHandler::handleFiles));
|
||||
|
||||
Common::ArchiveMemberList fileList = listArchive();
|
||||
for (Common::ArchiveMemberList::iterator it = fileList.begin(); it != fileList.end(); ++it) {
|
||||
Common::ArchiveMember const &m = **it;
|
||||
if (m.getName() == INDEX_PAGE_NAME) continue;
|
||||
if (m.getName() == FILES_PAGE_NAME) continue;
|
||||
server.addPathHandler("/" + m.getName(), new Common::Callback<IndexPageHandler, Client &>(this, &IndexPageHandler::handleResource));
|
||||
}
|
||||
}
|
||||
|
||||
Common::String IndexPageHandler::code() { return _code; }
|
||||
|
||||
/// utils
|
||||
|
||||
Common::Archive *IndexPageHandler::getZipArchive() {
|
||||
// first search in themepath
|
||||
if (ConfMan.hasKey("themepath")) {
|
||||
const Common::FSNode &node = Common::FSNode(ConfMan.get("themepath"));
|
||||
if (!node.exists() || !node.isReadable() || !node.isDirectory())
|
||||
return nullptr;
|
||||
|
||||
Common::FSNode fileNode = node.getChild(ARCHIVE_NAME);
|
||||
if (fileNode.exists() && fileNode.isReadable() && !fileNode.isDirectory()) {
|
||||
Common::SeekableReadStream *const stream = fileNode.createReadStream();
|
||||
Common::Archive *zipArchive = Common::makeZipArchive(stream);
|
||||
if (zipArchive) return zipArchive;
|
||||
}
|
||||
}
|
||||
|
||||
// then use SearchMan to find it
|
||||
Common::ArchiveMemberList fileList;
|
||||
SearchMan.listMatchingMembers(fileList, ARCHIVE_NAME);
|
||||
for (Common::ArchiveMemberList::iterator it = fileList.begin(); it != fileList.end(); ++it) {
|
||||
Common::ArchiveMember const &m = **it;
|
||||
Common::SeekableReadStream *const stream = m.createReadStream();
|
||||
Common::Archive *zipArchive = Common::makeZipArchive(stream);
|
||||
if (zipArchive) return zipArchive;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Common::ArchiveMemberList IndexPageHandler::listArchive() {
|
||||
Common::ArchiveMemberList resultList;
|
||||
Common::Archive *zipArchive = getZipArchive();
|
||||
if (zipArchive) {
|
||||
zipArchive->listMembers(resultList);
|
||||
delete zipArchive;
|
||||
}
|
||||
return resultList;
|
||||
}
|
||||
|
||||
Common::SeekableReadStream *IndexPageHandler::getArchiveFile(Common::String name) {
|
||||
Common::SeekableReadStream *result = nullptr;
|
||||
Common::Archive *zipArchive = getZipArchive();
|
||||
if (zipArchive) {
|
||||
const Common::ArchiveMemberPtr ptr = zipArchive->getMember(name);
|
||||
result = ptr->createReadStream();
|
||||
delete zipArchive;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Common::String IndexPageHandler::readEverythingFromStream(Common::SeekableReadStream *const stream) {
|
||||
Common::String result;
|
||||
char buf[1024];
|
||||
uint32 readBytes;
|
||||
while (!stream->eos()) {
|
||||
readBytes = stream->read(buf, 1024);
|
||||
result += Common::String(buf, readBytes);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
} // End of namespace Networking
|
|
@ -42,7 +42,9 @@ namespace Networking {
|
|||
|
||||
LocalWebserver::LocalWebserver(): _set(nullptr), _serverSocket(nullptr), _timerStarted(false),
|
||||
_stopOnIdle(false), _clients(0), _idlingFrames(0) {
|
||||
_indexPageHandler.addPathHandler(*this);
|
||||
addPathHandler("/", _indexPageHandler.getHandler());
|
||||
addPathHandler("/files", _filesPageHandler.getHandler());
|
||||
_defaultHandler = _resourceHandler.getHandler();
|
||||
}
|
||||
|
||||
LocalWebserver::~LocalWebserver() {
|
||||
|
@ -142,7 +144,7 @@ void LocalWebserver::stop() {
|
|||
|
||||
void LocalWebserver::stopOnIdle() { _stopOnIdle = true; }
|
||||
|
||||
void LocalWebserver::addPathHandler(Common::String path, ClientHandler handler) {
|
||||
void LocalWebserver::addPathHandler(Common::String path, ClientHandlerCallback handler) {
|
||||
if (_pathHandlers.contains(path)) warning("LocalWebserver::addPathHandler: path already had a handler");
|
||||
_pathHandlers[path] = handler;
|
||||
}
|
||||
|
@ -200,6 +202,8 @@ void LocalWebserver::handleClient(uint32 i) {
|
|||
//if PUT, check whether we know a handler for that URL
|
||||
if (_pathHandlers.contains(_client[i].path()))
|
||||
(*_pathHandlers[_client[i].path()])(_client[i]);
|
||||
else if (_defaultHandler)
|
||||
(*_defaultHandler)(_client[i]); //try default handler
|
||||
|
||||
if (_client[i].state() == BEING_HANDLED || _client[i].state() == INVALID) break;
|
||||
|
||||
|
|
|
@ -24,8 +24,10 @@
|
|||
#define BACKENDS_NETWORKING_SDL_NET_LOCALWEBSERVER_H
|
||||
|
||||
#include "backends/networking/sdl_net/client.h"
|
||||
#include "backends/networking/sdl_net/indexpagehandler.h"
|
||||
#include "common/callback.h"
|
||||
#include "backends/networking/sdl_net/handlers/basehandler.h"
|
||||
#include "backends/networking/sdl_net/handlers/filespagehandler.h"
|
||||
#include "backends/networking/sdl_net/handlers/indexpagehandler.h"
|
||||
#include "backends/networking/sdl_net/handlers/resourcehandler.h"
|
||||
#include "common/hash-str.h"
|
||||
#include "common/mutex.h"
|
||||
#include "common/singleton.h"
|
||||
|
@ -46,8 +48,6 @@ class LocalWebserver : public Common::Singleton<LocalWebserver> {
|
|||
static const uint32 SERVER_PORT = 12345;
|
||||
static const uint32 MAX_CONNECTIONS = 10;
|
||||
|
||||
typedef Common::BaseCallback<Client &> *ClientHandler;
|
||||
|
||||
friend void localWebserverTimer(void *); //calls handle()
|
||||
|
||||
SDLNet_SocketSet _set;
|
||||
|
@ -55,8 +55,11 @@ class LocalWebserver : public Common::Singleton<LocalWebserver> {
|
|||
Client _client[MAX_CONNECTIONS];
|
||||
int _clients;
|
||||
bool _timerStarted, _stopOnIdle;
|
||||
Common::HashMap<Common::String, ClientHandler> _pathHandlers;
|
||||
Common::HashMap<Common::String, ClientHandlerCallback> _pathHandlers;
|
||||
ClientHandlerCallback _defaultHandler;
|
||||
IndexPageHandler _indexPageHandler;
|
||||
FilesPageHandler _filesPageHandler;
|
||||
ResourceHandler _resourceHandler;
|
||||
uint32 _idlingFrames;
|
||||
Common::Mutex _handleMutex;
|
||||
Common::String _address;
|
||||
|
@ -74,7 +77,7 @@ public:
|
|||
void start();
|
||||
void stop();
|
||||
void stopOnIdle();
|
||||
void addPathHandler(Common::String path, ClientHandler handler);
|
||||
void addPathHandler(Common::String path, ClientHandlerCallback handler);
|
||||
void removePathHandler(Common::String path);
|
||||
|
||||
Common::String getAddress();
|
||||
|
|
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue