Ejemplo n.º 1
0
		private void DoPartialRead(string cleanUrl, URLRequestBase request,
								   ResourceResponse response)
		{
			string rangeValue = request.GetExtraHeader("Range");
			Match match = m_RangeRequestValue.Match (rangeValue);
			if (!match.Success)
			{
				response.SignalFailure();
				return;
			}

			long fileSize = new FileInfo(cleanUrl).Length;

			long startByte = long.Parse (match.Groups ["From"].Value);
			string endByteString = match.Groups ["To"].Value;
			long endByte = fileSize - 1;
			if (string.IsNullOrEmpty(endByteString))
			{
				// Clamp to a maximum chunk size
				const long MaxPartialReadSize = 16 * 1024 * 1024;
				if (endByte - startByte > MaxPartialReadSize)
				{
					endByte = startByte + MaxPartialReadSize;
				}
			}
			else
			{
				endByte = long.Parse(endByteString);
			}

			// Clamp to int.MaxValue since that's the type BinaryReader
			// allows us to read; if it could read more bytes, then we would
			// clamp the size to uint.MaxValue since ResourceResponse.GetBuffer
			// expects an uint value.
			long bufferSize = Math.Min((long)int.MaxValue,
									   endByte - startByte + 1);

			byte[] bytes = new byte[bufferSize];
			using (BinaryReader reader = new BinaryReader(
				new FileStream(cleanUrl, FileMode.Open)))
			{
				reader.BaseStream.Seek(startByte, SeekOrigin.Begin);
				reader.Read(bytes, 0, (int)bufferSize);
			}

			IntPtr buffer = response.GetBuffer((uint)bytes.Length);
			if (buffer == IntPtr.Zero)
			{
				response.SignalFailure();
				return;
			}

			Marshal.Copy(bytes, 0, buffer, bytes.Length);

			// Set required response headers
			response.SetStatus(206);
			response.SetResponseHeader("Accept-Ranges", "bytes");
			response.SetResponseHeader("Content-Range", "bytes " + startByte +
									   "-" + endByte + "/" + fileSize);
			response.SetResponseHeader("Content-Length",
									   bufferSize.ToString());

			response.SignalSuccess();
		}