314 lines
11 KiB
C++
314 lines
11 KiB
C++
// Filename: virtualFileMountHTTP.cxx
|
|
// Created by: drose (30Oct08)
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
//
|
|
// 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."
|
|
//
|
|
////////////////////////////////////////////////////////////////////
|
|
|
|
#include "virtualFileMountHTTP.h"
|
|
#include "virtualFileHTTP.h"
|
|
#include "virtualFileSystem.h"
|
|
|
|
#ifdef HAVE_OPENSSL
|
|
|
|
TypeHandle VirtualFileMountHTTP::_type_handle;
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::Constructor
|
|
// Access: Published
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
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);
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::Destructor
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
VirtualFileMountHTTP::
|
|
~VirtualFileMountHTTP() {
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::reload_vfs_mount_url
|
|
// Access: Published, Static
|
|
// Description: 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);
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::has_file
|
|
// Access: Public, Virtual
|
|
// Description: Returns true if the indicated file exists within the
|
|
// mount system.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool VirtualFileMountHTTP::
|
|
has_file(const Filename &) const {
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::is_directory
|
|
// Access: Public, Virtual
|
|
// Description: Returns true if the indicated file exists within the
|
|
// mount system and is a directory.
|
|
////////////////////////////////////////////////////////////////////
|
|
bool VirtualFileMountHTTP::
|
|
is_directory(const Filename &) const {
|
|
return false;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::is_regular_file
|
|
// Access: Public, Virtual
|
|
// Description: 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;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::make_virtual_file
|
|
// Access: Public, Virtual
|
|
// Description: 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 string &local_filename,
|
|
const Filename &original_filename, bool implicit_pz_file,
|
|
bool status_only) {
|
|
PT(VirtualFileHTTP) vfile =
|
|
new VirtualFileHTTP(this, local_filename, implicit_pz_file, status_only);
|
|
vfile->set_original_filename(original_filename);
|
|
|
|
return vfile.p();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::open_read_file
|
|
// Access: Public, Virtual
|
|
// Description: 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;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::get_file_size
|
|
// Access: Published, Virtual
|
|
// Description: 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.
|
|
////////////////////////////////////////////////////////////////////
|
|
off_t VirtualFileMountHTTP::
|
|
get_file_size(const Filename &, istream *) const {
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::get_file_size
|
|
// Access: Published, Virtual
|
|
// Description: Returns the current size on disk (or wherever it is)
|
|
// of the file before it has been opened.
|
|
////////////////////////////////////////////////////////////////////
|
|
off_t VirtualFileMountHTTP::
|
|
get_file_size(const Filename &) const {
|
|
return 0;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::get_timestamp
|
|
// Access: Published, Virtual
|
|
// Description: 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;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::scan_directory
|
|
// Access: Public, Virtual
|
|
// Description: 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;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::output
|
|
// Access: Public, Virtual
|
|
// Description:
|
|
////////////////////////////////////////////////////////////////////
|
|
void VirtualFileMountHTTP::
|
|
output(ostream &out) const {
|
|
out << _root;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::get_channel
|
|
// Access: Public
|
|
// Description: 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;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////
|
|
// Function: VirtualFileMountHTTP::recycle_channel
|
|
// Access: Public
|
|
// Description: 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
|