Adding support for 'k web --server kestrel'
This commit is contained in:
parent
9c7cb6a958
commit
6ac6419f4f
|
|
@ -14,6 +14,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleApp", "src\SampleApp\SampleApp.kproj", "{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleApp", "src\SampleApp\SampleApp.kproj", "{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Kestrel", "src\Kestrel\Kestrel.kproj", "{30B7617E-58EF-4382-B3EA-5B2E718CF1A6}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -32,6 +34,10 @@ Global
|
||||||
{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}.Release|Any CPU.Build.0 = Release|Any CPU
|
{2C3CB3DC-EEBF-4F52-9E1C-4F2F972E76C3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{30B7617E-58EF-4382-B3EA-5B2E718CF1A6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{30B7617E-58EF-4382-B3EA-5B2E718CF1A6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{30B7617E-58EF-4382-B3EA-5B2E718CF1A6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{30B7617E-58EF-4382-B3EA-5B2E718CF1A6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="12.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<PropertyGroup>
|
||||||
|
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">12.0</VisualStudioVersion>
|
||||||
|
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
</PropertyGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.Props" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
<PropertyGroup Label="Globals">
|
||||||
|
<ProjectGuid>30b7617e-58ef-4382-b3ea-5b2e718cf1a6</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="$(OutputType) == 'Console'">
|
||||||
|
<DebuggerFlavor>ConsoleDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="$(OutputType) == 'Web'">
|
||||||
|
<DebuggerFlavor>WebDebugger</DebuggerFlavor>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'" Label="Configuration">
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="ServerFactory.cs" />
|
||||||
|
<Compile Include="ServerInformation.cs" />
|
||||||
|
<Compile Include="ServerRequest.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="project.json" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
|
</Project>
|
||||||
|
|
@ -0,0 +1,35 @@
|
||||||
|
using Microsoft.AspNet.Hosting.Server;
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.Framework.ConfigurationModel;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
|
|
||||||
|
namespace Kestrel
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for ServerFactory
|
||||||
|
/// </summary>
|
||||||
|
public class ServerFactory : IServerFactory
|
||||||
|
{
|
||||||
|
public IServerInformation Initialize(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
var information = new ServerInformation();
|
||||||
|
information.Initialize(configuration);
|
||||||
|
return information;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IDisposable Start(IServerInformation serverInformation, Func<object, Task> application)
|
||||||
|
{
|
||||||
|
var information = (ServerInformation)serverInformation;
|
||||||
|
var engine = new KestrelEngine();
|
||||||
|
engine.Start(1);
|
||||||
|
engine.CreateServer(async frame =>
|
||||||
|
{
|
||||||
|
var request = new ServerRequest(frame);
|
||||||
|
await application.Invoke(request);
|
||||||
|
});
|
||||||
|
return engine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
using System;
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using Microsoft.Framework.ConfigurationModel;
|
||||||
|
|
||||||
|
namespace Kestrel
|
||||||
|
{
|
||||||
|
public class ServerInformation : IServerInformation
|
||||||
|
{
|
||||||
|
public void Initialize(IConfiguration configuration)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return "Kestrel";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
using Microsoft.AspNet.HttpFeature;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Kestrel
|
||||||
|
{
|
||||||
|
public class ServerRequest : IHttpRequestFeature, IHttpResponseFeature
|
||||||
|
{
|
||||||
|
Frame _frame;
|
||||||
|
string _scheme;
|
||||||
|
string _pathBase;
|
||||||
|
|
||||||
|
public ServerRequest(Frame frame)
|
||||||
|
{
|
||||||
|
_frame = frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpRequestFeature.Protocol
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.HttpVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.HttpVersion = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpRequestFeature.Scheme
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _scheme ?? "http";
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_scheme = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpRequestFeature.Method
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.Method;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.Method = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpRequestFeature.PathBase
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _pathBase ?? "";
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_pathBase = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpRequestFeature.Path
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.Path;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.Path = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpRequestFeature.QueryString
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.QueryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.QueryString = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IDictionary<string, string[]> IHttpRequestFeature.Headers
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.RequestHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.RequestHeaders = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream IHttpRequestFeature.Body
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.RequestBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.RequestBody = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int IHttpResponseFeature.StatusCode
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.StatusCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.StatusCode = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
string IHttpResponseFeature.ReasonPhrase
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.ReasonPhrase;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.ReasonPhrase = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
IDictionary<string, string[]> IHttpResponseFeature.Headers
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.ResponseHeaders;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.ResponseHeaders = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Stream IHttpResponseFeature.Body
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return _frame.ResponseBody;
|
||||||
|
}
|
||||||
|
|
||||||
|
set
|
||||||
|
{
|
||||||
|
_frame.ResponseBody = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void IHttpResponseFeature.OnSendingHeaders(Action<object> callback, object state)
|
||||||
|
{
|
||||||
|
_frame.OnSendingHeaders(callback, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
{
|
||||||
|
"version": "0.1-alpha-*",
|
||||||
|
"dependencies": {
|
||||||
|
"Microsoft.AspNet.Hosting": "0.1-*",
|
||||||
|
"Microsoft.AspNet.Server.Kestrel": "0.1-*"
|
||||||
|
},
|
||||||
|
"configurations": {
|
||||||
|
"net45": {
|
||||||
|
"dependencies": { }
|
||||||
|
},
|
||||||
|
"k10": {
|
||||||
|
"dependencies": {
|
||||||
|
"System.Runtime": "4.0.20.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,51 +0,0 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
|
||||||
|
|
||||||
using Microsoft.AspNet.HttpFeature;
|
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Summary description for CallContext
|
|
||||||
/// </summary>
|
|
||||||
public class CallContext :
|
|
||||||
IHttpRequestFeature,
|
|
||||||
IHttpResponseFeature
|
|
||||||
{
|
|
||||||
public CallContext()
|
|
||||||
{
|
|
||||||
((IHttpResponseFeature)this).StatusCode = 200;
|
|
||||||
}
|
|
||||||
|
|
||||||
Stream IHttpResponseFeature.Body { get; set; }
|
|
||||||
|
|
||||||
Stream IHttpRequestFeature.Body { get; set; }
|
|
||||||
|
|
||||||
IDictionary<string, string[]> IHttpResponseFeature.Headers { get; set; }
|
|
||||||
|
|
||||||
IDictionary<string, string[]> IHttpRequestFeature.Headers { get; set; }
|
|
||||||
|
|
||||||
string IHttpRequestFeature.Method { get; set; }
|
|
||||||
|
|
||||||
string IHttpRequestFeature.Path { get; set; }
|
|
||||||
|
|
||||||
string IHttpRequestFeature.PathBase { get; set; }
|
|
||||||
|
|
||||||
string IHttpRequestFeature.Protocol { get; set; }
|
|
||||||
|
|
||||||
string IHttpRequestFeature.QueryString { get; set; }
|
|
||||||
|
|
||||||
string IHttpResponseFeature.ReasonPhrase { get; set; }
|
|
||||||
|
|
||||||
string IHttpRequestFeature.Scheme { get; set; }
|
|
||||||
|
|
||||||
int IHttpResponseFeature.StatusCode { get; set; }
|
|
||||||
|
|
||||||
void IHttpResponseFeature.OnSendingHeaders(Action<object> callback, object state)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
|
||||||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using Microsoft.AspNet.HttpFeature;
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
@ -43,8 +43,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
public class Frame : FrameContext, IFrameControl
|
public class Frame : FrameContext, IFrameControl
|
||||||
{
|
{
|
||||||
Mode _mode;
|
|
||||||
|
|
||||||
enum Mode
|
enum Mode
|
||||||
{
|
{
|
||||||
StartLine,
|
StartLine,
|
||||||
|
|
@ -53,41 +51,43 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
Terminated,
|
Terminated,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Mode _mode;
|
||||||
private string _method;
|
|
||||||
private string _requestUri;
|
|
||||||
private string _path;
|
|
||||||
private string _queryString;
|
|
||||||
private string _httpVersion;
|
|
||||||
|
|
||||||
private readonly IDictionary<string, string[]> _requestHeaders =
|
|
||||||
new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
readonly IDictionary<string, string[]> _responseHeaders =
|
|
||||||
new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
|
||||||
|
|
||||||
private MessageBody _messageBody;
|
|
||||||
private bool _resultStarted;
|
private bool _resultStarted;
|
||||||
private bool _keepAlive;
|
private bool _keepAlive;
|
||||||
|
|
||||||
private CallContext _callContext;
|
|
||||||
/*
|
/*
|
||||||
//IDictionary<string, object> _environment;
|
//IDictionary<string, object> _environment;
|
||||||
|
|
||||||
CancellationTokenSource _cts = new CancellationTokenSource();
|
CancellationTokenSource _cts = new CancellationTokenSource();
|
||||||
*/
|
*/
|
||||||
FrameResponseStream _outputStream;
|
|
||||||
FrameRequestStream _inputStream;
|
|
||||||
FrameDuplexStream _duplexStream;
|
|
||||||
|
|
||||||
Task _upgradeTask = _completedTask;
|
List<KeyValuePair<Action<object>, object>> _onSendingHeaders;
|
||||||
static readonly Task _completedTask = Task.FromResult(0);
|
object _onSendingHeadersSync = new Object();
|
||||||
|
Stream _duplexStream;
|
||||||
|
|
||||||
public Frame(ConnectionContext context) : base(context)
|
public Frame(ConnectionContext context) : base(context)
|
||||||
{
|
{
|
||||||
FrameControl = this;
|
FrameControl = this;
|
||||||
|
StatusCode = 200;
|
||||||
|
RequestHeaders = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||||
|
ResponseHeaders = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public string Method { get; set; }
|
||||||
|
public string RequestUri { get; set; }
|
||||||
|
public string Path { get; set; }
|
||||||
|
public string QueryString { get; set; }
|
||||||
|
public string HttpVersion { get; set; }
|
||||||
|
public IDictionary<string, string[]> RequestHeaders { get; set; }
|
||||||
|
public MessageBody MessageBody { get; set; }
|
||||||
|
public Stream RequestBody { get; set; }
|
||||||
|
|
||||||
|
public int StatusCode { get; set; }
|
||||||
|
public string ReasonPhrase { get; set; }
|
||||||
|
public IDictionary<string, string[]> ResponseHeaders { get; set; }
|
||||||
|
public Stream ResponseBody { get; set; }
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
public bool LocalIntakeFin
|
public bool LocalIntakeFin
|
||||||
{
|
{
|
||||||
|
|
@ -151,12 +151,12 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Mode.MessageBody:
|
case Mode.MessageBody:
|
||||||
if (_messageBody.LocalIntakeFin)
|
if (MessageBody.LocalIntakeFin)
|
||||||
{
|
{
|
||||||
// NOTE: stop reading and resume on keepalive?
|
// NOTE: stop reading and resume on keepalive?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_messageBody.Consume();
|
MessageBody.Consume();
|
||||||
// NOTE: keep looping?
|
// NOTE: keep looping?
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -168,23 +168,53 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
private void Execute()
|
private void Execute()
|
||||||
{
|
{
|
||||||
_messageBody = MessageBody.For(
|
MessageBody = MessageBody.For(
|
||||||
_httpVersion,
|
HttpVersion,
|
||||||
_requestHeaders,
|
RequestHeaders,
|
||||||
this);
|
this);
|
||||||
_keepAlive = _messageBody.RequestKeepAlive;
|
_keepAlive = MessageBody.RequestKeepAlive;
|
||||||
_callContext = CreateCallContext();
|
RequestBody = new FrameRequestStream(MessageBody);
|
||||||
|
ResponseBody = new FrameResponseStream(this);
|
||||||
|
_duplexStream = new FrameDuplexStream(RequestBody, ResponseBody);
|
||||||
SocketInput.Free();
|
SocketInput.Free();
|
||||||
Task.Run(ExecuteAsync);
|
Task.Run(ExecuteAsync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnSendingHeaders(Action<object> callback, object state)
|
||||||
|
{
|
||||||
|
lock (_onSendingHeadersSync)
|
||||||
|
{
|
||||||
|
if (_onSendingHeaders == null)
|
||||||
|
{
|
||||||
|
_onSendingHeaders = new List<KeyValuePair<Action<object>, object>>();
|
||||||
|
}
|
||||||
|
_onSendingHeaders.Add(new KeyValuePair<Action<object>, object>(callback, state));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void FireOnSendingHeaders()
|
||||||
|
{
|
||||||
|
List<KeyValuePair<Action<object>, object>> onSendingHeaders = null;
|
||||||
|
lock (_onSendingHeadersSync)
|
||||||
|
{
|
||||||
|
onSendingHeaders = _onSendingHeaders;
|
||||||
|
_onSendingHeaders = null;
|
||||||
|
}
|
||||||
|
if (onSendingHeaders != null)
|
||||||
|
{
|
||||||
|
foreach (var entry in onSendingHeaders)
|
||||||
|
{
|
||||||
|
entry.Key.Invoke(entry.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async Task ExecuteAsync()
|
private async Task ExecuteAsync()
|
||||||
{
|
{
|
||||||
Exception error = null;
|
Exception error = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Application.Invoke(_callContext);
|
await Application.Invoke(this);
|
||||||
await _upgradeTask;
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
@ -196,77 +226,6 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private CallContext CreateCallContext()
|
|
||||||
{
|
|
||||||
_inputStream = new FrameRequestStream(_messageBody);
|
|
||||||
_outputStream = new FrameResponseStream(this);
|
|
||||||
_duplexStream = new FrameDuplexStream(_inputStream, _outputStream);
|
|
||||||
|
|
||||||
var remoteIpAddress = "127.0.0.1";
|
|
||||||
var remotePort = "0";
|
|
||||||
var localIpAddress = "127.0.0.1";
|
|
||||||
var localPort = "80";
|
|
||||||
var isLocal = false;
|
|
||||||
|
|
||||||
//if (_context.Socket != null)
|
|
||||||
//{
|
|
||||||
// var remoteEndPoint = _context.Socket.RemoteEndPoint as IPEndPoint;
|
|
||||||
// if (remoteEndPoint != null)
|
|
||||||
// {
|
|
||||||
// remoteIpAddress = remoteEndPoint.Address.ToString();
|
|
||||||
// remotePort = remoteEndPoint.Port.ToString(CultureInfo.InvariantCulture);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// var localEndPoint = _context.Socket.LocalEndPoint as IPEndPoint;
|
|
||||||
// if (localEndPoint != null)
|
|
||||||
// {
|
|
||||||
// localIpAddress = localEndPoint.Address.ToString();
|
|
||||||
// localPort = localEndPoint.Port.ToString(CultureInfo.InvariantCulture);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (remoteEndPoint != null && localEndPoint != null)
|
|
||||||
// {
|
|
||||||
// isLocal = Equals(remoteEndPoint.Address, localEndPoint.Address);
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
var callContext = new CallContext();
|
|
||||||
var request = (IHttpRequestFeature)callContext;
|
|
||||||
var response = (IHttpResponseFeature)callContext;
|
|
||||||
//var lifetime = (IHttpRequestLifetimeFeature)callContext;
|
|
||||||
request.Protocol = _httpVersion;
|
|
||||||
request.Scheme = "http";
|
|
||||||
request.Method = _method;
|
|
||||||
request.Path = _path;
|
|
||||||
request.PathBase = "";
|
|
||||||
request.QueryString = _queryString;
|
|
||||||
request.Headers = _requestHeaders;
|
|
||||||
request.Body = _inputStream;
|
|
||||||
response.Headers = _responseHeaders;
|
|
||||||
response.Body = _outputStream;
|
|
||||||
|
|
||||||
//var env = new Dictionary<string, object>();
|
|
||||||
//env["owin.Version"] = "1.0";
|
|
||||||
//env["owin.RequestProtocol"] = _httpVersion;
|
|
||||||
//env["owin.RequestScheme"] = "http";
|
|
||||||
//env["owin.RequestMethod"] = _method;
|
|
||||||
//env["owin.RequestPath"] = _path;
|
|
||||||
//env["owin.RequestPathBase"] = "";
|
|
||||||
//env["owin.RequestQueryString"] = _queryString;
|
|
||||||
//env["owin.RequestHeaders"] = _requestHeaders;
|
|
||||||
//env["owin.RequestBody"] = _inputStream;
|
|
||||||
//env["owin.ResponseHeaders"] = _responseHeaders;
|
|
||||||
//env["owin.ResponseBody"] = _outputStream;
|
|
||||||
//env["owin.CallCancelled"] = _cts.Token;
|
|
||||||
//env["opaque.Upgrade"] = (Action<IDictionary<string, object>, Func<IDictionary<string, object>, Task>>)Upgrade;
|
|
||||||
//env["opaque.Stream"] = _duplexStream;
|
|
||||||
//env["server.RemoteIpAddress"] = remoteIpAddress;
|
|
||||||
//env["server.RemotePort"] = remotePort;
|
|
||||||
//env["server.LocalIpAddress"] = localIpAddress;
|
|
||||||
//env["server.LocalPort"] = localPort;
|
|
||||||
//env["server.IsLocal"] = isLocal;
|
|
||||||
return callContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Write(ArraySegment<byte> data, Action<object> callback, object state)
|
public void Write(ArraySegment<byte> data, Action<object> callback, object state)
|
||||||
{
|
{
|
||||||
|
|
@ -279,7 +238,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
_keepAlive = false;
|
_keepAlive = false;
|
||||||
ProduceStart();
|
ProduceStart();
|
||||||
|
|
||||||
_upgradeTask = callback(_callContext);
|
// NOTE: needs changes
|
||||||
|
//_upgradeTask = callback(_callContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
byte[] _continueBytes = Encoding.ASCII.GetBytes("HTTP/1.1 100 Continue\r\n\r\n");
|
byte[] _continueBytes = Encoding.ASCII.GetBytes("HTTP/1.1 100 Continue\r\n\r\n");
|
||||||
|
|
@ -289,8 +249,8 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
if (_resultStarted) return;
|
if (_resultStarted) return;
|
||||||
|
|
||||||
string[] expect;
|
string[] expect;
|
||||||
if (_httpVersion.Equals("HTTP/1.1") &&
|
if (HttpVersion.Equals("HTTP/1.1") &&
|
||||||
_requestHeaders.TryGetValue("Expect", out expect) &&
|
RequestHeaders.TryGetValue("Expect", out expect) &&
|
||||||
(expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
|
(expect.FirstOrDefault() ?? "").Equals("100-continue", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
SocketOutput.Write(new ArraySegment<byte>(_continueBytes, 0, _continueBytes.Length), _ => { }, null);
|
SocketOutput.Write(new ArraySegment<byte>(_continueBytes, 0, _continueBytes.Length), _ => { }, null);
|
||||||
|
|
@ -300,15 +260,13 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
public void ProduceStart()
|
public void ProduceStart()
|
||||||
{
|
{
|
||||||
if (_resultStarted) return;
|
if (_resultStarted) return;
|
||||||
|
|
||||||
_resultStarted = true;
|
_resultStarted = true;
|
||||||
|
|
||||||
var response = (IHttpResponseFeature)_callContext;
|
FireOnSendingHeaders();
|
||||||
var status = ReasonPhrases.ToStatus(
|
|
||||||
response.StatusCode,
|
|
||||||
response.ReasonPhrase);
|
|
||||||
|
|
||||||
var responseHeader = CreateResponseHeader(status, _responseHeaders);
|
var status = ReasonPhrases.ToStatus(StatusCode, ReasonPhrase);
|
||||||
|
|
||||||
|
var responseHeader = CreateResponseHeader(status, ResponseHeaders);
|
||||||
SocketOutput.Write(responseHeader.Item1, x => ((IDisposable)x).Dispose(), responseHeader.Item2);
|
SocketOutput.Write(responseHeader.Item1, x => ((IDisposable)x).Dispose(), responseHeader.Item2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -325,12 +283,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
ConnectionControl.End(_keepAlive ? ProduceEndType.ConnectionKeepAlive : ProduceEndType.SocketDisconnect);
|
ConnectionControl.End(_keepAlive ? ProduceEndType.ConnectionKeepAlive : ProduceEndType.SocketDisconnect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Tuple<ArraySegment<byte>, IDisposable> CreateResponseHeader(
|
private Tuple<ArraySegment<byte>, IDisposable> CreateResponseHeader(
|
||||||
string status, IEnumerable<KeyValuePair<string, string[]>> headers)
|
string status, IEnumerable<KeyValuePair<string, string[]>> headers)
|
||||||
{
|
{
|
||||||
var writer = new MemoryPoolTextWriter(Memory);
|
var writer = new MemoryPoolTextWriter(Memory);
|
||||||
writer.Write(_httpVersion);
|
writer.Write(HttpVersion);
|
||||||
writer.Write(' ');
|
writer.Write(' ');
|
||||||
writer.Write(status);
|
writer.Write(status);
|
||||||
writer.Write('\r');
|
writer.Write('\r');
|
||||||
|
|
@ -381,11 +338,11 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
_keepAlive = false;
|
_keepAlive = false;
|
||||||
}
|
}
|
||||||
if (_keepAlive == false && hasConnection == false && _httpVersion == "HTTP/1.1")
|
if (_keepAlive == false && hasConnection == false && HttpVersion == "HTTP/1.1")
|
||||||
{
|
{
|
||||||
writer.Write("Connection: close\r\n\r\n");
|
writer.Write("Connection: close\r\n\r\n");
|
||||||
}
|
}
|
||||||
else if (_keepAlive && hasConnection == false && _httpVersion == "HTTP/1.0")
|
else if (_keepAlive && hasConnection == false && HttpVersion == "HTTP/1.0")
|
||||||
{
|
{
|
||||||
writer.Write("Connection: keep-alive\r\n\r\n");
|
writer.Write("Connection: keep-alive\r\n\r\n");
|
||||||
}
|
}
|
||||||
|
|
@ -418,19 +375,19 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("INVALID REQUEST FORMAT");
|
throw new InvalidOperationException("INVALID REQUEST FORMAT");
|
||||||
}
|
}
|
||||||
_method = GetString(remaining, 0, firstSpace);
|
Method = GetString(remaining, 0, firstSpace);
|
||||||
_requestUri = GetString(remaining, firstSpace + 1, secondSpace);
|
RequestUri = GetString(remaining, firstSpace + 1, secondSpace);
|
||||||
if (questionMark == -1)
|
if (questionMark == -1)
|
||||||
{
|
{
|
||||||
_path = _requestUri;
|
Path = RequestUri;
|
||||||
_queryString = string.Empty;
|
QueryString = string.Empty;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_path = GetString(remaining, firstSpace + 1, questionMark);
|
Path = GetString(remaining, firstSpace + 1, questionMark);
|
||||||
_queryString = GetString(remaining, questionMark, secondSpace);
|
QueryString = GetString(remaining, questionMark, secondSpace);
|
||||||
}
|
}
|
||||||
_httpVersion = GetString(remaining, secondSpace + 1, index);
|
HttpVersion = GetString(remaining, secondSpace + 1, index);
|
||||||
baton.Skip(index + 2);
|
baton.Skip(index + 2);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -540,15 +497,15 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
private void AddRequestHeader(string name, string value)
|
private void AddRequestHeader(string name, string value)
|
||||||
{
|
{
|
||||||
string[] existing;
|
string[] existing;
|
||||||
if (!_requestHeaders.TryGetValue(name, out existing) ||
|
if (!RequestHeaders.TryGetValue(name, out existing) ||
|
||||||
existing == null ||
|
existing == null ||
|
||||||
existing.Length == 0)
|
existing.Length == 0)
|
||||||
{
|
{
|
||||||
_requestHeaders[name] = new[] { value };
|
RequestHeaders[name] = new[] { value };
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_requestHeaders[name] = existing.Concat(new[] { value }).ToArray();
|
RequestHeaders[name] = existing.Concat(new[] { value }).ToArray();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
{
|
{
|
||||||
class FrameDuplexStream : Stream
|
class FrameDuplexStream : Stream
|
||||||
{
|
{
|
||||||
readonly FrameRequestStream _requestStream;
|
readonly Stream _requestStream;
|
||||||
readonly FrameResponseStream _responseStream;
|
readonly Stream _responseStream;
|
||||||
|
|
||||||
public FrameDuplexStream(FrameRequestStream requestStream, FrameResponseStream responseStream)
|
public FrameDuplexStream(Stream requestStream, Stream responseStream)
|
||||||
{
|
{
|
||||||
_requestStream = requestStream;
|
_requestStream = requestStream;
|
||||||
_responseStream = responseStream;
|
_responseStream = responseStream;
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
|
|
||||||
public KestrelThread Thread { get; set; }
|
public KestrelThread Thread { get; set; }
|
||||||
|
|
||||||
public Func<object, Task> Application { get; set; }
|
public Func<Frame, Task> Application { get; set; }
|
||||||
|
|
||||||
public IMemoryPool Memory { get; set; }
|
public IMemoryPool Memory { get; set; }
|
||||||
}
|
}
|
||||||
|
|
@ -45,10 +45,10 @@ namespace Microsoft.AspNet.Server.Kestrel.Http
|
||||||
Memory = memory;
|
Memory = memory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task StartAsync(KestrelThread thread, Func<object, Task> app)
|
public Task StartAsync(KestrelThread thread, Func<Frame, Task> application)
|
||||||
{
|
{
|
||||||
Thread = thread;
|
Thread = thread;
|
||||||
Application = app;
|
Application = application;
|
||||||
|
|
||||||
var tcs = new TaskCompletionSource<int>();
|
var tcs = new TaskCompletionSource<int>();
|
||||||
Thread.Post(OnStart, tcs);
|
Thread.Post(OnStart, tcs);
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
|
|
||||||
namespace Microsoft.AspNet.Server.Kestrel
|
namespace Microsoft.AspNet.Server.Kestrel
|
||||||
{
|
{
|
||||||
public class KestrelEngine
|
public class KestrelEngine : IDisposable
|
||||||
{
|
{
|
||||||
|
|
||||||
public KestrelEngine()
|
public KestrelEngine()
|
||||||
|
|
@ -39,7 +39,7 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Stop()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
foreach (var thread in Threads)
|
foreach (var thread in Threads)
|
||||||
{
|
{
|
||||||
|
|
@ -48,13 +48,13 @@ namespace Microsoft.AspNet.Server.Kestrel
|
||||||
Threads.Clear();
|
Threads.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IDisposable CreateServer(Func<object, Task> app)
|
public IDisposable CreateServer(Func<Frame, Task> application)
|
||||||
{
|
{
|
||||||
var listeners = new List<Listener>();
|
var listeners = new List<Listener>();
|
||||||
foreach (var thread in Threads)
|
foreach (var thread in Threads)
|
||||||
{
|
{
|
||||||
var listener = new Listener(Memory);
|
var listener = new Listener(Memory);
|
||||||
listener.StartAsync(thread, app).Wait();
|
listener.StartAsync(thread, application).Wait();
|
||||||
listeners.Add(listener);
|
listeners.Add(listener);
|
||||||
}
|
}
|
||||||
return new Disposable(() =>
|
return new Disposable(() =>
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,6 @@
|
||||||
<Content Include="project.json" />
|
<Content Include="project.json" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Http\CallContext.cs" />
|
|
||||||
<Compile Include="Http\FrameDuplexStream.cs" />
|
<Compile Include="Http\FrameDuplexStream.cs" />
|
||||||
<Compile Include="Http\FrameRequestStream.cs" />
|
<Compile Include="Http\FrameRequestStream.cs" />
|
||||||
<Compile Include="Http\FrameResponseStream.cs" />
|
<Compile Include="Http\FrameResponseStream.cs" />
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
{
|
{
|
||||||
"version": "0.1-alpha-*",
|
"version": "0.1-alpha-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Hosting": "0.1-*"
|
|
||||||
},
|
},
|
||||||
"configurations": {
|
"configurations": {
|
||||||
"net45": { },
|
"net45": { },
|
||||||
|
|
@ -13,7 +12,14 @@
|
||||||
"System.Diagnostics.TraceSource": "4.0.0.0",
|
"System.Diagnostics.TraceSource": "4.0.0.0",
|
||||||
"System.Text.Encoding": "4.0.20.0",
|
"System.Text.Encoding": "4.0.20.0",
|
||||||
"System.Threading.Tasks": "4.0.10.0",
|
"System.Threading.Tasks": "4.0.10.0",
|
||||||
"System.Diagnostics.Tracing": "4.0.10.0"
|
"System.Diagnostics.Tracing": "4.0.10.0",
|
||||||
|
"System.Collections": "4.0.0.0",
|
||||||
|
"System.IO": "4.0.0.0",
|
||||||
|
"System.Linq": "4.0.0.0",
|
||||||
|
"System.Net.Primitives": "4.0.10.0",
|
||||||
|
"System.Runtime.Extensions": "4.0.10.0",
|
||||||
|
"System.Threading": "4.0.0.0",
|
||||||
|
"System.Globalization": "4.0.10.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -1,39 +1,21 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace SampleApp
|
namespace SampleApp
|
||||||
{
|
{
|
||||||
public class Program
|
public class Program
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
private IServiceProvider _services;
|
||||||
|
|
||||||
|
public Program(IServiceProvider services)
|
||||||
{
|
{
|
||||||
var engine = new Microsoft.AspNet.Server.Kestrel.KestrelEngine();
|
_services = services;
|
||||||
engine.Start(1);
|
|
||||||
using (var server = engine.CreateServer(App))
|
|
||||||
{
|
|
||||||
Console.WriteLine("Hello World");
|
|
||||||
Console.ReadLine();
|
|
||||||
}
|
|
||||||
engine.Stop();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Main(string[] args)
|
||||||
|
|
||||||
private static async Task App(object arg)
|
|
||||||
{
|
{
|
||||||
var httpContext = new Microsoft.AspNet.PipelineCore.DefaultHttpContext(
|
new Microsoft.AspNet.Hosting.Program(_services).Main(new[] {
|
||||||
new Microsoft.AspNet.FeatureModel.FeatureCollection(
|
"--server","kestrel"
|
||||||
new Microsoft.AspNet.FeatureModel.FeatureObject(arg)));
|
});
|
||||||
|
|
||||||
Console.WriteLine("{0} {1}{2}{3}",
|
|
||||||
httpContext.Request.Method,
|
|
||||||
httpContext.Request.PathBase,
|
|
||||||
httpContext.Request.Path,
|
|
||||||
httpContext.Request.QueryString);
|
|
||||||
|
|
||||||
httpContext.Response.ContentType = "text/plain";
|
|
||||||
await httpContext.Response.WriteAsync("Hello world");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,12 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
<SchemaVersion>2.0</SchemaVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<CommandLineArguments>web</CommandLineArguments>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Program.cs" />
|
<Compile Include="Program.cs" />
|
||||||
|
<Compile Include="Startup.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Content Include="libuv.dll" />
|
<Content Include="libuv.dll" />
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
using Microsoft.AspNet.Builder;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SampleApp
|
||||||
|
{
|
||||||
|
public class Startup
|
||||||
|
{
|
||||||
|
public void Configure(IBuilder app)
|
||||||
|
{
|
||||||
|
app.Run(async context =>
|
||||||
|
{
|
||||||
|
Console.WriteLine("{0} {1}{2}{3}",
|
||||||
|
context.Request.Method,
|
||||||
|
context.Request.PathBase,
|
||||||
|
context.Request.Path,
|
||||||
|
context.Request.QueryString);
|
||||||
|
|
||||||
|
context.Response.ContentType = "text/plain";
|
||||||
|
await context.Response.WriteAsync("Hello world");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,14 +1,16 @@
|
||||||
{
|
{
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.AspNet.Server.Kestrel": "0.1-alpha-*",
|
"Kestrel": "0.1-alpha-*"
|
||||||
"Microsoft.AspNet.PipelineCore": "0.1-alpha-*"
|
|
||||||
},
|
},
|
||||||
"configurations" : {
|
"configurations": {
|
||||||
"net45" : { },
|
"net45": { },
|
||||||
"k10" : {
|
"k10": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Console": "4.0.0.0"
|
"System.Console": "4.0.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"commands": {
|
||||||
|
"web": "Microsoft.AspNet.Hosting --server kestrel"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
using Microsoft.AspNet.HttpFeature;
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
using Microsoft.AspNet.Server.Kestrel;
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
@ -15,31 +15,26 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EngineTests
|
public class EngineTests
|
||||||
{
|
{
|
||||||
private async Task App(object callContext)
|
private async Task App(Frame frame)
|
||||||
{
|
{
|
||||||
var request = callContext as IHttpRequestFeature;
|
|
||||||
var response = callContext as IHttpResponseFeature;
|
|
||||||
for (; ;)
|
for (; ;)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
var count = await request.Body.ReadAsync(buffer, 0, buffer.Length);
|
var count = await frame.RequestBody.ReadAsync(buffer, 0, buffer.Length);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
await response.Body.WriteAsync(buffer, 0, count);
|
await frame.ResponseBody.WriteAsync(buffer, 0, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private async Task AppChunked(object callContext)
|
private async Task AppChunked(Frame frame)
|
||||||
{
|
{
|
||||||
var request = callContext as IHttpRequestFeature;
|
|
||||||
var response = callContext as IHttpResponseFeature;
|
|
||||||
|
|
||||||
var data = new MemoryStream();
|
var data = new MemoryStream();
|
||||||
for (; ;)
|
for (; ;)
|
||||||
{
|
{
|
||||||
var buffer = new byte[8192];
|
var buffer = new byte[8192];
|
||||||
var count = await request.Body.ReadAsync(buffer, 0, buffer.Length);
|
var count = await frame.RequestBody.ReadAsync(buffer, 0, buffer.Length);
|
||||||
if (count == 0)
|
if (count == 0)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
|
|
@ -47,8 +42,8 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
data.Write(buffer, 0, count);
|
data.Write(buffer, 0, count);
|
||||||
}
|
}
|
||||||
var bytes = data.ToArray();
|
var bytes = data.ToArray();
|
||||||
response.Headers["Content-Length"] = new[] { bytes.Length.ToString() };
|
frame.ResponseHeaders["Content-Length"] = new[] { bytes.Length.ToString() };
|
||||||
await response.Body.WriteAsync(bytes, 0, bytes.Length);
|
await frame.ResponseBody.WriteAsync(bytes, 0, bytes.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -56,7 +51,7 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
{
|
{
|
||||||
var engine = new KestrelEngine();
|
var engine = new KestrelEngine();
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
engine.Stop();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -66,7 +61,7 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
engine.Start(1);
|
engine.Start(1);
|
||||||
var started = engine.CreateServer(App);
|
var started = engine.CreateServer(App);
|
||||||
started.Dispose();
|
started.Dispose();
|
||||||
engine.Stop();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -89,7 +84,7 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
var text = Encoding.ASCII.GetString(buffer, 0, length);
|
var text = Encoding.ASCII.GetString(buffer, 0, length);
|
||||||
}
|
}
|
||||||
started.Dispose();
|
started.Dispose();
|
||||||
engine.Stop();
|
engine.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,10 @@
|
||||||
<Compile Include="MessageBodyExchangerTests.cs" />
|
<Compile Include="MessageBodyExchangerTests.cs" />
|
||||||
<Compile Include="MessageBodyTests.cs" />
|
<Compile Include="MessageBodyTests.cs" />
|
||||||
<Compile Include="NetworkingTests.cs" />
|
<Compile Include="NetworkingTests.cs" />
|
||||||
|
<Compile Include="Program.cs" />
|
||||||
<Compile Include="TestConnection.cs" />
|
<Compile Include="TestConnection.cs" />
|
||||||
<Compile Include="TestInput.cs" />
|
<Compile Include="TestInput.cs" />
|
||||||
|
<Compile Include="TestServer.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
<Import Project="$(VSToolsPath)\AspNet\Microsoft.Web.AspNet.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||||
</Project>
|
</Project>
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Microsoft.AspNet.Server.KestralTests
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Summary description for Program
|
||||||
|
/// </summary>
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public void Main()
|
||||||
|
{
|
||||||
|
new EngineTests().Http11().Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
using Microsoft.AspNet.Server.Kestrel;
|
using Microsoft.AspNet.Server.Kestrel;
|
||||||
|
using Microsoft.AspNet.Server.Kestrel.Http;
|
||||||
using System;
|
using System;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
|
@ -12,12 +13,12 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
private KestrelEngine _engine;
|
private KestrelEngine _engine;
|
||||||
private IDisposable _server;
|
private IDisposable _server;
|
||||||
|
|
||||||
public TestServer(Func<object, Task> app)
|
public TestServer(Func<Frame, Task> app)
|
||||||
{
|
{
|
||||||
Create(app);
|
Create(app);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Create(Func<object,Task> app)
|
public void Create(Func<Frame, Task> app)
|
||||||
{
|
{
|
||||||
_engine = new KestrelEngine();
|
_engine = new KestrelEngine();
|
||||||
_engine.Start(1);
|
_engine.Start(1);
|
||||||
|
|
@ -28,7 +29,7 @@ namespace Microsoft.AspNet.Server.KestralTests
|
||||||
public void Dispose()
|
public void Dispose()
|
||||||
{
|
{
|
||||||
_server.Dispose();
|
_server.Dispose();
|
||||||
_engine.Stop();
|
_engine.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,12 +14,12 @@
|
||||||
"compilationOptions": { "define": [ "TRACE" ] },
|
"compilationOptions": { "define": [ "TRACE" ] },
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"System.Net.Sockets": "4.0.0.0",
|
"System.Net.Sockets": "4.0.0.0",
|
||||||
"System.Runtime.Handles": "4.0.0.0"
|
"System.Runtime.Handles": "4.0.0.0",
|
||||||
|
"System.IO": "4.0.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"commands": {
|
"commands": {
|
||||||
"run": "Xunit.KRunner -trait x=vs",
|
|
||||||
"test": "Xunit.KRunner"
|
"test": "Xunit.KRunner"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue