open_toontown_panda3d/panda/src/downloader/virtualFileMountHTTP.cxx

271 lines
7.3 KiB
C++

/**
* PANDA 3D SOFTWARE
* Copyright (c) Carnegie Mellon University. All rights reserved.
*
* All use of this software is subject to the terms of the revised BSD
* license. You should have received a copy of this license along
* with this source code in a file named "LICENSE."
*
* @file virtualFileMountHTTP.cxx
* @author drose
* @date 2008-10-30
*/
#include "virtualFileMountHTTP.h"
#include "virtualFileHTTP.h"
#include "virtualFileSystem.h"
#ifdef HAVE_OPENSSL
TypeHandle VirtualFileMountHTTP::_type_handle;
/**
*
*/
VirtualFileMountHTTP::
VirtualFileMountHTTP(const URLSpec &root, HTTPClient *http) :
_http(http),
_root(root)
{
// Make sure the root ends on a slash. The implicit trailing slash is a
// semi-standard internet convention.
string path = _root.get_path();
if (!path.empty() && path[path.length() - 1] != '/') {
path += '/';
_root.set_path(path);
}
}
/**
*
*/
VirtualFileMountHTTP::
~VirtualFileMountHTTP() {
}
/**
* Reads all of the vfs-mount-url lines in the Config.prc file and replaces
* the mount settings to match them.
*
* This will mount any url's mentioned in the config file, and unmount and
* unmount any url's no longer mentioned in the config file. Normally, it is
* called automatically at startup, and need not be called again, unless you
* have fiddled with some config settings.
*/
void VirtualFileMountHTTP::
reload_vfs_mount_url() {
VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
// First, unload the existing mounts.
int n = 0;
while (n < vfs->get_num_mounts()) {
PT(VirtualFileMount) mount = vfs->get_mount(n);
if (mount->is_of_type(VirtualFileMountHTTP::get_class_type())) {
vfs->unmount(mount);
// Don't increment n.
} else {
++n;
}
}
// Now, reload the newly specified mounts.
ConfigVariableList mounts
("vfs-mount-url",
PRC_DESC("vfs-mount-url http://site/path[:port] mount-point [options]"));
int num_unique_values = mounts.get_num_unique_values();
for (int i = 0; i < num_unique_values; i++) {
string mount_desc = mounts.get_unique_value(i);
size_t space = mount_desc.rfind(' ');
if (space == string::npos) {
downloader_cat.warning()
<< "No space in vfs-mount-url descriptor: " << mount_desc << "\n";
} else {
string mount_point = mount_desc.substr(space + 1);
while (space > 0 && isspace(mount_desc[space - 1])) {
space--;
}
mount_desc = mount_desc.substr(0, space);
string options;
space = mount_desc.rfind(' ');
if (space != string::npos) {
// If there's another space, we have the optional options field.
options = mount_point;
mount_point = mount_desc.substr(space + 1);
while (space > 0 && isspace(mount_desc[space - 1])) {
--space;
}
mount_desc = mount_desc.substr(0, space);
}
mount_desc = ExecutionEnvironment::expand_string(mount_desc);
URLSpec root(mount_desc);
int flags = 0;
string password;
// Split the options up by commas.
size_t p = 0;
size_t q = options.find(',', p);
while (q != string::npos) {
vfs->parse_option(options.substr(p, q - p),
flags, password);
p = q + 1;
q = options.find(',', p);
}
vfs->parse_option(options.substr(p), flags, password);
PT(VirtualFileMount) mount = new VirtualFileMountHTTP(root);
vfs->mount(mount, mount_point, flags);
}
}
}
/**
* Returns true if the indicated file exists within the mount system.
*/
bool VirtualFileMountHTTP::
has_file(const Filename &) const {
return false;
}
/**
* Returns true if the indicated file exists within the mount system and is a
* directory.
*/
bool VirtualFileMountHTTP::
is_directory(const Filename &) const {
return false;
}
/**
* Returns true if the indicated file exists within the mount system and is a
* regular file.
*/
bool VirtualFileMountHTTP::
is_regular_file(const Filename &) const {
return false;
}
/**
* Constructs and returns a new VirtualFile instance that corresponds to the
* indicated filename within this mount point. The returned VirtualFile
* object does not imply that the given file actually exists; but if the file
* does exist, then the handle can be used to read it.
*/
PT(VirtualFile) VirtualFileMountHTTP::
make_virtual_file(const Filename &local_filename,
const Filename &original_filename, bool implicit_pz_file,
int open_flags) {
PT(VirtualFileHTTP) vfile =
new VirtualFileHTTP(this, local_filename, implicit_pz_file, open_flags);
vfile->set_original_filename(original_filename);
return vfile.p();
}
/**
* Opens the file for reading, if it exists. Returns a newly allocated
* istream on success (which you should eventually delete when you are done
* reading). Returns NULL on failure.
*/
istream *VirtualFileMountHTTP::
open_read_file(const Filename &) const {
return NULL;
}
/**
* Returns the current size on disk (or wherever it is) of the already-open
* file. Pass in the stream that was returned by open_read_file(); some
* implementations may require this stream to determine the size.
*/
streamsize VirtualFileMountHTTP::
get_file_size(const Filename &, istream *) const {
return 0;
}
/**
* Returns the current size on disk (or wherever it is) of the file before it
* has been opened.
*/
streamsize VirtualFileMountHTTP::
get_file_size(const Filename &) const {
return 0;
}
/**
* Returns a time_t value that represents the time the file was last modified,
* to within whatever precision the operating system records this information
* (on a Windows95 system, for instance, this may only be accurate to within 2
* seconds).
*
* If the timestamp cannot be determined, either because it is not supported
* by the operating system or because there is some error (such as file not
* found), returns 0.
*/
time_t VirtualFileMountHTTP::
get_timestamp(const Filename &) const {
return 0;
}
/**
* Fills the given vector up with the list of filenames that are local to this
* directory, if the filename is a directory. Returns true if successful, or
* false if the file is not a directory or cannot be read.
*/
bool VirtualFileMountHTTP::
scan_directory(vector_string &, const Filename &) const {
return false;
}
/**
*
*/
void VirtualFileMountHTTP::
output(ostream &out) const {
out << _root;
}
/**
* Returns an HTTPChannel object suitable for use for extracting a document
* from the current URL root.
*/
PT(HTTPChannel) VirtualFileMountHTTP::
get_channel() {
PT(HTTPChannel) channel;
_channels_lock.acquire();
if (!_channels.empty()) {
// If we have some channels sitting around, grab one. Grab the one on the
// end; it was most recently pushed, and therefore most likely to be still
// alive.
channel = _channels.back();
_channels.pop_back();
} else {
// If we don't have any channels standing by, make a new one.
channel = _http->make_channel(true);
}
_channels_lock.release();
return channel;
}
/**
* Accepts an HTTPChannel that is no longer being used, and restores it to
* standby duty, so that it will be returned by a future call to
* get_channel().
*/
void VirtualFileMountHTTP::
recycle_channel(HTTPChannel *channel) {
_channels_lock.acquire();
_channels.push_back(channel);
_channels_lock.release();
}
#endif // HAVE_OPENSSL