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