jellyfin-server/Jellyfin.Server/SocketSharp/WebSocketSharpResponse.cs

182 lines
5.0 KiB
C#
Raw Normal View History

using System;
2016-06-19 16:53:43 +00:00
using System.Collections.Generic;
2014-07-19 01:28:40 +00:00
using System.IO;
using System.Net;
2019-01-01 15:27:11 +00:00
using System.Net.Sockets;
2016-11-08 18:44:23 +00:00
using System.Text;
2017-03-12 19:27:26 +00:00
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Model.IO;
2017-05-09 18:51:26 +00:00
using MediaBrowser.Model.Services;
2019-01-01 15:27:11 +00:00
using Microsoft.Extensions.Logging;
2015-01-03 19:38:22 +00:00
using HttpListenerResponse = SocketHttpListener.Net.HttpListenerResponse;
2016-10-25 19:02:04 +00:00
using IHttpResponse = MediaBrowser.Model.Services.IHttpResponse;
using IRequest = MediaBrowser.Model.Services.IRequest;
2014-07-19 01:28:40 +00:00
namespace Jellyfin.Server.SocketSharp
2014-07-19 01:28:40 +00:00
{
public class WebSocketSharpResponse : IHttpResponse
{
private readonly ILogger _logger;
2019-02-13 17:55:23 +00:00
2016-10-25 19:02:04 +00:00
private readonly HttpListenerResponse _response;
2014-07-19 01:28:40 +00:00
2016-06-19 16:53:43 +00:00
public WebSocketSharpResponse(ILogger logger, HttpListenerResponse response, IRequest request)
2014-07-19 01:28:40 +00:00
{
_logger = logger;
2016-10-25 19:02:04 +00:00
this._response = response;
2016-06-19 16:53:43 +00:00
Items = new Dictionary<string, object>();
Request = request;
2014-07-19 01:28:40 +00:00
}
2016-06-19 16:53:43 +00:00
public IRequest Request { get; private set; }
2019-02-13 17:55:23 +00:00
2016-06-19 16:53:43 +00:00
public Dictionary<string, object> Items { get; private set; }
2019-02-13 17:55:23 +00:00
public object OriginalResponse => _response;
2014-07-19 01:28:40 +00:00
public int StatusCode
{
get => this._response.StatusCode;
set => this._response.StatusCode = value;
2014-07-19 01:28:40 +00:00
}
public string StatusDescription
{
get => this._response.StatusDescription;
set => this._response.StatusDescription = value;
2014-07-19 01:28:40 +00:00
}
public string ContentType
{
get => _response.ContentType;
set => _response.ContentType = value;
2014-07-19 01:28:40 +00:00
}
2019-02-13 17:55:23 +00:00
public QueryParamCollection Headers => _response.Headers;
2014-07-19 01:28:40 +00:00
2019-02-16 10:37:25 +00:00
private static string AsHeaderValue(Cookie cookie)
{
DateTime defaultExpires = DateTime.MinValue;
var path = cookie.Expires == defaultExpires
? "/"
: cookie.Path ?? "/";
var sb = new StringBuilder();
sb.Append($"{cookie.Name}={cookie.Value};path={path}");
if (cookie.Expires != defaultExpires)
{
sb.Append($";expires={cookie.Expires:R}");
}
if (!string.IsNullOrEmpty(cookie.Domain))
{
sb.Append($";domain={cookie.Domain}");
}
if (cookie.Secure)
{
sb.Append(";Secure");
}
if (cookie.HttpOnly)
{
sb.Append(";HttpOnly");
}
return sb.ToString();
}
2014-07-19 01:28:40 +00:00
public void AddHeader(string name, string value)
{
if (string.Equals(name, "Content-Type", StringComparison.OrdinalIgnoreCase))
{
ContentType = value;
return;
}
2016-10-25 19:02:04 +00:00
_response.AddHeader(name, value);
2014-07-19 01:28:40 +00:00
}
2016-06-19 16:53:43 +00:00
public string GetHeader(string name)
{
2016-10-25 19:02:04 +00:00
return _response.Headers[name];
2016-06-19 16:53:43 +00:00
}
2014-07-19 01:28:40 +00:00
public void Redirect(string url)
{
2016-10-25 19:02:04 +00:00
_response.Redirect(url);
2014-07-19 01:28:40 +00:00
}
public Stream OutputStream => _response.OutputStream;
2014-07-19 01:28:40 +00:00
public void Close()
{
if (!this.IsClosed)
{
this.IsClosed = true;
try
{
2018-09-12 17:26:21 +00:00
var response = this._response;
var outputStream = response.OutputStream;
// This is needed with compression
outputStream.Flush();
outputStream.Dispose();
response.Close();
}
catch (SocketException)
{
2014-07-19 01:28:40 +00:00
}
catch (Exception ex)
{
2018-12-20 12:11:26 +00:00
_logger.LogError(ex, "Error in HttpListenerResponseWrapper");
2014-07-19 01:28:40 +00:00
}
}
}
public bool IsClosed
{
get;
private set;
}
public void SetContentLength(long contentLength)
{
// you can happily set the Content-Length header in Asp.Net
// but HttpListener will complain if you do - you have to set ContentLength64 on the response.
// workaround: HttpListener throws "The parameter is incorrect" exceptions when we try to set the Content-Length header
2016-10-25 19:02:04 +00:00
_response.ContentLength64 = contentLength;
2014-07-19 01:28:40 +00:00
}
public void SetCookie(Cookie cookie)
{
2016-11-08 18:44:23 +00:00
var cookieStr = AsHeaderValue(cookie);
_response.Headers.Add("Set-Cookie", cookieStr);
}
2014-07-19 01:28:40 +00:00
public bool SendChunked
{
get => _response.SendChunked;
set => _response.SendChunked = value;
2014-07-19 01:28:40 +00:00
}
2014-11-15 15:51:49 +00:00
public bool KeepAlive { get; set; }
2016-06-19 16:53:43 +00:00
public void ClearCookies()
{
}
2017-03-12 19:27:26 +00:00
2017-03-13 04:08:23 +00:00
public Task TransmitFile(string path, long offset, long count, FileShareMode fileShareMode, CancellationToken cancellationToken)
2017-03-12 19:27:26 +00:00
{
2017-03-13 04:08:23 +00:00
return _response.TransmitFile(path, offset, count, fileShareMode, cancellationToken);
2017-03-12 19:27:26 +00:00
}
2014-07-19 01:28:40 +00:00
}
}