WebSocketSharpResponse.cs 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Runtime.InteropServices;
  5. using System.Threading;
  6. using System.Threading.Tasks;
  7. using MediaBrowser.Model.IO;
  8. using MediaBrowser.Model.Services;
  9. using Microsoft.AspNetCore.Http;
  10. using Microsoft.Extensions.Logging;
  11. using IRequest = MediaBrowser.Model.Services.IRequest;
  12. namespace Emby.Server.Implementations.SocketSharp
  13. {
  14. public class WebSocketSharpResponse : IResponse
  15. {
  16. private readonly ILogger _logger;
  17. public WebSocketSharpResponse(ILogger logger, HttpResponse response)
  18. {
  19. _logger = logger;
  20. OriginalResponse = response;
  21. }
  22. public HttpResponse OriginalResponse { get; }
  23. public int StatusCode
  24. {
  25. get => OriginalResponse.StatusCode;
  26. set => OriginalResponse.StatusCode = value;
  27. }
  28. public string StatusDescription { get; set; }
  29. public string ContentType
  30. {
  31. get => OriginalResponse.ContentType;
  32. set => OriginalResponse.ContentType = value;
  33. }
  34. public void AddHeader(string name, string value)
  35. {
  36. if (string.Equals(name, "Content-Type", StringComparison.OrdinalIgnoreCase))
  37. {
  38. ContentType = value;
  39. return;
  40. }
  41. OriginalResponse.Headers.Add(name, value);
  42. }
  43. public void Redirect(string url)
  44. {
  45. OriginalResponse.Redirect(url);
  46. }
  47. public Stream OutputStream => OriginalResponse.Body;
  48. public bool SendChunked { get; set; }
  49. const int StreamCopyToBufferSize = 81920;
  50. public async Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, IFileSystem fileSystem, IStreamHelper streamHelper, CancellationToken cancellationToken)
  51. {
  52. var allowAsync = !RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
  53. //if (count <= 0)
  54. //{
  55. // allowAsync = true;
  56. //}
  57. var fileOpenOptions = FileOpenOptions.SequentialScan;
  58. if (allowAsync)
  59. {
  60. fileOpenOptions |= FileOpenOptions.Asynchronous;
  61. }
  62. // use non-async filestream along with read due to https://github.com/dotnet/corefx/issues/6039
  63. using (var fs = fileSystem.GetFileStream(path, FileOpenMode.Open, FileAccessMode.Read, fileShareMode, fileOpenOptions))
  64. {
  65. if (offset > 0)
  66. {
  67. fs.Position = offset;
  68. }
  69. if (count > 0)
  70. {
  71. await streamHelper.CopyToAsync(fs, OutputStream, count, cancellationToken).ConfigureAwait(false);
  72. }
  73. else
  74. {
  75. await fs.CopyToAsync(OutputStream, StreamCopyToBufferSize, cancellationToken).ConfigureAwait(false);
  76. }
  77. }
  78. }
  79. }
  80. }