FileConnection.cs 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311
  1. using System;
  2. using System.Collections.Generic;
  3. #if NETFX_CORE
  4. using FileStream = BestHTTP.PlatformSupport.IO.FileStream;
  5. using FileMode = BestHTTP.PlatformSupport.IO.FileMode;
  6. using FileAccess = BestHTTP.PlatformSupport.IO.FileAccess;
  7. using Directory = BestHTTP.PlatformSupport.IO.Directory;
  8. using File = BestHTTP.PlatformSupport.IO.File;
  9. #else
  10. using FileStream = System.IO.FileStream;
  11. using FileMode = System.IO.FileMode;
  12. using FileAccess = System.IO.FileAccess;
  13. #endif
  14. using BestHTTP.Extensions;
  15. namespace BestHTTP
  16. {
  17. public sealed class StreamList : System.IO.Stream
  18. {
  19. private System.IO.Stream[] Streams;
  20. private int CurrentIdx;
  21. public StreamList(params System.IO.Stream[] streams)
  22. {
  23. this.Streams = streams;
  24. this.CurrentIdx = 0;
  25. }
  26. public override bool CanRead
  27. {
  28. get {
  29. if (CurrentIdx >= Streams.Length)
  30. return false;
  31. return Streams[CurrentIdx].CanRead;
  32. }
  33. }
  34. public override bool CanSeek { get { return false; } }
  35. public override bool CanWrite
  36. {
  37. get {
  38. if (CurrentIdx >= Streams.Length)
  39. return false;
  40. return Streams[CurrentIdx].CanWrite;
  41. }
  42. }
  43. public override void Flush()
  44. {
  45. if (CurrentIdx >= Streams.Length)
  46. return;
  47. // We have to call the flush to all previous streams, as we may advanced the CurrentIdx
  48. for (int i = 0; i <= CurrentIdx; ++i)
  49. Streams[i].Flush();
  50. }
  51. public override long Length
  52. {
  53. get {
  54. if (CurrentIdx >= Streams.Length)
  55. return 0;
  56. long length = 0;
  57. for (int i = 0; i < Streams.Length; ++i)
  58. length += Streams[i].Length;
  59. return length;
  60. }
  61. }
  62. public override int Read(byte[] buffer, int offset, int count)
  63. {
  64. if (CurrentIdx >= Streams.Length)
  65. return -1;
  66. int readCount = Streams[CurrentIdx].Read(buffer, offset, count);
  67. while (readCount < count && CurrentIdx++ < Streams.Length)
  68. {
  69. readCount += Streams[CurrentIdx].Read(buffer, offset + readCount, count - readCount);
  70. }
  71. return readCount;
  72. }
  73. public override void Write(byte[] buffer, int offset, int count)
  74. {
  75. if (CurrentIdx >= Streams.Length)
  76. return;
  77. Streams[CurrentIdx].Write(buffer, offset, count);
  78. }
  79. public void Write(string str)
  80. {
  81. byte[] bytes = str.GetASCIIBytes();
  82. this.Write(bytes, 0, bytes.Length);
  83. }
  84. protected override void Dispose(bool disposing)
  85. {
  86. for (int i = 0; i < Streams.Length; ++i)
  87. {
  88. try
  89. {
  90. Streams[i].Dispose();
  91. }
  92. catch(Exception ex)
  93. {
  94. HTTPManager.Logger.Exception("StreamList", "Dispose", ex);
  95. }
  96. }
  97. }
  98. public override long Position
  99. {
  100. get
  101. {
  102. throw new NotImplementedException("Position get");
  103. }
  104. set
  105. {
  106. throw new NotImplementedException("Position set");
  107. }
  108. }
  109. public override long Seek(long offset, System.IO.SeekOrigin origin)
  110. {
  111. if (CurrentIdx >= Streams.Length)
  112. return 0;
  113. return Streams[CurrentIdx].Seek(offset, origin);
  114. }
  115. public override void SetLength(long value)
  116. {
  117. throw new NotImplementedException("SetLength");
  118. }
  119. }
  120. /*public static class AndroidFileHelper
  121. {
  122. // AndroidJavaClass jc = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
  123. // AndroidJavaObject jo = jc.GetStatic<AndroidJavaObject>("currentActivity");
  124. public static Stream GetAPKFileStream(string path)
  125. {
  126. UnityEngine.AndroidJavaClass up = new UnityEngine.AndroidJavaClass("com.unity3d.player.UnityPlayer");
  127. UnityEngine.AndroidJavaObject cActivity = up.GetStatic<UnityEngine.AndroidJavaObject>("currentActivity");
  128. UnityEngine.AndroidJavaObject assetManager = cActivity.GetStatic<UnityEngine.AndroidJavaObject>("getAssets");
  129. return new AndroidInputStream(assetManager.Call<UnityEngine.AndroidJavaObject>("open", path));
  130. }
  131. }
  132. public sealed class AndroidInputStream : Stream
  133. {
  134. private UnityEngine.AndroidJavaObject baseStream;
  135. public override bool CanRead
  136. {
  137. get { throw new NotImplementedException(); }
  138. }
  139. public override bool CanSeek
  140. {
  141. get { throw new NotImplementedException(); }
  142. }
  143. public override bool CanWrite
  144. {
  145. get { throw new NotImplementedException(); }
  146. }
  147. public override void Flush()
  148. {
  149. throw new NotImplementedException();
  150. }
  151. public override long Length
  152. {
  153. get { throw new NotImplementedException(); }
  154. }
  155. public override long Position
  156. {
  157. get
  158. {
  159. throw new NotImplementedException();
  160. }
  161. set
  162. {
  163. throw new NotImplementedException();
  164. }
  165. }
  166. public AndroidInputStream(UnityEngine.AndroidJavaObject inputStream)
  167. {
  168. this.baseStream = inputStream;
  169. }
  170. public override int Read(byte[] buffer, int offset, int count)
  171. {
  172. return this.baseStream.Call<int>("read", buffer, offset, count);
  173. }
  174. public override long Seek(long offset, SeekOrigin origin)
  175. {
  176. throw new NotImplementedException();
  177. }
  178. public override void SetLength(long value)
  179. {
  180. throw new NotImplementedException();
  181. }
  182. public override void Write(byte[] buffer, int offset, int count)
  183. {
  184. throw new NotImplementedException();
  185. }
  186. }*/
  187. internal sealed class FileConnection : ConnectionBase
  188. {
  189. public FileConnection(string serverAddress)
  190. :base(serverAddress)
  191. { }
  192. internal override void Abort(HTTPConnectionStates newState)
  193. {
  194. State = newState;
  195. switch (State)
  196. {
  197. case HTTPConnectionStates.TimedOut: TimedOutStart = DateTime.UtcNow; break;
  198. }
  199. throw new NotImplementedException();
  200. }
  201. protected override void ThreadFunc(object param)
  202. {
  203. try
  204. {
  205. // Step 1 : create a stream with header information
  206. // Step 2 : create a stream from the file
  207. // Step 3 : create a StreamList
  208. // Step 4 : create a HTTPResponse object
  209. // Step 5 : call the Receive function of the response object
  210. using (FileStream fs = new FileStream(this.CurrentRequest.CurrentUri.LocalPath, FileMode.Open, FileAccess.Read))
  211. //using (Stream fs = AndroidFileHelper.GetAPKFileStream(this.CurrentRequest.CurrentUri.LocalPath))
  212. using (StreamList stream = new StreamList(new System.IO.MemoryStream(), fs))
  213. {
  214. // This will write to the MemoryStream
  215. stream.Write("HTTP/1.1 200 Ok\r\n");
  216. stream.Write("Content-Type: application/octet-stream\r\n");
  217. stream.Write("Content-Length: " + fs.Length.ToString() + "\r\n");
  218. stream.Write("\r\n");
  219. stream.Seek(0, System.IO.SeekOrigin.Begin);
  220. base.CurrentRequest.Response = new HTTPResponse(base.CurrentRequest, stream, base.CurrentRequest.UseStreaming, false);
  221. if (!CurrentRequest.Response.Receive())
  222. CurrentRequest.Response = null;
  223. }
  224. }
  225. catch(Exception ex)
  226. {
  227. if (CurrentRequest != null)
  228. {
  229. // Something gone bad, Response must be null!
  230. CurrentRequest.Response = null;
  231. switch (State)
  232. {
  233. case HTTPConnectionStates.AbortRequested:
  234. CurrentRequest.State = HTTPRequestStates.Aborted;
  235. break;
  236. case HTTPConnectionStates.TimedOut:
  237. CurrentRequest.State = HTTPRequestStates.TimedOut;
  238. break;
  239. default:
  240. CurrentRequest.Exception = ex;
  241. CurrentRequest.State = HTTPRequestStates.Error;
  242. break;
  243. }
  244. }
  245. }
  246. finally
  247. {
  248. State = HTTPConnectionStates.Closed;
  249. if (CurrentRequest.State == HTTPRequestStates.Processing)
  250. {
  251. if (CurrentRequest.Response != null)
  252. CurrentRequest.State = HTTPRequestStates.Finished;
  253. else
  254. CurrentRequest.State = HTTPRequestStates.Error;
  255. }
  256. }
  257. }
  258. }
  259. }