diff options
author | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
---|---|---|
committer | chai <chaifix@163.com> | 2019-08-14 22:50:43 +0800 |
commit | 15740faf9fe9fe4be08965098bbf2947e096aeeb (patch) | |
tree | a730ec236656cc8cab5b13f088adfaed6bb218fb /Runtime/Export/WWW.h |
Diffstat (limited to 'Runtime/Export/WWW.h')
-rw-r--r-- | Runtime/Export/WWW.h | 420 |
1 files changed, 420 insertions, 0 deletions
diff --git a/Runtime/Export/WWW.h b/Runtime/Export/WWW.h new file mode 100644 index 0000000..9bc48c5 --- /dev/null +++ b/Runtime/Export/WWW.h @@ -0,0 +1,420 @@ +#ifndef WWW_H +#define WWW_H + +#if ENABLE_WWW + +#if (WEBPLUG || UNITY_IPHONE || UNITY_ANDROID || UNITY_FLASH || UNITY_XENON || UNITY_PS3 || UNITY_WINRT) +#define WWW_USE_CURL 0 +#else +#define WWW_USE_CURL 1 +#endif + +#define WWW_USE_BROWSER WEBPLUG && !WWW_USE_CURL + +#if WWW_USE_CURL +#include "External/Curl/include/minimalcurl.h" +#endif + +#include <stdlib.h> +#include <string.h> +#include "Runtime/Threads/Mutex.h" +#include "Runtime/Threads/Thread.h" +#include "Runtime/Threads/AtomicRefCounter.h" +#include "Runtime/GameCode/CallDelayed.h" +#include "Runtime/Utilities/LogAssert.h" +#include "Runtime/Input/TimeManager.h" +#include "Runtime/Utilities/NonCopyable.h" + +/// The time since startup +double GetTimeSinceStartup (); + +class Thread; +class Download; +class UnityWebStream; +class AsyncCachedUnityWebStream; +class AssetBundle; +class AudioClip; + +#include <map> + +enum WWWType { + kWWWTypeCurl, + kWWWTypeBrowser, + kWWWTypeCached, + kWWWTypeCrossDomainChecked, + kWWWFlash +}; + +class WWW : private NonCopyable +{ +private: + UnityWebStream* m_UnityWebStream; + bool m_DidParseUnityWebStream; + int m_StreamingPosition; + + #if SUPPORT_REPRODUCE_LOG + int m_ReproRemapCount; + #endif + + AudioClip* m_AudioClip; + +protected: + bool m_Cached; + int m_CacheVersion; + UInt32 m_RequestedCRC; + friend class WWWCached; + + ThreadPriority m_ThreadPriority; + string m_ResponseHeaders; + void FeedUnityWebStream (bool isCompleted); + bool SetErrorFromResponseHeaders (); // Returns true when error is set, otherwise returns false + UInt32 GetEstimatedDownloadSize() const; + +public: + + class AutoLock + { + public: + AutoLock( WWW& www ) + : m_WWW(&www) + { + www.LockPartialData(); + } + + ~AutoLock() + { + m_WWW->UnlockPartialData(); + } + + private: + AutoLock(const AutoLock&); + AutoLock& operator=(const AutoLock&); + + private: + WWW* m_WWW; + }; + + enum SecurityPolicy + { + kSecurityPolicyDontKnowYet=0, + kSecurityPolicyAllowAccess=1, + kSecurityPolicyDenyAccess=2 + }; + + WWW (bool cached, int cacheVersion, UInt32 crc) + // Private members (initialized by the order of their definition) + : m_UnityWebStream(NULL) + , m_DidParseUnityWebStream(false) + , m_StreamingPosition(0) + #if SUPPORT_REPRODUCE_LOG + , m_ReproRemapCount(0) + #endif + , m_AudioClip(NULL) + + // Protected members + , m_Cached(cached) + , m_CacheVersion(cacheVersion) + , m_RequestedCRC(crc) + , m_ThreadPriority(kNormalPriority) + , m_ResponseHeaders() // Initially empty + + // Private thread-safe reference counter + , m_RefCount() + {} + + typedef std::map<std::string,std::string> WWWHeaders; + + static WWW* Create (const char* url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool crossDomainChecked = true, bool cached = false, int cacheVersion = 0, UInt32 crc = 0); + + virtual const UInt8* GetData() = 0; + virtual const UInt8* GetPartialData() const = 0; + virtual size_t GetSize() = 0; + virtual size_t GetPartialSize() const = 0; + + virtual double GetETA() const = 0; //seconds remaining until we're done. + + virtual void LockPartialData() = 0; + virtual void UnlockPartialData() = 0; + + // Returns true when the download is complete or failed. + virtual void Cancel() = 0; + bool IsDone() const; + virtual float GetProgress() const = 0; + virtual float GetUploadProgress() const = 0; + virtual const char* GetError() = 0; + virtual void SetError (const std::string& error) {} + virtual const char* GetUrl() const = 0; + virtual std::string GetResponseHeaders(); + virtual bool HasDownloadedOrMayBlock () = 0; + virtual void BlockUntilDone () = 0; + virtual SecurityPolicy GetSecurityPolicy() const; + + virtual WWWType GetType () const = 0; + + virtual UnityWebStream* GetUnityWebStream () const; + + virtual bool IsCached () const; + + void CallWhenDone(DelayedCall* func, Object* o, void* userData, CleanupUserData* cleanup); +#if SUPPORT_THREADS + ThreadPriority GetThreadPriority() const { return m_ThreadPriority; } + virtual void SetThreadPriority( ThreadPriority priority ); +#endif + + #if SUPPORT_REPRODUCE_LOG + int* GetReproRemapCount () { return &m_ReproRemapCount; } + #endif + + AudioClip* GetAudioClip() const { return m_AudioClip; } + void SetAudioClip(AudioClip* clip) { m_AudioClip = clip; } + +protected: + virtual ~WWW (); + +#if ENABLE_WEBPLAYER_SECURITY + friend class WWWCrossDomainChecked; +#endif + virtual bool IsDownloadingDone() const = 0; + +public: + /// These functions must be thread safe as they are called from the garbage collector thread + void Retain(); + void Release(); + +private: + AtomicRefCounter m_RefCount; +}; + +#if WWW_USE_BROWSER +class WWWBrowser : public WWW +{ + Download* m_Download; + std::vector<UInt8> m_Buffer; + double m_Eta; + double m_StartDownloadTime; + std::string m_Url; + std::string m_Error; + std::string m_HeadersString; + char* m_PostData; + size_t m_PostLength; + + int m_LockedPartialData; + + int GetTotalBytesUntilLoadable() const; + +public: + + WWWBrowser (const char* postDataPtr, int postDataLength, const WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc); + + virtual const UInt8* GetData(); + virtual size_t GetSize(); + + virtual bool IsDownloadingDone() const; + + virtual float GetProgress() const; + virtual float GetUploadProgress() const; + + virtual const char* GetError(); + virtual void SetError (const std::string& error); + + virtual const char* GetUrl() const; + + virtual const UInt8* GetPartialData() const; + virtual size_t GetPartialSize() const; + virtual void LockPartialData(); + virtual void UnlockPartialData(); + virtual double GetETA() const; //seconds remaining until we're done. + + virtual bool HasDownloadedOrMayBlock (); + virtual void BlockUntilDone (); + virtual void Cancel (); + + void ForceProgressDownload (); + + virtual WWWType GetType () const { return kWWWTypeBrowser; } + static int ProgressDownload(Download* download); + +public: + static WWWBrowser* CreateBrowser (const char* url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool cached, int cacheVersion, UInt32 crc); + +protected: + virtual ~WWWBrowser (); +}; +#endif // WWW_USE_BROWSER + + +#if WWW_USE_CURL + +class WWWCurl : public WWW +{ + private: + size_t alloc_size; + curl_slist* curlHeaders; + curl_slist* GetHeaderSList () ; + + Mutex mutex; + size_t size; + UInt8* data; + char* errorBuffer; + bool abortDownload; + float progress; + float uploadProgress; + unsigned totalSize; + double eta; + double startTime; + + char* postData; + int postLength; // -1 for GET requests + int postPosition; + + WWWHeaders requestHeaders; + + size_t AppendBytes(void * moreData, size_t bytes); + size_t PostBytes(void * moreData, size_t bytes); + + CURLcode GetURL( const char* url ); + + Thread thread; + char* url; + + int result; + + void DoInit( const char* in_url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers); + void Cleanup(); + + static size_t WriteCallback(void * data, size_t size, size_t elements, WWWCurl * myData); + static size_t ReadCallback(void * data, size_t size, size_t elements, WWWCurl * myData); + static size_t HeaderCallback(void * data, size_t size, size_t elements, WWWCurl * myData); + static int ProgressCallback (WWWCurl *myData, double dltotal, double dlnow, double ultotal, double ulnow); + + public: + + WWWCurl( const char* in_url, const char * in_postData, int in_postLength, const WWWHeaders& in_headers, bool cached, int cacheVersion, UInt32 crc ); + + virtual bool IsDownloadingDone() const; + virtual const UInt8* GetData(); + virtual const char* GetError(); + virtual void SetError (const std::string& error); + virtual const char* GetUrl() const; + virtual size_t GetSize(); + virtual const UInt8* GetPartialData() const; + virtual size_t GetPartialSize() const; + virtual float GetProgress() const; + virtual float GetUploadProgress() const; + virtual double GetETA() const; + + virtual void LockPartialData(); + virtual void UnlockPartialData(); + virtual bool HasDownloadedOrMayBlock (); + + virtual void Cancel (); + virtual void SetThreadPriority( ThreadPriority priority ); + void BlockUntilDone(); + + virtual WWWType GetType () const { return kWWWTypeCurl; } + virtual std::string GetResponseHeaders(); + + protected: + ~WWWCurl(); + + private: + void StartThread(); + static void* WWW_ThreadEntryPoint(void* data); + UInt32 GetEstimatedDownloadSize() const; +}; +#endif // WWW_USE_CURL + +class WWWDelayCall { + private: + WWW* m_wait_for; + DelayedCall* m_func; + Object* m_o; + void * m_userData; + CleanupUserData* m_cleanup; + public: + WWWDelayCall(WWW* www, DelayedCall* func, Object* o, void* userData, CleanupUserData* cleanup); + ~WWWDelayCall(); + static void Callback(Object* o, void* userData); + static void Cleanup(void* userData); + static bool MatchForCancel(void* callBackUserData, void* cancelUserData); +}; + +#if ENABLE_WEBPLAYER_SECURITY + +void ProcessCrossDomainRequestsFromNonMainThread(); + +class WWWCrossDomainCheckedImpl; +class WWWCrossDomainChecked : public WWW +{ +private: + const char* m_PostData; + int m_PostDataLength; + std::string m_PostDataDataCopy; + WWWHeaders m_Headers; + + WWWCrossDomainCheckedImpl* m_CrossChecker; + WWW* m_WWW; + + bool CanCreateDownloader() const; + bool RequestLooksSafeEnoughToMakeWithoutPolicyAccess() const; + void StartEmbeddedDownload(); + void BlockedStartEmbeddedDownload(); + +public: + WWWCrossDomainChecked (const char* url, const char* postData, int postDataLength, const WWWHeaders& headers, bool cached, int cacheVersion, UInt32 crc); + + virtual SecurityPolicy GetSecurityPolicy() const; + virtual UnityWebStream* GetUnityWebStream() const; + virtual const UInt8* GetData(); + virtual const UInt8* GetPartialData() const; + virtual size_t GetSize(); + virtual size_t GetPartialSize() const; + + virtual double GetETA() const; + + virtual bool IsCached () const; + + virtual void LockPartialData(); + virtual void UnlockPartialData(); + + // Returns true when the download is complete or failed. + virtual void Cancel(); + virtual bool IsDownloadingDone() const; + virtual float GetProgress() const; + virtual float GetUploadProgress() const { return 0.f; } + virtual const char* GetError(); + virtual const char* GetUrl() const; + virtual std::string GetResponseHeaders(); + virtual bool HasDownloadedOrMayBlock (); + virtual void BlockUntilDone (); + + virtual void SetThreadPriority( ThreadPriority priority ); + + virtual WWWType GetType () const { return kWWWTypeCrossDomainChecked; } + +protected: + ~WWWCrossDomainChecked (); +}; +#endif //ENABLE_WEBPLAYER_SECURITY + +// Constant error strings +extern const char* kWWWErrCustomHeadersWithGET; +extern const char* kWWWErrZeroPostData; +extern const char* kWWWErrNULLPostDataWithPositiveLength; +extern const char* kWWWErrCancelled; +extern const char* kWWWErrPostDataWithNonHTTPSchema; +extern const char* kWWWErrHeadersWithNonHTTPSchema; + +double CalculateEta (int downloadedBytes, int totalBytes, double startTime); + +const char* GetCachedWWWError(const WWW& www, std::string& err); + +#if !UNITY_FLASH + +std::string DecodeEscapedURL(const std::string& url); + +#endif + +#endif // ENABLE_WWW + +#endif // WWW_H |