Statistics
| Branch: | Tag: | Revision:

root / Assets / Plugins / UnityHTTP / DiskCache.cs @ 9:37719e88568d

History | View | Annotate | Download (3.6 kB)

1
using UnityEngine;
2
using System.Collections;
3
using System.IO;
4
using System;
5
using HTTP;
6
7
namespace HTTP
8
{
9
	public class DiskCacheOperation
10
	{
11
		public bool isDone = false;
12
		public bool fromCache = false;
13
		public Request request = null;
14
	}
15
16
#if UNITY_WEBPLAYER
17
	public class DiskCache : MonoBehaviour
18
	{
19
		static DiskCache _instance = null;
20
		public static DiskCache Instance {
21
			get {
22
				if (_instance == null) {
23
					var g = new GameObject ("DiskCache", typeof(DiskCache));
24
					g.hideFlags = HideFlags.HideAndDontSave;
25
					_instance = g.GetComponent<DiskCache> ();
26
				}
27
				return _instance;
28
			}
29
		}
30
31
		public DiskCacheOperation Fetch (Request request)
32
		{
33
			var handle = new DiskCacheOperation ();
34
			handle.request = request;
35
			StartCoroutine (Download (request, handle));
36
			return handle;
37
		}
38
39
		IEnumerator Download(Request request, DiskCacheOperation handle)
40
		{
41
			request.Send ();
42
			while (!request.isDone)
43
				yield return new WaitForEndOfFrame ();
44
			handle.isDone = true;
45
		}
46
	}
47
#else
48
	public class DiskCache : MonoBehaviour
49
	{
50
		string cachePath = null;
51
52
		static DiskCache _instance = null;
53
		public static DiskCache Instance {
54
			get {
55
				if (_instance == null) {
56
					var g = new GameObject ("DiskCache", typeof(DiskCache));
57
					g.hideFlags = HideFlags.HideAndDontSave;
58
					_instance = g.GetComponent<DiskCache> ();
59
				}
60
				return _instance;
61
			}
62
		}
63
64
		void Awake ()
65
		{
66
			cachePath = System.IO.Path.Combine (Environment.GetFolderPath (Environment.SpecialFolder.LocalApplicationData), "uwcache");
67
			if (!Directory.Exists (cachePath))
68
				Directory.CreateDirectory (cachePath);
69
		}
70
71
		public DiskCacheOperation Fetch (Request request)
72
		{
73
			var guid = "";
74
            // MD5 is disposable
75
            // http://msdn.microsoft.com/en-us/library/system.security.cryptography.md5.aspx#3
76
            using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create ()) {
77
                foreach (var b in md5.ComputeHash (System.Text.ASCIIEncoding.ASCII.GetBytes (request.uri.ToString ()))) {
78
                    guid = guid + b.ToString ("X2");
79
                }
80
            }
81
82
			var filename = System.IO.Path.Combine (cachePath, guid);
83
			if (File.Exists (filename) && File.Exists (filename + ".etag"))
84
				request.SetHeader ("If-None-Match", File.ReadAllText (filename + ".etag"));
85
			var handle = new DiskCacheOperation ();
86
			handle.request = request;
87
			StartCoroutine (DownloadAndSave (request, filename, handle));
88
			return handle;
89
		}
90
91
		IEnumerator DownloadAndSave (Request request, string filename, DiskCacheOperation handle)
92
		{
93
			var useCachedVersion = File.Exists(filename);
94
            Action< HTTP.Request > callback = request.completedCallback;
95
			request.Send(); // will clear the completedCallback
96
			while (!request.isDone)
97
				yield return new WaitForEndOfFrame ();
98
			if (request.exception == null && request.response != null) {
99
				if (request.response.status == 200) {
100
					var etag = request.response.GetHeader ("etag");
101
					if (etag != "") {
102
						File.WriteAllBytes (filename, request.response.bytes);
103
						File.WriteAllText (filename + ".etag", etag);
104
					}
105
					useCachedVersion = false;
106
				}
107
			}
108
109
			if(useCachedVersion) {
110
				if(request.exception != null) {
111
					Debug.LogWarning("Using cached version due to exception:" + request.exception);
112
					request.exception = null;
113
				}
114
				request.response.status = 304;
115
				request.response.bytes = File.ReadAllBytes (filename);
116
				request.isDone = true;
117
			}
118
			handle.isDone = true;
119
120
            if ( callback != null )
121
            {
122
                callback( request );
123
            }
124
		}
125
126
	}
127
#endif
128
}