OpenShot Library | libopenshot-audio  0.2.0
juce_URL.h
1 
2 /** @weakgroup juce_core-network
3  * @{
4  */
5 /*
6  ==============================================================================
7 
8  This file is part of the JUCE library.
9  Copyright (c) 2017 - ROLI Ltd.
10 
11  JUCE is an open source library subject to commercial or open-source
12  licensing.
13 
14  The code included in this file is provided under the terms of the ISC license
15  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
16  To use, copy, modify, and/or distribute this software for any purpose with or
17  without fee is hereby granted provided that the above copyright notice and
18  this permission notice appear in all copies.
19 
20  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
21  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
22  DISCLAIMED.
23 
24  ==============================================================================
25 */
26 
27 namespace juce
28 {
29 
30 class WebInputStream;
31 
32 //==============================================================================
33 /**
34  Represents a URL and has a bunch of useful functions to manipulate it.
35 
36  This class can be used to launch URLs in browsers, and also to create
37  InputStreams that can read from remote http or ftp sources.
38 
39  @tags{Core}
40 */
42 {
43 public:
44  //==============================================================================
45  /** Creates an empty URL. */
46  URL() noexcept;
47 
48  /** Creates a URL from a string.
49  This will parse any embedded parameters after a '?' character and store them
50  in the list (see getParameterNames etc). If you don't want this to happen, you
51  can use createWithoutParsing().
52  */
53  URL (const String& url);
54 
55  URL (const URL&) = default;
56  URL& operator= (const URL&) = default;
57 
58  // VS2013 can't default move constructors and assignments
59  URL (URL&&);
60  URL& operator= (URL&&);
61 
62  /** Creates URL referring to a local file on your disk using the file:// scheme. */
63  explicit URL (File);
64 
65  /** Destructor. */
66  ~URL();
67 
68  /** Compares two URLs.
69  All aspects of the URLs must be identical for them to match, including any parameters,
70  upload files, etc.
71  */
72  bool operator== (const URL&) const;
73  bool operator!= (const URL&) const;
74 
75  //==============================================================================
76  /** Returns a string version of the URL.
77 
78  If includeGetParameters is true and any parameters have been set with the
79  withParameter() method, then the string will have these appended on the
80  end and url-encoded.
81  */
82  String toString (bool includeGetParameters) const;
83 
84  /** Returns true if the URL is an empty string. */
85  bool isEmpty() const noexcept;
86 
87  /** True if it seems to be valid. */
88  bool isWellFormed() const;
89 
90  /** Returns just the domain part of the URL.
91  E.g. for "http://www.xyz.com/foobar", this will return "www.xyz.com".
92  */
93  String getDomain() const;
94 
95  /** Returns the path part of the URL.
96  E.g. for "http://www.xyz.com/foo/bar?x=1", this will return "foo/bar".
97  */
98  String getSubPath() const;
99 
100  /** Returns the scheme of the URL.
101  E.g. for "http://www.xyz.com/foobar", this will return "http". (It won't
102  include the colon).
103  */
104  String getScheme() const;
105 
106  /** Returns true if this URL refers to a local file. */
107  bool isLocalFile() const;
108 
109  /** Returns the file path of the local file to which this URL refers to.
110  If the URL does not represent a local file URL (i.e. the URL's scheme is not 'file')
111  then this method will assert.
112 
113  This method also supports converting Android's content:// URLs to
114  local file paths.
115 
116  @see isLocalFile
117  */
118  File getLocalFile() const;
119 
120  /** Returns the file name. For all but Android's content:// scheme, it will
121  simply return the last segment of the URL.
122  E.g. for "http://www.xyz.com/foo/bar.txt", this will return "bar.txt".
123 
124  For Android's content:// scheme, it will attempt to resolve the filename
125  located under the URL.
126  */
127  String getFileName() const;
128 
129  /** Attempts to read a port number from the URL.
130  @returns the port number, or 0 if none is explicitly specified.
131  */
132  int getPort() const;
133 
134  /** Returns a new version of this URL with a different domain and path.
135  E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
136  "abc.com/zzz", it'll return "http://abc.com/zzz?x=1".
137  @see withNewSubPath
138  */
139  URL withNewDomainAndPath (const String& newFullPath) const;
140 
141  /** Returns a new version of this URL with a different sub-path.
142  E.g. if the URL is "http://www.xyz.com/foo?x=1" and you call this with
143  "bar", it'll return "http://www.xyz.com/bar?x=1".
144  @see withNewDomainAndPath
145  */
146  URL withNewSubPath (const String& newPath) const;
147 
148  /** Returns a new URL that refers to a sub-path relative to this one.
149  E.g. if the URL is "http://www.xyz.com/foo" and you call this with
150  "bar", it'll return "http://www.xyz.com/foo/bar". Note that there's no way for
151  this method to know whether the original URL is a file or directory, so it's
152  up to you to make sure it's a directory. It also won't attempt to be smart about
153  the content of the childPath string, so if this string is an absolute URL, it'll
154  still just get bolted onto the end of the path.
155 
156  @see File::getChildFile
157  */
158  URL getChildURL (const String& subPath) const;
159 
160  //==============================================================================
161  /** Returns a copy of this URL, with a GET or POST parameter added to the end.
162 
163  Any control characters in the value will be encoded.
164  e.g. calling "withParameter ("amount", "some fish") for the url "www.fish.com"
165  would produce a new url whose toString(true) method would return
166  "www.fish.com?amount=some+fish".
167 
168  @see getParameterNames, getParameterValues
169  */
170  URL withParameter (const String& parameterName,
171  const String& parameterValue) const;
172 
173  /** Returns a copy of this URL, with a set of GET or POST parameters added.
174  This is a convenience method, equivalent to calling withParameter for each value.
175  @see withParameter
176  */
177  URL withParameters (const StringPairArray& parametersToAdd) const;
178 
179  /** Returns a copy of this URL, with a file-upload type parameter added to it.
180 
181  When performing a POST where one of your parameters is a binary file, this
182  lets you specify the file.
183 
184  Note that the filename is stored, but the file itself won't actually be read
185  until this URL is later used to create a network input stream. If you want to
186  upload data from memory, use withDataToUpload().
187 
188  @see withDataToUpload
189  */
190  URL withFileToUpload (const String& parameterName,
191  const File& fileToUpload,
192  const String& mimeType) const;
193 
194  /** Returns a copy of this URL, with a file-upload type parameter added to it.
195 
196  When performing a POST where one of your parameters is a binary file, this
197  lets you specify the file content.
198  Note that the filename parameter should not be a full path, it's just the
199  last part of the filename.
200 
201  @see withFileToUpload
202  */
203  URL withDataToUpload (const String& parameterName,
204  const String& filename,
205  const MemoryBlock& fileContentToUpload,
206  const String& mimeType) const;
207 
208  /** Returns an array of the names of all the URL's parameters.
209 
210  E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would
211  contain two items: "type" and "amount".
212 
213  You can call getParameterValues() to get the corresponding value of each
214  parameter. Note that the list can contain multiple parameters with the same name.
215 
216  @see getParameterValues, withParameter
217  */
218  const StringArray& getParameterNames() const noexcept { return parameterNames; }
219 
220  /** Returns an array of the values of all the URL's parameters.
221 
222  E.g. for the url "www.fish.com?type=haddock&amount=some+fish", this array would
223  contain two items: "haddock" and "some fish".
224 
225  The values returned will have been cleaned up to remove any escape characters.
226 
227  You can call getParameterNames() to get the corresponding name of each
228  parameter. Note that the list can contain multiple parameters with the same name.
229 
230  @see getParameterNames, withParameter
231  */
232  const StringArray& getParameterValues() const noexcept { return parameterValues; }
233 
234  /** Returns a copy of this URL, with a block of data to send as the POST data.
235 
236  If you're setting the POST data, be careful not to have any parameters set
237  as well, otherwise it'll all get thrown in together, and might not have the
238  desired effect.
239 
240  If the URL already contains some POST data, this will replace it, rather
241  than being appended to it.
242 
243  This data will only be used if you specify a post operation when you call
244  createInputStream().
245  */
246  URL withPOSTData (const String& postData) const;
247 
248  /** Returns a copy of this URL, with a block of data to send as the POST data.
249 
250  If you're setting the POST data, be careful not to have any parameters set
251  as well, otherwise it'll all get thrown in together, and might not have the
252  desired effect.
253 
254  If the URL already contains some POST data, this will replace it, rather
255  than being appended to it.
256 
257  This data will only be used if you specify a post operation when you call
258  createInputStream().
259  */
260  URL withPOSTData (const MemoryBlock& postData) const;
261 
262  /** Returns the data that was set using withPOSTData(). */
263  String getPostData() const noexcept { return postData.toString(); }
264 
265  /** Returns the data that was set using withPOSTData() as MemoryBlock. */
266  const MemoryBlock& getPostDataAsMemoryBlock() const noexcept { return postData; }
267 
268  //==============================================================================
269  /** Tries to launch the system's default browser to open the URL.
270  Returns true if this seems to have worked.
271  */
272  bool launchInDefaultBrowser() const;
273 
274  //==============================================================================
275  /** Takes a guess as to whether a string might be a valid website address.
276  This isn't foolproof!
277  */
278  static bool isProbablyAWebsiteURL (const String& possibleURL);
279 
280  /** Takes a guess as to whether a string might be a valid email address.
281  This isn't foolproof!
282  */
283  static bool isProbablyAnEmailAddress (const String& possibleEmailAddress);
284 
285  //==============================================================================
286  /** This callback function can be used by the createInputStream() method.
287 
288  It allows your app to receive progress updates during a lengthy POST operation. If you
289  want to continue the operation, this should return true, or false to abort.
290  */
291  using OpenStreamProgressCallback = bool (void* context, int bytesSent, int totalBytes);
292 
293  /** Attempts to open a stream that can read from this URL.
294 
295  Note that this method will block until the first byte of data has been received or an
296  error has occurred.
297 
298  Note that on some platforms (Android, for example) it's not permitted to do any network
299  action from the message thread, so you must only call it from a background thread.
300 
301  Unless the URL represents a local file, this method returns an instance of a
302  WebInputStream. You can use dynamic_cast to cast the return value to a WebInputStream
303  which allows you more fine-grained control of the transfer process.
304 
305  If the URL represents a local file, then this method simply returns a FileInputStream.
306 
307  @param doPostLikeRequest if true, the parameters added to this class will be transferred
308  via the HTTP headers which is typical for POST requests. Otherwise
309  the parameters will be added to the URL address. Additionally,
310  if the parameter httpRequestCmd is not specified (or empty) then this
311  parameter will determine which HTTP request command will be used
312  (POST or GET).
313  @param progressCallback if this is not a nullptr, it lets you supply a callback function
314  to keep track of the operation's progress. This can be useful
315  for lengthy POST operations, so that you can provide user feedback.
316  @param progressCallbackContext if a callback is specified, this value will be passed to
317  the function
318  @param extraHeaders if not empty, this string is appended onto the headers that
319  are used for the request. It must therefore be a valid set of HTML
320  header directives, separated by newlines.
321  @param connectionTimeOutMs if 0, this will use whatever default setting the OS chooses. If
322  a negative number, it will be infinite. Otherwise it specifies a
323  time in milliseconds.
324  @param responseHeaders if this is non-null, all the (key, value) pairs received as headers
325  in the response will be stored in this array
326  @param statusCode if this is non-null, it will get set to the http status code, if one
327  is known, or 0 if a code isn't available
328  @param numRedirectsToFollow specifies the number of redirects that will be followed before
329  returning a response (ignored for Android which follows up to 5 redirects)
330  @param httpRequestCmd Specify which HTTP Request to use. If this is empty, then doPostRequest
331  will determine the HTTP request.
332  @returns an input stream that the caller must delete, or a null pointer if there was an
333  error trying to open it.
334  */
335  InputStream* createInputStream (bool doPostLikeRequest,
336  OpenStreamProgressCallback* progressCallback = nullptr,
337  void* progressCallbackContext = nullptr,
338  String extraHeaders = String(),
339  int connectionTimeOutMs = 0,
340  StringPairArray* responseHeaders = nullptr,
341  int* statusCode = nullptr,
342  int numRedirectsToFollow = 5,
343  String httpRequestCmd = String()) const;
344 
345  /** Attempts to open an output stream to a URL for writing
346 
347  This method can only be used for certain scheme types such as local files
348  and content:// URIs on Android.
349  */
350  OutputStream* createOutputStream() const;
351 
352  //==============================================================================
353  /** Represents a download task.
354  Returned by downloadToFile to allow querying and controlling the download task.
355  */
357  {
358  public:
359  /** Used to receive callbacks for download progress */
361  {
362  virtual ~Listener();
363 
364  /** Called when the download has finished. Be aware that this callback may
365  come on an arbitrary thread. */
366  virtual void finished (URL::DownloadTask* task, bool success) = 0;
367 
368  /** Called periodically by the OS to indicate download progress.
369  Beware that this callback may come on an arbitrary thread.
370  */
371  virtual void progress (URL::DownloadTask* task, int64 bytesDownloaded, int64 totalLength);
372  };
373 
374  /** Releases the resources of the download task, unregisters the listener
375  and cancels the download if necessary. */
376  virtual ~DownloadTask();
377 
378  /** Returns the total length of the download task. This may return -1 if the length
379  was not returned by the server. */
380  int64 getTotalLength() const { return contentLength; }
381 
382  /** Returns the number of bytes that have been downloaded so far. */
383  int64 getLengthDownloaded() const { return downloaded; }
384 
385  /** Returns true if the download finished or there was an error. */
386  bool isFinished() const { return finished; }
387 
388  /** Returns the status code of the server's response.
389  This will only be valid after the download has finished.
390  @see isFinished
391  */
392  int statusCode() const { return httpCode; }
393 
394  /** Returns true if there was an error. */
395  inline bool hadError() const { return error; }
396 
397  /** Returns the target file location that was provided in URL::downloadToFile. */
398  File getTargetLocation() const { return targetLocation; }
399 
400  protected:
401  int64 contentLength = -1, downloaded = 0;
402  bool finished = false, error = false;
403  int httpCode = -1;
404  File targetLocation;
405 
406  DownloadTask();
407 
408  private:
409  friend class URL;
410  static DownloadTask* createFallbackDownloader (const URL&, const File&, const String&, Listener*, bool);
411 
412  public:
413  #if JUCE_IOS
414  /** internal **/
415  static void juce_iosURLSessionNotify (const String&);
416  #endif
417 
418  private:
419  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (DownloadTask)
420  };
421 
422  /** Download the URL to a file.
423 
424  This method attempts to download the URL to a given file location.
425 
426  Using this method to download files on mobile is less flexible but more reliable
427  than using createInputStream or WebInputStreams as it will attempt to download the file
428  using a native OS background network task. Such tasks automatically deal with
429  network re-connections and continuing your download while your app is suspended.
430  */
431  DownloadTask* downloadToFile (const File& targetLocation,
432  String extraHeaders = String(),
433  DownloadTask::Listener* listener = nullptr,
434  bool usePostCommand = false);
435 
436  //==============================================================================
437  /** Tries to download the entire contents of this URL into a binary data block.
438 
439  If it succeeds, this will return true and append the data it read onto the end
440  of the memory block.
441 
442  Note that on some platforms (Android, for example) it's not permitted to do any network
443  action from the message thread, so you must only call it from a background thread.
444 
445  @param destData the memory block to append the new data to
446  @param usePostCommand whether to use a POST command to get the data (uses
447  a GET command if this is false)
448  @see readEntireTextStream, readEntireXmlStream
449  */
450  bool readEntireBinaryStream (MemoryBlock& destData,
451  bool usePostCommand = false) const;
452 
453  /** Tries to download the entire contents of this URL as a string.
454 
455  If it fails, this will return an empty string, otherwise it will return the
456  contents of the downloaded file. If you need to distinguish between a read
457  operation that fails and one that returns an empty string, you'll need to use
458  a different method, such as readEntireBinaryStream().
459 
460  Note that on some platforms (Android, for example) it's not permitted to do any network
461  action from the message thread, so you must only call it from a background thread.
462 
463  @param usePostCommand whether to use a POST command to get the data (uses
464  a GET command if this is false)
465  @see readEntireBinaryStream, readEntireXmlStream
466  */
467  String readEntireTextStream (bool usePostCommand = false) const;
468 
469  /** Tries to download the entire contents of this URL and parse it as XML.
470 
471  If it fails, or if the text that it reads can't be parsed as XML, this will
472  return nullptr.
473 
474  When it returns a valid XmlElement object, the caller is responsible for deleting
475  this object when no longer needed.
476 
477  Note that on some platforms (Android, for example) it's not permitted to do any network
478  action from the message thread, so you must only call it from a background thread.
479 
480  @param usePostCommand whether to use a POST command to get the data (uses
481  a GET command if this is false)
482 
483  @see readEntireBinaryStream, readEntireTextStream
484  */
485  XmlElement* readEntireXmlStream (bool usePostCommand = false) const;
486 
487  //==============================================================================
488  /** Adds escape sequences to a string to encode any characters that aren't
489  legal in a URL.
490 
491  E.g. any spaces will be replaced with "%20".
492 
493  This is the opposite of removeEscapeChars().
494 
495  @param stringToAddEscapeCharsTo The string to escape.
496  @param isParameter If true then the string is going to be
497  used as a parameter, so it also encodes
498  '$' and ',' (which would otherwise be
499  legal in a URL.
500  @param roundBracketsAreLegal Technically round brackets are ok in URLs,
501  however, some servers (like AWS) also want
502  round brackets to be escaped.
503 
504  @see removeEscapeChars
505  */
506  static String addEscapeChars (const String& stringToAddEscapeCharsTo,
507  bool isParameter,
508  bool roundBracketsAreLegal = true);
509 
510  /** Replaces any escape character sequences in a string with their original
511  character codes.
512 
513  E.g. any instances of "%20" will be replaced by a space.
514 
515  This is the opposite of addEscapeChars().
516 
517  @see addEscapeChars
518  */
519  static String removeEscapeChars (const String& stringToRemoveEscapeCharsFrom);
520 
521  /** Returns a URL without attempting to remove any embedded parameters from the string.
522  This may be necessary if you need to create a request that involves both POST
523  parameters and parameters which are embedded in the URL address itself.
524  */
525  static URL createWithoutParsing (const String& url);
526 
527 private:
528  //==============================================================================
529  friend class WebInputStream;
530 
531  String url;
532  MemoryBlock postData;
533  StringArray parameterNames, parameterValues;
534 
535  static File fileFromFileSchemeURL (const URL&);
536  String getDomainInternal (bool) const;
537 
538  struct Upload : public ReferenceCountedObject
539  {
540  Upload (const String&, const String&, const String&, const File&, MemoryBlock*);
541  String parameterName, filename, mimeType;
542  File file;
543  std::unique_ptr<MemoryBlock> data;
544 
545  JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (Upload)
546  };
547 
548  ReferenceCountedArray<Upload> filesToUpload;
549 
550  #if JUCE_IOS
551  struct Bookmark : public ReferenceCountedObject
552  {
554 
555  Bookmark (void*);
556  ~Bookmark();
557 
558  void* data;
559  };
560 
561  Bookmark::Ptr bookmark;
562 
563  friend void setURLBookmark (URL&, void*);
564  friend void* getURLBookmark (URL&);
565  #endif
566 
567  URL (const String&, int);
568  void init();
569  void addParameter (const String&, const String&);
570  void createHeadersAndPostData (String&, MemoryBlock&) const;
571  URL withUpload (Upload*) const;
572 
573  JUCE_LEAK_DETECTOR (URL)
574 };
575 
576 } // namespace juce
577 
578 /** @}*/
int statusCode() const
Returns the status code of the server&#39;s response.
Definition: juce_URL.h:392
#define JUCE_API
This macro is added to all JUCE public class declarations.
Represents a download task.
Definition: juce_URL.h:356
const StringArray & getParameterValues() const noexcept
Returns an array of the values of all the URL&#39;s parameters.
Definition: juce_URL.h:232
The base class for streams that read data.
Used to build a tree of elements representing an XML document.
A special array for holding a list of strings.
The JUCE String class!
Definition: juce_String.h:42
An InputStream which can be used to read from a given url.
bool hadError() const
Returns true if there was an error.
Definition: juce_URL.h:395
String toString() const
Attempts to parse the contents of the block as a zero-terminated UTF8 string.
const StringArray & getParameterNames() const noexcept
Returns an array of the names of all the URL&#39;s parameters.
Definition: juce_URL.h:218
Represents a local file or directory.
Definition: juce_File.h:44
The base class for streams that write data to some kind of destination.
bool isFinished() const
Returns true if the download finished or there was an error.
Definition: juce_URL.h:386
int64 getTotalLength() const
Returns the total length of the download task.
Definition: juce_URL.h:380
int64 getLengthDownloaded() const
Returns the number of bytes that have been downloaded so far.
Definition: juce_URL.h:383
File getTargetLocation() const
Returns the target file location that was provided in URL::downloadToFile.
Definition: juce_URL.h:398
const MemoryBlock & getPostDataAsMemoryBlock() const noexcept
Returns the data that was set using withPOSTData() as MemoryBlock.
Definition: juce_URL.h:266
A container for holding a set of strings which are keyed by another string.
Used to receive callbacks for download progress.
Definition: juce_URL.h:360
A base class which provides methods for reference-counting.
A class to hold a resizable block of raw data.
String getPostData() const noexcept
Returns the data that was set using withPOSTData().
Definition: juce_URL.h:263
bool(void *context, int bytesSent, int totalBytes) OpenStreamProgressCallback
This callback function can be used by the createInputStream() method.
Definition: juce_URL.h:291
Represents a URL and has a bunch of useful functions to manipulate it.
Definition: juce_URL.h:41