/// <summary> /// Applies new fragment received from client to the upload session. /// Returns a boolean: is the new fragment last in session /// </summary> /// <param name="file_total_length"></param> /// <param name="range_start"></param> /// <param name="range_end"></param> /// <param name="data"></param> /// <returns></returns> public async Task <bool> AddFragment(long file_total_length, long range_start, long range_end, byte[] data) { // check if fragment size exceeds server limit if (range_end - range_start > _fragmentSizeLimit) { throw new Bits.FragmentTooLarge(range_end - range_start); } // case new fragment is the first fragment in this session if (_expectedFileLength == -1) { _expectedFileLength = file_total_length; } if (LastRangeEnd + 1 < range_start) // case new fragment's range is not contiguous with the previous fragment, will cause the server to respond with status code 416 { throw new Bits.InvalidFragment(LastRangeEnd, range_start); } if (LastRangeEnd + 1 > range_start) // case new fragment partially overlaps last fragment, BITS protocol states that server should treat only the non-overlapping part { range_start = LastRangeEnd + 1; } try { if (_stream.CanSeek) { Console.WriteLine("Can seek"); } else { Console.WriteLine("Can't seek"); } } catch (Exception ex) { Console.WriteLine(ex.Message); await OpenFile(); } var stream = new PartialFileStream(_stream, range_start, range_end); await stream.WriteAsync(data, 0, (int)stream.Length, CancellationToken.None); await stream.FlushAsync(); _fragments.Add(new Fragment { RangeStart = range_start, RangeEnd = range_end }); // case new fragment is the first fragment in this session, // we write the final uploaded data to file if (range_end + 1 == _expectedFileLength) { //await _file.WriteAsync(GetFinalDataFromFragments(), 0, 0); return(true); } return(false); }
public async Task <HttpResponseMessage> Stream(string fileName, string folder = "Published") { try { DirectoryEnum directory = folder == "Uploaded" ? DirectoryEnum.Uploaded : DirectoryEnum.Published; if (!await _fileProvider.Exists(fileName, directory)) { return(new HttpResponseMessage(HttpStatusCode.NotFound)); } long totalSize = await _fileProvider.GetLengthAsync(fileName, directory); if (Request.Headers.Range != null) { return(await CreateRangeResponse(Request, fileName, "application/octet-stream")); } ContentInfo contentInfo = GetContentInfoFromRequest(Request, totalSize); if (contentInfo == null) { return(new HttpResponseMessage(HttpStatusCode.RequestedRangeNotSatisfiable)); } Stream stream = new PartialFileStream(await _fileProvider.OpenRead(fileName, directory), contentInfo.From, contentInfo.To); HttpResponseMessage httpResponse = new HttpResponseMessage { Content = new StreamContent(stream, StreamExtensions.BufferSize) }; SetResponseHeaders(httpResponse, contentInfo, totalSize, fileName); return(httpResponse); } catch (Exception e) { var errorResponse = new HttpResponseMessage(HttpStatusCode.InternalServerError) { Content = new StringContent(e.ToString()) }; return(errorResponse); } }