Panda3D
virtualFileMountHTTP.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file virtualFileMountHTTP.cxx
10  * @author drose
11  * @date 2008-10-30
12  */
13 
14 #include "virtualFileMountHTTP.h"
15 #include "virtualFileHTTP.h"
16 #include "virtualFileSystem.h"
17 
18 #ifdef HAVE_OPENSSL
19 
20 using std::string;
21 
22 TypeHandle VirtualFileMountHTTP::_type_handle;
23 
24 
25 /**
26  *
27  */
28 VirtualFileMountHTTP::
29 VirtualFileMountHTTP(const URLSpec &root, HTTPClient *http) :
30  _http(http),
31  _root(root)
32 {
33  // Make sure the root ends on a slash. The implicit trailing slash is a
34  // semi-standard internet convention.
35  string path = _root.get_path();
36  if (!path.empty() && path[path.length() - 1] != '/') {
37  path += '/';
38  _root.set_path(path);
39  }
40 }
41 
42 /**
43  *
44  */
45 VirtualFileMountHTTP::
46 ~VirtualFileMountHTTP() {
47 }
48 
49 
50 /**
51  * Reads all of the vfs-mount-url lines in the Config.prc file and replaces
52  * the mount settings to match them.
53  *
54  * This will mount any url's mentioned in the config file, and unmount and
55  * unmount any url's no longer mentioned in the config file. Normally, it is
56  * called automatically at startup, and need not be called again, unless you
57  * have fiddled with some config settings.
58  */
59 void VirtualFileMountHTTP::
60 reload_vfs_mount_url() {
62 
63  // First, unload the existing mounts.
64  int n = 0;
65  while (n < vfs->get_num_mounts()) {
66  PT(VirtualFileMount) mount = vfs->get_mount(n);
67  if (mount->is_of_type(VirtualFileMountHTTP::get_class_type())) {
68  vfs->unmount(mount);
69  // Don't increment n.
70  } else {
71  ++n;
72  }
73  }
74 
75  // Now, reload the newly specified mounts.
76  ConfigVariableList mounts
77  ("vfs-mount-url",
78  PRC_DESC("vfs-mount-url http://site/path[:port] mount-point [options]"));
79 
80  int num_unique_values = mounts.get_num_unique_values();
81  for (int i = 0; i < num_unique_values; i++) {
82  string mount_desc = mounts.get_unique_value(i);
83 
84  size_t space = mount_desc.rfind(' ');
85  if (space == string::npos) {
86  downloader_cat.warning()
87  << "No space in vfs-mount-url descriptor: " << mount_desc << "\n";
88 
89  } else {
90  string mount_point = mount_desc.substr(space + 1);
91  while (space > 0 && isspace(mount_desc[space - 1])) {
92  space--;
93  }
94  mount_desc = mount_desc.substr(0, space);
95  string options;
96 
97  space = mount_desc.rfind(' ');
98  if (space != string::npos) {
99  // If there's another space, we have the optional options field.
100  options = mount_point;
101  mount_point = mount_desc.substr(space + 1);
102  while (space > 0 && isspace(mount_desc[space - 1])) {
103  --space;
104  }
105  mount_desc = mount_desc.substr(0, space);
106  }
107 
108  mount_desc = ExecutionEnvironment::expand_string(mount_desc);
109  URLSpec root(mount_desc);
110 
111  int flags = 0;
112  string password;
113 
114  // Split the options up by commas.
115  size_t p = 0;
116  size_t q = options.find(',', p);
117  while (q != string::npos) {
118  vfs->parse_option(options.substr(p, q - p),
119  flags, password);
120  p = q + 1;
121  q = options.find(',', p);
122  }
123  vfs->parse_option(options.substr(p), flags, password);
124 
125  PT(VirtualFileMount) mount = new VirtualFileMountHTTP(root);
126  vfs->mount(mount, mount_point, flags);
127  }
128  }
129 }
130 
131 /**
132  * Returns true if the indicated file exists within the mount system.
133  */
134 bool VirtualFileMountHTTP::
135 has_file(const Filename &) const {
136  return false;
137 }
138 
139 /**
140  * Returns true if the indicated file exists within the mount system and is a
141  * directory.
142  */
143 bool VirtualFileMountHTTP::
144 is_directory(const Filename &) const {
145  return false;
146 }
147 
148 /**
149  * Returns true if the indicated file exists within the mount system and is a
150  * regular file.
151  */
152 bool VirtualFileMountHTTP::
153 is_regular_file(const Filename &) const {
154  return false;
155 }
156 
157 /**
158  * Constructs and returns a new VirtualFile instance that corresponds to the
159  * indicated filename within this mount point. The returned VirtualFile
160  * object does not imply that the given file actually exists; but if the file
161  * does exist, then the handle can be used to read it.
162  */
163 PT(VirtualFile) VirtualFileMountHTTP::
164 make_virtual_file(const Filename &local_filename,
165  const Filename &original_filename, bool implicit_pz_file,
166  int open_flags) {
167  PT(VirtualFileHTTP) vfile =
168  new VirtualFileHTTP(this, local_filename, implicit_pz_file, open_flags);
169  vfile->set_original_filename(original_filename);
170 
171  return vfile;
172 }
173 
174 /**
175  * Opens the file for reading, if it exists. Returns a newly allocated
176  * istream on success (which you should eventually delete when you are done
177  * reading). Returns NULL on failure.
178  */
179 std::istream *VirtualFileMountHTTP::
180 open_read_file(const Filename &) const {
181  return nullptr;
182 }
183 
184 /**
185  * Returns the current size on disk (or wherever it is) of the already-open
186  * file. Pass in the stream that was returned by open_read_file(); some
187  * implementations may require this stream to determine the size.
188  */
189 std::streamsize VirtualFileMountHTTP::
190 get_file_size(const Filename &, std::istream *) const {
191  return 0;
192 }
193 
194 /**
195  * Returns the current size on disk (or wherever it is) of the file before it
196  * has been opened.
197  */
198 std::streamsize VirtualFileMountHTTP::
199 get_file_size(const Filename &) const {
200  return 0;
201 }
202 
203 /**
204  * Returns a time_t value that represents the time the file was last modified,
205  * to within whatever precision the operating system records this information
206  * (on a Windows95 system, for instance, this may only be accurate to within 2
207  * seconds).
208  *
209  * If the timestamp cannot be determined, either because it is not supported
210  * by the operating system or because there is some error (such as file not
211  * found), returns 0.
212  */
213 time_t VirtualFileMountHTTP::
214 get_timestamp(const Filename &) const {
215  return 0;
216 }
217 
218 /**
219  * Fills the given vector up with the list of filenames that are local to this
220  * directory, if the filename is a directory. Returns true if successful, or
221  * false if the file is not a directory or cannot be read.
222  */
223 bool VirtualFileMountHTTP::
224 scan_directory(vector_string &, const Filename &) const {
225  return false;
226 }
227 
228 /**
229  *
230  */
231 void VirtualFileMountHTTP::
232 output(std::ostream &out) const {
233  out << _root;
234 }
235 
236 /**
237  * Returns an HTTPChannel object suitable for use for extracting a document
238  * from the current URL root.
239  */
240 PT(HTTPChannel) VirtualFileMountHTTP::
241 get_channel() {
242  PT(HTTPChannel) channel;
243  _channels_lock.lock();
244 
245  if (!_channels.empty()) {
246  // If we have some channels sitting around, grab one. Grab the one on the
247  // end; it was most recently pushed, and therefore most likely to be still
248  // alive.
249  channel = _channels.back();
250  _channels.pop_back();
251  } else {
252  // If we don't have any channels standing by, make a new one.
253  channel = _http->make_channel(true);
254  }
255 
256  _channels_lock.unlock();
257  return channel;
258 }
259 
260 /**
261  * Accepts an HTTPChannel that is no longer being used, and restores it to
262  * standby duty, so that it will be returned by a future call to
263  * get_channel().
264  */
265 void VirtualFileMountHTTP::
266 recycle_channel(HTTPChannel *channel) {
267  _channels_lock.lock();
268  _channels.push_back(channel);
269  _channels_lock.unlock();
270 }
271 
272 #endif // HAVE_OPENSSL
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A container for a URL, e.g.
Definition: urlSpec.h:28
A hierarchy of directories and files that appears to be one continuous file system, even though the files may originate from several different sources that may not be related to the actual OS&#39;s file system.
The abstract base class for a file or directory within the VirtualFileSystem.
Definition: virtualFile.h:35
This class is similar to ConfigVariable, but it reports its value as a list of strings.
bool mount(Multifile *multifile, const Filename &mount_point, int flags)
Mounts the indicated Multifile at the given mount point.
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
static std::string expand_string(const std::string &str)
Reads the string, looking for environment variable names marked by a $.
static VirtualFileSystem * get_global_ptr()
Returns the default global VirtualFileSystem.
int unmount(Multifile *multifile)
Unmounts all appearances of the indicated Multifile from the file system.
static void parse_option(const std::string &option, int &flags, std::string &password)
Parses one of the option flags in the options list on the vfs-mount Config.prc line.
The abstract base class for a mount definition used within a VirtualFileSystem.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_mount
Returns the nth mount in the system.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81