2016-11-10 20:29:51 -07:00
|
|
|
|
using System;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using System.Net.Security;
|
|
|
|
|
using System.Net.Sockets;
|
|
|
|
|
using System.Security.Cryptography.X509Certificates;
|
2017-05-24 12:12:55 -07:00
|
|
|
|
using System.Threading;
|
2016-11-10 20:29:51 -07:00
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
|
using Emby.Common.Implementations.Net;
|
|
|
|
|
using Emby.Server.Implementations.HttpServer;
|
|
|
|
|
using MediaBrowser.Common.Net;
|
|
|
|
|
using MediaBrowser.Controller;
|
|
|
|
|
using MediaBrowser.Controller.Configuration;
|
|
|
|
|
using MediaBrowser.Controller.Net;
|
|
|
|
|
using MediaBrowser.Model.Cryptography;
|
|
|
|
|
using MediaBrowser.Model.IO;
|
|
|
|
|
using MediaBrowser.Model.Logging;
|
|
|
|
|
using MediaBrowser.Model.Net;
|
|
|
|
|
using MediaBrowser.Model.Serialization;
|
|
|
|
|
using MediaBrowser.Model.System;
|
|
|
|
|
using MediaBrowser.Model.Text;
|
|
|
|
|
using ServiceStack.Text.Jsv;
|
|
|
|
|
using SocketHttpListener.Primitives;
|
|
|
|
|
|
2016-11-11 10:33:10 -07:00
|
|
|
|
namespace Emby.Server.Core
|
2016-11-10 20:29:51 -07:00
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Class ServerFactory
|
|
|
|
|
/// </summary>
|
|
|
|
|
public static class HttpServerFactory
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Creates the server.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <returns>IHttpServer.</returns>
|
|
|
|
|
public static IHttpServer CreateServer(IServerApplicationHost applicationHost,
|
|
|
|
|
ILogManager logManager,
|
2017-05-24 12:12:55 -07:00
|
|
|
|
IServerConfigurationManager config,
|
2016-11-10 20:29:51 -07:00
|
|
|
|
INetworkManager networkmanager,
|
|
|
|
|
IMemoryStreamFactory streamProvider,
|
2017-05-24 12:12:55 -07:00
|
|
|
|
string serverName,
|
2016-11-10 20:29:51 -07:00
|
|
|
|
string defaultRedirectpath,
|
|
|
|
|
ITextEncoding textEncoding,
|
|
|
|
|
ISocketFactory socketFactory,
|
|
|
|
|
ICryptoProvider cryptoProvider,
|
|
|
|
|
IJsonSerializer json,
|
|
|
|
|
IXmlSerializer xml,
|
|
|
|
|
IEnvironmentInfo environment,
|
2016-11-18 22:52:49 -07:00
|
|
|
|
ICertificate certificate,
|
2017-03-12 12:27:26 -07:00
|
|
|
|
IFileSystem fileSystem,
|
2016-11-18 22:52:49 -07:00
|
|
|
|
bool enableDualModeSockets)
|
2016-11-10 20:29:51 -07:00
|
|
|
|
{
|
|
|
|
|
var logger = logManager.GetLogger("HttpServer");
|
|
|
|
|
|
|
|
|
|
return new HttpListenerHost(applicationHost,
|
2017-05-24 12:12:55 -07:00
|
|
|
|
logger,
|
|
|
|
|
config,
|
|
|
|
|
serverName,
|
|
|
|
|
defaultRedirectpath,
|
|
|
|
|
networkmanager,
|
|
|
|
|
streamProvider,
|
|
|
|
|
textEncoding,
|
|
|
|
|
socketFactory,
|
|
|
|
|
cryptoProvider,
|
|
|
|
|
json,
|
2016-11-10 20:29:51 -07:00
|
|
|
|
xml,
|
|
|
|
|
environment,
|
|
|
|
|
certificate,
|
|
|
|
|
new StreamFactory(),
|
2016-11-18 22:52:49 -07:00
|
|
|
|
GetParseFn,
|
2017-03-12 12:27:26 -07:00
|
|
|
|
enableDualModeSockets,
|
|
|
|
|
fileSystem);
|
2016-11-10 20:29:51 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static Func<string, object> GetParseFn(Type propertyType)
|
|
|
|
|
{
|
|
|
|
|
return s => JsvReader.GetParseFn(propertyType)(s);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class StreamFactory : IStreamFactory
|
|
|
|
|
{
|
2017-03-02 13:50:09 -07:00
|
|
|
|
public Stream CreateNetworkStream(IAcceptSocket acceptSocket, bool ownsSocket)
|
2016-11-10 20:29:51 -07:00
|
|
|
|
{
|
2017-03-02 13:50:09 -07:00
|
|
|
|
var netSocket = (NetAcceptSocket)acceptSocket;
|
2016-11-10 20:29:51 -07:00
|
|
|
|
|
2017-05-24 12:12:55 -07:00
|
|
|
|
return new WritableNetworkStream(netSocket.Socket, ownsSocket);
|
2016-11-10 20:29:51 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Task AuthenticateSslStreamAsServer(Stream stream, ICertificate certificate)
|
|
|
|
|
{
|
|
|
|
|
var sslStream = (SslStream)stream;
|
|
|
|
|
var cert = (Certificate)certificate;
|
|
|
|
|
|
|
|
|
|
return sslStream.AuthenticateAsServerAsync(cert.X509Certificate);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public Stream CreateSslStream(Stream innerStream, bool leaveInnerStreamOpen)
|
|
|
|
|
{
|
|
|
|
|
return new SslStream(innerStream, leaveInnerStreamOpen);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public class Certificate : ICertificate
|
|
|
|
|
{
|
|
|
|
|
public Certificate(X509Certificate x509Certificate)
|
|
|
|
|
{
|
|
|
|
|
X509Certificate = x509Certificate;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public X509Certificate X509Certificate { get; private set; }
|
|
|
|
|
}
|
2017-05-24 12:12:55 -07:00
|
|
|
|
|
|
|
|
|
public class WritableNetworkStream : Stream
|
|
|
|
|
{
|
|
|
|
|
private readonly Socket _socket;
|
|
|
|
|
|
|
|
|
|
public WritableNetworkStream(Socket socket, bool ownsSocket)
|
|
|
|
|
{
|
|
|
|
|
_socket = socket;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Flush()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override bool CanRead
|
|
|
|
|
{
|
|
|
|
|
get { return true; }
|
|
|
|
|
}
|
|
|
|
|
public override bool CanSeek
|
|
|
|
|
{
|
|
|
|
|
get { return false; }
|
|
|
|
|
}
|
|
|
|
|
public override bool CanWrite
|
|
|
|
|
{
|
|
|
|
|
get { return true; }
|
|
|
|
|
}
|
|
|
|
|
public override long Length
|
|
|
|
|
{
|
|
|
|
|
get { throw new NotImplementedException(); }
|
|
|
|
|
}
|
|
|
|
|
public override long Position
|
|
|
|
|
{
|
|
|
|
|
get { throw new NotImplementedException(); }
|
|
|
|
|
set { throw new NotImplementedException(); }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void Write(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
|
|
|
|
_socket.Send(buffer, offset, count, SocketFlags.None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override IAsyncResult BeginWrite(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
|
|
|
|
{
|
|
|
|
|
return _socket.BeginSend(buffer, offset, count, SocketFlags.None, callback, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void EndWrite(IAsyncResult asyncResult)
|
|
|
|
|
{
|
|
|
|
|
_socket.EndSend(asyncResult);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override void SetLength(long value)
|
|
|
|
|
{
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override long Seek(long offset, SeekOrigin origin)
|
|
|
|
|
{
|
|
|
|
|
throw new NotImplementedException();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int Read(byte[] buffer, int offset, int count)
|
|
|
|
|
{
|
|
|
|
|
return _socket.Receive(buffer, offset, count, SocketFlags.None);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override IAsyncResult BeginRead(byte[] buffer, int offset, int count, AsyncCallback callback, object state)
|
|
|
|
|
{
|
|
|
|
|
return _socket.BeginReceive(buffer, offset, count, SocketFlags.None, callback, state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public override int EndRead(IAsyncResult asyncResult)
|
|
|
|
|
{
|
|
|
|
|
return _socket.EndReceive(asyncResult);
|
|
|
|
|
}
|
|
|
|
|
}
|
2016-11-10 20:29:51 -07:00
|
|
|
|
}
|