├── VERSION.txt ├── src ├── .nuget │ ├── NuGet.exe │ ├── NuGet.Config │ └── NuGet.targets ├── Fix │ ├── NugetPack.cmd │ ├── IFixAdapter.cs │ ├── Body.cs │ ├── EnumerableEx.cs │ ├── TaskHelper.cs │ ├── ExceptionBody.cs │ ├── InvokeAndForget.cs │ ├── AssemblyManager.cs │ ├── Fixer.cs │ ├── OwinKeys.cs │ ├── Mapper.cs │ ├── Converter.cs │ ├── Fix40.csproj │ ├── Fix.csproj │ └── AppFuncBuilder.cs ├── Fix.AspNet │ ├── NugetPack.cmd │ ├── web.config.transform │ ├── FixHttpHandler.cs │ ├── Fix.AspNet40.csproj │ ├── Fix.AspNet.csproj │ └── Bridge.cs ├── Fix.AppBuilder │ ├── packages.config │ ├── AppBuilderAdapter.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ ├── FixAppBuilder.cs │ ├── Fix.AppBuilder40.csproj │ └── Fix.AppBuilder.csproj ├── FixConsole │ ├── app.config │ ├── Program.cs │ └── FixUp.csproj ├── SimpleNowinDemo │ ├── App.config │ ├── packages.config │ ├── Program.cs │ ├── Properties │ │ └── AssemblyInfo.cs │ └── SimpleNowinDemo.csproj ├── FileHandler │ ├── index.html │ ├── FileHandler.csproj │ └── FileReturner.cs ├── OwinHelpers │ ├── NullDisposable.cs │ ├── ExceptionBody.cs │ ├── DictionaryExtensions.cs │ ├── FileBody.cs │ ├── BodyExtensions.cs │ ├── EnvironmentExtensions.cs │ ├── ActionObserver.cs │ ├── EnumerableDictionaryExtension.cs │ ├── StringBody.cs │ ├── DelegateExtensions.cs │ ├── AsyncExtensions.cs │ ├── Body.cs │ └── OwinHelpers.csproj ├── Tests │ └── Fix.AppBuilder.Test │ │ ├── packages.config │ │ ├── Properties │ │ └── AssemblyInfo.cs │ │ ├── AppBuilderAdapterTest.cs │ │ └── Fix.AppBuilder.Test.csproj ├── packages │ └── repositories.config ├── TestServer │ ├── StreamEx.cs │ ├── NameValueCollectionEx.cs │ ├── TestServer.csproj │ └── Server.cs ├── CommonAssemblyInfo.cs ├── FixAsp │ ├── Web.config │ ├── Web.Debug.config │ ├── OwinAppSetup.cs │ ├── Web.Release.config │ └── FixAsp.csproj ├── TestModule │ ├── MethodDownshifter.cs │ └── TestModule.csproj ├── Info │ ├── InfoPrinter.cs │ └── Info.csproj ├── Print │ ├── Print.csproj │ └── RequestPrinter.cs └── Fix.sln ├── tools └── xUnit │ ├── xunit.dll │ ├── xunit.console.exe │ ├── xunit.console.clr4.exe │ ├── xunit.console.x86.exe │ ├── xunit.extensions.dll │ ├── xunit.runner.tdnet.dll │ ├── xunit.runner.msbuild.dll │ ├── xunit.runner.utility.dll │ ├── xunit.console.clr4.x86.exe │ ├── xunit.dll.tdnet │ ├── xunit.console.exe.config │ ├── xunit.console.x86.exe.config │ ├── xunit.console.clr4.exe.config │ ├── xunit.console.clr4.x86.exe.config │ ├── license.txt │ ├── NUnitXml.xslt │ └── HTML.xslt ├── Gemfile ├── InstallGems.bat ├── installgems.sh ├── .gitignore ├── README.md ├── packaging └── nuspec │ ├── Fix.nuspec │ ├── Fix.AppBuilder.nuspec │ └── Fix.AspNet.nuspec ├── LICENSE.txt └── rakefile.rb /VERSION.txt: -------------------------------------------------------------------------------- 1 | BUILD_VERSION = "0.8.1" 2 | NUGET_PACKAGE_VERSION = "0.8.1-pre" -------------------------------------------------------------------------------- /src/.nuget/NuGet.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/src/.nuget/NuGet.exe -------------------------------------------------------------------------------- /tools/xUnit/xunit.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.dll -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.console.exe -------------------------------------------------------------------------------- /src/Fix/NugetPack.cmd: -------------------------------------------------------------------------------- 1 | nuget pack -sym Fix.csproj -Properties Configuration=Release;Platform=AnyCPU -Build 2 | -------------------------------------------------------------------------------- /src/Fix.AspNet/NugetPack.cmd: -------------------------------------------------------------------------------- 1 | nuget pack -sym Fix.AspNet.csproj -Properties Configuration=Release;Platform=AnyCPU -Build -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.clr4.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.console.clr4.exe -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.console.x86.exe -------------------------------------------------------------------------------- /tools/xUnit/xunit.extensions.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.extensions.dll -------------------------------------------------------------------------------- /tools/xUnit/xunit.runner.tdnet.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.runner.tdnet.dll -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source :rubygems 2 | 3 | gem "rubyzip", "0.9.8" 4 | gem "albacore", ">=0.3.4.0" 5 | gem "rake", ">=10.0.3.0" -------------------------------------------------------------------------------- /tools/xUnit/xunit.runner.msbuild.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.runner.msbuild.dll -------------------------------------------------------------------------------- /tools/xUnit/xunit.runner.utility.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.runner.utility.dll -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.clr4.x86.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/FixProject/Fix/HEAD/tools/xUnit/xunit.console.clr4.x86.exe -------------------------------------------------------------------------------- /InstallGems.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | SETLOCAL 3 | 4 | @call bundle -v 5 | IF ERRORLEVEL 1 (@call gem install bundler) 6 | 7 | @call bundle install 8 | -------------------------------------------------------------------------------- /src/Fix.AppBuilder/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/FixConsole/app.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /installgems.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if ! which bundle > /dev/null; then 4 | echo "*** Installing Bundler" 5 | gem install bundler --no-rdoc --no-ri 6 | fi 7 | 8 | bundle install 9 | -------------------------------------------------------------------------------- /src/Fix/IFixAdapter.cs: -------------------------------------------------------------------------------- 1 | namespace Fix 2 | { 3 | using System; 4 | 5 | public interface IFixerAdapter 6 | { 7 | Type AdaptedType { get; } 8 | object Adapt(Fixer fixer); 9 | } 10 | } -------------------------------------------------------------------------------- /src/SimpleNowinDemo/App.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /tools/xUnit/xunit.dll.tdnet: -------------------------------------------------------------------------------- 1 | 2 | xUnit.net {0}.{1}.{2} build {3} 3 | xunit.runner.tdnet.dll 4 | Xunit.Runner.TdNet.TdNetRunner 5 | -------------------------------------------------------------------------------- /src/FileHandler/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Static HTML file 5 | 6 | 7 |

This is a static HTML file.

8 | 9 | -------------------------------------------------------------------------------- /src/Fix.AspNet/web.config.transform: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/OwinHelpers/NullDisposable.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace OwinHelpers 4 | { 5 | internal class NullDisposable : IDisposable 6 | { 7 | public void Dispose() 8 | { 9 | 10 | } 11 | } 12 | } -------------------------------------------------------------------------------- /src/Tests/Fix.AppBuilder.Test/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/SimpleNowinDemo/packages.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/.nuget/NuGet.Config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/packages/repositories.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/Fix/Body.cs: -------------------------------------------------------------------------------- 1 | namespace Fix 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | 8 | public static class Body 9 | { 10 | public static Func FromException(Exception ex) 11 | { 12 | return new ExceptionBody(ex).ToAction(); 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/TestServer/StreamEx.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace TestServer 4 | { 5 | static class StreamEx 6 | { 7 | public static byte[] ToBytes(this Stream stream) 8 | { 9 | var bytes = new byte[stream.Length]; 10 | if (bytes.Length > 0) 11 | stream.Read(bytes, 0, bytes.Length); 12 | return bytes; 13 | } 14 | } 15 | } -------------------------------------------------------------------------------- /src/Fix.AppBuilder/AppBuilderAdapter.cs: -------------------------------------------------------------------------------- 1 | namespace Fix.AppBuilder 2 | { 3 | using System; 4 | using Owin; 5 | 6 | public class AppBuilderAdapter : IFixerAdapter 7 | { 8 | public Type AdaptedType 9 | { 10 | get { return typeof (IAppBuilder); } 11 | } 12 | 13 | public object Adapt(Fixer fixer) 14 | { 15 | return new FixAppBuilder(fixer); 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | obj 2 | bin 3 | deploy 4 | *.csproj.user 5 | *.suo 6 | *.cache 7 | ~$* 8 | *~ 9 | *ReSharper* 10 | *.swp 11 | *.testsettings 12 | TestResults/* 13 | *.dbmdl 14 | Releases/2* 15 | *ncrunch* 16 | Fix.sln.DotSettings 17 | Fix.sln.DotSettings.user 18 | *.nupkg 19 | nohup.out 20 | build 21 | src/CommonAssemblyInfo.cs 22 | Gemfile.lock 23 | results 24 | nuget 25 | src/packages/* 26 | !src/packages/repositories.config 27 | artifacts 28 | src/Fix.sln.ide 29 | 30 | -------------------------------------------------------------------------------- /src/Fix/EnumerableEx.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Fix 7 | { 8 | static class EnumerableEx 9 | { 10 | public static IEnumerable Append(this IEnumerable source, T itemToAppend) 11 | { 12 | foreach (var item in source) 13 | { 14 | yield return item; 15 | } 16 | 17 | yield return itemToAppend; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Fix/TaskHelper.cs: -------------------------------------------------------------------------------- 1 | namespace Fix 2 | { 3 | using System.Threading.Tasks; 4 | 5 | public static class TaskHelper 6 | { 7 | public static Task Completed() 8 | { 9 | var tcs = new TaskCompletionSource(); 10 | tcs.SetResult(0); 11 | return tcs.Task; 12 | } 13 | 14 | public static Task Completed(T result) 15 | { 16 | var tcs = new TaskCompletionSource(); 17 | tcs.SetResult(result); 18 | return tcs.Task; 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/TestServer/NameValueCollectionEx.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Collections.Specialized; 3 | using System.Linq; 4 | 5 | namespace TestServer 6 | { 7 | static class NameValueCollectionEx 8 | { 9 | public static IEnumerable> ToKeyValuePairs(this NameValueCollection nameValueCollection) 10 | { 11 | return from key in nameValueCollection.AllKeys 12 | from value in nameValueCollection.GetValues(key) 13 | select new KeyValuePair(key, value); 14 | } 15 | } 16 | } -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 14 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.x86.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 14 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.clr4.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 14 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /tools/xUnit/xunit.console.clr4.x86.exe.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | 8 | 9 | 10 | 14 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/CommonAssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Runtime.CompilerServices; 2 | using System.Reflection; 3 | using System.Runtime.InteropServices; 4 | [assembly: AssemblyCompany("Mark Rendle")] 5 | [assembly: AssemblyProduct("Fix")] 6 | [assembly: AssemblyCopyright("Copyright (C) Mark Rendle 2010-2013")] 7 | [assembly: AssemblyTrademark("28779d381dcc746ac339e92e6e3eed69b358bdd7")] 8 | [assembly: ComVisible(false)] 9 | [assembly: AssemblyVersion("0.4.0.50044")] 10 | [assembly: AssemblyFileVersion("0.4.0.50044")] 11 | 12 | [assembly: AssemblyConfiguration("Release")] 13 | [assembly: AssemblyInformationalVersion("0.4.0.50044")] 14 | 15 | [assembly: InternalsVisibleTo("Tests")] 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fix 2 | An ultra-lightweight web glue for .NET, written in C#. 3 | ## README needs updating 4 | This README is out of date. I've just picked Fix up again to use with Simple.Web, so the information below is wrong. I'll update it soon. 5 | MR 21-Jul-2012 6 | ## What? 7 | Fix joins together web servers, request handlers and "infixes", or middleware, in such a way that the implementations of each don't need to know anything about each other, or, indeed, about Fix itself. 8 | ### Example? 9 | Hello again. I've completely failed to update this, but I have at least deleted the old wrong examples. 10 | MR 02-Dec-2013 11 | 12 | I'd love to hear people's thoughts on this. Best way is to catch me on [Twitter](http://twitter.com/markrendle). 13 | -------------------------------------------------------------------------------- /src/Fix/ExceptionBody.cs: -------------------------------------------------------------------------------- 1 | namespace Fix 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Text; 6 | using System.Threading; 7 | using System.Threading.Tasks; 8 | 9 | internal class ExceptionBody 10 | { 11 | private readonly Exception _error; 12 | 13 | public ExceptionBody(Exception error) 14 | { 15 | _error = error; 16 | } 17 | 18 | public Func ToAction() 19 | { 20 | var buffer = Encoding.Default.GetBytes(_error.ToString()); 21 | return (stream, token) => Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, buffer, 0, buffer.Length, null); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/Fix.AspNet/FixHttpHandler.cs: -------------------------------------------------------------------------------- 1 | namespace Fix.AspNet 2 | { 3 | using System; 4 | using System.Web; 5 | 6 | public class FixHttpHandler : IHttpAsyncHandler 7 | { 8 | public void ProcessRequest(HttpContext context) 9 | { 10 | throw new NotImplementedException(); 11 | } 12 | 13 | public bool IsReusable { get; private set; } 14 | 15 | public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) 16 | { 17 | var task = Bridge.RunContext(context); 18 | task.ContinueWith(t => cb(task)); 19 | return task; 20 | } 21 | 22 | public void EndProcessRequest(IAsyncResult result) 23 | { 24 | } 25 | } 26 | } -------------------------------------------------------------------------------- /src/OwinHelpers/ExceptionBody.cs: -------------------------------------------------------------------------------- 1 | namespace OwinHelpers 2 | { 3 | using System; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | using BodyDelegate = System.Func; 7 | 8 | internal class ExceptionBody 9 | { 10 | private readonly Exception _error; 11 | 12 | public ExceptionBody(Exception error) 13 | { 14 | _error = error; 15 | } 16 | 17 | public BodyDelegate ToAction() 18 | { 19 | var buffer = Encoding.Default.GetBytes(_error.ToString()); 20 | return (stream, token) => Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, buffer, 0, buffer.Length, null); 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/OwinHelpers/DictionaryExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace OwinHelpers 7 | { 8 | public static class DictionaryExtensions 9 | { 10 | public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key, TValue defaultValue) 11 | { 12 | TValue value; 13 | if (!dictionary.TryGetValue(key, out value)) 14 | { 15 | value = defaultValue; 16 | } 17 | return value; 18 | } 19 | 20 | public static TValue GetValueOrDefault(this IDictionary dictionary, TKey key) 21 | { 22 | return GetValueOrDefault(dictionary, key, default(TValue)); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/FixAsp/Web.config: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /src/OwinHelpers/FileBody.cs: -------------------------------------------------------------------------------- 1 | namespace OwinHelpers 2 | { 3 | using System; 4 | using System.IO; 5 | using System.Threading; 6 | using System.Threading.Tasks; 7 | using BodyDelegate = System.Func; 8 | 9 | internal class FileBody 10 | { 11 | private readonly FileInfo _fileInfo; 12 | 13 | public FileBody(FileInfo fileInfo) 14 | { 15 | _fileInfo = fileInfo; 16 | } 17 | 18 | public BodyDelegate ToAction() 19 | { 20 | return (stream, token) => 21 | { 22 | using (var fileStream = _fileInfo.OpenRead()) 23 | { 24 | fileStream.CopyTo(stream); 25 | } 26 | return TaskHelper.Completed(); 27 | }; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /packaging/nuspec/Fix.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fix 5 | 0.3.2 6 | Mark Rendle 7 | Mark Rendle 8 | Mark Rendle 9 | http://www.opensource.org/licenses/mit-license.php 10 | http://github.com/FixProject/Fix 11 | false 12 | A glue for OWIN. 13 | A glue for OWIN. 14 | fix owin http 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Mark Rendle 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /src/Fix/InvokeAndForget.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using RequestHandler = System.Action>, System.Func, System.Action>, System.Func>, System.Action, System.Delegate>; 4 | using ResponseHandler = System.Action>, System.Func>; 5 | 6 | namespace Fix 7 | { 8 | //static class InvokeAndForgetEx 9 | //{ 10 | // public static void InvokeAndForget(this RequestHandler handler, IEnumerable> env, Func body, ResponseHandler responseHandler, Action exceptionHandler, Delegate next) 11 | // { 12 | // handler.BeginInvoke(env, body, responseHandler, exceptionHandler, next, handler.EndInvoke, null); 13 | // } 14 | //} 15 | } 16 | -------------------------------------------------------------------------------- /src/FixConsole/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ComponentModel.Composition; 3 | using System.ComponentModel.Composition.Hosting; 4 | using System.Linq; 5 | using Fix; 6 | using TestServer; 7 | 8 | namespace FixUp 9 | { 10 | class Program 11 | { 12 | static void Main(string[] args) 13 | { 14 | var prefix = args.Length == 1 ? args[0] : "http://*:3333/"; 15 | using (var server = new Server(prefix)) 16 | { 17 | var fixer = new Fixer(func => server.Start(func), server.Stop); 18 | 19 | using (var catalog = new DirectoryCatalog(Environment.CurrentDirectory)) 20 | { 21 | var container = new CompositionContainer(catalog); 22 | container.ComposeParts(fixer); 23 | } 24 | 25 | fixer.Start(); 26 | Console.Write("Running. Press Enter to stop."); 27 | Console.ReadLine(); 28 | fixer.Stop(); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/OwinHelpers/BodyExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace OwinHelpers 7 | { 8 | public static class BodyExtensions 9 | { 10 | public static IObservable ToObservable(this Action, Action, Action> source) 11 | { 12 | return new ActionObservable(source); 13 | } 14 | 15 | private class ActionObservable : IObservable 16 | { 17 | private readonly Action, Action, Action> _action; 18 | 19 | public ActionObservable(Action, Action, Action> action) 20 | { 21 | _action = action; 22 | } 23 | 24 | public IDisposable Subscribe(IObserver observer) 25 | { 26 | _action.BeginInvoke(observer.OnNext, observer.OnCompleted, observer.OnError, _action.EndInvoke, null); 27 | return new NullDisposable(); 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /packaging/nuspec/Fix.AppBuilder.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fix.AppBuilder 5 | 0.4.0.51807 6 | Mark Rendle 7 | Mark Rendle 8 | Mark Rendle 9 | http://www.opensource.org/licenses/mit-license.php 10 | http://github.com/FixProject/Fix 11 | false 12 | A glue for OWIN. 13 | Owin.IAppBuilder support for Fix, a glue for OWIN. 14 | fix owin http 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /packaging/nuspec/Fix.AspNet.nuspec: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Fix.AspNet 5 | 0.0.0 6 | Mark Rendle 7 | Mark Rendle 8 | Mark Rendle 9 | http://www.opensource.org/licenses/mit-license.php 10 | http://github.com/FixProject/Fix 11 | false 12 | A glue for OWIN. 13 | Asp.Net support for Fix, a glue for OWIN. 14 | fix owin http 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/OwinHelpers/EnvironmentExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Environment = System.Collections.Generic.IEnumerable>; 6 | 7 | namespace OwinHelpers 8 | { 9 | public static class EnvironmentExtensions 10 | { 11 | public static string GetPath(this Environment env) 12 | { 13 | return GetValue(env, "owin.RequestPath"); 14 | } 15 | 16 | public static string GetRequestMethod(this Environment env) 17 | { 18 | return GetValue(env, "owin.RequestMethod"); 19 | } 20 | 21 | private static string GetValue(Environment env, string key) 22 | { 23 | var dictionary = env as IDictionary; 24 | if (dictionary != null) 25 | { 26 | return dictionary.GetValueOrDefault(key, string.Empty).ToString(); 27 | } 28 | var pair = env.FirstOrDefault(kvp => kvp.Key.Equals(key)); 29 | return (pair.Value != null) ? pair.Value.ToString() : string.Empty; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/Fix/AssemblyManager.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace Fix 7 | { 8 | using System.Reflection; 9 | 10 | public static class AssemblyManager 11 | { 12 | private static List _cache; 13 | 14 | public static IEnumerable GetReferencedAssemblies() 15 | { 16 | return _cache ?? FindReferencedAssemblies(); 17 | } 18 | 19 | private static IEnumerable FindReferencedAssemblies() 20 | { 21 | var assembly = Assembly.GetEntryAssembly(); 22 | var cache = new List {assembly}; 23 | yield return assembly; 24 | 25 | foreach (var referencedAssembly in assembly.GetReferencedAssemblies()) 26 | { 27 | assembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == referencedAssembly.FullName) ?? 28 | Assembly.Load(referencedAssembly); 29 | cache.Add(assembly); 30 | yield return assembly; 31 | } 32 | 33 | _cache = cache; 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/SimpleNowinDemo/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SimpleNowinDemo 4 | { 5 | using Fix; 6 | using Nowin; 7 | using Simple.Web; 8 | using Simple.Web.Behaviors; 9 | 10 | class Program 11 | { 12 | static void Main() 13 | { 14 | // Build the OWIN app 15 | var app = new Fixer() 16 | .Use(next => env => Application.Run(env, () => next(env))) 17 | .Build(); 18 | 19 | // Set up the Nowin server 20 | var builder = ServerBuilder.New() 21 | .SetPort(31337) 22 | .SetOwinApp(app); 23 | 24 | // Run 25 | using (builder.Start()) 26 | { 27 | Console.WriteLine("Listening on port 31337. Enter to exit."); 28 | Console.ReadLine(); 29 | } 30 | } 31 | } 32 | 33 | [UriTemplate("/")] 34 | public class Index : IGet, IOutput 35 | { 36 | public Status Get() 37 | { 38 | return 200; 39 | } 40 | 41 | public RawHtml Output 42 | { 43 | get { return "

Ta dah!

"; } 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/OwinHelpers/ActionObserver.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | 4 | namespace OwinHelpers 5 | { 6 | internal class ActionObserver : IObserver 7 | { 8 | private readonly Action _onFile; 9 | private readonly Action _onNext; 10 | private readonly Action _onCompleted; 11 | private readonly Action _onError; 12 | 13 | public ActionObserver(Action onNext, Action onFile, Action onCompleted, Action onError) 14 | { 15 | _onFile = onFile; 16 | _onNext = onNext ?? new Action(x => { }); 17 | _onError = onError ?? new Action(x => { }); 18 | _onCompleted = onCompleted ?? new Action(() => { }); 19 | } 20 | 21 | public void OnNext(T value) 22 | { 23 | _onNext(value); 24 | } 25 | 26 | public void OnFile(FileInfo fileInfo) 27 | { 28 | _onFile(fileInfo); 29 | } 30 | 31 | public void OnError(Exception error) 32 | { 33 | _onError(error); 34 | } 35 | 36 | public void OnCompleted() 37 | { 38 | _onCompleted(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/OwinHelpers/EnumerableDictionaryExtension.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace OwinHelpers 7 | { 8 | public static class EnumerableDictionaryExtension 9 | { 10 | public static IDictionary ToDictionary(this IEnumerable> source) 11 | { 12 | var alreadyDictionary = source as IDictionary; 13 | if (alreadyDictionary != null) 14 | { 15 | return new Dictionary(alreadyDictionary); 16 | } 17 | return source.ToDictionary(kvp => kvp.Key, kvp => kvp.Value); 18 | } 19 | 20 | public static IEnumerable> Mutate(this IEnumerable> source, 21 | Func, bool> predicate, Func,KeyValuePair> mutator) 22 | { 23 | foreach (var pair in source) 24 | { 25 | if (predicate(pair)) 26 | { 27 | yield return mutator(pair); 28 | } 29 | else 30 | { 31 | yield return pair; 32 | } 33 | } 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/FixAsp/Web.Debug.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 29 | 30 | -------------------------------------------------------------------------------- /src/FixAsp/OwinAppSetup.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using System.IO; 5 | 6 | namespace FixAsp 7 | { 8 | using System.Text; 9 | using Fix; 10 | using AppFunc = Func, Task>; 11 | 12 | public static class OwinAppSetup 13 | { 14 | public static void Setup(Action> use, Action> map) 15 | { 16 | map("/mapped", next => async env => 17 | { 18 | var stream = (Stream) env["owin.ResponseBody"]; 19 | await stream.WriteAsync("

MAPPED!

"); 20 | await stream.WriteAsync("

" + env[OwinKeys.RequestPath] + "

"); 21 | env["owin.ResponseStatusCode"] = 200; 22 | }); 23 | use(next => async env => 24 | { 25 | var stream = (Stream) env["owin.ResponseBody"]; 26 | await stream.WriteAsync("

OWIN!

"); 27 | await stream.WriteAsync("

" + env[OwinKeys.RequestPath] + "

"); 28 | env["owin.ResponseStatusCode"] = 200; 29 | }); 30 | } 31 | 32 | public static Task WriteAsync(this Stream stream, string text) 33 | { 34 | var bytes = Encoding.Default.GetBytes(text); 35 | return stream.WriteAsync(bytes, 0, bytes.Length); 36 | } 37 | } 38 | } -------------------------------------------------------------------------------- /src/FixAsp/Web.Release.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 17 | 18 | 19 | 30 | 31 | -------------------------------------------------------------------------------- /src/OwinHelpers/StringBody.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | 6 | namespace OwinHelpers 7 | { 8 | using System.Threading.Tasks; 9 | using BodyDelegate = System.Func; 10 | internal class StringBody : IObservable> 11 | { 12 | private readonly byte[] _bytes; 13 | 14 | public StringBody(string text) : this(text, Encoding.Default) 15 | { 16 | } 17 | 18 | public StringBody(string text, Encoding encoding) 19 | { 20 | _bytes = encoding.GetBytes(text); 21 | } 22 | 23 | public BodyDelegate ToAction() 24 | { 25 | return (stream, token) => Task.Factory.FromAsync(stream.BeginWrite, stream.EndWrite, _bytes, 0, _bytes.Length, null); 26 | } 27 | 28 | public int Length 29 | { 30 | get { return _bytes.Length; } 31 | } 32 | 33 | public IDisposable Subscribe(IObserver> observer) 34 | { 35 | Action action = () => 36 | { 37 | observer.OnNext(new ArraySegment(_bytes)); 38 | observer.OnCompleted(); 39 | }; 40 | action.BeginInvoke(action.EndInvoke, null); 41 | return new NullDisposable(); 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/TestModule/MethodDownshifter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using OwinHelpers; 5 | using App = System.Action>, System.Func, System.Action>, System.Action>, System.Action, System.Action, System.Action>>, System.Delegate>; 6 | using ResponseHandler = System.Action>, System.Action>, System.Action, System.Action, System.Action>>; 7 | 8 | namespace TestModule 9 | { 10 | public class MethodDownshifter 11 | { 12 | [Export("Owin.Middleware")] 13 | public void DownshiftMethod(IEnumerable> env, Func body, 14 | ResponseHandler responseHandler, Delegate next) 15 | { 16 | var nextInfix = next as App; 17 | if (nextInfix != null) 18 | { 19 | env = env.Mutate(kvp => kvp.Key.Equals("REQUEST_METHOD"), 20 | kvp => new KeyValuePair("REQUEST_METHOD", kvp.Value.ToString().ToLower())); 21 | nextInfix(env, body, responseHandler, null); 22 | } 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/Fix.AppBuilder/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Fix.AppBuilder")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Fix.AppBuilder")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("867778ee-13e4-4c41-994e-50914f30d78a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/SimpleNowinDemo/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("SimpleNowinDemo")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("SimpleNowinDemo")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("942f5e77-092f-40fb-9e26-ae5afd434f6d")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Tests/Fix.AppBuilder.Test/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Fix.AppBuilder.Test")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("Fix.AppBuilder.Test")] 13 | [assembly: AssemblyCopyright("Copyright © 2013")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("377e7b0a-c54b-4b7a-b328-a27a6f24a974")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /src/Fix.AppBuilder/FixAppBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | using Owin; 5 | 6 | namespace Fix.AppBuilder 7 | { 8 | using AppFunc = Func, Task>; 9 | 10 | class FixAppBuilder : IAppBuilder 11 | { 12 | private readonly IDictionary _properties = new Dictionary(); 13 | private readonly Fixer _fixer; 14 | 15 | public FixAppBuilder(Fixer fixer) 16 | { 17 | _fixer = fixer; 18 | } 19 | 20 | public IAppBuilder Use(object middleware, params object[] args) 21 | { 22 | var properFunc = middleware as Func; 23 | if (properFunc != null) 24 | { 25 | _fixer.Use(properFunc); 26 | return this; 27 | } 28 | throw new NotSupportedException("FixAppBuilder can't use that middleware."); 29 | } 30 | 31 | public object Build(Type returnType) 32 | { 33 | var output = _fixer.Build(); 34 | if (output.GetType() != returnType) 35 | { 36 | throw new NotSupportedException("FixAppBuilder can't Build that Type."); 37 | } 38 | return output; 39 | } 40 | 41 | public IAppBuilder New() 42 | { 43 | return new FixAppBuilder(new Fixer()); 44 | } 45 | 46 | public IDictionary Properties 47 | { 48 | get 49 | { 50 | return _properties; 51 | } 52 | } 53 | } 54 | } -------------------------------------------------------------------------------- /src/OwinHelpers/DelegateExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using Env = System.Collections.Generic.IDictionary; 6 | using Headers = System.Collections.Generic.IDictionary; 7 | using BodyDelegate = System.Func; 8 | using ResponseHandler = System.Func, System.Func, System.Threading.Tasks.Task>; 9 | using App = System.Func, System.Collections.Generic.IDictionary, System.IO.Stream, System.Threading.CancellationToken, System.Func, System.Func, System.Threading.Tasks.Task>, System.Delegate, System.Threading.Tasks.Task>; 10 | 11 | namespace OwinHelpers 12 | { 13 | using System.IO; 14 | using System.Threading; 15 | using System.Threading.Tasks; 16 | 17 | public static class DelegateExtensions 18 | { 19 | public static Task InvokeAsNextApp(this Delegate @delegate, Env env, Headers headers, Stream body, CancellationToken token, ResponseHandler responseHandler) 20 | { 21 | var nextApp = @delegate as App; 22 | if (nextApp != null) 23 | { 24 | return nextApp(env, headers, body, token, responseHandler, null); 25 | } 26 | 27 | return TaskHelper.Completed(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/Tests/Fix.AppBuilder.Test/AppBuilderAdapterTest.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace Fix.AppBuilder.Test 8 | { 9 | using System.Reflection; 10 | using Owin; 11 | using Xunit; 12 | using AppFunc = Func, Task>; 13 | 14 | public class AppBuilderAdapterTest 15 | { 16 | [Fact] 17 | public void FixWorksWithIAppBuilderUsingAdapter() 18 | { 19 | var assemblies = new[] {Assembly.GetExecutingAssembly(), typeof (AppBuilderAdapter).Assembly}; 20 | var startupEnv = new Dictionary(); 21 | var appFuncBuilder = AppFuncBuilder.Create(assemblies, startupEnv); 22 | var func = appFuncBuilder.Build(); 23 | var dict = new Dictionary(); 24 | func(dict); 25 | Assert.Equal("Yes", startupEnv["Constructed"]); 26 | Assert.Equal("Passed", dict["Test"]); 27 | } 28 | } 29 | 30 | public class OwinAppSetup 31 | { 32 | public OwinAppSetup(IDictionary startupEnv) 33 | { 34 | startupEnv["Constructed"] = "Yes"; 35 | } 36 | 37 | public void Setup(Action> use) 38 | { 39 | use(Run); 40 | } 41 | 42 | private static AppFunc Run(AppFunc _) 43 | { 44 | return env => 45 | { 46 | env["Test"] = "Passed"; 47 | var tcs = new TaskCompletionSource(); 48 | tcs.SetResult(0); 49 | return tcs.Task; 50 | }; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/Fix/Fixer.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace Fix 6 | { 7 | using System.Threading; 8 | using Env = IDictionary; 9 | using ComponentFunc = Func, Func,Task>, Task>; 10 | using BuilderFunc = Func, Task>, Func, Task>>; 11 | using AppFunc = Func, Task>; 12 | 13 | public class Fixer 14 | { 15 | private readonly Stack _funcs = new Stack(); 16 | private int _useCount = 0; 17 | 18 | public Fixer Use(BuilderFunc component) 19 | { 20 | _funcs.Push(component); 21 | return this; 22 | } 23 | 24 | public Fixer Map(string mapPath, BuilderFunc component) 25 | { 26 | _funcs.Push(Mapper.Map(mapPath, component)); 27 | return this; 28 | } 29 | 30 | public AppFunc Build() 31 | { 32 | if (Interlocked.Increment(ref _useCount) > 1) 33 | { 34 | throw new InvalidOperationException("Fixer instances may only be used once."); 35 | } 36 | 37 | var lastFunc = _funcs.Pop(); 38 | AppFunc f = lastFunc(Completed); 39 | 40 | while (_funcs.Count > 0) 41 | { 42 | var func = _funcs.Pop(); 43 | f = func(f); 44 | } 45 | 46 | return f; 47 | } 48 | 49 | private static Task Completed(IDictionary _) 50 | { 51 | var tcs = new TaskCompletionSource(); 52 | tcs.SetResult(0); 53 | return tcs.Task; 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Fix/OwinKeys.cs: -------------------------------------------------------------------------------- 1 | namespace Fix 2 | { 3 | public static class OwinKeys 4 | { 5 | public const string CallCompleted = "owin.CallCompleted"; 6 | public const string RequestScheme = "owin.RequestScheme"; 7 | public const string RequestMethod = "owin.RequestMethod"; 8 | public const string RequestPathBase = "owin.RequestPathBase"; 9 | public const string RequestPath = "owin.RequestPath"; 10 | public const string RequestQueryString = "owin.RequestQueryString"; 11 | public const string RequestProtocol = "owin.RequestProtocol"; 12 | 13 | public const string RequestHeaders = "owin.RequestHeaders"; 14 | public const string RequestBody = "owin.RequestBody"; 15 | 16 | public const string ResponseBody = "owin.ResponseBody"; 17 | public const string ResponseHeaders = "owin.ResponseHeaders"; 18 | public const string ResponseStatusCode = "owin.ResponseStatusCode"; 19 | public const string ResponseReasonPhrase = "owin.ResponseReasonPhrase"; 20 | public const string ResponseProtocol = "owin.ResponseProtocol"; 21 | 22 | public const string Version = "owin.Version"; 23 | public const string CallCancelled = "owin.CallCancelled"; 24 | } 25 | 26 | public static class ServerKeys 27 | { 28 | public const string RemoteIpAddress = "server.RemoteIpAddress"; 29 | public const string RemotePort = "server.RemotePort"; 30 | public const string LocalIpAddress = "server.LocalIpAddress"; 31 | public const string LocalPort = "server.LocalPort"; 32 | public const string IsLocal = "server.IsLocal"; 33 | } 34 | 35 | public static class SendFileKeys 36 | { 37 | public const string Version = "sendfile.Version"; 38 | public const string Support = "sendfile.Support"; 39 | public const string Concurrency = "sendfile.Concurrency"; 40 | public const string SendAsync = "sendfile.SendAsync"; 41 | } 42 | } -------------------------------------------------------------------------------- /src/Fix/Mapper.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Threading.Tasks; 4 | 5 | namespace Fix 6 | { 7 | using AppFunc = Func, Task>; 8 | public static class Mapper 9 | { 10 | public static Func Map(string mapPath, Func mappedFunc) 11 | { 12 | if (mapPath == null) throw new ArgumentNullException("mapPath"); 13 | mapPath = '/' + mapPath.Trim('/'); 14 | 15 | return next => 16 | { 17 | var func = mappedFunc(NotFound); 18 | return async env => 19 | { 20 | var path = (string)env["owin.RequestPath"]; 21 | if (path.Equals(mapPath, StringComparison.OrdinalIgnoreCase)) 22 | { 23 | var pathBase = env.GetValueOrDefault("owin.RequestPathBase", string.Empty); 24 | env["owin.RequestPathBase"] = pathBase + mapPath; 25 | await func(env); 26 | } 27 | else if (path.StartsWith(mapPath + '/')) 28 | { 29 | var pathBase = env.GetValueOrDefault("owin.RequestPathBase", string.Empty); 30 | env["owin.RequestPathBase"] = pathBase + mapPath; 31 | env["owin.RequestPath"] = path.Substring(mapPath.Length); 32 | await func(env); 33 | } 34 | else 35 | { 36 | await next(env); 37 | } 38 | }; 39 | }; 40 | } 41 | 42 | private static Task NotFound(IDictionary env) 43 | { 44 | env["owin.ResponseStatusCode"] = 404; 45 | return Task.FromResult(0); 46 | } 47 | public static T GetValueOrDefault(this IDictionary dict, string key, 48 | T defaultValue = default(T)) 49 | { 50 | object value; 51 | if (!dict.TryGetValue(key, out value)) return defaultValue; 52 | return value != null ? (T)value : defaultValue; 53 | } 54 | 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/Fix/Converter.cs: -------------------------------------------------------------------------------- 1 | //namespace Fix 2 | //{ 3 | // using System; 4 | // using System.Collections.Generic; 5 | // using System.IO; 6 | // using System.Threading; 7 | // using System.Threading.Tasks; 8 | // using _BodyDelegate = System.Func; 9 | // using _ResponseHandler = System.Func, System.Func, System.Threading.Tasks.Task>; 10 | // using _App = System.Func, System.Collections.Generic.IDictionary, System.IO.Stream, System.Threading.CancellationToken, System.Func, System.Func, System.Threading.Tasks.Task>, System.Threading.Tasks.Task>; 11 | 12 | // public delegate Task Body(Stream stream, CancellationToken cancellationToken); 13 | 14 | // public delegate Task Respond(int status, IDictionary headers, Body body); 15 | 16 | // public delegate Task App(IDictionary env, IDictionary headers, Stream input, CancellationToken cancellation, Respond respond); 17 | 18 | // public static class Converter 19 | // { 20 | // public static App ToApp(Func, IDictionary, Stream, CancellationToken, Func, Func, Task>, Task> appFunc) 21 | // { 22 | // return (env, headers, input, cancellation, respond) => 23 | // appFunc(env, headers, input, cancellation, respond.ToRespondFunc()); 24 | // } 25 | 26 | // public static Body ToBody(this Func bodyFunc) 27 | // { 28 | // return (stream, token) => bodyFunc(stream, token); 29 | // } 30 | 31 | // public static Func, Func,Task> ToRespondFunc(this Respond respond) 32 | // { 33 | // return (status, headers, body) => respond(status, headers, body.ToBody()); 34 | // } 35 | // } 36 | //} -------------------------------------------------------------------------------- /src/OwinHelpers/AsyncExtensions.cs: -------------------------------------------------------------------------------- 1 | namespace OwinHelpers 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.IO; 6 | using System.Text; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using Result = System.Tuple< //Result 10 | System.Collections.Generic.IDictionary, // Properties 11 | int, // Status 12 | System.Collections.Generic.IDictionary, // Headers 13 | System.Func< // Body 14 | System.IO.Stream, // Output 15 | System.Threading.Tasks.Task>>; // Done 16 | 17 | public static class AsyncExtensions 18 | { 19 | public static Task WriteAsync(this Stream stream, byte[] bytes, int offset, int count, CancellationToken cancellationToken = default(CancellationToken)) 20 | { 21 | var factory = cancellationToken.Equals(default(CancellationToken)) 22 | ? Task.Factory 23 | : new TaskFactory(cancellationToken); 24 | return factory.FromAsync(stream.BeginWrite, stream.EndWrite, bytes, offset, count, null); 25 | } 26 | 27 | public static Task WriteAsync(this Stream stream, string text) 28 | { 29 | var bytes = Encoding.UTF8.GetBytes(text); 30 | return stream.WriteAsync(bytes, 0, bytes.Length); 31 | } 32 | } 33 | 34 | public static class TaskHelper 35 | { 36 | public static Task Completed() 37 | { 38 | var tcs = new TaskCompletionSource(); 39 | tcs.SetResult(null); 40 | return tcs.Task; 41 | } 42 | 43 | public static Task Completed(IDictionary properties, int status, IDictionary headers, Func body) 44 | { 45 | var tcs = new TaskCompletionSource(); 46 | tcs.SetResult(new Result(properties, status, headers, body)); 47 | return tcs.Task; 48 | } 49 | 50 | public static Task NotFound() 51 | { 52 | return Completed(null, 404, null, null); 53 | } 54 | 55 | public static Task Error(Exception ex) 56 | { 57 | return Completed(null, 500, null, stream => stream.WriteAsync(ex.ToString())); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /tools/xUnit/license.txt: -------------------------------------------------------------------------------- 1 | This license governs use of the accompanying software. If you use the software, you accept this license. If you do not accept the license, do not use the software. 2 | 3 | 1. Definitions 4 | 5 | The terms "reproduce," "reproduction," "derivative works," and "distribution" have the same meaning here as under U.S. copyright law. 6 | 7 | A "contribution" is the original software, or any additions or changes to the software. 8 | 9 | A "contributor" is any person that distributes its contribution under this license. 10 | 11 | "Licensed patents" are a contributor's patent claims that read directly on its contribution. 12 | 13 | 2. Grant of Rights 14 | 15 | (A) Copyright Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free copyright license to reproduce its contribution, prepare derivative works of its contribution, and distribute its contribution or any derivative works that you create. 16 | 17 | (B) Patent Grant- Subject to the terms of this license, including the license conditions and limitations in section 3, each contributor grants you a non-exclusive, worldwide, royalty-free license under its licensed patents to make, have made, use, sell, offer for sale, import, and/or otherwise dispose of its contribution in the software or derivative works of the contribution in the software. 18 | 19 | 3. Conditions and Limitations 20 | 21 | (A) No Trademark License- This license does not grant you rights to use any contributors' name, logo, or trademarks. 22 | 23 | (B) If you bring a patent claim against any contributor over patents that you claim are infringed by the software, your patent license from such contributor to the software ends automatically. 24 | 25 | (C) If you distribute any portion of the software, you must retain all copyright, patent, trademark, and attribution notices that are present in the software. 26 | 27 | (D) If you distribute any portion of the software in source code form, you may do so only under this license by including a complete copy of this license with your distribution. If you distribute any portion of the software in compiled or object code form, you may only do so under a license that complies with this license. 28 | 29 | (E) The software is licensed "as-is." You bear the risk of using it. The contributors give no express warranties, guarantees or conditions. You may have additional consumer rights under your local laws which this license cannot change. To the extent permitted under your local laws, the contributors exclude the implied warranties of merchantability, fitness for a particular purpose and non-infringement. -------------------------------------------------------------------------------- /src/TestServer/TestServer.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386} 9 | Library 10 | Properties 11 | TestServer 12 | TestServer 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\..\build 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Properties\CommonAssemblyInfo.cs 46 | 47 | 48 | 49 | 50 | 51 | 58 | -------------------------------------------------------------------------------- /src/Info/InfoPrinter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using System.Text; 5 | using OwinHelpers; 6 | using AppFunc = System.Func< // Call 7 | System.Collections.Generic.IDictionary, // Environment 8 | System.Collections.Generic.IDictionary, // Headers 9 | System.IO.Stream, // Body 10 | System.Threading.Tasks.Task, // Properties 12 | int, // Status 13 | System.Collections.Generic.IDictionary, // Headers 14 | System.Func< // Body 15 | System.IO.Stream, // Output 16 | System.Threading.Tasks.Task>>>>; // Done 17 | using Result = System.Tuple< //Result 18 | System.Collections.Generic.IDictionary, // Properties 19 | int, // Status 20 | System.Collections.Generic.IDictionary, // Headers 21 | System.Func< // Body 22 | System.IO.Stream, // Output 23 | System.Threading.Tasks.Task>>; // Done 24 | 25 | namespace Info 26 | { 27 | using System.IO; 28 | using System.Threading; 29 | using System.Threading.Tasks; 30 | 31 | public class InfoPrinter 32 | { 33 | [Export("Owin.Application")] 34 | public Task PrintInfo(IDictionary env, IDictionary headers, Stream body) 35 | { 36 | try 37 | { 38 | if (env.GetPath().ToLower().Equals("/info", StringComparison.CurrentCultureIgnoreCase)) 39 | { 40 | return HandleRequest(); 41 | } 42 | 43 | return TaskHelper.NotFound(); 44 | } 45 | catch (Exception ex) 46 | { 47 | return TaskHelper.Error(ex); 48 | } 49 | } 50 | 51 | private static Task HandleRequest() 52 | { 53 | return TaskHelper.Completed(null, 200, 54 | new Dictionary {{"Content-Type", new[] {"text/html"}}}, 55 | WriteHtml); 56 | } 57 | 58 | private static Task WriteHtml(Stream s) 59 | { 60 | var bytes = 61 | Encoding.UTF8.GetBytes( 62 | "

This server is running on Fix.

"); 63 | return s.WriteAsync(bytes, 0, bytes.Length); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /src/OwinHelpers/Body.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using System.Text; 6 | using ResponseHandler = System.Func, System.Func, System.Threading.Tasks.Task>; 7 | using BodyDelegate = System.Func; 8 | 9 | namespace OwinHelpers 10 | { 11 | using System.Threading.Tasks; 12 | 13 | public static class Body 14 | { 15 | public static BodyDelegate FromException(Exception ex) 16 | { 17 | return new ExceptionBody(ex).ToAction(); 18 | } 19 | 20 | public static BodyDelegate FromString(string text) 21 | { 22 | return new StringBody(text).ToAction(); 23 | } 24 | 25 | public static BodyDelegate FromFile(FileInfo fileInfo) 26 | { 27 | return new FileBody(fileInfo).ToAction(); 28 | } 29 | 30 | public static Task WriteString(this ResponseHandler responseHandler, Func textGenerator, string contentType) 31 | { 32 | try 33 | { 34 | var text = textGenerator(); 35 | var body = FromString(text); 36 | 37 | var headers = BuildBasicHeaders(text.Length, contentType); 38 | headers["Set-Cookie"] = new[] {"foo=bar"}; 39 | return responseHandler(200, headers, body); 40 | } 41 | catch (Exception ex) 42 | { 43 | return responseHandler(500, null, FromException(ex)); 44 | } 45 | } 46 | 47 | private static IDictionary BuildBasicHeaders(long contentLength, string contentType) 48 | { 49 | return new Dictionary 50 | { 51 | {"Content-Type", new[] {contentType}}, 52 | {"Content-Length", new[] {contentLength.ToString()}}, 53 | }; 54 | } 55 | 56 | public static Task WriteHtml(this ResponseHandler responseHandler, Func htmlGenerator) 57 | { 58 | return WriteString(responseHandler, htmlGenerator, "text/html"); 59 | } 60 | 61 | public static Task WriteFile(this ResponseHandler responseHandler, FileInfo fileInfo, string contentType) 62 | { 63 | if (fileInfo == null) throw new ArgumentNullException("fileInfo"); 64 | var headers = BuildBasicHeaders(fileInfo.Length, contentType); 65 | return responseHandler(200, headers, FromFile(fileInfo)); 66 | } 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/Print/Print.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E} 9 | Library 10 | Properties 11 | Print 12 | Print 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\..\build 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | Properties\CommonAssemblyInfo.cs 46 | 47 | 48 | 49 | 50 | 51 | {92c89faf-d1f0-4e9e-b2c6-49d7587e01b3} 52 | OwinHelpers 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /src/TestModule/TestModule.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {09082961-1494-4A68-9BD2-90454F41E0C5} 9 | Library 10 | Properties 11 | TestModule 12 | TestModule 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\..\build 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Properties\CommonAssemblyInfo.cs 47 | 48 | 49 | 50 | 51 | {92c89faf-d1f0-4e9e-b2c6-49d7587e01b3} 52 | OwinHelpers 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /src/Fix.AspNet/Fix.AspNet40.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {092A4868-9F00-4417-A965-5493224FC9F8} 8 | Library 9 | Properties 10 | Fix.AspNet 11 | Fix.AspNet4 12 | v4.0 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\net40\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | ..\..\build\net40\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\CommonAssemblyInfo.cs 51 | 52 | 53 | 54 | 61 | -------------------------------------------------------------------------------- /src/Print/RequestPrinter.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using System.Text; 5 | using OwinHelpers; 6 | using AppFunc = System.Func< // Call 7 | System.Collections.Generic.IDictionary, // Environment 8 | System.Threading.Tasks.Task>; // Done 9 | 10 | namespace Print 11 | { 12 | using System.IO; 13 | using System.Threading; 14 | using System.Threading.Tasks; 15 | 16 | public class RequestPrinter 17 | { 18 | [Export("Owin.Application")] 19 | public Task PrintRequest(IDictionary env, Func next) 20 | { 21 | try 22 | { 23 | var scriptName = env.GetPath().ToLower(); 24 | if (!(scriptName.Contains("/info") || scriptName.Contains("."))) 25 | { 26 | return HandlePrintRequest(env); 27 | } 28 | } 29 | catch (Exception ex) 30 | { 31 | return TaskHelper.Error(ex); 32 | } 33 | return next(); 34 | } 35 | 36 | private static Task HandlePrintRequest(IDictionary env) 37 | { 38 | env["owin.ResponseStatusCode"] = 200; 39 | env["owin.ResponseHeaders"] = 40 | new Dictionary {{"Content-Type", new[] {"text/html"}}}; 41 | return ((Stream) env["owin.ResponseBody"]).WriteAsync(BuildHtml(env)); 42 | } 43 | 44 | private static string BuildHtml(IDictionary env) 45 | { 46 | var builder = new StringBuilder(""); 47 | builder.AppendFormat("

{0}

", ConstructUri(env)); 48 | builder.AppendFormat("

{0}

", env["owin.RequestMethod"]); 49 | foreach (var header in env) 50 | { 51 | builder.AppendFormat("

{0}: {1}

", header.Key, header.Value); 52 | } 53 | builder.Append(""); 54 | return builder.ToString(); 55 | } 56 | 57 | private static string ConstructUri(IDictionary env) 58 | { 59 | object serverName; 60 | if (!env.TryGetValue("host.ServerName", out serverName)) 61 | { 62 | serverName = "*"; 63 | } 64 | var builder = new StringBuilder(env["owin.RequestScheme"] + "://" + serverName); 65 | if (env.ContainsKey("host.ServerPort") && env["host.ServerPort"].ToString() != "80") 66 | { 67 | builder.AppendFormat(":{0}", env["host.ServerPort"]); 68 | } 69 | if (!string.IsNullOrEmpty(env["owin.RequestPath"].ToString())) 70 | { 71 | builder.AppendFormat("{0}", env["owin.RequestPath"]); 72 | } 73 | return builder.ToString(); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/OwinHelpers/OwinHelpers.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3} 9 | Library 10 | Properties 11 | OwinHelpers 12 | OwinHelpers 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\..\build 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Properties\CommonAssemblyInfo.cs 55 | 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /src/FileHandler/FileHandler.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {88EEAA81-6680-4EAD-B66B-D14667EA3236} 9 | Library 10 | Properties 11 | FileHandler 12 | FileHandler 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\..\build 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | Properties\CommonAssemblyInfo.cs 48 | 49 | 50 | 51 | 52 | Always 53 | 54 | 55 | 56 | 57 | {92c89faf-d1f0-4e9e-b2c6-49d7587e01b3} 58 | OwinHelpers 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /src/Info/Info.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {606BAC3F-F5A2-46A9-AFFB-EDF7231850FD} 9 | Library 10 | Properties 11 | Info 12 | Info 13 | v4.0 14 | 512 15 | ..\ 16 | true 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | ..\..\build 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | Properties\CommonAssemblyInfo.cs 49 | 50 | 51 | 52 | 53 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3} 54 | OwinHelpers 55 | 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /src/Fix.AspNet/Fix.AspNet.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD} 8 | Library 9 | Properties 10 | Fix.AspNet 11 | Fix.AspNet 12 | v4.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\net45\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | pdbonly 28 | true 29 | ..\..\build\net45\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\CommonAssemblyInfo.cs 51 | 52 | 53 | 54 | 55 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 56 | Fix 57 | 58 | 59 | 60 | 67 | -------------------------------------------------------------------------------- /src/Fix/Fix40.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {740D1911-6C2B-4E30-8D79-75E8BF91C138} 9 | Library 10 | Properties 11 | Fix 12 | Fix4 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\net40\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | ..\..\build\net40\ 29 | TRACE 30 | prompt 31 | 4 32 | ..\..\build\net40\Fix4.XML 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | Properties\CommonAssemblyInfo.cs 59 | 60 | 61 | 62 | 63 | 70 | -------------------------------------------------------------------------------- /src/Fix.AppBuilder/Fix.AppBuilder40.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {92E8D1C4-D73A-4FC2-8942-2CBA1BFBFFC0} 8 | Library 9 | Properties 10 | Fix.AppBuilder 11 | Fix.AppBuilder4 12 | v4.0 13 | 512 14 | ..\ 15 | true 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\net40\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | pdbonly 29 | true 30 | ..\..\build\net40\ 31 | TRACE 32 | prompt 33 | 4 34 | 35 | 36 | 37 | ..\packages\Owin.1.0\lib\net40\Owin.dll 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 64 | -------------------------------------------------------------------------------- /src/Fix/Fix.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 9 | Library 10 | Properties 11 | Fix 12 | Fix 13 | v4.5 14 | 512 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\net45\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | ..\..\build\net45\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | ..\..\build\net45\Fix.XML 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | Properties\CommonAssemblyInfo.cs 62 | 63 | 64 | 65 | 66 | 73 | -------------------------------------------------------------------------------- /src/Fix.AppBuilder/Fix.AppBuilder.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {D6511122-F753-45FD-922F-9857E20521AF} 8 | Library 9 | Properties 10 | Fix.AppBuilder 11 | Fix.AppBuilder 12 | v4.5 13 | 512 14 | ..\ 15 | true 16 | 17 | 18 | 19 | true 20 | full 21 | false 22 | bin\net45\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | false 27 | 28 | 29 | pdbonly 30 | true 31 | ..\..\build\net45\ 32 | TRACE 33 | prompt 34 | 4 35 | false 36 | 37 | 38 | 39 | ..\packages\Owin.1.0\lib\net40\Owin.dll 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 60 | Fix 61 | 62 | 63 | 64 | 65 | 72 | -------------------------------------------------------------------------------- /src/SimpleNowinDemo/SimpleNowinDemo.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011} 8 | Exe 9 | Properties 10 | SimpleNowinDemo 11 | SimpleNowinDemo 12 | v4.5 13 | 512 14 | ..\ 15 | true 16 | 17 | 18 | AnyCPU 19 | true 20 | full 21 | false 22 | bin\Debug\ 23 | DEBUG;TRACE 24 | prompt 25 | 4 26 | 27 | 28 | AnyCPU 29 | pdbonly 30 | true 31 | bin\Release\ 32 | TRACE 33 | prompt 34 | 4 35 | 36 | 37 | 38 | ..\packages\Nowin.0.9.1.0\lib\net45\Nowin.dll 39 | 40 | 41 | False 42 | ..\packages\Simple.Web.0.10.2.50111\lib\net40\Simple.Web.dll 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 63 | Fix 64 | 65 | 66 | 67 | 68 | 75 | -------------------------------------------------------------------------------- /src/Tests/Fix.AppBuilder.Test/Fix.AppBuilder.Test.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6} 8 | Library 9 | Properties 10 | Fix.AppBuilder.Test 11 | Fix.AppBuilder.Test 12 | v4.5 13 | 512 14 | ..\..\ 15 | true 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | 34 | 35 | 36 | ..\..\packages\Owin.1.0\lib\net40\Owin.dll 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ..\..\packages\xunit.1.9.2\lib\net20\xunit.dll 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {D6511122-F753-45FD-922F-9857E20521AF} 59 | Fix.AppBuilder 60 | 61 | 62 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 63 | Fix 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 78 | -------------------------------------------------------------------------------- /src/FixConsole/FixUp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | x86 6 | 8.0.30703 7 | 2.0 8 | {B7F7506F-0292-464F-95F6-2AD47865C79E} 9 | Exe 10 | Properties 11 | FixUp 12 | FixUp 13 | v4.0 14 | 15 | 16 | 512 17 | 18 | 19 | x86 20 | true 21 | full 22 | false 23 | bin\Debug\ 24 | DEBUG;TRACE 25 | prompt 26 | 4 27 | 28 | 29 | x86 30 | pdbonly 31 | true 32 | ..\..\build 33 | TRACE 34 | prompt 35 | 4 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | Properties\CommonAssemblyInfo.cs 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | {88EEAA81-6680-4EAD-B66B-D14667EA3236} 59 | FileHandler 60 | 61 | 62 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 63 | Fix 64 | 65 | 66 | {606BAC3F-F5A2-46A9-AFFB-EDF7231850FD} 67 | Info 68 | 69 | 70 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E} 71 | Print 72 | 73 | 74 | {09082961-1494-4A68-9BD2-90454F41E0C5} 75 | TestModule 76 | 77 | 78 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386} 79 | TestServer 80 | 81 | 82 | 83 | 90 | -------------------------------------------------------------------------------- /tools/xUnit/NUnitXml.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | False 35 | True 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | False 54 | True 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | False 80 | True 81 | 82 | 83 | 84 | False 85 | True 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | -------------------------------------------------------------------------------- /src/FileHandler/FileReturner.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel.Composition; 4 | using System.IO; 5 | using System.Linq; 6 | using System.Text; 7 | using OwinHelpers; 8 | //using ResponseHandler = System.Action>, System.Action>, System.Action, System.Action, System.Action>>; 9 | //using App = System.Action>, System.Func, System.Action>, System.Action>, System.Action, System.Action, System.Action>>, System.Delegate>; 10 | 11 | using BodyDelegate = System.Func; 12 | using ResponseHandler = System.Func, System.Func, System.Threading.Tasks.Task>; 13 | using App = System.Func, System.Collections.Generic.IDictionary, System.IO.Stream, System.Threading.CancellationToken, System.Func, System.Func, System.Threading.Tasks.Task>, System.Delegate, System.Threading.Tasks.Task>; 14 | 15 | namespace FileHandler 16 | { 17 | using System.Diagnostics; 18 | using System.Threading; 19 | using System.Threading.Tasks; 20 | using System.Web; 21 | 22 | public class FileReturner 23 | { 24 | [Export("Owin.Application")] 25 | public Task ReturnFile(IDictionary env) 26 | { 27 | var tcs = new TaskCompletionSource(); 28 | if (env.GetPath().ToLower().Equals("/index.html", StringComparison.CurrentCultureIgnoreCase)) 29 | { 30 | try 31 | { 32 | env["owin.ResponseHeaders"] = new Dictionary 33 | { 34 | { 35 | "Content-Type", 36 | new[] {"text/html"} 37 | } 38 | }; 39 | HandleRequest(env); 40 | env["owin.ResponseStatusCode"] = 200; 41 | tcs.SetResult(0); 42 | } 43 | catch (Exception ex) 44 | { 45 | Trace.TraceError(ex.Message); 46 | tcs.SetCanceled(); 47 | } 48 | } 49 | else 50 | { 51 | tcs.SetCanceled(); 52 | } 53 | return tcs.Task; 54 | } 55 | 56 | private static void HandleRequest(IDictionary env) 57 | { 58 | var responseStream = (Stream) env["owin.ResponseBody"]; 59 | FileInfo fileInfo = null; 60 | if (env.ContainsKey("aspnet.Context")) 61 | { 62 | var context = (HttpContext) env["aspnet.Context"]; 63 | fileInfo = new FileInfo(Path.Combine(context.Server.MapPath("bin"), "index.html")); 64 | } 65 | else 66 | { 67 | fileInfo = new FileInfo(Path.Combine(Environment.CurrentDirectory, "index.html")); 68 | } 69 | using (var source = fileInfo.OpenRead()) 70 | { 71 | source.CopyTo(responseStream); 72 | } 73 | } 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/TestServer/Server.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Net; 5 | using System.Threading.Tasks; 6 | 7 | namespace TestServer 8 | { 9 | using System.Threading; 10 | using OwinEnvironment = IDictionary; 11 | using OwinHeaders = IDictionary; 12 | using Starter = Action, Task>>; 13 | using AppFunc = System.Func< // Call 14 | System.Collections.Generic.IDictionary, // Environment 15 | System.Threading.Tasks.Task>; 16 | using System.Linq; 17 | 18 | public class Server : IDisposable 19 | { 20 | readonly HttpListener _listener; 21 | 22 | public Server(string prefix) 23 | { 24 | _listener = new HttpListener(); 25 | _listener.Prefixes.Add(prefix); 26 | } 27 | 28 | public void Start(AppFunc app) 29 | { 30 | _listener.Start(); 31 | _listener.BeginGetContext(GotContext, app); 32 | } 33 | 34 | public void Stop() 35 | { 36 | try 37 | { 38 | _listener.Stop(); 39 | } 40 | catch (Exception ex) 41 | { 42 | Console.WriteLine(ex.ToString()); 43 | } 44 | } 45 | 46 | private void GotContext(IAsyncResult result) 47 | { 48 | try 49 | { 50 | var context = _listener.EndGetContext(result); 51 | var app = (AppFunc) result.AsyncState; 52 | var env = CreateEnvironmentHash(context.Request); 53 | var headers = CreateRequestHeaders(context.Request); 54 | app(env) 55 | .ContinueWith(t => 56 | { 57 | context.Response.StatusCode = (int) env["owin.ResponseStatusCode"]; 58 | WriteHeaders((IDictionary)env["owin.ResponseHeaders"], context); 59 | return Complete(); 60 | }, TaskContinuationOptions.None) 61 | .ContinueWith(t => context.Response.Close()); 62 | 63 | _listener.BeginGetContext(GotContext, app); 64 | } 65 | catch (Exception ex) 66 | { 67 | Console.WriteLine(ex.ToString()); 68 | } 69 | } 70 | 71 | private static Task Complete() 72 | { 73 | var tcs = new TaskCompletionSource(); 74 | tcs.SetResult(null); 75 | return tcs.Task; 76 | } 77 | 78 | private static void WriteHeaders(IEnumerable> outputHeaders, HttpListenerContext context) 79 | { 80 | if (outputHeaders != null) 81 | { 82 | context.Response.Headers.Clear(); 83 | foreach (var outputHeader in outputHeaders) 84 | { 85 | if (SpecialCase(outputHeader.Key, outputHeader.Value, context.Response)) continue; 86 | foreach (var value in outputHeader.Value) 87 | { 88 | context.Response.Headers.Add(outputHeader.Key, value); 89 | } 90 | } 91 | } 92 | } 93 | 94 | private static bool SpecialCase(string key, string[] value, HttpListenerResponse response) 95 | { 96 | if (key.Equals("Content-Length", StringComparison.OrdinalIgnoreCase)) 97 | { 98 | response.ContentLength64 = long.Parse(value[0]); 99 | return true; 100 | } 101 | if (key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) 102 | { 103 | response.ContentType = value[0]; 104 | return true; 105 | } 106 | return false; 107 | } 108 | 109 | private static IDictionary CreateEnvironmentHash(HttpListenerRequest request) 110 | { 111 | return new Dictionary(StringComparer.OrdinalIgnoreCase) 112 | { 113 | 114 | {"owin.RequestMethod", request.HttpMethod}, 115 | {"owin.RequestPath", request.Url.AbsolutePath}, 116 | {"owin.RequestPathBase", string.Empty}, 117 | {"owin.RequestQueryString", request.Url.Query}, 118 | {"host.ServerName", request.Url.Host}, 119 | {"host.ServerPort", request.Url.Port.ToString()}, 120 | {"owin.RequestProtocol", "HTTP/" + request.ProtocolVersion.ToString(2)}, 121 | {"owin.RequestScheme", request.Url.Scheme}, 122 | {"owin.Version", "1.0"}, 123 | }; 124 | } 125 | 126 | private static IDictionary CreateRequestHeaders(HttpListenerRequest request) 127 | { 128 | return request.Headers.AllKeys.ToDictionary(k => k, k => request.Headers.GetValues(k), 129 | StringComparer.OrdinalIgnoreCase); 130 | } 131 | 132 | public void Dispose() 133 | { 134 | ((IDisposable)_listener).Dispose(); 135 | } 136 | 137 | private static string GetStatusText(int status) 138 | { 139 | return StatusTexts.ContainsKey(status) ? StatusTexts[status] : string.Empty; 140 | } 141 | 142 | private static readonly Dictionary StatusTexts = new Dictionary 143 | { 144 | {200, "OK"}, 145 | }; 146 | } 147 | } 148 | -------------------------------------------------------------------------------- /src/FixAsp/FixAsp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | 8 | 9 | 2.0 10 | {34AA28DF-087C-46DA-9E62-652EB36789AA} 11 | {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} 12 | Library 13 | Properties 14 | FixAsp 15 | FixAsp 16 | v4.5 17 | true 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | true 26 | full 27 | false 28 | bin\ 29 | DEBUG;TRACE 30 | prompt 31 | 4 32 | false 33 | 34 | 35 | pdbonly 36 | true 37 | ..\..\build 38 | TRACE 39 | prompt 40 | 4 41 | false 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Properties\CommonAssemblyInfo.cs 68 | 69 | 70 | 71 | 72 | 73 | Web.config 74 | 75 | 76 | 77 | 78 | Web.config 79 | 80 | 81 | 82 | 83 | {88eeaa81-6680-4ead-b66b-d14667ea3236} 84 | FileHandler 85 | 86 | 87 | {ccac0a87-18f1-4db9-bf12-9185a81917cd} 88 | Fix.AspNet 89 | 90 | 91 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0} 92 | Fix 93 | 94 | 95 | {0316d0f1-ef56-41de-a501-68dc0dff8e5e} 96 | Print 97 | 98 | 99 | 100 | 12.0 101 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | True 111 | True 112 | 0 113 | / 114 | http://localhost:20549/ 115 | False 116 | False 117 | 118 | 119 | False 120 | 121 | 122 | 123 | 124 | 131 | -------------------------------------------------------------------------------- /tools/xUnit/HTML.xslt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ]]> 6 | 7 | 8 | 9 | xUnit.net Test Results - <xsl:value-of select="@name"/> 10 | 11 | 30 | 41 | 42 | 43 |

Assemblies Run

44 | 45 | 46 |

Summary

47 |
48 | Tests run:   49 | Failures: , 50 | Skipped: , 51 | Run time: s 52 |
53 | 54 |
55 |

Failed tests

56 | 57 |
58 | 59 |
60 |

Failed fixtures

61 | 62 |
63 | 64 |
65 |

Skipped tests

66 | 67 |
68 |
69 |

All tests

70 |
Click test class name to expand/collapse test details
71 | 72 | 73 | 74 |
75 | 76 | 77 |
78 |
79 | 80 | 81 |
82 | altrow 83 | s 84 | Skipped 85 | 86 | 87 |   88 | : 89 |
90 | 91 |
92 |
93 | 94 |

Output

95 |
96 |
97 |
98 |
99 | 100 | 101 | :
102 | Stack Trace:
103 |
104 |
105 | 106 | 107 |

108 | s 109 | 110 | ToggleClass('class') 111 | ToggleClass('class') 112 | 113 | 114 |   115 |  ( tests) 116 | 117 |
118 |

119 |
120 | display: none; 121 | class 122 | 123 |
124 |
125 | 126 |
-------------------------------------------------------------------------------- /src/.nuget/NuGet.targets: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | $(MSBuildProjectDirectory)\..\ 5 | 6 | 7 | false 8 | 9 | 10 | false 11 | 12 | 13 | true 14 | 15 | 16 | false 17 | 18 | 19 | 20 | 21 | 22 | 26 | 27 | 28 | 29 | 30 | $([System.IO.Path]::Combine($(SolutionDir), ".nuget")) 31 | $([System.IO.Path]::Combine($(ProjectDir), "packages.config")) 32 | $([System.IO.Path]::Combine($(SolutionDir), "packages")) 33 | 34 | 35 | 36 | 37 | $(SolutionDir).nuget 38 | packages.config 39 | $(SolutionDir)packages 40 | 41 | 42 | 43 | 44 | $(NuGetToolsPath)\NuGet.exe 45 | @(PackageSource) 46 | 47 | "$(NuGetExePath)" 48 | mono --runtime=v4.0.30319 $(NuGetExePath) 49 | 50 | $(TargetDir.Trim('\\')) 51 | 52 | -RequireConsent 53 | 54 | $(NuGetCommand) install "$(PackagesConfig)" -source "$(PackageSources)" $(RequireConsentSwitch) -o "$(PackagesDir)" 55 | $(NuGetCommand) pack "$(ProjectPath)" -p Configuration=$(Configuration) -o "$(PackageOutputDir)" -symbols 56 | 57 | 58 | 59 | RestorePackages; 60 | $(ResolveReferencesDependsOn); 61 | 62 | 63 | 64 | 65 | $(BuildDependsOn); 66 | BuildPackage; 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 89 | 90 | 93 | 94 | 95 | 96 | 98 | 99 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 150 | 151 | 152 | 153 | -------------------------------------------------------------------------------- /src/Fix.AspNet/Bridge.cs: -------------------------------------------------------------------------------- 1 | namespace Fix.AspNet 2 | { 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Net.Mail; 6 | using System.Reflection; 7 | using System.Threading; 8 | using System.Threading.Tasks; 9 | using System.Web; 10 | using System.Web.Compilation; 11 | using Fix; 12 | using OwinEnvironment = System.Collections.Generic.IDictionary; 13 | using OwinHeaders = System.Collections.Generic.IDictionary; 14 | using AppFunc = System.Func< // Call 15 | System.Collections.Generic.IDictionary, // Environment 16 | System.Threading.Tasks.Task>; 17 | using System.Linq; 18 | 19 | internal class Bridge 20 | { 21 | private static readonly object SyncApp = new object(); 22 | private static AppFunc _app; 23 | private static IDictionary _serverVariables; 24 | 25 | public static Task RunContext(HttpContext context) 26 | { 27 | if (_app == null) 28 | { 29 | Initialize(context); 30 | if (_app == null) 31 | { 32 | throw new InvalidOperationException("No application found."); 33 | } 34 | } 35 | 36 | var env = CreateEnvironmentHash(context); 37 | var tcs = new TaskCompletionSource(); 38 | env.Add(OwinKeys.CallCompleted, tcs.Task); 39 | var task = _app(env); 40 | return task 41 | .ContinueWith(t => 42 | { 43 | if (t.Exception != null) 44 | { 45 | context.Response.StatusCode = 500; 46 | 47 | foreach (Exception ex in t.Exception.InnerExceptions) 48 | { 49 | context.AddError(ex); 50 | } 51 | } 52 | else if (!env.ContainsKey(OwinKeys.ResponseStatusCode)) 53 | { 54 | context.Response.StatusCode = 404; 55 | } 56 | else 57 | { 58 | context.Response.StatusCode = (int)env[OwinKeys.ResponseStatusCode]; 59 | } 60 | 61 | if (env.ContainsKey(OwinKeys.ResponseHeaders)) 62 | { 63 | WriteHeaders((IDictionary)env[OwinKeys.ResponseHeaders], context); 64 | } 65 | return TaskHelper.Completed(); 66 | 67 | }, TaskContinuationOptions.None) 68 | .Unwrap() 69 | .ContinueWith(t => SetOwinCallCompleted(t, tcs)); 70 | } 71 | 72 | private static void SetOwinCallCompleted(Task t, TaskCompletionSource tcs) 73 | { 74 | if (t.IsFaulted) 75 | { 76 | tcs.TrySetException(t.Exception ?? new Exception("An unknown error occurred.")); 77 | } 78 | else if (t.IsCanceled) 79 | { 80 | tcs.TrySetCanceled(); 81 | } 82 | else 83 | { 84 | tcs.SetResult(null); 85 | } 86 | } 87 | 88 | private static void Initialize(HttpContext context) 89 | { 90 | lock (SyncApp) 91 | { 92 | if (_app != null) return; 93 | 94 | _app = AppFuncBuilder.Create(BuildManager.GetReferencedAssemblies().Cast()).Build(); 95 | _serverVariables = context.Request.ServerVariables.AllKeys 96 | .ToDictionary(v => v, v => context.Request.ServerVariables.Get(v)); 97 | } 98 | } 99 | 100 | private static void WriteHeaders(IEnumerable> outputHeaders, HttpContext context) 101 | { 102 | if (outputHeaders != null) 103 | { 104 | foreach (var outputHeader in outputHeaders) 105 | { 106 | if (SpecialCase(outputHeader.Key, outputHeader.Value, context.Response)) continue; 107 | foreach (var value in outputHeader.Value) 108 | { 109 | context.Response.Headers.Add(outputHeader.Key, value); 110 | } 111 | } 112 | } 113 | } 114 | 115 | private static bool SpecialCase(string key, string[] value, HttpResponse response) 116 | { 117 | if (key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase)) 118 | { 119 | response.ContentType = value[0]; 120 | return true; 121 | } 122 | return false; 123 | } 124 | 125 | private static OwinEnvironment CreateEnvironmentHash(HttpContext context) 126 | { 127 | var request = context.Request; 128 | string localAddr; 129 | string remoteAddr; 130 | string remotePort; 131 | string serverPort; 132 | string httpVersion; 133 | 134 | _serverVariables.TryGetValue("LOCAL_ADDR", out localAddr); 135 | _serverVariables.TryGetValue("REMOTE_ADDR", out remoteAddr); 136 | _serverVariables.TryGetValue("REMOTE_PORT", out remotePort); 137 | _serverVariables.TryGetValue("SERVER_PORT", out serverPort); 138 | _serverVariables.TryGetValue("HTTP_VERSION", out httpVersion); 139 | 140 | return new Dictionary(StringComparer.Ordinal) 141 | { 142 | {OwinKeys.RequestMethod, request.HttpMethod}, 143 | {OwinKeys.RequestPath, request.AppRelativeCurrentExecutionFilePath.MaybeSubstring(1) + request.PathInfo}, 144 | {OwinKeys.RequestPathBase, FixPath(HttpRuntime.AppDomainAppVirtualPath)}, 145 | {OwinKeys.RequestQueryString, request.Url.Query.TrimStart('?')}, 146 | {ServerKeys.LocalIpAddress, localAddr}, 147 | {ServerKeys.RemoteIpAddress, remoteAddr}, 148 | {ServerKeys.RemotePort, remotePort}, 149 | {ServerKeys.LocalPort, serverPort}, 150 | {OwinKeys.RequestProtocol, httpVersion}, 151 | {OwinKeys.RequestScheme, request.Url.Scheme}, 152 | {OwinKeys.RequestBody, request.InputStream}, 153 | {OwinKeys.RequestHeaders, CreateRequestHeaders(request)}, 154 | {OwinKeys.Version, "1.0"}, 155 | {OwinKeys.ResponseBody, context.Response.OutputStream}, 156 | {OwinKeys.ResponseHeaders, new Dictionary()}, 157 | {OwinKeys.CallCancelled, new CancellationToken()}, 158 | {SendFileKeys.SendAsync, CreateSendFileFunc(context.Response)}, 159 | {"aspnet.Context", context}, 160 | }; 161 | } 162 | 163 | private static Func CreateSendFileFunc(HttpResponse response) 164 | { 165 | return (path, offset, byteCount, cancel) => 166 | { 167 | var length = byteCount.HasValue ? byteCount.Value : -1; 168 | response.TransmitFile(path, offset, length); 169 | return TaskHelper.Completed(); 170 | }; 171 | } 172 | 173 | private static IDictionary CreateRequestHeaders(HttpRequest request) 174 | { 175 | return request.Headers.AllKeys.ToDictionary(k => k, k => request.Headers.GetValues(k), 176 | StringComparer.OrdinalIgnoreCase); 177 | } 178 | 179 | private static string FixPath(string path) 180 | { 181 | if (string.IsNullOrWhiteSpace(path) || path == "/") return string.Empty; 182 | 183 | return path[0] == '/' ? path : '/' + path; 184 | } 185 | } 186 | 187 | static class StringMaybe 188 | { 189 | public static string MaybeSubstring(this string str, int index) 190 | { 191 | return str == null ? string.Empty : str.Substring(1); 192 | } 193 | } 194 | } 195 | -------------------------------------------------------------------------------- /src/Fix/AppFuncBuilder.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using System.Threading.Tasks; 6 | 7 | namespace Fix 8 | { 9 | using UseAction = Action, Func, Task>>; 10 | using AppFunc = Func, Task>; 11 | 12 | public class AppFuncBuilder 13 | { 14 | private readonly IDictionary _startupEnv; 15 | private static IList _adapters; 16 | private readonly IList _assemblies; 17 | 18 | private AppFuncBuilder(IList assemblies, IDictionary startupEnv) 19 | { 20 | _assemblies = assemblies; 21 | _startupEnv = startupEnv; 22 | } 23 | 24 | public static AppFuncBuilder Create() 25 | { 26 | return Create(new Dictionary()); 27 | } 28 | 29 | public static AppFuncBuilder Create(IDictionary startupEnv) 30 | { 31 | var assemblies = AssemblyManager.GetReferencedAssemblies().ToList(); 32 | if (_adapters == null) 33 | { 34 | LoadAdapters(assemblies); 35 | } 36 | return new AppFuncBuilder(assemblies, startupEnv); 37 | } 38 | 39 | public static AppFuncBuilder Create(IEnumerable assemblies) 40 | { 41 | return Create(assemblies, new Dictionary()); 42 | } 43 | 44 | public static AppFuncBuilder Create(IEnumerable assemblies, IDictionary startupEnv) 45 | { 46 | var list = assemblies.ToList(); 47 | if (_adapters == null) 48 | { 49 | LoadAdapters(list); 50 | } 51 | return new AppFuncBuilder(list, startupEnv); 52 | } 53 | 54 | private static void LoadAdapters(IEnumerable assemblies) 55 | { 56 | var adapters = 57 | assemblies.SelectMany(TryGetExportedFixerAdapterTypes) 58 | .Distinct() 59 | .Select(Activator.CreateInstance) 60 | .Cast(); 61 | _adapters = new List(adapters); 62 | } 63 | 64 | private static IEnumerable TryGetExportedFixerAdapterTypes(Assembly a) 65 | { 66 | try 67 | { 68 | return a.GetExportedTypes().Where(t => !t.IsInterface).Where(typeof(IFixerAdapter).IsAssignableFrom); 69 | } 70 | catch (Exception) 71 | { 72 | return Enumerable.Empty(); 73 | } 74 | } 75 | 76 | private const BindingFlags MethodBindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; 77 | 78 | public Func, Task> Build() 79 | { 80 | var fixerSetupMethod = FindFixerSetupMethod(); 81 | var fixer = new Fixer(); 82 | 83 | object instance = fixerSetupMethod.IsStatic || fixerSetupMethod.DeclaringType == null 84 | ? null 85 | : CreateInstanceOfOwinAppSetupClass(fixerSetupMethod.DeclaringType); 86 | 87 | object[] parameters; 88 | 89 | var parameterInfos = fixerSetupMethod.GetParameters(); 90 | if (parameterInfos.Length == 1) 91 | { 92 | parameters = new object[1]; 93 | var parameterType = parameterInfos[0].ParameterType; 94 | if (parameterType.IsAssignableFrom(typeof (Fixer))) 95 | { 96 | parameters[0] = fixer; 97 | } 98 | else 99 | { 100 | var adapter = _adapters.FirstOrDefault(a => parameterType.IsAssignableFrom(a.AdaptedType)); 101 | if (adapter != null) 102 | { 103 | parameters[0] = adapter.Adapt(fixer); 104 | } 105 | } 106 | if (parameters[0] == null) 107 | { 108 | parameters[0] = new Action>(f => fixer.Use(f)); 109 | } 110 | } 111 | else 112 | { 113 | var useAction = new Action>(f => fixer.Use(f)); 114 | var mapAction = new Action>((p,f) => fixer.Map(p,f)); 115 | parameters = new object[]{useAction, mapAction}; 116 | } 117 | 118 | fixerSetupMethod.Invoke(instance, parameters); 119 | return fixer.Build(); 120 | } 121 | 122 | private object CreateInstanceOfOwinAppSetupClass(Type type) 123 | { 124 | var constructors = type.GetConstructors(); 125 | var withStartupEnv = (from constructor in constructors 126 | let parameters = constructor.GetParameters() 127 | where parameters.Length == 1 && parameters[0].ParameterType == typeof(IDictionary) 128 | select constructor).FirstOrDefault(); 129 | if (withStartupEnv != null) 130 | { 131 | return Activator.CreateInstance(type, _startupEnv); 132 | } 133 | return Activator.CreateInstance(type); 134 | } 135 | 136 | private MethodInfo FindFixerSetupMethod() 137 | { 138 | var fixerSetupMethods = _assemblies 139 | .SelectMany(TryGetExportedFixerMethods) 140 | .Where(m => !ReferenceEquals(m, null)) 141 | .ToList(); 142 | 143 | if (fixerSetupMethods.Count == 0) 144 | throw new EntryPointNotFoundException( 145 | "No type was found called OwinAppSetup with a method taking a valid parameter type."); 146 | if (fixerSetupMethods.Count > 1) 147 | throw new EntryPointNotFoundException( 148 | "More than one type was found called OwinAppSetup with a method taking a valid parameter type."); 149 | 150 | var fixerSetupMethod = fixerSetupMethods.Single(); 151 | return fixerSetupMethod; 152 | } 153 | 154 | private static IEnumerable TryGetExportedFixerMethods(Assembly a) 155 | { 156 | try 157 | { 158 | return a.GetExportedTypes().Where(t => t.Name.Equals("OwinAppSetup")).Select(FixerMethod); 159 | } 160 | catch (Exception) 161 | { 162 | return Enumerable.Empty(); 163 | } 164 | } 165 | 166 | private static MethodInfo FixerMethod(Type type) 167 | { 168 | return type.GetMethods(MethodBindingFlags).FirstOrDefault(MethodTakesFixerParameter) 169 | ?? 170 | type.GetMethods(MethodBindingFlags).FirstOrDefault(MethodTakesUseAndMapActionParameters) 171 | ?? 172 | type.GetMethods(MethodBindingFlags).FirstOrDefault(MethodTakesUseActionParameter) 173 | ?? 174 | type.GetMethods(MethodBindingFlags).FirstOrDefault(MethodTakesAdapterParameter); 175 | } 176 | 177 | private static bool MethodTakesAdapterParameter(MethodInfo methodInfo) 178 | { 179 | try 180 | { 181 | var parameters = methodInfo.GetParameters(); 182 | return parameters.Length == 1 && _adapters.Any(a => parameters[0].ParameterType == a.AdaptedType); 183 | } 184 | catch 185 | { 186 | return false; 187 | } 188 | } 189 | 190 | private static bool MethodTakesFixerParameter(MethodInfo methodInfo) 191 | { 192 | try 193 | { 194 | var parameters = methodInfo.GetParameters(); 195 | return parameters.Length == 1 196 | && 197 | parameters[0].ParameterType == typeof(Fixer); 198 | } 199 | catch 200 | { 201 | return false; 202 | } 203 | } 204 | 205 | private static bool MethodTakesUseActionParameter(MethodInfo methodInfo) 206 | { 207 | var actionType = typeof (Action>); 208 | try 209 | { 210 | var parameters = methodInfo.GetParameters(); 211 | return parameters.Length == 1 && parameters[0].ParameterType == actionType; 212 | } 213 | catch 214 | { 215 | return false; 216 | } 217 | } 218 | private static bool MethodTakesUseAndMapActionParameters(MethodInfo methodInfo) 219 | { 220 | var useType = typeof (Action>); 221 | var mapType = typeof (Action>); 222 | try 223 | { 224 | var parameters = methodInfo.GetParameters(); 225 | return parameters.Length == 2 226 | && parameters[0].ParameterType == useType 227 | && parameters[1].ParameterType == mapType; 228 | } 229 | catch 230 | { 231 | return false; 232 | } 233 | } 234 | } 235 | } 236 | -------------------------------------------------------------------------------- /src/Fix.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 2013 4 | VisualStudioVersion = 12.0.30324.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Print", "Print\Print.csproj", "{0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestServer", "TestServer\TestServer.csproj", "{CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}" 9 | EndProject 10 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{42ADB526-636D-444A-9947-3060A6062D69}" 11 | ProjectSection(SolutionItems) = preProject 12 | CommonAssemblyInfo.cs = CommonAssemblyInfo.cs 13 | README.md = README.md 14 | EndProjectSection 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fix", "Fix\Fix.csproj", "{AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FileHandler", "FileHandler\FileHandler.csproj", "{88EEAA81-6680-4EAD-B66B-D14667EA3236}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fix.AspNet", "Fix.AspNet\Fix.AspNet.csproj", "{CCAC0A87-18F1-4DB9-BF12-9185A81917CD}" 21 | EndProject 22 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{5E40E1FF-B35B-43E0-B5CD-9468D54C8553}" 23 | ProjectSection(SolutionItems) = preProject 24 | .nuget\NuGet.Config = .nuget\NuGet.Config 25 | .nuget\NuGet.exe = .nuget\NuGet.exe 26 | EndProjectSection 27 | EndProject 28 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SimpleNowinDemo", "SimpleNowinDemo\SimpleNowinDemo.csproj", "{044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}" 29 | EndProject 30 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fix.AppBuilder", "Fix.AppBuilder\Fix.AppBuilder.csproj", "{D6511122-F753-45FD-922F-9857E20521AF}" 31 | EndProject 32 | Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{F39406E5-857A-43C7-A692-B4ABF4B0B3C8}" 33 | EndProject 34 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Fix.AppBuilder.Test", "Tests\Fix.AppBuilder.Test\Fix.AppBuilder.Test.csproj", "{3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}" 35 | EndProject 36 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OwinHelpers", "OwinHelpers\OwinHelpers.csproj", "{92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}" 37 | EndProject 38 | Global 39 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 40 | Debug|Any CPU = Debug|Any CPU 41 | Debug|Mixed Platforms = Debug|Mixed Platforms 42 | Debug|x86 = Debug|x86 43 | Release|Any CPU = Release|Any CPU 44 | Release|Mixed Platforms = Release|Mixed Platforms 45 | Release|x86 = Release|x86 46 | EndGlobalSection 47 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 48 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 51 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 52 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Debug|x86.ActiveCfg = Debug|Any CPU 53 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Release|Any CPU.ActiveCfg = Release|Any CPU 54 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Release|Any CPU.Build.0 = Release|Any CPU 55 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 56 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Release|Mixed Platforms.Build.0 = Release|Any CPU 57 | {0316D0F1-EF56-41DE-A501-68DC0DFF8E5E}.Release|x86.ActiveCfg = Release|Any CPU 58 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 59 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Debug|Any CPU.Build.0 = Debug|Any CPU 60 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 61 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 62 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Debug|x86.ActiveCfg = Debug|Any CPU 63 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Release|Any CPU.ActiveCfg = Release|Any CPU 64 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Release|Any CPU.Build.0 = Release|Any CPU 65 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 66 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Release|Mixed Platforms.Build.0 = Release|Any CPU 67 | {CAFD0C47-ADF9-43F6-BCA5-8FF093B98386}.Release|x86.ActiveCfg = Release|Any CPU 68 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 69 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Debug|Any CPU.Build.0 = Debug|Any CPU 70 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 71 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 72 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Debug|x86.ActiveCfg = Debug|Any CPU 73 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Release|Any CPU.ActiveCfg = Release|Any CPU 74 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Release|Any CPU.Build.0 = Release|Any CPU 75 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 76 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Release|Mixed Platforms.Build.0 = Release|Any CPU 77 | {AE24B4A3-30AE-4479-BB37-A37BB65BFBC0}.Release|x86.ActiveCfg = Release|Any CPU 78 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 79 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Debug|Any CPU.Build.0 = Debug|Any CPU 80 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 81 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 82 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Debug|x86.ActiveCfg = Debug|Any CPU 83 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Release|Any CPU.ActiveCfg = Release|Any CPU 84 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Release|Any CPU.Build.0 = Release|Any CPU 85 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 86 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Release|Mixed Platforms.Build.0 = Release|Any CPU 87 | {88EEAA81-6680-4EAD-B66B-D14667EA3236}.Release|x86.ActiveCfg = Release|Any CPU 88 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 89 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Debug|Any CPU.Build.0 = Debug|Any CPU 90 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 91 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 92 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Debug|x86.ActiveCfg = Debug|Any CPU 93 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Release|Any CPU.ActiveCfg = Release|Any CPU 94 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Release|Any CPU.Build.0 = Release|Any CPU 95 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 96 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Release|Mixed Platforms.Build.0 = Release|Any CPU 97 | {CCAC0A87-18F1-4DB9-BF12-9185A81917CD}.Release|x86.ActiveCfg = Release|Any CPU 98 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 99 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Debug|Any CPU.Build.0 = Debug|Any CPU 100 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 101 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 102 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Debug|x86.ActiveCfg = Debug|Any CPU 103 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Release|Any CPU.ActiveCfg = Release|Any CPU 104 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Release|Any CPU.Build.0 = Release|Any CPU 105 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 106 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Release|Mixed Platforms.Build.0 = Release|Any CPU 107 | {044ECF9C-8FDC-41F4-AFCE-DCDC6169D011}.Release|x86.ActiveCfg = Release|Any CPU 108 | {D6511122-F753-45FD-922F-9857E20521AF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 109 | {D6511122-F753-45FD-922F-9857E20521AF}.Debug|Any CPU.Build.0 = Debug|Any CPU 110 | {D6511122-F753-45FD-922F-9857E20521AF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 111 | {D6511122-F753-45FD-922F-9857E20521AF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 112 | {D6511122-F753-45FD-922F-9857E20521AF}.Debug|x86.ActiveCfg = Debug|Any CPU 113 | {D6511122-F753-45FD-922F-9857E20521AF}.Release|Any CPU.ActiveCfg = Release|Any CPU 114 | {D6511122-F753-45FD-922F-9857E20521AF}.Release|Any CPU.Build.0 = Release|Any CPU 115 | {D6511122-F753-45FD-922F-9857E20521AF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 116 | {D6511122-F753-45FD-922F-9857E20521AF}.Release|Mixed Platforms.Build.0 = Release|Any CPU 117 | {D6511122-F753-45FD-922F-9857E20521AF}.Release|x86.ActiveCfg = Release|Any CPU 118 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 119 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Debug|Any CPU.Build.0 = Debug|Any CPU 120 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 121 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 122 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Debug|x86.ActiveCfg = Debug|Any CPU 123 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Release|Any CPU.ActiveCfg = Release|Any CPU 124 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Release|Any CPU.Build.0 = Release|Any CPU 125 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 126 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Release|Mixed Platforms.Build.0 = Release|Any CPU 127 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6}.Release|x86.ActiveCfg = Release|Any CPU 128 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 129 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Debug|Any CPU.Build.0 = Debug|Any CPU 130 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU 131 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU 132 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Debug|x86.ActiveCfg = Debug|Any CPU 133 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Release|Any CPU.ActiveCfg = Release|Any CPU 134 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Release|Any CPU.Build.0 = Release|Any CPU 135 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU 136 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Release|Mixed Platforms.Build.0 = Release|Any CPU 137 | {92C89FAF-D1F0-4E9E-B2C6-49D7587E01B3}.Release|x86.ActiveCfg = Release|Any CPU 138 | EndGlobalSection 139 | GlobalSection(SolutionProperties) = preSolution 140 | HideSolutionNode = FALSE 141 | EndGlobalSection 142 | GlobalSection(NestedProjects) = preSolution 143 | {3D3797D4-A8DC-4C39-BAA9-71E0D5C6A3C6} = {F39406E5-857A-43C7-A692-B4ABF4B0B3C8} 144 | EndGlobalSection 145 | EndGlobal 146 | -------------------------------------------------------------------------------- /rakefile.rb: -------------------------------------------------------------------------------- 1 | include FileTest 2 | 3 | # Build information 4 | SOLUTION_NAME = "Fix" 5 | SOLUTION_DESC = "A glue for OWIN." 6 | SOLUTION_LICENSE = "http://www.opensource.org/licenses/mit-license.php" 7 | SOLUTION_URL = "http://github.com/markrendle/Fix" 8 | SOLUTION_COMPANY = "Mark Rendle" 9 | SOLUTION_COPYRIGHT = "Copyright (C) #{SOLUTION_COMPANY} 2010-2013" 10 | 11 | # Build configuration 12 | load "VERSION.txt" 13 | 14 | CONFIG = ENV["config"] || "Release" 15 | PLATFORM = ENV["platform"] || "x86" 16 | BUILD_NUMBER = "#{BUILD_VERSION}.#{(ENV["BUILD_NUMBER"] || Time.new.strftime('5%H%M'))}" 17 | MONO = !RUBY_PLATFORM.match("linux|darwin").nil? 18 | TEAMCITY = (!ENV["BUILD_NUMBER"].nil? or !ENV["TEAMCITY_BUILD_PROPERTIES_FILE"].nil?) 19 | TEAMCITY_BRANCH = !TEAMCITY ? nil : ENV["BRANCH"] 20 | 21 | # NuGet configuration 22 | NUGET_APIKEY_LOCAL = ENV["apikey_local"] 23 | NUGET_APIURL_LOCAL = ENV["apiurl_local"] 24 | NUGET_APIKEY_REMOTE = ENV["apikey_remote"] 25 | NUGET_APIURL_REMOTE = ENV["apiurl_remote"] 26 | ENV["EnableNuGetPackageRestore"] = "true" 27 | 28 | # Symbol server configuration 29 | # SYMBOL_APIURL_LOCAL = ENV["symbol_local"] 30 | SYMBOL_APIURL_REMOTE = ENV["symbol_remote"] 31 | 32 | # Paths 33 | BASE_PATH = File.expand_path(File.dirname(__FILE__)) 34 | SOURCE_PATH = "#{BASE_PATH}/src" 35 | TESTS_PATH = "#{BASE_PATH}/src" 36 | SPECS_PATH = "#{BASE_PATH}/specs" 37 | BUILD_PATH = "#{BASE_PATH}/build" 38 | RESULTS_PATH = "#{BASE_PATH}/results" 39 | ARTIFACTS_PATH = "#{BASE_PATH}/artifacts" 40 | NUSPEC_PATH = "#{BASE_PATH}/packaging/nuspec" 41 | NUGET_PATH = "#{ARTIFACTS_PATH}/nuget" 42 | TOOLS_PATH = "#{BASE_PATH}/tools" 43 | 44 | # Files 45 | ASSEMBLY_INFO = "#{SOURCE_PATH}/CommonAssemblyInfo.cs" 46 | SOLUTION_FILE = "#{SOURCE_PATH}/Fix.sln" 47 | VERSION_INFO = "#{BASE_PATH}/VERSION.txt" 48 | 49 | # Matching 50 | TEST_ASSEMBLY_PATTERN_PREFIX = "Tests" 51 | TEST_ASSEMBLY_PATTERN_UNIT = "#{TEST_ASSEMBLY_PATTERN_PREFIX}.Unit" 52 | TEST_ASSEMBLY_PATTERN_INTEGRATION = "#{TEST_ASSEMBLY_PATTERN_PREFIX}.Integration" 53 | SPEC_ASSEMBLY_PATTERN = ".Specs" 54 | ROOT_NAMESPACE = "" 55 | 56 | # Commands 57 | # XUNIT_COMMAND = "#{TOOLS_PATH}/xunit/xunit.console.clr4.#{(PLATFORM.empty? or PLATFORM.eql?('x86') ? 'x86' : '')}.exe" 58 | XUNIT_COMMAND = "#{TOOLS_PATH}/xUnit/xunit.console.clr4.exe" 59 | MSPEC_COMMAND = "#{TOOLS_PATH}/mspec/mspec.exe" 60 | NUGET_COMMAND = "#{SOURCE_PATH}/.nuget/NuGet.exe" 61 | 62 | # Set up our build system 63 | require 'albacore' 64 | require 'pathname' 65 | require 'rake/clean' 66 | require 'rexml/document' 67 | 68 | # Check dependencies 69 | raise "You do not have the required dependencies, run '.\\InstallGem.bat' or './installgem.sh'." \ 70 | unless `bundle check`.include? "The Gemfile's dependencies are satisfied\n" 71 | 72 | # Configure albacore 73 | Albacore.configure do |config| 74 | config.log_level = (TEAMCITY ? :verbose : :normal) 75 | 76 | config.msbuild.solution = SOLUTION_FILE 77 | config.msbuild.properties = { :configuration => CONFIG } 78 | config.msbuild.use :net4 79 | config.msbuild.targets = [ :Clean, :Build ] 80 | config.msbuild.verbosity = "normal" 81 | 82 | config.xbuild.solution = SOLUTION_FILE 83 | config.xbuild.properties = { :configuration => CONFIG, :vstoolspath => (RUBY_PLATFORM.downcase.include?('darwin') ? '/Library/Frameworks/Mono.framework/Libraries' : '/usr/lib') + '/mono/xbuild/Microsoft/VisualStudio/v9.0' } 84 | config.xbuild.targets = [ :Build ] #:Clean upsets xbuild 85 | config.xbuild.verbosity = "normal" 86 | 87 | config.mspec.command = (MONO ? 'mono' : XUNIT_COMMAND) 88 | config.mspec.assemblies = FileList.new("#{SPECS_PATH}/**/*#{SPEC_ASSEMBLY_PATTERN}.dll").exclude(/obj\//).collect! { |element| ((MONO ? "#{MSPEC_COMMAND} " : '') + element) } 89 | 90 | CLEAN.include(FileList["#{SOURCE_PATH}/**/obj"]) 91 | CLOBBER.include(NUGET_PATH) 92 | CLOBBER.include(FileList["#{SOURCE_PATH}/**/bin"]) 93 | CLOBBER.include(ARTIFACTS_PATH) 94 | CLOBBER.include(BUILD_PATH) 95 | CLOBBER.include(RESULTS_PATH) 96 | end 97 | 98 | # Tasks 99 | task :default => [:test] 100 | 101 | desc "Build" 102 | task :build => [:init, :assemblyinfo] do 103 | if MONO 104 | Rake::Task[:xbuild].invoke 105 | else 106 | Rake::Task[:msbuild].invoke 107 | end 108 | end 109 | 110 | desc "Build + Tests (default)" 111 | task :test => [:build] do 112 | RunTests "#{TEST_ASSEMBLY_PATTERN_PREFIX}*" 113 | end 114 | 115 | desc "Build + Unit tests" 116 | task :quick => [:build] do 117 | RunTests TEST_ASSEMBLY_PATTERN_UNIT 118 | end 119 | 120 | desc "Build + Tests + Specs" 121 | task :full => [:test] #[:test, :mspec] 122 | 123 | desc "Build + Tests + Specs + Publish (local)" 124 | task :publocal => [:full] do 125 | raise "Environment variable \"APIURL_LOCAL\" must be a valid nuget server url." unless !NUGET_APIURL_LOCAL.nil? 126 | raise "Environment variable \"APIKEY_LOCAL\" must be that of your nuget api key." unless !NUGET_APIKEY_LOCAL.nil? 127 | 128 | PublishNugets BUILD_NUMBER, NUGET_APIURL_LOCAL, NUGET_APIKEY_LOCAL, SYMBOL_APIURL_LOCAL 129 | end 130 | 131 | desc "Build + Tests + Specs + Package" 132 | task :package => [:full] do 133 | PackageNugets NUGET_PACKAGE_VERSION 134 | end 135 | 136 | desc "Build + Tests + Specs + Publish (remote)" 137 | task :publish => [:full] do 138 | raise "Environment variable \"APIURL_REMOTE\" must be a valid nuget server url." unless !NUGET_APIURL_REMOTE.nil? 139 | raise "Environment variable \"APIKEY_REMOTE\" must be that of your nuget api key." unless !NUGET_APIKEY_REMOTE.nil? 140 | 141 | if not TEAMCITY 142 | puts "\n\nThis will publish your local build to the remote nuget feed. Are you sure (y/n)?" 143 | response = $stdin.gets.chomp 144 | 145 | raise "Publish aborted." unless response.downcase.eql?("y") 146 | end 147 | 148 | PublishNugets NUGET_PACKAGE_VERSION, NUGET_APIURL_REMOTE, NUGET_APIKEY_REMOTE, SYMBOL_APIURL_REMOTE 149 | 150 | Rake::Task[:tag].invoke() 151 | end 152 | 153 | # Hidden tasks 154 | task :init => [:clobber] do 155 | if not TEAMCITY 156 | indexupdate = `git update-index --assume-unchanged #{SOURCE_PATH}/CommonAssemblyInfo.cs` 157 | raise "Unable to perform git index operation, cannot continue (#{indexupdate})." unless indexupdate.empty? 158 | end 159 | 160 | Dir.mkdir BUILD_PATH unless File.exists?(BUILD_PATH) 161 | Dir.mkdir RESULTS_PATH unless File.exists?(RESULTS_PATH) 162 | Dir.mkdir ARTIFACTS_PATH unless File.exists?(ARTIFACTS_PATH) 163 | Dir.mkdir NUGET_PATH unless File.exists?(NUGET_PATH) 164 | end 165 | 166 | task :tag do 167 | tagupdate = `git tag -a \"v#{BUILD_VERSION}\" -m \"Published nugets version #{BUILD_VERSION}.\"` 168 | raise "Unable to perform git tag operation (#{BUILD_VERSION})." unless tagupdate.empty? 169 | 170 | tagpush = `git push --tags` unless !tagupdate.empty? 171 | raise "Unable to push git tag changes." unless tagpush.empty? 172 | end 173 | 174 | task :ci => [:package] 175 | 176 | msbuild :msbuild 177 | 178 | xbuild :xbuild 179 | 180 | assemblyinfo :assemblyinfo do |asm| 181 | asm_version = BUILD_NUMBER 182 | 183 | begin 184 | commit = `git log -1 --pretty=format:%H` 185 | rescue 186 | commit = "git unavailable" 187 | end 188 | 189 | testassemblies = FileList.new("#{TESTS_PATH}/*#{TEST_ASSEMBLY_PATTERN_PREFIX}.*/", "#{TESTS_PATH}/*#{TEST_ASSEMBLY_PATTERN_PREFIX}/") 190 | .pathmap("%f") 191 | .collect! { |assemblyname| 192 | "[assembly: InternalsVisibleTo(\"#{ROOT_NAMESPACE}#{assemblyname}\")]" 193 | } 194 | 195 | asm.language = "C#" 196 | asm.version = BUILD_NUMBER 197 | asm.trademark = commit 198 | asm.file_version = BUILD_NUMBER 199 | asm.company_name = SOLUTION_COMPANY 200 | asm.product_name = SOLUTION_NAME 201 | asm.copyright = SOLUTION_COPYRIGHT 202 | asm.namespaces 'System.Runtime.CompilerServices' 203 | asm.custom_attributes :AssemblyConfiguration => CONFIG, :AssemblyInformationalVersion => asm_version 204 | asm.custom_data testassemblies 205 | asm.output_file = ASSEMBLY_INFO 206 | asm.com_visible = false 207 | end 208 | 209 | mspec :mspec 210 | 211 | # Helper methods 212 | def RunTests(boundary = "*") 213 | runner = XUnitTestRunnerCustom.new(MONO ? 'mono' : XUNIT_COMMAND) 214 | runner.html_output = RESULTS_PATH 215 | 216 | assemblies = Array.new 217 | 218 | boundary.split(/,/).each do |this_boundary| 219 | FileList.new("#{TESTS_PATH}/*#{this_boundary}") 220 | .collect! { |element| 221 | FileList.new("#{element}/**/*#{this_boundary}.dll") 222 | .exclude(/obj\//) 223 | .each do |this_file| 224 | assemblies.push (MONO ? "#{XUNIT_COMMAND} " : '') + this_file 225 | end 226 | } 227 | end 228 | 229 | if assemblies.length > 0 230 | runner.assemblies = assemblies 231 | runner.execute 232 | end 233 | end 234 | 235 | def PublishNugets(version, apiurl, apikey, symbolurl) 236 | PackageNugets(version) 237 | 238 | nupkgs = FileList["#{NUGET_PATH}/*#{$version}.nupkg"] 239 | nupkgs.each do |nupkg| 240 | puts "Pushing #{Pathname.new(nupkg).basename}" 241 | nuget_push = NuGetPush.new 242 | nuget_push.source = "\"" + ((not symbolurl.nil? and nupkg.include?(".symbols.")) ? symbolurl : apiurl) + "\"" 243 | nuget_push.apikey = apikey 244 | nuget_push.command = NUGET_COMMAND 245 | nuget_push.package = (MONO ? nupkg : nupkg.gsub('/','\\')) 246 | nuget_push.create_only = false 247 | nuget_push.execute 248 | end 249 | end 250 | 251 | def PackageNugets(nuspec_version) 252 | raise "Invalid nuspec version specified." unless !nuspec_version.nil? 253 | 254 | Dir.mkdir "#{ARTIFACTS_PATH}/nuspec" unless File.exists?("#{ARTIFACTS_PATH}/nuspec") 255 | 256 | FileUtils.cp_r FileList["#{NUSPEC_PATH}/**/*.nuspec"], "#{ARTIFACTS_PATH}/nuspec" 257 | 258 | nuspecs = FileList["#{ARTIFACTS_PATH}/nuspec/**/*.nuspec"] 259 | 260 | UpdateNuSpecVersions nuspecs, nuspec_version 261 | 262 | nuspecs.each do |nuspec| 263 | nuget = NuGetPackCustom.new 264 | nuget.command = NUGET_COMMAND 265 | nuget.nuspec = nuspec 266 | nuget.output = NUGET_PATH 267 | nuget.base_folder = NUSPEC_PATH 268 | nuget.execute 269 | end 270 | end 271 | 272 | def UpdateNuSpecVersions(nuspecs, nuspec_version) 273 | raise "No nuspecs to update." unless !nuspecs.nil? 274 | raise "Invalid nuspec version specified." unless !nuspec_version.nil? 275 | 276 | suffix = "" 277 | suffix << "-#{TEAMCITY_BRANCH}" unless (TEAMCITY_BRANCH.nil? or TEAMCITY_BRANCH.eql? "master" or TEAMCITY_BRANCH.eql? "") 278 | suffix << "-mono" unless !MONO 279 | 280 | nuspecs.each do |nuspec| 281 | puts "Updating #{Pathname.new(nuspec).basename}" 282 | update_xml nuspec do |xml| 283 | nuspec_id = xml.root.elements["metadata/id"].text 284 | nuspec_mm_version = "[#{nuspec_version.split(".").first(4).join(".")}]" 285 | 286 | xml.root.elements["metadata/id"].text = (nuspec_id + suffix) 287 | xml.root.elements["metadata/version"].text = nuspec_version 288 | xml.root.elements["metadata/authors"].text = SOLUTION_COMPANY 289 | xml.root.elements["metadata/summary"].text = SOLUTION_DESC 290 | xml.root.elements["metadata/licenseUrl"].text = SOLUTION_LICENSE 291 | xml.root.elements["metadata/projectUrl"].text = SOLUTION_URL 292 | 293 | xml.root.get_elements("//dependency").each { |e| 294 | if e.attributes["id"].downcase.include? SOLUTION_NAME.downcase 295 | e.attributes["id"] = (e.attributes["id"] + suffix) 296 | e.attributes["version"] = "#{nuspec_mm_version}" 297 | end 298 | } 299 | 300 | xml.root.get_elements("//file").each { |e| 301 | e.attributes["src"] = e.attributes["src"].gsub((MONO ? '\\' : '/'), (!MONO ? '\\' : '/')) 302 | e.attributes["target"] = e.attributes["target"].gsub((MONO ? '\\' : '/'), (!MONO ? '\\' : '/')) 303 | } 304 | end 305 | end 306 | end 307 | 308 | def update_xml(xml_path) 309 | xml_file = File.new(xml_path) 310 | xml = REXML::Document.new xml_file 311 | 312 | yield xml 313 | 314 | xml_file.close 315 | 316 | xml_file = File.open(xml_path, "w") 317 | formatter = REXML::Formatters::Default.new(5) 318 | formatter.write(xml, xml_file) 319 | xml_file.close 320 | end 321 | 322 | # Albacore needs some Mono help 323 | class XUnitTestRunnerCustom < XUnitTestRunner 324 | def build_html_output 325 | fail_with_message 'Directory is required for html_output' if !File.directory?(File.expand_path(@html_output)) 326 | "/nunit \"@#{File.join(File.expand_path(@html_output),"%s.html")}\"" 327 | end 328 | end 329 | 330 | class NuGetPackCustom < NuGetPack 331 | def execute 332 | fail_with_message 'nuspec must be specified.' if @nuspec.nil? 333 | 334 | params = [] 335 | params << "pack" 336 | params << "-Symbols" if @symbols 337 | params << nuspec 338 | params << "-BasePath \"#{base_folder}\"" unless @base_folder.nil? 339 | params << "-OutputDirectory \"#{output}\"" unless @output.nil? 340 | params << "-NoDefaultExcludes" unless !MONO 341 | params << "-Verbosity detailed" unless !TEAMCITY 342 | params << "-Symbols" 343 | params << build_properties unless @properties.nil? || @properties.empty? 344 | 345 | merged_params = params.join(' ') 346 | 347 | cmd = "#{MONO ? 'mono ' : ''}#{File.expand_path(@command)} #{merged_params}" 348 | result = false 349 | 350 | @logger.debug "Build NuGet pack Command Line: #{cmd}" 351 | 352 | Dir.chdir(@working_directory) do 353 | result = system(cmd) 354 | end 355 | 356 | failure_message = 'NuGet Failed. See Build Log For Detail' 357 | fail_with_message failure_message if !result 358 | end 359 | end 360 | 361 | class NuGetPublishCustom < NuGetPackCustom 362 | def execute 363 | 364 | fail_with_message 'id must be specified.' if @id.nil? 365 | fail_with_message 'version must be specified.' if @version.nil? 366 | # don't validate @apikey as required, coz it might have been set in the config file using 'SetApiKey' 367 | 368 | puts @create_only 369 | params = [] 370 | params << "publish" 371 | params << "#{@id}" 372 | params << "#{@version}" 373 | params << "#{@apikey}" if @apikey 374 | params << "-Source #{source}" unless @source.nil? 375 | 376 | merged_params = params.join(' ') 377 | 378 | cmd = "#{MONO ? 'mono ' : ''}#{File.expand_path(@command)} #{merged_params}" 379 | result = false 380 | 381 | @logger.debug "Build NuGet publish Command Line: #{cmd}" 382 | 383 | Dir.chdir(@working_directory) do 384 | result = system(cmd) 385 | end 386 | 387 | failure_message = 'NuGet Publish Failed. See Build Log For Details' 388 | fail_with_message failure_message if !result 389 | end 390 | end --------------------------------------------------------------------------------