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