vfs-mount-url

This commit is contained in:
David Rose 2008-11-08 02:36:33 +00:00
parent e80cd79f6b
commit 3c5ac474f4
7 changed files with 171 additions and 86 deletions

View File

@ -61,43 +61,12 @@ ConfigVariableInt patcher_buffer_size
"Patcher::run(). Increasing this may help the Patcher "
"perform more work before returning."));
ConfigVariableBool verify_ssl
("verify-ssl", true,
PRC_DESC("Configure this true (the default) to insist on verifying all SSL "
"(e.g. https) servers against a known certificate, or false to allow "
"an unverified connection. This controls the default behavior; the "
"specific behavior for a particular HTTPClient can be adjusted at "
"runtime with set_verify_ssl()."));
ConfigVariableString ssl_cipher_list
("ssl-cipher-list", "DEFAULT",
PRC_DESC("This is the default value for HTTPClient::set_cipher_list()."));
ConfigVariableList expected_ssl_server
("expected-ssl-server");
ConfigVariableList ssl_certificates
("ssl-certificates");
ConfigVariableString http_proxy
("http-proxy", "",
PRC_DESC("This specifies the default value for HTTPClient::set_proxy_spec(). "
"It is a semicolon-delimited list of proxies that we use to contact "
"all HTTP hosts that don't specify otherwise. See "
"set_proxy_spec() for more information."));
ConfigVariableString http_direct_hosts
("http-direct-hosts", "",
PRC_DESC("This specifies the default value for HTTPClient::set_direct_host_spec(). "
"It is a semicolon-delimited list of host names that do not require a "
"proxy. See set_direct_host_spec() for more information."));
ConfigVariableBool http_try_all_direct
("http-try-all-direct", true,
PRC_DESC("This specifies the default value for HTTPClient::set_try_all_direct(). "
"If this is true, a direct connection will always be attempted after an "
"attempt to connect through a proxy fails."));
ConfigVariableString http_proxy_username
("http-proxy-username", "",
PRC_DESC("This specifies a default username:password to pass to the proxy."));
ConfigVariableBool http_proxy_tunnel
("http-proxy-tunnel", false,
PRC_DESC("This specifies the default value for HTTPChannel::set_proxy_tunnel(). "
@ -140,29 +109,6 @@ ConfigVariableInt http_max_connect_count
"prevent the code from attempting runaway connections; this limit "
"should never be reached in practice."));
ConfigVariableFilename http_client_certificate_filename
("http-client-certificate-filename", "",
PRC_DESC("This provides a default client certificate to offer up should an "
"SSL server demand one. The file names a PEM-formatted file "
"that includes a public and private key specification. A "
"connection-specific certificate may also be specified at runtime on "
"the HTTPClient object, but this will require having a different "
"HTTPClient object for each differently-certificated connection."));
ConfigVariableString http_client_certificate_passphrase
("http-client-certificate-passphrase", "",
PRC_DESC("This specifies the passphrase to use to decode the certificate named "
"by http-client-certificate-filename."));
ConfigVariableList http_username
("http-username",
PRC_DESC("Adds one or more username/password pairs to all HTTP clients. The client "
"will present this username/password when asked to authenticate a request "
"for a particular server and/or realm. The username is of the form "
"server:realm:username:password, where either or both of server and "
"realm may be empty, or just realm:username:password or username:password. "
"If the server or realm is empty, they will match anything."));
ConfigureFn(config_downloader) {
init_libdownloader();
}
@ -188,6 +134,8 @@ init_libdownloader() {
VirtualFileHTTP::init_type();
VirtualFileMountHTTP::init_type();
VirtualFileMountHTTP::reload_vfs_mount_url();
// We need to define this here, rather than above, to guarantee that
// it has been initialized by the time we check it.
ConfigVariableBool early_random_seed

View File

@ -38,24 +38,15 @@ extern ConfigVariableDouble decompressor_step_time;
extern ConfigVariableDouble extractor_step_time;
extern ConfigVariableInt patcher_buffer_size;
extern ConfigVariableBool verify_ssl;
extern ConfigVariableString ssl_cipher_list;
extern ConfigVariableList expected_ssl_server;
extern ConfigVariableList ssl_certificates;
extern ConfigVariableString http_proxy;
extern ConfigVariableString http_direct_hosts;
extern ConfigVariableBool http_try_all_direct;
extern ConfigVariableString http_proxy_username;
extern ConfigVariableBool http_proxy_tunnel;
extern ConfigVariableDouble http_connect_timeout;
extern ConfigVariableDouble http_timeout;
extern ConfigVariableInt http_skip_body_size;
extern ConfigVariableDouble http_idle_timeout;
extern ConfigVariableInt http_max_connect_count;
extern ConfigVariableFilename http_client_certificate_filename;
extern ConfigVariableString http_client_certificate_passphrase;
extern ConfigVariableList http_username;
extern EXPCL_PANDAEXPRESS void init_libdownloader();

View File

@ -94,6 +94,64 @@ tokenize(const string &str, vector_string &words, const string &delimiters) {
////////////////////////////////////////////////////////////////////
HTTPClient::
HTTPClient() {
ConfigVariableBool verify_ssl
("verify-ssl", true,
PRC_DESC("Configure this true (the default) to insist on verifying all SSL "
"(e.g. https) servers against a known certificate, or false to allow "
"an unverified connection. This controls the default behavior; the "
"specific behavior for a particular HTTPClient can be adjusted at "
"runtime with set_verify_ssl()."));
ConfigVariableString ssl_cipher_list
("ssl-cipher-list", "DEFAULT",
PRC_DESC("This is the default value for HTTPClient::set_cipher_list()."));
ConfigVariableString http_proxy
("http-proxy", "",
PRC_DESC("This specifies the default value for HTTPClient::set_proxy_spec(). "
"It is a semicolon-delimited list of proxies that we use to contact "
"all HTTP hosts that don't specify otherwise. See "
"set_proxy_spec() for more information."));
ConfigVariableString http_direct_hosts
("http-direct-hosts", "",
PRC_DESC("This specifies the default value for HTTPClient::set_direct_host_spec(). "
"It is a semicolon-delimited list of host names that do not require a "
"proxy. See set_direct_host_spec() for more information."));
ConfigVariableBool http_try_all_direct
("http-try-all-direct", true,
PRC_DESC("This specifies the default value for HTTPClient::set_try_all_direct(). "
"If this is true, a direct connection will always be attempted after an "
"attempt to connect through a proxy fails."));
ConfigVariableString http_proxy_username
("http-proxy-username", "",
PRC_DESC("This specifies a default username:password to pass to the proxy."));
ConfigVariableList http_username
("http-username",
PRC_DESC("Adds one or more username/password pairs to all HTTP clients. The client "
"will present this username/password when asked to authenticate a request "
"for a particular server and/or realm. The username is of the form "
"server:realm:username:password, where either or both of server and "
"realm may be empty, or just realm:username:password or username:password. "
"If the server or realm is empty, they will match anything."));
ConfigVariableFilename http_client_certificate_filename
("http-client-certificate-filename", "",
PRC_DESC("This provides a default client certificate to offer up should an "
"SSL server demand one. The file names a PEM-formatted file "
"that includes a public and private key specification. A "
"connection-specific certificate may also be specified at runtime on "
"the HTTPClient object, but this will require having a different "
"HTTPClient object for each differently-certificated connection."));
ConfigVariableString http_client_certificate_passphrase
("http-client-certificate-passphrase", "",
PRC_DESC("This specifies the passphrase to use to decode the certificate named "
"by http-client-certificate-filename."));
_http_version = HTTPEnum::HV_11;
_verify_ssl = verify_ssl ? VS_normal : VS_no_verify;
_ssl_ctx = (SSL_CTX *)NULL;

View File

@ -50,6 +50,92 @@ 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

View File

@ -39,6 +39,8 @@ PUBLISHED:
INLINE HTTPClient *get_http_client() const;
INLINE const URLSpec &get_root() const;
static void reload_vfs_mount_url();
public:
virtual PT(VirtualFile) make_virtual_file(const string &local_filename,
const Filename &original_filename,

View File

@ -544,7 +544,6 @@ find_all_files(const Filename &filename, const DSearchPath &searchpath,
void VirtualFileSystem::
write(ostream &out) const {
((VirtualFileSystem *)this)->_lock.acquire();
out << "_cwd" << _cwd << "\n_mounts:\n";
Mounts::const_iterator mi;
for (mi = _mounts.begin(); mi != _mounts.end(); ++mi) {
VirtualFileMount *mount = (*mi);
@ -745,6 +744,26 @@ scan_mount_points(vector_string &names, const Filename &path) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::parse_option
// Access: Public, Static
// Description: Parses one of the option flags in the options list on
// the vfs-mount Config.prc line.
////////////////////////////////////////////////////////////////////
void VirtualFileSystem::
parse_option(const string &option, int &flags, string &password) {
if (option == "0" || option.empty()) {
// 0 is the null option.
} else if (option == "ro") {
flags |= MF_read_only;
} else if (option.substr(0, 3) == "pw:") {
password = option.substr(3);
} else {
express_cat.warning()
<< "Invalid option on vfs-mount: \"" << option << "\"\n";
}
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::normalize_mount_point
// Access: Private
@ -1008,23 +1027,3 @@ consider_mount_mf(const Filename &filename) {
// Recurse.
return consider_mount_mf(dirname);
}
////////////////////////////////////////////////////////////////////
// Function: VirtualFileSystem::parse_option
// Access: Private, Static
// Description: Parses one of the option flags in the options list on
// the vfs-mount Config.prc line.
////////////////////////////////////////////////////////////////////
void VirtualFileSystem::
parse_option(const string &option, int &flags, string &password) {
if (option == "0" || option.empty()) {
// 0 is the null option.
} else if (option == "ro") {
flags |= MF_read_only;
} else if (option.substr(0, 3) == "pw:") {
password = option.substr(3);
} else {
express_cat.warning()
<< "Invalid option on vfs-mount: \"" << option << "\"\n";
}
}

View File

@ -95,6 +95,9 @@ public:
void scan_mount_points(vector_string &names, const Filename &path) const;
static void parse_option(const string &option,
int &flags, string &password);
private:
Filename normalize_mount_point(const string &mount_point) const;
bool do_mount(VirtualFileMount *mount, const string &mount_point, int flags);
@ -104,8 +107,6 @@ private:
const Filename &original_filename, bool implicit_pz_file,
bool status_only) const;
bool consider_mount_mf(const Filename &filename);
static void parse_option(const string &option,
int &flags, string &password);
MutexImpl _lock;
typedef pvector<PT(VirtualFileMount) > Mounts;