commit 3fee9b2c4777d70ed7c6e6ce47dcff59c44893a9 Author: Michael Nolan Date: Mon Aug 22 12:30:32 2022 -0500 Initial commit diff --git a/Tesses.Http.Example/MainServer.cs b/Tesses.Http.Example/MainServer.cs new file mode 100644 index 0000000..e9f2922 --- /dev/null +++ b/Tesses.Http.Example/MainServer.cs @@ -0,0 +1,25 @@ +using System.Text; +using Tesses.Http; +internal class MainServer : ASPEndpointRequestHandler +{ + public MainServer() + { + + } + [HttpGet("/")] + public IResponse Index(int a) + { + return String($"{a} is 42"); + } + [HttpGet("/form")] + public void SomePage(ServerContext ctx) + { + ctx.Response.StatusLine=200; + ctx.Response.SendStatusCodeHtml(); + } + [HttpGet("/4ever4me")] + public IResponse ForEverForMe() + { + return File(System.IO.File.OpenRead("/home/mike/Music/Demi Lovato/Holy Fvck/16 4 EVER 4 ME.mp3"),"audio/mpeg","4Ever4Me.mp3",true); + } +} \ No newline at end of file diff --git a/Tesses.Http.Example/Program.cs b/Tesses.Http.Example/Program.cs new file mode 100644 index 0000000..f2e1513 --- /dev/null +++ b/Tesses.Http.Example/Program.cs @@ -0,0 +1,14 @@ +using System.Net.Sockets; +using System.Text; +using Tesses.Http; + + + +HTTPServer server = new HTTPServer(new MainServer(),new TcpListener(System.Net.IPAddress.Any,3222)); +server.FirstTime = (e)=>{ + Console.WriteLine("Connection Made"); + return true; +}; +server.CatchExceptions=false; +server.AllowMultipleRequestsOnOneConnection=true; +await server.ListenAsync(); diff --git a/Tesses.Http.Example/Tesses.Http.Example.csproj b/Tesses.Http.Example/Tesses.Http.Example.csproj new file mode 100644 index 0000000..12fb25c --- /dev/null +++ b/Tesses.Http.Example/Tesses.Http.Example.csproj @@ -0,0 +1,18 @@ + + + + + + + + + + + + Exe + net6.0 + enable + enable + + + diff --git a/Tesses.Http.Example/bin/Debug/net6.0/MimeTypesMap.dll b/Tesses.Http.Example/bin/Debug/net6.0/MimeTypesMap.dll new file mode 100755 index 0000000..81df59c Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/MimeTypesMap.dll differ diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Newtonsoft.Json.dll b/Tesses.Http.Example/bin/Debug/net6.0/Newtonsoft.Json.dll new file mode 100755 index 0000000..1ffeabe Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/Newtonsoft.Json.dll differ diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example new file mode 100755 index 0000000..e6b4832 Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example differ diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.deps.json b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.deps.json new file mode 100644 index 0000000..4015c96 --- /dev/null +++ b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.deps.json @@ -0,0 +1,71 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v6.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v6.0": { + "Tesses.Http.Example/1.0.0": { + "dependencies": { + "MimeTypesMap": "1.0.8", + "Tesses.Http": "1.0.0" + }, + "runtime": { + "Tesses.Http.Example.dll": {} + } + }, + "MimeTypesMap/1.0.8": { + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": { + "assemblyVersion": "1.0.8.0", + "fileVersion": "1.0.8.0" + } + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "Tesses.Http/1.0.0": { + "dependencies": { + "MimeTypesMap": "1.0.8", + "Newtonsoft.Json": "13.0.1" + }, + "runtime": { + "Tesses.Http.dll": {} + } + } + } + }, + "libraries": { + "Tesses.Http.Example/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "MimeTypesMap/1.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "path": "mimetypesmap/1.0.8", + "hashPath": "mimetypesmap.1.0.8.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "Tesses.Http/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.dll b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.dll new file mode 100644 index 0000000..8bc3e5f Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.dll differ diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.pdb b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.pdb new file mode 100644 index 0000000..a90d54c Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.pdb differ diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.runtimeconfig.json b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.runtimeconfig.json new file mode 100644 index 0000000..4986d16 --- /dev/null +++ b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.runtimeconfig.json @@ -0,0 +1,9 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + } + } +} \ No newline at end of file diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.dll b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.dll new file mode 100644 index 0000000..8d5cd3d Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.dll differ diff --git a/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.pdb b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.pdb new file mode 100644 index 0000000..11cc659 Binary files /dev/null and b/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.pdb differ diff --git a/Tesses.Http.Example/index.html b/Tesses.Http.Example/index.html new file mode 100644 index 0000000..99ee7ee --- /dev/null +++ b/Tesses.Http.Example/index.html @@ -0,0 +1,18 @@ + + + + + + + My fucking random form + + +
+ + + + + +
+ + \ No newline at end of file diff --git a/Tesses.Http.Example/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs b/Tesses.Http.Example/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs new file mode 100644 index 0000000..f795be5 --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfo.cs b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfo.cs new file mode 100644 index 0000000..3831862 --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfo.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Tesses.Http.Example")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("Tesses.Http.Example")] +[assembly: System.Reflection.AssemblyTitleAttribute("Tesses.Http.Example")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfoInputs.cache b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfoInputs.cache new file mode 100644 index 0000000..7f0eb21 --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +669e612f9f7f7dd7046fa4644507cb226ea518f5 diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GeneratedMSBuildEditorConfig.editorconfig b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..4f90fc3 --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,10 @@ +is_global = true +build_property.TargetFramework = net6.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = Tesses.Http.Example +build_property.ProjectDir = /home/mike/Documents/Tesses.Http/Tesses.Http.Example/ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GlobalUsings.g.cs b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.assets.cache b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.assets.cache new file mode 100644 index 0000000..c9ec603 Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.assets.cache differ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.AssemblyReference.cache b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.AssemblyReference.cache new file mode 100644 index 0000000..731a32f Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.AssemblyReference.cache differ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CopyComplete b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CopyComplete new file mode 100644 index 0000000..e69de29 diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CoreCompileInputs.cache b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..530f10d --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +6363edc47200916f9b9c1a2d710f4dcb56cb3e38 diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.FileListAbsolute.txt b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..8e4c847 --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.FileListAbsolute.txt @@ -0,0 +1,20 @@ +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.deps.json +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.runtimeconfig.json +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.Example.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Newtonsoft.Json.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/Tesses.Http.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.AssemblyReference.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.GeneratedMSBuildEditorConfig.editorconfig +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfoInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.AssemblyInfo.cs +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CoreCompileInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.csproj.CopyComplete +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/refint/Tesses.Http.Example.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.genruntimeconfig.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/Debug/net6.0/ref/Tesses.Http.Example.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.Example/bin/Debug/net6.0/MimeTypesMap.dll diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.dll b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.dll new file mode 100644 index 0000000..8bc3e5f Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.dll differ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.genruntimeconfig.cache b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.genruntimeconfig.cache new file mode 100644 index 0000000..f9b0a70 --- /dev/null +++ b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.genruntimeconfig.cache @@ -0,0 +1 @@ +99157670c863174d3ac2f8d212efc02e0f9034cc diff --git a/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.pdb b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.pdb new file mode 100644 index 0000000..a90d54c Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/Tesses.Http.Example.pdb differ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/apphost b/Tesses.Http.Example/obj/Debug/net6.0/apphost new file mode 100755 index 0000000..e6b4832 Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/apphost differ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/ref/Tesses.Http.Example.dll b/Tesses.Http.Example/obj/Debug/net6.0/ref/Tesses.Http.Example.dll new file mode 100644 index 0000000..591c897 Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/ref/Tesses.Http.Example.dll differ diff --git a/Tesses.Http.Example/obj/Debug/net6.0/refint/Tesses.Http.Example.dll b/Tesses.Http.Example/obj/Debug/net6.0/refint/Tesses.Http.Example.dll new file mode 100644 index 0000000..591c897 Binary files /dev/null and b/Tesses.Http.Example/obj/Debug/net6.0/refint/Tesses.Http.Example.dll differ diff --git a/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.dgspec.json b/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.dgspec.json new file mode 100644 index 0000000..ec89d82 --- /dev/null +++ b/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.dgspec.json @@ -0,0 +1,135 @@ +{ + "format": 1, + "restore": { + "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj": {} + }, + "projects": { + "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj", + "projectName": "Tesses.Http.Example", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": { + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + }, + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "projectName": "Tesses.Http", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + }, + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.g.props b/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.g.props new file mode 100644 index 0000000..baf2bd1 --- /dev/null +++ b/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /home/mike/.nuget/packages/ + /home/mike/.nuget/packages/ + PackageReference + 6.2.1 + + + + + \ No newline at end of file diff --git a/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.g.targets b/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.g.targets new file mode 100644 index 0000000..3dc06ef --- /dev/null +++ b/Tesses.Http.Example/obj/Tesses.Http.Example.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Tesses.Http.Example/obj/project.assets.json b/Tesses.Http.Example/obj/project.assets.json new file mode 100644 index 0000000..9924fa0 --- /dev/null +++ b/Tesses.Http.Example/obj/project.assets.json @@ -0,0 +1,159 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "MimeTypesMap/1.0.8": { + "type": "package", + "compile": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + }, + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + } + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + }, + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + } + }, + "Tesses.Http/1.0.0": { + "type": "project", + "framework": ".NETStandard,Version=v2.0", + "dependencies": { + "MimeTypesMap": "1.0.8", + "Newtonsoft.Json": "13.0.1" + }, + "compile": { + "bin/placeholder/Tesses.Http.dll": {} + }, + "runtime": { + "bin/placeholder/Tesses.Http.dll": {} + } + } + } + }, + "libraries": { + "MimeTypesMap/1.0.8": { + "sha512": "iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "type": "package", + "path": "mimetypesmap/1.0.8", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net452/MimeTypesMap.dll", + "lib/netstandard1.1/MimeTypesMap.dll", + "lib/netstandard2.0/MimeTypesMap.dll", + "mimetypesmap.1.0.8.nupkg.sha512", + "mimetypesmap.nuspec" + ] + }, + "Newtonsoft.Json/13.0.1": { + "sha512": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "type": "package", + "path": "newtonsoft.json/13.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.1.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "Tesses.Http/1.0.0": { + "type": "project", + "path": "../Tesses.Http/Tesses.Http.csproj", + "msbuildProject": "../Tesses.Http/Tesses.Http.csproj" + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "MimeTypesMap >= 1.0.8", + "Tesses.Http >= 1.0.0" + ] + }, + "packageFolders": { + "/home/mike/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj", + "projectName": "Tesses.Http.Example", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": { + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http.Example/obj/project.nuget.cache b/Tesses.Http.Example/obj/project.nuget.cache new file mode 100644 index 0000000..8988d88 --- /dev/null +++ b/Tesses.Http.Example/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "A8woRyUpBEU4D6Le2DtxwMxVTptzZORCoTf3qdNFIhnjolqjQ1PwH3yb6qegoOMCCGR84l4l+OBCQm87Yz4w6g==", + "success": true, + "projectFilePath": "/home/mike/Documents/Tesses.Http/Tesses.Http.Example/Tesses.Http.Example.csproj", + "expectedPackageFiles": [ + "/home/mike/.nuget/packages/mimetypesmap/1.0.8/mimetypesmap.1.0.8.nupkg.sha512", + "/home/mike/.nuget/packages/newtonsoft.json/13.0.1/newtonsoft.json.13.0.1.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/Program.cs b/Tesses.Http.KitchenSink/Program.cs new file mode 100644 index 0000000..6b394e6 --- /dev/null +++ b/Tesses.Http.KitchenSink/Program.cs @@ -0,0 +1,75 @@ +using System.Net; + +namespace Tesses.Http.KitchenSink; + +class AspRouteStyle : ASPEndpointRequestHandler +{ + [HttpGet] + public string Add(int a,int b) + { + return $"{a} + {b} = {a+b}"; + } + [HttpGet] + public object Something(bool b,int i,double f,string sz) + { + return new { + Boolean = b, + Integer = i, + Double=f, + String=sz + + + }; + } +} + +class Program +{ + public static async Task Main(string[] args) + { + + MountableServer mountableServer=new MountableServer(RequestHandler.FromDirectory("WebSite")); + mountableServer.Mount("/SrcDl",RequestHandler.FromDelegateSync(e=>{ + e.Response.SendFileAsDownload("Program.cs"); + })); + mountableServer.Mount("/PasswordProtected",new BasicAuthRequestHandler((user,pass)=>{return user=="ddlovato" && pass=="somepassword";},RequestHandler.FromDelegateSync(e=>{ + e.Response.WithContentType("text/plain").SendText("Password Protected Data"); + }))); + mountableServer.Mount("/4d",RequestHandler.FromDelegateSync(e=>{ + HTTPClient client = HTTPClient.Open("GET","https://nextcloud.tesses.cf/apps/files_sharing/publicpreview/aYHgTAxNcAXNG3R?x=2258&y=727&a=true&file=celluloid-shot1007.jpg&scalingup=0"); + client.SendToServer(e); + })); + mountableServer.Mount("/Endpoints/ASP",new AspRouteStyle()); + mountableServer.Mount("/Endpoints/upload_data/", + RequestHandler.FromDelegateSync(e=>{ + + var parser=e.Request.GetMultipartParser(); + + parser.Parse((a,b,c)=>{ + + return File.Create(Path.Combine("WebSite","Endpoints","uploads",b)); + },true).ToArray(); + e.Response.WithContentType("text/plain").SendText("HELLO"); + }) + ); + SendEvents evts=new SendEvents(); + mountableServer.Mount("/counter/count",RequestHandler.FromDelegateSync(e=>{ + + e.Response.ServerSentEvents(evts); + + + })); + + Thread t=new Thread(()=>{ + for(long i =0;;i++){ + evts.SendEvent($"Ran for {i} Seconds"); + Thread.Sleep(1000); + } + }); + t.Start(); + + HTTPServer server=new HTTPServer(mountableServer,new System.Net.Sockets.TcpListener(new IPEndPoint(0,3333))); + server.AllowMultipleRequestsOnOneConnection=true; + await server.ListenAsync(); + } +} \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj b/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj new file mode 100644 index 0000000..39e95af --- /dev/null +++ b/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj @@ -0,0 +1,14 @@ + + + + + + + + Exe + net6.0 + enable + enable + + + diff --git a/Tesses.Http.KitchenSink/WebSite/Endpoints/apitest.html b/Tesses.Http.KitchenSink/WebSite/Endpoints/apitest.html new file mode 100644 index 0000000..032ecdc --- /dev/null +++ b/Tesses.Http.KitchenSink/WebSite/Endpoints/apitest.html @@ -0,0 +1,16 @@ + + + + + + + Upload a file + + +
+ + + +
+ + \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/1.jpg b/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/1.jpg new file mode 100644 index 0000000..65473e3 Binary files /dev/null and b/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/1.jpg differ diff --git a/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/7.jpg b/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/7.jpg new file mode 100644 index 0000000..66bf381 Binary files /dev/null and b/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/7.jpg differ diff --git a/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/993.jpg b/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/993.jpg new file mode 100644 index 0000000..0cc2cc4 Binary files /dev/null and b/Tesses.Http.KitchenSink/WebSite/Endpoints/uploads/993.jpg differ diff --git a/Tesses.Http.KitchenSink/WebSite/Folder2/77.jpg b/Tesses.Http.KitchenSink/WebSite/Folder2/77.jpg new file mode 100644 index 0000000..17f7655 Binary files /dev/null and b/Tesses.Http.KitchenSink/WebSite/Folder2/77.jpg differ diff --git a/Tesses.Http.KitchenSink/WebSite/counter/index.html b/Tesses.Http.KitchenSink/WebSite/counter/index.html new file mode 100644 index 0000000..a1bbc3a --- /dev/null +++ b/Tesses.Http.KitchenSink/WebSite/counter/index.html @@ -0,0 +1,21 @@ + + + + + + + Counter + + +

Counter

+

+ + + + \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/WebSite/sub/index.html b/Tesses.Http.KitchenSink/WebSite/sub/index.html new file mode 100644 index 0000000..9f4502b --- /dev/null +++ b/Tesses.Http.KitchenSink/WebSite/sub/index.html @@ -0,0 +1,12 @@ + + + + + + + Document + + +

Substance

+ + \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/MimeTypesMap.dll b/Tesses.Http.KitchenSink/bin/Debug/net6.0/MimeTypesMap.dll new file mode 100755 index 0000000..81df59c Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/MimeTypesMap.dll differ diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Newtonsoft.Json.dll b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Newtonsoft.Json.dll new file mode 100755 index 0000000..1ffeabe Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Newtonsoft.Json.dll differ diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink new file mode 100755 index 0000000..1dfdf47 Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink differ diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.deps.json b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.deps.json new file mode 100644 index 0000000..bd2f352 --- /dev/null +++ b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.deps.json @@ -0,0 +1,70 @@ +{ + "runtimeTarget": { + "name": ".NETCoreApp,Version=v6.0", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETCoreApp,Version=v6.0": { + "Tesses.Http.KitchenSink/1.0.0": { + "dependencies": { + "Tesses.Http": "1.0.0" + }, + "runtime": { + "Tesses.Http.KitchenSink.dll": {} + } + }, + "MimeTypesMap/1.0.8": { + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": { + "assemblyVersion": "1.0.8.0", + "fileVersion": "1.0.8.0" + } + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "Tesses.Http/1.0.0": { + "dependencies": { + "MimeTypesMap": "1.0.8", + "Newtonsoft.Json": "13.0.1" + }, + "runtime": { + "Tesses.Http.dll": {} + } + } + } + }, + "libraries": { + "Tesses.Http.KitchenSink/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "MimeTypesMap/1.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "path": "mimetypesmap/1.0.8", + "hashPath": "mimetypesmap.1.0.8.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "Tesses.Http/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.dll b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.dll new file mode 100644 index 0000000..cfd78b9 Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.dll differ diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.pdb b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.pdb new file mode 100644 index 0000000..22a230d Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.pdb differ diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.runtimeconfig.json b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.runtimeconfig.json new file mode 100644 index 0000000..4986d16 --- /dev/null +++ b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.runtimeconfig.json @@ -0,0 +1,9 @@ +{ + "runtimeOptions": { + "tfm": "net6.0", + "framework": { + "name": "Microsoft.NETCore.App", + "version": "6.0.0" + } + } +} \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.dll b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.dll new file mode 100644 index 0000000..4c68742 Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.dll differ diff --git a/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.pdb b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.pdb new file mode 100644 index 0000000..c5b1c3e Binary files /dev/null and b/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.pdb differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs b/Tesses.Http.KitchenSink/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs new file mode 100644 index 0000000..f795be5 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/.NETCoreApp,Version=v6.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETCoreApp,Version=v6.0", FrameworkDisplayName = "")] diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfo.cs b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfo.cs new file mode 100644 index 0000000..c74561a --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfo.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Tesses.Http.KitchenSink")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("Tesses.Http.KitchenSink")] +[assembly: System.Reflection.AssemblyTitleAttribute("Tesses.Http.KitchenSink")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfoInputs.cache b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfoInputs.cache new file mode 100644 index 0000000..ea6518e --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +e30a4ccd016835e1cef63b026d9deaeba2652d2f diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GeneratedMSBuildEditorConfig.editorconfig b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..0b4fb55 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,10 @@ +is_global = true +build_property.TargetFramework = net6.0 +build_property.TargetPlatformMinVersion = +build_property.UsingMicrosoftNETSdkWeb = +build_property.ProjectTypeGuids = +build_property.InvariantGlobalization = +build_property.PlatformNeutralAssembly = +build_property._SupportedPlatformList = Linux,macOS,Windows +build_property.RootNamespace = Tesses.Http.KitchenSink +build_property.ProjectDir = /home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GlobalUsings.g.cs b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GlobalUsings.g.cs new file mode 100644 index 0000000..8578f3d --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GlobalUsings.g.cs @@ -0,0 +1,8 @@ +// +global using global::System; +global using global::System.Collections.Generic; +global using global::System.IO; +global using global::System.Linq; +global using global::System.Net.Http; +global using global::System.Threading; +global using global::System.Threading.Tasks; diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.assets.cache b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.assets.cache new file mode 100644 index 0000000..cda48aa Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.assets.cache differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.AssemblyReference.cache b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.AssemblyReference.cache new file mode 100644 index 0000000..15c0102 Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.AssemblyReference.cache differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CopyComplete b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CopyComplete new file mode 100644 index 0000000..e69de29 diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CoreCompileInputs.cache b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..1acb2c6 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +a746a4ef62ea153b4753b4a691f371551d06ef73 diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.FileListAbsolute.txt b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..9bd6878 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.FileListAbsolute.txt @@ -0,0 +1,20 @@ +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.deps.json +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.runtimeconfig.json +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.KitchenSink.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/MimeTypesMap.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Newtonsoft.Json.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/bin/Debug/net6.0/Tesses.Http.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.AssemblyReference.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.GeneratedMSBuildEditorConfig.editorconfig +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfoInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.AssemblyInfo.cs +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CoreCompileInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.csproj.CopyComplete +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/refint/Tesses.Http.KitchenSink.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.genruntimeconfig.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/Debug/net6.0/ref/Tesses.Http.KitchenSink.dll diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.dll b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.dll new file mode 100644 index 0000000..cfd78b9 Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.dll differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.genruntimeconfig.cache b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.genruntimeconfig.cache new file mode 100644 index 0000000..16ec821 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.genruntimeconfig.cache @@ -0,0 +1 @@ +fdff5d1ced5cbad40fd00269d754d3a7cf9b38cd diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.pdb b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.pdb new file mode 100644 index 0000000..22a230d Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/Tesses.Http.KitchenSink.pdb differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/apphost b/Tesses.Http.KitchenSink/obj/Debug/net6.0/apphost new file mode 100755 index 0000000..1dfdf47 Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/apphost differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/ref/Tesses.Http.KitchenSink.dll b/Tesses.Http.KitchenSink/obj/Debug/net6.0/ref/Tesses.Http.KitchenSink.dll new file mode 100644 index 0000000..7c56396 Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/ref/Tesses.Http.KitchenSink.dll differ diff --git a/Tesses.Http.KitchenSink/obj/Debug/net6.0/refint/Tesses.Http.KitchenSink.dll b/Tesses.Http.KitchenSink/obj/Debug/net6.0/refint/Tesses.Http.KitchenSink.dll new file mode 100644 index 0000000..7c56396 Binary files /dev/null and b/Tesses.Http.KitchenSink/obj/Debug/net6.0/refint/Tesses.Http.KitchenSink.dll differ diff --git a/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.dgspec.json b/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.dgspec.json new file mode 100644 index 0000000..418a1bc --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.dgspec.json @@ -0,0 +1,129 @@ +{ + "format": 1, + "restore": { + "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj": {} + }, + "projects": { + "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj", + "projectName": "Tesses.Http.KitchenSink", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": { + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + }, + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "projectName": "Tesses.Http", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + }, + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.g.props b/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.g.props new file mode 100644 index 0000000..baf2bd1 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /home/mike/.nuget/packages/ + /home/mike/.nuget/packages/ + PackageReference + 6.2.1 + + + + + \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.g.targets b/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.g.targets new file mode 100644 index 0000000..3dc06ef --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/Tesses.Http.KitchenSink.csproj.nuget.g.targets @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/obj/project.assets.json b/Tesses.Http.KitchenSink/obj/project.assets.json new file mode 100644 index 0000000..44e31b0 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/project.assets.json @@ -0,0 +1,152 @@ +{ + "version": 3, + "targets": { + "net6.0": { + "MimeTypesMap/1.0.8": { + "type": "package", + "compile": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + }, + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + } + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + }, + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + } + }, + "Tesses.Http/1.0.0": { + "type": "project", + "framework": ".NETStandard,Version=v2.0", + "dependencies": { + "MimeTypesMap": "1.0.8", + "Newtonsoft.Json": "13.0.1" + }, + "compile": { + "bin/placeholder/Tesses.Http.dll": {} + }, + "runtime": { + "bin/placeholder/Tesses.Http.dll": {} + } + } + } + }, + "libraries": { + "MimeTypesMap/1.0.8": { + "sha512": "iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "type": "package", + "path": "mimetypesmap/1.0.8", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net452/MimeTypesMap.dll", + "lib/netstandard1.1/MimeTypesMap.dll", + "lib/netstandard2.0/MimeTypesMap.dll", + "mimetypesmap.1.0.8.nupkg.sha512", + "mimetypesmap.nuspec" + ] + }, + "Newtonsoft.Json/13.0.1": { + "sha512": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "type": "package", + "path": "newtonsoft.json/13.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.1.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "Tesses.Http/1.0.0": { + "type": "project", + "path": "../Tesses.Http/Tesses.Http.csproj", + "msbuildProject": "../Tesses.Http/Tesses.Http.csproj" + } + }, + "projectFileDependencyGroups": { + "net6.0": [ + "Tesses.Http >= 1.0.0" + ] + }, + "packageFolders": { + "/home/mike/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj", + "projectName": "Tesses.Http.KitchenSink", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "net6.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "projectReferences": { + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "net6.0": { + "targetAlias": "net6.0", + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "frameworkReferences": { + "Microsoft.NETCore.App": { + "privateAssets": "all" + } + }, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http.KitchenSink/obj/project.nuget.cache b/Tesses.Http.KitchenSink/obj/project.nuget.cache new file mode 100644 index 0000000..7eec0b2 --- /dev/null +++ b/Tesses.Http.KitchenSink/obj/project.nuget.cache @@ -0,0 +1,11 @@ +{ + "version": 2, + "dgSpecHash": "V66VwZpW5UH8tYt+PlfbHAUTOj/+7/ZIV0E+qE9G+sD+0OWCrjem0xeUpchbVXkoPjrA3TP9s79jvfQpk0SVGQ==", + "success": true, + "projectFilePath": "/home/mike/Documents/Tesses.Http/Tesses.Http.KitchenSink/Tesses.Http.KitchenSink.csproj", + "expectedPackageFiles": [ + "/home/mike/.nuget/packages/mimetypesmap/1.0.8/mimetypesmap.1.0.8.nupkg.sha512", + "/home/mike/.nuget/packages/newtonsoft.json/13.0.1/newtonsoft.json.13.0.1.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/Tesses.Http.VFSCollection/Class1.cs b/Tesses.Http.VFSCollection/Class1.cs new file mode 100644 index 0000000..19aa265 --- /dev/null +++ b/Tesses.Http.VFSCollection/Class1.cs @@ -0,0 +1,731 @@ +using System; +using System.Linq; +using System.IO; +using System.Collections.Generic; + +namespace Tesses.Http.VFSCollection +{ + public static class Extensions + { + public static void ExtractTessesArchive(this VirtualStorage storage,Stream strm,bool ownStream) + { + using(TArchiveReader reader=new TArchiveReader(strm,ownStream)) + { + reader.ExtractEverything((t,n,len)=>{ + if(t == EntryType.File) + { + string pardir = Path.GetDirectoryName(n.TrimStart('.').TrimStart('/')); + storage.CreateDirectory(pardir); + return storage.Open(pardir,FileMode.Create,FileAccess.Write,FileShare.None); + } + if(t == EntryType.Directory) + { + storage.CreateDirectory(n.TrimStart('.').TrimStart('/')); + } + + return Stream.Null; + }); + } + } + } + public enum EntryType : byte + { + File=0b00000000, + Directory=0b00000001, + Symlink=0b00000010 + } + public class TArchiveReader : IDisposable +{ + public delegate Stream ExtractEverythingDelegate(EntryType type,string name,long entLen); + public delegate void DoneWriting(Stream strm,string name); + public delegate void Symlink(string linkPath,string linkDest); + Stream strm; + bool own; + public TArchiveReader(Stream strm,bool ownStream=false) + { + this.strm=strm; + own=ownStream; + } + public TArchiveReader(string filename) + { + this.strm = File.OpenRead(filename); + own =true; + } + private void ReadLittleEndian(byte[] arrayToFill) + { + strm.Read(arrayToFill,0,arrayToFill.Length); + + if(!BitConverter.IsLittleEndian) + { + Array.Reverse(arrayToFill); + } + } + private bool ReadEntryAttributes(out EntryType type, out string name,out long len) + { + // strm.WriteByte((byte)type); + //WriteString(name); + //WriteLittleEndian(BitConverter.GetBytes(len)); + int t=strm.ReadByte(); + if(t == -1) + { + type=EntryType.File; + name="ENDOFSTREAM.BIN"; + len=0; + return false; + } + type=(EntryType)t; + name=ReadString(); + byte[] len0 = new byte[8]; + ReadLittleEndian(len0); + len=BitConverter.ToInt64(len0,0); + return true; + } + + private string ReadString() + { + byte[] len = new byte[4]; + ReadLittleEndian(len); + byte[] strdat=new byte[BitConverter.ToInt32(len,0)]; + strm.Read(strdat,0,strdat.Length); + return System.Text.Encoding.UTF8.GetString(strdat); + } + private void ReadAndDiscard(long l) + { + + if(strm.CanSeek) + { + strm.Seek(l,SeekOrigin.Current); + }else{ + _copyTo(Stream.Null,l); + } + } + private void _copyTo(Stream strm,long len) + { + byte[] buff=new byte[1024]; + long pos=0; + int read=0; + do{ + read=(int)Math.Min(1024,len-pos); + if(read == 0) return; + read=this.strm.Read(buff,0,read); + strm.Write(buff,0,read); + pos+=read; + }while(read != 0); + } + + public void ExtractStartingWith(string archivePath,string outputDir,Symlink symlink=null) + { + Dictionary> _f=new Dictionary>(); + ExtractEverything((type,name,len)=>{ + if(name.StartsWith(archivePath)){ + switch(type) + { + case EntryType.File: + string fname=Path.Combine(outputDir,name); + string dirname = Path.GetDirectoryName(fname); + if(!string.IsNullOrWhiteSpace(dirname)) + { + Directory.CreateDirectory(dirname); + } + return File.Create(fname); + case EntryType.Directory: + string fname0=Path.Combine(outputDir,name); + Directory.CreateDirectory(fname0); + break; + } + } + return Stream.Null; + },(strm0,name)=>{strm0.Dispose();},symlink); + } + public void Extract(string archivePath,Stream strm) + { + bool hasGone=false;; + ExtractEverything((type,name,len)=>{ + if(hasGone) return null; + if(type == EntryType.File && name==archivePath){ + hasGone=true; + return strm; + } + return Stream.Null; + }); + } + + public void ExtractEverything(string outputDir,Symlink symlink=null) + { + Dictionary> _f=new Dictionary>(); + ExtractEverything((type,name,len)=>{ + switch(type) + { + case EntryType.File: + string fname=Path.Combine(outputDir,name); + + string dirname = Path.GetDirectoryName(fname); + if(!string.IsNullOrWhiteSpace(dirname)) + { + Directory.CreateDirectory(dirname); + + } + + return File.Create(fname); + case EntryType.Directory: + string fname0=Path.Combine(outputDir,name); + Directory.CreateDirectory(fname0); + break; + } + return Stream.Null; + },(strm0,name)=>{strm0.Dispose();},symlink); + } + public void ExtractEverything(ExtractEverythingDelegate del,DoneWriting doneWriting=null,Symlink symlink=null) + { + if(del == null) return; + if(hasRead && strm.CanSeek) + { + strm.Seek(0,SeekOrigin.Begin); + } + if(hasRead && !strm.CanSeek) + { + throw new Exception("Can't Seek Stream"); + }else{ + bool read=false; + do{ + EntryType type; + string name; + long len; + read=ReadEntryAttributes(out type,out name,out len); + if(read) + { + if(type == EntryType.Symlink) + { + MemoryStream strm=new MemoryStream(); + _copyTo(strm,len); + using(StreamReader rdr=new StreamReader(strm)) + { + string res= rdr.ReadToEnd(); + symlink?.Invoke(name,res); + } + + }else{ + Stream strm=del(type,name,len); + if(strm == Stream.Null) + { + if(len>0) + ReadAndDiscard(len); + } + else if(strm != null) + { + _copyTo(strm,len); + if(doneWriting != null) + { + doneWriting(strm,name); + }else{ + strm.Close(); + } + }else{ + hasRead=true; + return; + } + }} + }while(read); + + hasRead=true; + } + + } + bool hasRead=false; + public void Dispose() + { + if(own) strm.Dispose(); + } +} + + + public class MemoryStorage : VirtualStorage + { + protected override void DeleteEmptyDirectory(string dir) + { + string[] _p=dir.Split('/'); + if(_p.Length < 1) return; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + if(!(dir0.Entries[_p[_p.Length-1]].IsFile)) + dir0.Entries.Remove(_p[_p.Length-1]); + } + } + public override string ActualPath => "mem:///"; + public override void SetCreationTime(string filename, DateTime time) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + dir0.Entries[_p[_p.Length]].Created=time; + } + } + public override void SetLastAccessTime(string filename, DateTime time) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + dir0.Entries[_p[_p.Length]].LastAccess=time; + } + } + public override void SetLastWriteTime(string filename, DateTime time) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + dir0.Entries[_p[_p.Length]].LastWrite=time; + } + } + public override DateTime GetCreationTime(string filename) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return DateTime.Now; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + return dir0.Entries[_p[_p.Length]].Created; + }else{ + return DateTime.Now; + } + } + public override DateTime GetLastWriteTime(string filename) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return DateTime.Now; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + return dir0.Entries[_p[_p.Length]].LastWrite; + }else{ + return DateTime.Now; + } + } + public override DateTime GetLastAccessTime(string filename) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return DateTime.Now; + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + if(dir0.Entries.ContainsKey(_p[_p.Length-1])) + { + return dir0.Entries[_p[_p.Length]].LastAccess; + }else{ + return DateTime.Now; + } + } + private abstract class MemoryEntry + { + public abstract bool IsFile {get;} + + + public DateTime Created {get;set;} + public DateTime LastWrite {get;set;} + public DateTime LastAccess {get;set;} + } + private class MemoryFile : MemoryEntry + { + public MemoryFile() + { + LastAccess=DateTime.Now; + LastWrite=DateTime.Now; + Created=DateTime.Now; + } + public bool HasWriteAccess=false; + public override bool IsFile => true; + public byte[] Data=new byte[0]; + + public void Overwrite(byte[] data) + { + lock(this) + { + Data=data; + LastWrite = DateTime.Now; + + } + } + } + private class MemoryStream2 : MemoryStream + { + MemoryFile _f; + bool _canWrite; + + public MemoryStream2(MemoryFile file,bool canWrite) : base(file.Data.ToArray(),canWrite) //copies data into file + { + file.LastAccess = DateTime.Now; + _f=file; + _canWrite=canWrite; + if(file.HasWriteAccess && _canWrite) + { + throw new IOException("MemoryStorage doesn't support simulatious writers"); + } + if(!file.HasWriteAccess) + file.HasWriteAccess=_canWrite; + } + + public override void Close() + { + if(_canWrite) + { + _f.Overwrite(this.ToArray()); + _f.HasWriteAccess=false; + } + base.Close(); + } + } + private class MemoryDirectory : MemoryEntry + { + + public MemoryDirectory() + { + Created = DateTime.Now; + LastWrite=DateTime.Now; + LastAccess=DateTime.Now; + Entries=new Dictionary(); + + } + + public override bool IsFile => false; + public Dictionary Entries {get;set;} + } + MemoryDirectory root=new MemoryDirectory(); + public static MemoryStorage FromTessesArchive(Stream strm,bool ownStream) + { + MemoryStorage storage=new MemoryStorage(); + storage.ExtractTessesArchive(strm,ownStream); + //public delegate Stream ExtractEverythingDelegate(EntryType type,string name,long entLen); + + + + return storage; + } + private MemoryDirectory _create(MemoryDirectory dir,string p) + { + if(!dir.Entries.ContainsKey(p)) + { + dir.Entries.Add(p,new MemoryDirectory()); + } + var dir2= dir.Entries[p] as MemoryDirectory; + return dir2; + } + private MemoryEntry _get(MemoryDirectory dir,string p) + { + if(!dir.Entries.ContainsKey(p)) + { + return null; + } + + return dir.Entries[p]; + } + public override void CreateDirectory(string path) + { + string[] _p=path.Split('/'); + var dir = root; + List __c=new List(); + foreach(var item in _p) + { + dir= _create(root,item); + __c.Add(item); + if(dir == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + } + + public override void Delete(string file) + { + string[] _p=file.Split('/'); + if(_p.Length < 1) return; + List __c=new List(); + MemoryDirectory dir=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir=_get(dir,item) as MemoryDirectory; + __c.Add(item); + if(dir == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + if(dir.Entries.ContainsKey(_p[_p.Length-1])) + { + if(dir.Entries[_p[_p.Length-1]].IsFile) + dir.Entries.Remove(_p[_p.Length-1]); + } + } + + public override bool DirectoryExists(string filename) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return false; + List __c=new List(); + MemoryDirectory dir=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir=_get(dir,item) as MemoryDirectory; + __c.Add(item); + if(dir == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + if(dir.Entries.ContainsKey(_p[_p.Length-1])) + { + return !(dir.Entries[_p[_p.Length-1]].IsFile); + } + return false; + } + + public override IEnumerable EnumerateDirectories(string dir) + { + string[] _p=dir.Split('/'); + + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + foreach(var items in dir0.Entries) + { + if(!items.Value.IsFile) + yield return items.Key; + } + + + } + + public override IEnumerable EnumerateFiles(string dir) + { + + string[] _p=dir.Split('/'); + + List __c=new List(); + MemoryDirectory dir0=root; + foreach(var item in _p) + { + dir0=_get(dir0,item) as MemoryDirectory; + __c.Add(item); + if(dir0 == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + foreach(var items in dir0.Entries) + { + if(items.Value.IsFile) + yield return items.Key; + } + + + + + + } + + public override bool FileExists(string filename) + { + string[] _p=filename.Split('/'); + if(_p.Length < 1) return false; + List __c=new List(); + MemoryDirectory dir=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir=_get(dir,item) as MemoryDirectory; + __c.Add(item); + if(dir == null) + { + throw new Exception($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + if(dir.Entries.ContainsKey(_p[_p.Length-1])) + { + return (dir.Entries[_p[_p.Length-1]].IsFile); + } + return false; + } + + public override Stream Open(string file, FileMode mode, FileAccess access, FileShare share) + { + string[] _p=file.Split('/'); + if(_p.Length < 1) throw new IOException("Path empty"); + List __c=new List(); + MemoryDirectory dir=root; + foreach(var item in _p.Take(_p.Length -1)) + { + dir=_get(dir,item) as MemoryDirectory; + __c.Add(item); + if(dir == null) + { + throw new IOException($"The path {PathCombine(__c)} is a file, should be a directory"); + } + } + + //we will now try to get the file + string filename=_p[_p.Length -1]; + if(dir.Entries.ContainsKey(filename)) + { + if(!dir.Entries[filename].IsFile) throw new IOException("Not a file"); + //the file exists + if(mode == FileMode.CreateNew) throw new IOException("File Exists"); + + var _file= dir.Entries[filename] as MemoryFile; + lock(_file) + { + if(mode == FileMode.Create) { + _file.Data=new byte[0]; + } + //we need to open file + MemoryStream2 strm=new MemoryStream2(_file,access != FileAccess.Read); + + if(mode != FileMode.Truncate) + { + strm.Position=0; + }else{ + strm.Position=strm.Length; + } + return strm; + } + + }else{ + if(mode == FileMode.Open) throw new IOException("File Doesn't Exist"); + MemoryFile _file=new MemoryFile(); + dir.Entries.Add(filename,_file); + + lock(_file) + { + MemoryStream2 strm=new MemoryStream2(_file,access != FileAccess.Read); + return strm; + } + + //the file doesnt exist + } + + } + } + + public class SSHStorage : VirtualStorage + { + public override void CreateDirectory(string path) + { + throw new NotImplementedException(); + } + + public override void Delete(string file) + { + throw new NotImplementedException(); + } + + public override bool DirectoryExists(string filename) + { + throw new NotImplementedException(); + } + + public override IEnumerable EnumerateDirectories(string dir) + { + throw new NotImplementedException(); + } + + public override IEnumerable EnumerateFiles(string dir) + { + throw new NotImplementedException(); + } + + public override bool FileExists(string filename) + { + throw new NotImplementedException(); + } + + public override Stream Open(string file, FileMode mode, FileAccess access, FileShare share) + { + throw new NotImplementedException(); + } + } +} diff --git a/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj b/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj new file mode 100644 index 0000000..4528819 --- /dev/null +++ b/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj @@ -0,0 +1,15 @@ + + + + + + + + + + + + netstandard2.0 + + + diff --git a/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.deps.json b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.deps.json new file mode 100644 index 0000000..3f7baf5 --- /dev/null +++ b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.deps.json @@ -0,0 +1,92 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "Tesses.Http.VFSCollection/1.0.0": { + "dependencies": { + "NETStandard.Library": "2.0.3", + "Tesses.Http": "1.0.0" + }, + "runtime": { + "Tesses.Http.VFSCollection.dll": {} + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "MimeTypesMap/1.0.8": { + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": { + "assemblyVersion": "1.0.8.0", + "fileVersion": "1.0.8.0" + } + } + }, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + }, + "Tesses.Http/1.0.0": { + "dependencies": { + "MimeTypesMap": "1.0.8", + "Newtonsoft.Json": "13.0.1" + }, + "runtime": { + "Tesses.Http.dll": {} + } + } + } + }, + "libraries": { + "Tesses.Http.VFSCollection/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "MimeTypesMap/1.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "path": "mimetypesmap/1.0.8", + "hashPath": "mimetypesmap.1.0.8.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + }, + "Tesses.Http/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + } + } +} \ No newline at end of file diff --git a/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll new file mode 100644 index 0000000..eaa75f0 Binary files /dev/null and b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll differ diff --git a/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb new file mode 100644 index 0000000..c450687 Binary files /dev/null and b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb differ diff --git a/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.dll b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.dll new file mode 100644 index 0000000..8f73669 Binary files /dev/null and b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.dll differ diff --git a/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.pdb b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.pdb new file mode 100644 index 0000000..e6ead8e Binary files /dev/null and b/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.pdb differ diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs new file mode 100644 index 0000000..4c9a2c1 --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfo.cs b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfo.cs new file mode 100644 index 0000000..28497ff --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfo.cs @@ -0,0 +1,22 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Tesses.Http.VFSCollection")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("Tesses.Http.VFSCollection")] +[assembly: System.Reflection.AssemblyTitleAttribute("Tesses.Http.VFSCollection")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfoInputs.cache b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfoInputs.cache new file mode 100644 index 0000000..706562a --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +e923dcb2a108173e8b86fc6ff1172ab495aac9d0 diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.GeneratedMSBuildEditorConfig.editorconfig b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..83a8a22 --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,3 @@ +is_global = true +build_property.RootNamespace = Tesses.Http.VFSCollection +build_property.ProjectDir = /home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/ diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.assets.cache b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.assets.cache new file mode 100644 index 0000000..5804324 Binary files /dev/null and b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.assets.cache differ diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.AssemblyReference.cache b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.AssemblyReference.cache new file mode 100644 index 0000000..b9e8924 Binary files /dev/null and b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.AssemblyReference.cache differ diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CopyComplete b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CopyComplete new file mode 100644 index 0000000..e69de29 diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CoreCompileInputs.cache b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..20ba72d --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +a592453a8b5bace07babb87dbe5b1e4bf71dead9 diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.FileListAbsolute.txt b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..9fa129c --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.FileListAbsolute.txt @@ -0,0 +1,13 @@ +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.deps.json +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/bin/Debug/netstandard2.0/Tesses.Http.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.AssemblyReference.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.GeneratedMSBuildEditorConfig.editorconfig +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfoInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.AssemblyInfo.cs +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CoreCompileInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.csproj.CopyComplete +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll +/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll new file mode 100644 index 0000000..eaa75f0 Binary files /dev/null and b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.dll differ diff --git a/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb new file mode 100644 index 0000000..c450687 Binary files /dev/null and b/Tesses.Http.VFSCollection/obj/Debug/netstandard2.0/Tesses.Http.VFSCollection.pdb differ diff --git a/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.dgspec.json b/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.dgspec.json new file mode 100644 index 0000000..051ebde --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.dgspec.json @@ -0,0 +1,136 @@ +{ + "format": 1, + "restore": { + "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj": {} + }, + "projects": { + "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj", + "projectName": "Tesses.Http.VFSCollection", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": { + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "SSH.NET": { + "target": "Package", + "version": "[2020.0.2, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + }, + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "projectName": "Tesses.Http", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + }, + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.g.props b/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.g.props new file mode 100644 index 0000000..baf2bd1 --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /home/mike/.nuget/packages/ + /home/mike/.nuget/packages/ + PackageReference + 6.2.1 + + + + + \ No newline at end of file diff --git a/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.g.targets b/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.g.targets new file mode 100644 index 0000000..8284cdf --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/Tesses.Http.VFSCollection.csproj.nuget.g.targets @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Tesses.Http.VFSCollection/obj/project.assets.json b/Tesses.Http.VFSCollection/obj/project.assets.json new file mode 100644 index 0000000..29b5301 --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/project.assets.json @@ -0,0 +1,414 @@ +{ + "version": 3, + "targets": { + ".NETStandard,Version=v2.0": { + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + } + }, + "MimeTypesMap/1.0.8": { + "type": "package", + "compile": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + }, + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + } + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + }, + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + }, + "build": { + "build/netstandard2.0/NETStandard.Library.targets": {} + } + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + }, + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": {} + } + }, + "SSH.NET/2020.0.2": { + "type": "package", + "dependencies": { + "SshNet.Security.Cryptography": "[1.3.0]" + }, + "compile": { + "lib/netstandard2.0/Renci.SshNet.dll": {} + }, + "runtime": { + "lib/netstandard2.0/Renci.SshNet.dll": {} + } + }, + "SshNet.Security.Cryptography/1.3.0": { + "type": "package", + "compile": { + "lib/netstandard2.0/SshNet.Security.Cryptography.dll": {} + }, + "runtime": { + "lib/netstandard2.0/SshNet.Security.Cryptography.dll": {} + } + }, + "Tesses.Http/1.0.0": { + "type": "project", + "framework": ".NETStandard,Version=v2.0", + "dependencies": { + "MimeTypesMap": "1.0.8", + "Newtonsoft.Json": "13.0.1" + }, + "compile": { + "bin/placeholder/Tesses.Http.dll": {} + }, + "runtime": { + "bin/placeholder/Tesses.Http.dll": {} + } + } + } + }, + "libraries": { + "Microsoft.NETCore.Platforms/1.1.0": { + "sha512": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "type": "package", + "path": "microsoft.netcore.platforms/1.1.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "ThirdPartyNotices.txt", + "dotnet_library_license.txt", + "lib/netstandard1.0/_._", + "microsoft.netcore.platforms.1.1.0.nupkg.sha512", + "microsoft.netcore.platforms.nuspec", + "runtime.json" + ] + }, + "MimeTypesMap/1.0.8": { + "sha512": "iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "type": "package", + "path": "mimetypesmap/1.0.8", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net452/MimeTypesMap.dll", + "lib/netstandard1.1/MimeTypesMap.dll", + "lib/netstandard2.0/MimeTypesMap.dll", + "mimetypesmap.1.0.8.nupkg.sha512", + "mimetypesmap.nuspec" + ] + }, + "NETStandard.Library/2.0.3": { + "sha512": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "type": "package", + "path": "netstandard.library/2.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "build/netstandard2.0/NETStandard.Library.targets", + "build/netstandard2.0/ref/Microsoft.Win32.Primitives.dll", + "build/netstandard2.0/ref/System.AppContext.dll", + "build/netstandard2.0/ref/System.Collections.Concurrent.dll", + "build/netstandard2.0/ref/System.Collections.NonGeneric.dll", + "build/netstandard2.0/ref/System.Collections.Specialized.dll", + "build/netstandard2.0/ref/System.Collections.dll", + "build/netstandard2.0/ref/System.ComponentModel.Composition.dll", + "build/netstandard2.0/ref/System.ComponentModel.EventBasedAsync.dll", + "build/netstandard2.0/ref/System.ComponentModel.Primitives.dll", + "build/netstandard2.0/ref/System.ComponentModel.TypeConverter.dll", + "build/netstandard2.0/ref/System.ComponentModel.dll", + "build/netstandard2.0/ref/System.Console.dll", + "build/netstandard2.0/ref/System.Core.dll", + "build/netstandard2.0/ref/System.Data.Common.dll", + "build/netstandard2.0/ref/System.Data.dll", + "build/netstandard2.0/ref/System.Diagnostics.Contracts.dll", + "build/netstandard2.0/ref/System.Diagnostics.Debug.dll", + "build/netstandard2.0/ref/System.Diagnostics.FileVersionInfo.dll", + "build/netstandard2.0/ref/System.Diagnostics.Process.dll", + "build/netstandard2.0/ref/System.Diagnostics.StackTrace.dll", + "build/netstandard2.0/ref/System.Diagnostics.TextWriterTraceListener.dll", + "build/netstandard2.0/ref/System.Diagnostics.Tools.dll", + "build/netstandard2.0/ref/System.Diagnostics.TraceSource.dll", + "build/netstandard2.0/ref/System.Diagnostics.Tracing.dll", + "build/netstandard2.0/ref/System.Drawing.Primitives.dll", + "build/netstandard2.0/ref/System.Drawing.dll", + "build/netstandard2.0/ref/System.Dynamic.Runtime.dll", + "build/netstandard2.0/ref/System.Globalization.Calendars.dll", + "build/netstandard2.0/ref/System.Globalization.Extensions.dll", + "build/netstandard2.0/ref/System.Globalization.dll", + "build/netstandard2.0/ref/System.IO.Compression.FileSystem.dll", + "build/netstandard2.0/ref/System.IO.Compression.ZipFile.dll", + "build/netstandard2.0/ref/System.IO.Compression.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.DriveInfo.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.Primitives.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.Watcher.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.dll", + "build/netstandard2.0/ref/System.IO.IsolatedStorage.dll", + "build/netstandard2.0/ref/System.IO.MemoryMappedFiles.dll", + "build/netstandard2.0/ref/System.IO.Pipes.dll", + "build/netstandard2.0/ref/System.IO.UnmanagedMemoryStream.dll", + "build/netstandard2.0/ref/System.IO.dll", + "build/netstandard2.0/ref/System.Linq.Expressions.dll", + "build/netstandard2.0/ref/System.Linq.Parallel.dll", + "build/netstandard2.0/ref/System.Linq.Queryable.dll", + "build/netstandard2.0/ref/System.Linq.dll", + "build/netstandard2.0/ref/System.Net.Http.dll", + "build/netstandard2.0/ref/System.Net.NameResolution.dll", + "build/netstandard2.0/ref/System.Net.NetworkInformation.dll", + "build/netstandard2.0/ref/System.Net.Ping.dll", + "build/netstandard2.0/ref/System.Net.Primitives.dll", + "build/netstandard2.0/ref/System.Net.Requests.dll", + "build/netstandard2.0/ref/System.Net.Security.dll", + "build/netstandard2.0/ref/System.Net.Sockets.dll", + "build/netstandard2.0/ref/System.Net.WebHeaderCollection.dll", + "build/netstandard2.0/ref/System.Net.WebSockets.Client.dll", + "build/netstandard2.0/ref/System.Net.WebSockets.dll", + "build/netstandard2.0/ref/System.Net.dll", + "build/netstandard2.0/ref/System.Numerics.dll", + "build/netstandard2.0/ref/System.ObjectModel.dll", + "build/netstandard2.0/ref/System.Reflection.Extensions.dll", + "build/netstandard2.0/ref/System.Reflection.Primitives.dll", + "build/netstandard2.0/ref/System.Reflection.dll", + "build/netstandard2.0/ref/System.Resources.Reader.dll", + "build/netstandard2.0/ref/System.Resources.ResourceManager.dll", + "build/netstandard2.0/ref/System.Resources.Writer.dll", + "build/netstandard2.0/ref/System.Runtime.CompilerServices.VisualC.dll", + "build/netstandard2.0/ref/System.Runtime.Extensions.dll", + "build/netstandard2.0/ref/System.Runtime.Handles.dll", + "build/netstandard2.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll", + "build/netstandard2.0/ref/System.Runtime.InteropServices.dll", + "build/netstandard2.0/ref/System.Runtime.Numerics.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Formatters.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Json.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Primitives.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Xml.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.dll", + "build/netstandard2.0/ref/System.Runtime.dll", + "build/netstandard2.0/ref/System.Security.Claims.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Algorithms.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Csp.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Encoding.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Primitives.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.X509Certificates.dll", + "build/netstandard2.0/ref/System.Security.Principal.dll", + "build/netstandard2.0/ref/System.Security.SecureString.dll", + "build/netstandard2.0/ref/System.ServiceModel.Web.dll", + "build/netstandard2.0/ref/System.Text.Encoding.Extensions.dll", + "build/netstandard2.0/ref/System.Text.Encoding.dll", + "build/netstandard2.0/ref/System.Text.RegularExpressions.dll", + "build/netstandard2.0/ref/System.Threading.Overlapped.dll", + "build/netstandard2.0/ref/System.Threading.Tasks.Parallel.dll", + "build/netstandard2.0/ref/System.Threading.Tasks.dll", + "build/netstandard2.0/ref/System.Threading.Thread.dll", + "build/netstandard2.0/ref/System.Threading.ThreadPool.dll", + "build/netstandard2.0/ref/System.Threading.Timer.dll", + "build/netstandard2.0/ref/System.Threading.dll", + "build/netstandard2.0/ref/System.Transactions.dll", + "build/netstandard2.0/ref/System.ValueTuple.dll", + "build/netstandard2.0/ref/System.Web.dll", + "build/netstandard2.0/ref/System.Windows.dll", + "build/netstandard2.0/ref/System.Xml.Linq.dll", + "build/netstandard2.0/ref/System.Xml.ReaderWriter.dll", + "build/netstandard2.0/ref/System.Xml.Serialization.dll", + "build/netstandard2.0/ref/System.Xml.XDocument.dll", + "build/netstandard2.0/ref/System.Xml.XPath.XDocument.dll", + "build/netstandard2.0/ref/System.Xml.XPath.dll", + "build/netstandard2.0/ref/System.Xml.XmlDocument.dll", + "build/netstandard2.0/ref/System.Xml.XmlSerializer.dll", + "build/netstandard2.0/ref/System.Xml.dll", + "build/netstandard2.0/ref/System.dll", + "build/netstandard2.0/ref/mscorlib.dll", + "build/netstandard2.0/ref/netstandard.dll", + "build/netstandard2.0/ref/netstandard.xml", + "lib/netstandard1.0/_._", + "netstandard.library.2.0.3.nupkg.sha512", + "netstandard.library.nuspec" + ] + }, + "Newtonsoft.Json/13.0.1": { + "sha512": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "type": "package", + "path": "newtonsoft.json/13.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.1.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + }, + "SSH.NET/2020.0.2": { + "sha512": "G0dNlTBAM00KZXv1wWVwgg26d9/METcM6qWBpNQwllzQmmbu+Zu+FS1L1X4fFgGdPu3e8k9mmTBu6SwtQ0614g==", + "type": "package", + "path": "ssh.net/2020.0.2", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net35/Renci.SshNet.dll", + "lib/net35/Renci.SshNet.xml", + "lib/net40/Renci.SshNet.dll", + "lib/net40/Renci.SshNet.xml", + "lib/netstandard1.3/Renci.SshNet.dll", + "lib/netstandard1.3/Renci.SshNet.xml", + "lib/netstandard2.0/Renci.SshNet.dll", + "lib/netstandard2.0/Renci.SshNet.xml", + "lib/sl4/Renci.SshNet.dll", + "lib/sl4/Renci.SshNet.xml", + "lib/sl5/Renci.SshNet.dll", + "lib/sl5/Renci.SshNet.xml", + "lib/uap10/Renci.SshNet.dll", + "lib/uap10/Renci.SshNet.xml", + "lib/wp71/Renci.SshNet.dll", + "lib/wp71/Renci.SshNet.xml", + "lib/wp8/Renci.SshNet.dll", + "lib/wp8/Renci.SshNet.xml", + "ssh.net.2020.0.2.nupkg.sha512", + "ssh.net.nuspec" + ] + }, + "SshNet.Security.Cryptography/1.3.0": { + "sha512": "5pBIXRjcSO/amY8WztpmNOhaaCNHY/B6CcYDI7FSTgqSyo/ZUojlLiKcsl+YGbxQuLX439qIkMfP0PHqxqJi/Q==", + "type": "package", + "path": "sshnet.security.cryptography/1.3.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net20/SshNet.Security.Cryptography.dll", + "lib/net20/SshNet.Security.Cryptography.xml", + "lib/net40/SshNet.Security.Cryptography.dll", + "lib/net40/SshNet.Security.Cryptography.xml", + "lib/net45/SshNet.Security.Cryptography.dll", + "lib/net45/SshNet.Security.Cryptography.xml", + "lib/netstandard1.0/SshNet.Security.Cryptography.dll", + "lib/netstandard1.0/SshNet.Security.Cryptography.xml", + "lib/netstandard1.3/SshNet.Security.Cryptography.dll", + "lib/netstandard1.3/SshNet.Security.Cryptography.xml", + "lib/netstandard2.0/SshNet.Security.Cryptography.dll", + "lib/netstandard2.0/SshNet.Security.Cryptography.xml", + "lib/portable-net45+win8+wpa81/SshNet.Security.Cryptography.dll", + "lib/portable-net45+win8+wpa81/SshNet.Security.Cryptography.xml", + "lib/sl4/SshNet.Security.Cryptography.dll", + "lib/sl4/SshNet.Security.Cryptography.xml", + "lib/sl5/SshNet.Security.Cryptography.dll", + "lib/sl5/SshNet.Security.Cryptography.xml", + "lib/uap10.0/SshNet.Security.Cryptography.dll", + "lib/uap10.0/SshNet.Security.Cryptography.xml", + "lib/wp71/SshNet.Security.Cryptography.dll", + "lib/wp71/SshNet.Security.Cryptography.xml", + "lib/wp8/SshNet.Security.Cryptography.dll", + "lib/wp8/SshNet.Security.Cryptography.xml", + "sshnet.security.cryptography.1.3.0.nupkg.sha512", + "sshnet.security.cryptography.nuspec" + ] + }, + "Tesses.Http/1.0.0": { + "type": "project", + "path": "../Tesses.Http/Tesses.Http.csproj", + "msbuildProject": "../Tesses.Http/Tesses.Http.csproj" + } + }, + "projectFileDependencyGroups": { + ".NETStandard,Version=v2.0": [ + "NETStandard.Library >= 2.0.3", + "SSH.NET >= 2020.0.2", + "Tesses.Http >= 1.0.0" + ] + }, + "packageFolders": { + "/home/mike/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj", + "projectName": "Tesses.Http.VFSCollection", + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "/usr/share/dotnet/library-packs": {}, + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": { + "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "projectPath": "/home/mike/Documents/Tesses.Http/Tesses.Http/Tesses.Http.csproj" + } + } + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "SSH.NET": { + "target": "Package", + "version": "[2020.0.2, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.302/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http.VFSCollection/obj/project.nuget.cache b/Tesses.Http.VFSCollection/obj/project.nuget.cache new file mode 100644 index 0000000..acf06c4 --- /dev/null +++ b/Tesses.Http.VFSCollection/obj/project.nuget.cache @@ -0,0 +1,15 @@ +{ + "version": 2, + "dgSpecHash": "Tpviiwao27yHwlw/jaZfgfslyiUqqYM9sFSMDY5pwqTbFMinid1RpT1ua6/ecBv6/fhW5NjAwUYtdS24ZyhdDA==", + "success": true, + "projectFilePath": "/home/mike/Documents/Tesses.Http/Tesses.Http.VFSCollection/Tesses.Http.VFSCollection.csproj", + "expectedPackageFiles": [ + "/home/mike/.nuget/packages/microsoft.netcore.platforms/1.1.0/microsoft.netcore.platforms.1.1.0.nupkg.sha512", + "/home/mike/.nuget/packages/mimetypesmap/1.0.8/mimetypesmap.1.0.8.nupkg.sha512", + "/home/mike/.nuget/packages/netstandard.library/2.0.3/netstandard.library.2.0.3.nupkg.sha512", + "/home/mike/.nuget/packages/newtonsoft.json/13.0.1/newtonsoft.json.13.0.1.nupkg.sha512", + "/home/mike/.nuget/packages/ssh.net/2020.0.2/ssh.net.2020.0.2.nupkg.sha512", + "/home/mike/.nuget/packages/sshnet.security.cryptography/1.3.0/sshnet.security.cryptography.1.3.0.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file diff --git a/Tesses.Http/ASPNetStyleEndpoint.cs b/Tesses.Http/ASPNetStyleEndpoint.cs new file mode 100644 index 0000000..3f2d7db --- /dev/null +++ b/Tesses.Http/ASPNetStyleEndpoint.cs @@ -0,0 +1,441 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using Newtonsoft.Json; +using System.Reflection; +using System.Linq; +using HeyRed.Mime; + +namespace Tesses.Http +{ + + + public abstract class ASPEndpointRequestHandler : IRequestHandler + { + protected virtual Stream GetPostFileStream(string name,string filename,string contentType) + { + return new MemoryStream(); + } + + List<___RouteMethod> ___RouteMethods=new List<___RouteMethod>(); + + private class ___RouteMethod + { + public string Method; + public bool ContainsServerCtx; + public bool ContainsMultipart; + public bool ReturnsVoid; + + public string Name; + + public MethodInfo info; + + public ASPEndpointRequestHandler _instance; + + + public void Call(ServerContext ctx,MultipartParser p,Dictionary> args) + { + + if(!ContainsMultipart && p != null) + { + foreach(var item in p.Parse(_instance.GetPostFileStream,true)) + { + if(!item.HasFileName) + { + args.Add(item.Name,item.GetStringData()); + } + } + } + object[] ar_= _args.Select<___Arg,object>((e)=>{ + return e.GetArgument(ctx,p,args); + }).ToArray(); + + + object o=info.Invoke(_instance,ar_); + if(!ReturnsVoid) + { + IResponse r = o as IResponse; + Stream s = o as Stream; + string r2 = o as string; + StringBuilder b=o as StringBuilder; + + + if(r!=null) + { + r.Handle(ctx); + }else if(s != null) + { + FileResponse resp=new FileResponse(s,"application/octet-stream",true); + resp.Handle(ctx); + }else if(b != null) + { + TextResponse resp=new TextResponse(b.ToString(),"text/plain"); + resp.Handle(ctx); + } + else if(!string.IsNullOrEmpty(r2)) + { + TextResponse resp=new TextResponse(r2,"text/plain"); + resp.Handle(ctx); + }else{ + TextResponse resp=new TextResponse(JsonConvert.SerializeObject(o),"application/json"); + resp.Handle(ctx); + } + + + } + } + + public List<___Arg> _args=new List<___Arg>(); + } + private class ___Arg + { + + public bool _isServerCtx; + public bool _isMultipart; + public string name; + public Type type; + private object Default() + { + if(type.GetTypeInfo().IsValueType) + { + return Activator.CreateInstance(type); + } + return null; + + } + private object ___to_type_ar(Type t,List items) + { + object o; + if(t.IsArray) + { + var t0=t.MakeArrayType(); + object[] items2=new object[items.Count]; + foreach(var item in items) + { + ___to_type(t0,item); + } + o=items; + }else{ + o=___to_type(t,items.FirstOrDefault()); + } + return o; + } + private object ___to_type(Type t,string value) + { + try{ + if(t == typeof(String)) + { + return value; + } + foreach(var item in t.GetMethods()) + { + var _params = item.GetParameters(); + if(_params.Length != 1) + { + continue; + } + if(_params[0].ParameterType != typeof(String)) continue; + + if(item.IsStatic && !item.IsConstructor && item.Name == "Parse") + { + return item.Invoke(null,new object[]{value}); + } + if(item.IsConstructor) + { + return Activator.CreateInstance(t,value); + } + + } + + MethodInfo method = typeof(JsonConvert).GetMethod(nameof(JsonConvert.SerializeObject)); + MethodInfo generic = method.MakeGenericMethod(t); + return generic.Invoke(null,new object[]{value}); + }catch(Exception ex) + { + _=ex; + return Default(); + } + } + public object GetArgument(ServerContext ctx,MultipartParser p,Dictionary> args) + { + if(_isServerCtx) + { + return ctx; + } + if(_isMultipart) + { + return p; + } + + + + foreach(var item in args) + { + if(item.Key.ToLower() == name) + { + return ___to_type_ar(type,item.Value); + } + } + + return Default(); + + + } + } + + + public TextResponse String(string text,string mimeType="text/html") + { + + return new TextResponse(text,mimeType); + } + + public FileResponse File(Stream strm,string mimeType,bool ownStream=true) + { + return new FileResponse(strm,mimeType,ownStream); + } + + public FileResponse File(string filename,bool inline=true) + { + return new FileResponse(filename,inline); + } + public FileResponse File(Stream strm,string mimeType,string filename,bool inline=false,bool ownStream=false) + { + return new FileResponse(strm,mimeType,filename,inline,ownStream); + } + + + bool ___has_loaded=false; + + + + + + private void ___lazy_load_everything() + { + if(!___has_loaded) + { + Type t=GetType(); + foreach(var item in t.GetMethods()) + { + IHttpRoute route = new HttpGetAttribute($"/{item.Name}"); + + foreach(var r in item.GetCustomAttributes()) + { + var rte=r as IHttpRoute; + if(rte != null) + { + route=rte; + if(string.IsNullOrWhiteSpace(rte.RouteName)) + { + + route.RouteName = $"/{item.Name}"; + } + + break; + } + } + + ___RouteMethod m=new ___RouteMethod(); + var __props = item.GetParameters(); + m.ContainsServerCtx = __props.Any(e=>e.ParameterType == typeof(ServerContext)); + m.ContainsMultipart = __props.Any(e=>e.ParameterType == typeof(MultipartParser)); + m.ReturnsVoid = item.ReturnType == typeof(void); + m.info=item; + m.Name = route.RouteName; + m.Method=route.Method; + m._instance = this; + m._args=new List<___Arg>(); + + if(m.ContainsServerCtx || !m.ReturnsVoid) + { + //add route to + foreach(var args in __props) + { + ___Arg a=new ___Arg(); + a._isServerCtx = args.ParameterType == typeof(ServerContext); + a._isMultipart = args.ParameterType == typeof(MultipartParser); + a.name = args.Name.ToLower(); + a.type = args.ParameterType; + m._args.Add(a); + } + ___RouteMethods.Add(m); + + } + } + } + ___has_loaded=true; + } + public async Task Handle(ServerContext ctx) + { + ___lazy_load_everything(); + Dictionary> args=new Dictionary>(); + MultipartParser parser=null; + foreach(var m in ___RouteMethods) + { + args.Clear(); + string p=ctx.Request.GetQueryParameters(ctx.Request.CurrentUrl,args); + + if(m.Method == ctx.Request.RequestLine.Method && m.Name ==p) + { + //want to check for method + + + if(m.Method == "POST") + { + string _ctt; + if(ctx.Request.Headers.TryGetFirst("Content-Type",out _ctt)) + { + if(_ctt.StartsWith("multipart/form-data")) + { + parser = ctx.Request.GetMultipartParser(); + } + if(_ctt == "application/x-www-form-urlencoded") + { + ctx.Request.GetUrlEncodedPost(args); + } + } + } + + m.Call(ctx,parser,args); + + break; + } + } + + await Task.CompletedTask; + } + } + + + public class FileResponse : IResponse + { + bool inline; + public FileResponse(Stream strm,string mimeType,bool ownStream) + { + this.ownStream=ownStream; + Stream = strm; + MimeType=mimeType; + FileName=""; + } + public FileResponse(Stream strm,string mimeType,string filename,bool inline,bool ownStream) + { + this.ownStream=ownStream; + Stream =strm; + MimeType = mimeType; + FileName=filename; + this.inline=inline; + } + bool ownStream; + public FileResponse(string filename,bool inline) + { + ownStream=true; + MimeType=MimeTypesMap.GetMimeType(filename); + Stream=File.OpenRead(filename); + FileName = Path.GetFileName(filename); + this.inline=inline; + } + public Stream Stream {get;set;} + public string MimeType {get;set;} + + public string FileName {get;set;} + + public void Handle(ServerContext ctx) + { + if(string.IsNullOrWhiteSpace(FileName)) + { + ctx.Response.WithContentType(MimeType).SendRangableResponseStream(Stream); + + }else{ + ctx.Response.WithContentType(MimeType).WithFileName(FileName,inline).SendRangableResponseStream(Stream); + + } + if(ownStream) + Stream.Dispose(); + } + } + + public class TextResponse : IResponse + { + public TextResponse(string text,string mime) + { + Text=text; + MimeType=mime; + } + public string Text {get;set;} + public string MimeType {get;set;} + + public void Handle(ServerContext ctx) + { + ctx.Response.WithContentType(MimeType).SendText(Text); + } + } + + public interface IResponse + { + void Handle(ServerContext ctx); + } + + public interface IHttpRoute + { + string RouteName {get;set;} + + string Method {get;} + } + + [AttributeUsage(AttributeTargets.Method)] + + public sealed class HttpGetAttribute :Attribute, IHttpRoute + { + public string Method {get{return "GET";}} + public string RouteName {get;set;} + public HttpGetAttribute(string name) + { + RouteName=name; + } + public HttpGetAttribute() + { + RouteName = ""; + } + } + [AttributeUsage(AttributeTargets.Method)] + + public sealed class HttpPostAttribute :Attribute, IHttpRoute + { + public string Method {get{return "POST";}} + public string RouteName {get;set;} + public HttpPostAttribute(string name) + { + RouteName=name; + } + public HttpPostAttribute() + { + RouteName = ""; + } + } + + public sealed class HttpMethodAttribute : Attribute, IHttpRoute + { + string _meth; + public string Method {get{return _meth;}} + + public string RouteName {get;set;} + + public HttpMethodAttribute(string method) + { + _meth=method; + RouteName=""; + } + public HttpMethodAttribute(string method,string route) + { + _meth = method; + RouteName = route; + } + } + + +} \ No newline at end of file diff --git a/Tesses.Http/BasicAuthRequestHandler.cs b/Tesses.Http/BasicAuthRequestHandler.cs new file mode 100644 index 0000000..fa0112e --- /dev/null +++ b/Tesses.Http/BasicAuthRequestHandler.cs @@ -0,0 +1,138 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using Newtonsoft.Json; +using System.Reflection; +using System.Linq; +using HeyRed.Mime; + +namespace Tesses.Http +{/// + /// Check username and password are correct or if request can be anonymous + /// + /// Username, can and will be "" on first request for resource + /// Password, can and will be "" on first request for resource + /// true for authorized, false for unauthorized + public delegate bool Authenticate(string username, string password); + /// + /// Check username and password are correct or if request can be anonymous + /// + /// Server Context + /// Username, can and will be "" on first request for resource + /// Password, can and will be "" on first request for resource + /// true for authorized, false for unauthorized + public delegate bool AuthenticateWithContext(ServerContext context,string username,string password); + /// + /// Protect server with password + /// + public class BasicAuthRequestHandler : IRequestHandler + { + /// + /// Construct server for user authorization + /// + /// callback for authorization + /// server to protect + /// realm parameter in WWW-Auhenticate Header + public BasicAuthRequestHandler(Authenticate auth,IRequestHandler inner,string realm="SampleRealm") + { + Authenticate = auth; + InnerServer = inner; + Realm = realm; + } + /// + /// Construct server for user authorization (With ServerContext in callback) + /// + /// callback for authorization + /// server to protect + /// realm parameter in WWW-Auhenticate Header + public BasicAuthRequestHandler(AuthenticateWithContext auth,IRequestHandler inner,string realm = "SampleRealm") + { + AuthenticateWithContext=auth; + InnerServer=inner; + Realm = realm; + } + public async Task Handle(ServerContext ctx) + { + if(await Authorize(ctx)) + { + + await RequestHandler.Guaranteed(ctx,InnerServer).Handle(ctx); + + } + + } + + /// + /// Server to protect + /// + + public IRequestHandler InnerServer { get; set; } + /// + /// Authentication callback without ServerContext + /// + public Authenticate Authenticate { get; set; } + /// + /// Authentication callback with ServerContext + /// + + public AuthenticateWithContext AuthenticateWithContext {get;set;} + /// + /// Realm parameter in WWW-Authenticate header + /// + public string Realm { get; set; } + + private bool ValidAuth(ServerContext ctx) + { + string auth; + if(Authenticate == null && AuthenticateWithContext == null) return true; + if (ctx.Request.Headers.TryGetFirst("Authorization", out auth)) + { + string[] authorization = auth.Split(' '); + //authorization_basic + + if (authorization[0] == "Basic") + { + string[] userPass = Encoding.UTF8.GetString(Convert.FromBase64String(authorization[1])).Split(new char[] { ':' },2); + //return userPass.Equals($"{config.UserName}:{config.Password}", StringComparison.Ordinal); + if(Authenticate != null) + return Authenticate(userPass[0], userPass[1]); + + if(AuthenticateWithContext != null) + return AuthenticateWithContext(ctx,userPass[0],userPass[2]); + + + } + }else{ + if(Authenticate != null) + return Authenticate("", ""); + + if(AuthenticateWithContext != null) + return AuthenticateWithContext(ctx,"",""); + + } + return false; + } + private async Task Authorize(ServerContext ctx) + { + if (Authenticate == null && AuthenticateWithContext == null) + return true; + + if (ValidAuth(ctx)) + return true; + + ctx.Response.Headers.Add("WWW-Authenticate", $"Basic realm=\"{Realm}\""); + ctx.Response.StatusLine = 401; + await UnauthorizedPage(ctx); + return false; + } + protected virtual async Task UnauthorizedPage(ServerContext ctx) + { + ctx.Response.SendStatusCodeHtml(); + await Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/Tesses.Http/ChangableRequestHandler.cs b/Tesses.Http/ChangableRequestHandler.cs new file mode 100644 index 0000000..694570c --- /dev/null +++ b/Tesses.Http/ChangableRequestHandler.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using Newtonsoft.Json; +using System.Reflection; +using System.Linq; +using HeyRed.Mime; + +namespace Tesses.Http +{ + public class ChangableRequestHandler : IRequestHandler + { + public IRequestHandler Handler {get;set;} + public async Task Handle(ServerContext ctx) + { + await RequestHandler.Guaranteed(ctx,Handler).Handle(ctx); + } + } +} \ No newline at end of file diff --git a/Tesses.Http/ErrorRequestHandler.cs b/Tesses.Http/ErrorRequestHandler.cs new file mode 100644 index 0000000..1abddd3 --- /dev/null +++ b/Tesses.Http/ErrorRequestHandler.cs @@ -0,0 +1,13 @@ +using System.Threading.Tasks; + +namespace Tesses.Http +{ + public class ErrorRequestHandler : IRequestHandler + { + public async Task Handle(ServerContext ctx) + { + ctx.Response.SendStatusCodeHtml(); + await Task.CompletedTask; + } + } +} \ No newline at end of file diff --git a/Tesses.Http/HttpExtensions.cs b/Tesses.Http/HttpExtensions.cs new file mode 100644 index 0000000..6ffadb3 --- /dev/null +++ b/Tesses.Http/HttpExtensions.cs @@ -0,0 +1,152 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading; +using System.Text; + +namespace Tesses.Http +{ + public static class Extensions + { + private static Lazy> _statusCodeMap = new Lazy>(() => new Dictionary() + { + [202] = "Accepted", + [502] = "Bad Gateway", + [400] = "Bad Request", + [409] = "Conflict", + [100] = "Continue", + [201] = "Created", + [417] = "Expectation Failed", + [403] = "Forbidden", + [302] = "Found", + [504] = "Gateway Timeout", + [410] = "Gone", + [505] = "HTTP Version Not Supported", + [500] = "Internal Server Error", + [411] = "Length Required", + [405] = "Method Not Allowed", + [301] = "Moved Permanently", + [300] = "Multiple Choices", + [204] = "No Content", + [203] = "Non Authoritative Information", + [406] = "Not Acceptable", + [404] = "Not Found", + [501] = "Not Implemented", + [304] = "Not Modified", + [200] = "OK", + [206] = "Partial Content", + [402] = "Payment Required", + [412] = "Precondition Failed", + [407] = "Proxy Authentication Required", + [302] = "Redirect", + [307] = "Redirect Keep Verb", + [303] = "Redirect Method", + [416] = "Requested Range Not Satisfiable", + [413] = "Request Entry Too Large", + [408] = "Request Timeout", + [414] = "Request Uri Too Long", + [205] = "Reset Content", + [503] = "Service Unavailable", + [101] = "Switching Protocols", + [307] = "Temporary Redirect", + [401] = "Unauthorized", + [415] = "Unsupported Media Type", + [306] = "Unused", + [426] = "Upgrade Required", + [305] = "Use Proxy", + [429] = "Too Many Requests" + + }); + public static byte[] AsArray(this Stream strm,bool begin=true) + { + if(strm.Position != 0 && begin) + strm.Position=0; + + byte[] data=new byte[strm.Length-strm.Position]; + strm.Read(data,0,data.Length); + return data; + } + public static string AsString(this byte[] data) + { + return Encoding.UTF8.GetString(data); + } + public static string GetReasonPhrase(this StatusLine line) + { + string res; + if(_statusCodeMap.Value.TryGetValue(line.StatusCode,out res)) + { + return res; + } + return ""; + } + /// + /// StringBuilder ends with + /// + /// string builder + /// text to check + /// comparison type + /// true if sb ends with test, false if it does not + internal static bool EndsWith(this StringBuilder sb, string test, + StringComparison comparison) + { + if (sb.Length < test.Length) + return false; + + string end = sb.ToString(sb.Length - test.Length, test.Length); + return end.Equals(test, comparison); + } + internal static string ReadHttpHeaders(this Stream strm) + { + StringBuilder s = new StringBuilder(); + + var decoder = Encoding.UTF8.GetDecoder(); + var nextChar = new char[1]; + while (!s.EndsWith("\r\n\r\n",StringComparison.Ordinal)) + { + + int data = strm.ReadByte(); + if(data == -1) + { + break; + } + int charCount=decoder.GetChars(new byte[] { (byte)data }, 0, 1, nextChar, 0); + if (charCount == 0) continue; + s.Append(nextChar); + + } + + + return s.ToString(); + } + + + public static void Add(this Dictionary> headers,T1 key,T2 value) + { + if(!headers.ContainsKey(key)) + { + headers.Add(key,new List()); + } + headers[key].Add(value); + } + public static bool TryGetFirst(this Dictionary> headers,T1 key,out T2 value) + { + value=default(T2); + if(headers ==null) return false; + if(headers.ContainsKey(key) && headers[key] !=null && headers[key].Count > 0) + { + value=headers[key][0]; + return true; + } + return false; + } + public static bool TryGetFirst(this Dictionary> headers,T key,out long value) + { + value=0; + string v; + + return (headers.TryGetFirst(key,out v) && long.TryParse(v,out value)); + } + } +} \ No newline at end of file diff --git a/Tesses.Http/HttpParser.cs b/Tesses.Http/HttpParser.cs new file mode 100644 index 0000000..589b6af --- /dev/null +++ b/Tesses.Http/HttpParser.cs @@ -0,0 +1,354 @@ +using System; +using System.IO; +using System.Net; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Threading; +using System.Text; +using System.Net.Http; + +namespace Tesses.Http +{ + + public struct FirstLine + { + public FirstLine(string line) + { + LineText=line; + } + public string LineText {get;set;} + + public static implicit operator FirstLine(string text) + { + return new FirstLine(text); + } + public static implicit operator string(FirstLine line) + { + return line.ToString(); + } + public override string ToString() + { + return LineText; + } + + } + public struct RequestLine + { + + public RequestLine(string method,string path,string httpVersion) + { + Method = method; + Path= path; + HttpVersion=httpVersion; + } + public RequestLine(string method,string path) + { + Method=method; + Path=path; + HttpVersion = "HTTP/1.1"; + } + + public string Method {get;set;} + + public string Path {get;set;} + + public string HttpVersion {get;set;} + + public static implicit operator RequestLine(FirstLine line) + { + string[] data=line.LineText.Split(' '); + RequestLine Rline=new RequestLine(data[0],data[1],data[2]); + + return Rline; + } + + public static implicit operator FirstLine(RequestLine line) + { + return new FirstLine(line.ToString()); + } + public static implicit operator RequestLine(string path) + { + RequestLine req=new RequestLine(); + req.Method="GET"; + req.Path=path; + req.HttpVersion="HTTP/1.1"; + return req; + } + public override string ToString() + { + return $"{Method} {Path} {HttpVersion}"; + } + } + public struct StatusLine + { + public StatusLine(string httpVersion,HttpStatusCode code) + { + HttpVersion = httpVersion; + StatusCode=(int)code; + } + public StatusLine(string httpVersion,int code) + { + HttpVersion = httpVersion; + StatusCode = code; + } + + public string HttpVersion {get;set;} + public int StatusCode {get;set;} + public static implicit operator StatusLine(FirstLine line) + { + //HTTP/1.1 200 OK + StatusLine Sline=new StatusLine(); + string[] data=line.LineText.Split(' '); + Sline.HttpVersion = data[0]; + int n=200; + if(!int.TryParse(data[1],out n)) + { + n=500; + } + Sline.StatusCode=n; + return Sline; + } + public static implicit operator StatusLine(int code) + { + StatusLine line = new StatusLine(); + line.HttpVersion= "HTTP/1.1"; + line.StatusCode=code; + return line; + } + public static implicit operator FirstLine(StatusLine line) + { + return new FirstLine(line.ToString()); + } + + public override string ToString() + { + return $"{HttpVersion} {StatusCode}"; + } + } + public class HeaderCollection : Dictionary> + { + public HeaderCollection() + { + FirstLine=""; + } + public HeaderCollection(string firstLine) + { + FirstLine=firstLine; + } + public HeaderCollection(Stream strm) + { + string[] headers=strm.ReadHttpHeaders().Split(new string[]{"\r\n"},StringSplitOptions.RemoveEmptyEntries); + foreach(var hdr in headers) + { + Add(hdr); + } + } + public FirstLine FirstLine {get;set;} + public void Add(string header) + { + if(header.Contains(":")) + { + //its a kvp + string[] hdr=header.Split(new string[]{": "},2,StringSplitOptions.None); + if(hdr.Length ==1) + { + this.Add(hdr[0],""); + }else{ + this.Add(hdr[0],hdr[1]); + } + }else{ + FirstLine = header; + } + } + + public override string ToString() + { + StringBuilder b=new StringBuilder(); + b.Append($"{FirstLine}\r\n"); + + foreach(var kvps in this) + { + foreach(var value in kvps.Value) + { + b.Append($"{kvps.Key}: {value}\r\n"); + } + } + b.Append("\r\n"); + return b.ToString(); + } + internal byte[] AsBytes() + { + + return Encoding.UTF8.GetBytes(ToString()); + } + public void WriteHeaders(Stream strm) + { + byte[] buff=AsBytes(); + strm.Write(buff,0,buff.Length); + strm.Flush(); + } + } + + public class HttpParser + { + private class HttpBodyStream : Stream + { + Stream strm; + long length; + public HttpBodyStream(Stream src,long len) + { + this.strm = src; + this.length=len; + } + public override bool CanRead => strm.CanRead; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length => length; + + private long read=0; + public override long Position { get {return read;} set => throw new NotImplementedException(); } + + public override void Flush() + { + strm.Flush(); + } + public override int ReadByte() + { + if(length > 0 && read >= length) return -1; + return strm.ReadByte(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + int read0=0; + if(length == 0) { + + read0= strm.Read(buffer,offset,count); + read+=read0; + return read0; + } + + //i want to read some data + read0=(int)Math.Min(count,length-read); + if(read0 == 0) return 0; + + read0=strm.Read(buffer,offset,read0); + + read+=read0; + + return read0; + } + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + int read0=0; + if(length == 0) { + + read0= await strm.ReadAsync(buffer,offset,count); + read+=read0; + return read0; + } + + //i want to read some data + read0=(int)Math.Min(count,length-read); + if(read0 == 0) return 0; + + read0=await strm.ReadAsync(buffer,offset,read0); + + read+=read0; + + return read0; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + public override void Close() + { + strm.Close(); + } + protected override void Dispose(bool disposing) + { + if(disposing) + { + strm.Dispose(); + } + } + public override async Task FlushAsync(CancellationToken cancellationToken) + { + await strm.FlushAsync(cancellationToken); + } + } + + Stream _strm; + public HttpParser(Stream strm) + { + + _strm=strm; + + } + public Stream GetRawStream() + { + return _strm; + } + public HeaderCollection SentHeaders {get;set;} + + public HeaderCollection ReceivedHeaders {get;set;} + + + + public void SendHeaders() + { + SentHeaders.WriteHeaders(_strm); + + } + + public void ReceiveHeaders() + { + ReceivedHeaders = new HeaderCollection(_strm); + } + public void WriteBody(Stream strm) + { + strm.CopyTo(_strm); + _strm.Flush(); + } + public void WriteBody(string text) + { + WriteBody(System.Text.Encoding.UTF8.GetBytes(text)); + } + public void WriteBody(byte[] data) + { + using(var ms = new MemoryStream()) + { + ms.Write(data,0,data.Length); + ms.Seek(0,SeekOrigin.Begin); + WriteBody(ms); + } + } + + public Stream ReadBody() + { + long res=0; + + if(!ReceivedHeaders.TryGetFirst("Content-Length",out res)) + { + res=0; + } + + return new HttpBodyStream(_strm,res); + } + } +} \ No newline at end of file diff --git a/Tesses.Http/HttpPassthroughReverseProxy.cs b/Tesses.Http/HttpPassthroughReverseProxy.cs new file mode 100644 index 0000000..278c82c --- /dev/null +++ b/Tesses.Http/HttpPassthroughReverseProxy.cs @@ -0,0 +1,334 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Security; +using System.Net.Sockets; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Newtonsoft.Json; + +namespace Tesses.Http +{ + public sealed class HTTPClientRequest + { + HttpParser p; + internal HTTPClientRequest(HttpParser parser) + { + p=parser; + } + public Dictionary> Headers {get {return p.SentHeaders;}} + public void WriteRequestBody(string data) + { + WriteRequestBody(Encoding.UTF8.GetBytes(data)); + } + public HTTPClientRequest WithHeader(string key,string value) + { + Headers.Add(key,value); + return this; + } + public HTTPClientRequest WithRange(long? start,long? end) + { + string _s=""; + string _e=""; + if(start.HasValue) + { + _s=start.Value.ToString(); + } + if(end.HasValue) + { + _e =end.Value.ToString(); + } + string ohdr=$"{_s}-{_e}"; + WithHeader("Range",ohdr); + return this; + } + public void WriteRequestBody(object o) + { + WithContentType("application/json").WriteRequestBody(JsonConvert.SerializeObject(o)); + } + public void WriteRequestBody(byte[] data) + { + WriteRequestBody(new MemoryStream(data)); + } + public void WriteRequestBody(Stream strm) + { + //we need to write request body + Headers.Add("Content-Length",strm.Length.ToString()); + p.SendHeaders(); + p.WriteBody(strm); + p.ReceiveHeaders(); + } + public HTTPClientRequest WithContentType(string content_type) + { + Headers.Add("Content-Type",content_type); + return this; + } + + public void WriteUrlEncodedPost(Dictionary> args) + { + string urlencoded= string.Join("&",args.Select>,string>(e=>{ + StringBuilder b=new StringBuilder(); + foreach(var item in e.Value) + { + b.Append($"{e.Key}={WebUtility.UrlEncode(item)}"); + } + return b.ToString(); + })); + + WithContentType("application/x-www-form-urlencoded").WriteRequestBody(urlencoded); + } + public void WriteEmptyRequest() + { + p.SendHeaders(); + p.ReceiveHeaders(); + } + public RequestLine RequestLine {get{return p.SentHeaders.FirstLine;} set{p.SentHeaders.FirstLine=value;}} + } + public sealed class HTTPClient + { + TcpClient client; + Stream strm; + HttpParser parser; + private HTTPClient(string method,string url) + { + string host=""; + int port; + string hostHdr; + Uri uri=new Uri(url); + hostHdr = uri.Host; + host=hostHdr; + bool isSecure; + + isSecure = uri.Scheme != "http" && uri.Scheme != "ws"; + if(((uri.Scheme == "http") && uri.Port != 80 ) || ((uri.Scheme == "https") && uri.Port != 443)) + { + hostHdr += $":{uri.Port}"; + port = uri.Port; + }else{ + if(uri.Scheme=="http") + { + port=80; + } + else{ + port=443; + } + } + client=new TcpClient(); + client.Connect(host,port); + if(isSecure) + { + + var m=new SslStream(client.GetStream()); + m.AuthenticateAsClient(host); + strm=m; + + }else{ + strm = client.GetStream(); + } + parser=new HttpParser(strm); + parser.SentHeaders=new HeaderCollection(); + parser.SentHeaders.FirstLine = new RequestLine(method,uri.PathAndQuery,"HTTP/1.1"); + Request=new HTTPClientRequest(parser); + Response=new HTTPClientResponse(parser); + Request.Headers.Add("Host",hostHdr); + } + public static HTTPClient Open(string method,string url) + { + return new HTTPClient(method,url); + } + + public HTTPClientRequest Request {get;private set;} + + public HTTPClientResponse Response {get;private set;} + + public void SendToServer(ServerContext ctx,bool replaceHost=false) + { + //Send Request to Server + foreach(var hdr in ctx.Request.Headers) + { + if(hdr.Key != "Host") + { + if(parser.SentHeaders.ContainsKey(hdr.Key)) + { + parser.SentHeaders[hdr.Key].Clear(); + } + foreach(var value in hdr.Value) + { + parser.SentHeaders.Add(hdr.Key,value); + } + + } + } + if(replaceHost) + { + if(parser.SentHeaders.ContainsKey("Host") && ctx.Request.Headers.ContainsKey("Host")) + { + parser.SentHeaders["Host"].Clear(); + parser.SentHeaders.Add("Host",ctx.Request.Headers["Host"][0]); + } + + } + + //we will send to the second server we are reverse proxing + + //we need to set dest Method + RequestLine req=parser.SentHeaders.FirstLine; + parser.SentHeaders.FirstLine = new RequestLine(ctx.Request.RequestLine.Method,req.Path,req.HttpVersion); + parser.SendHeaders(); + if(ctx.Request.Headers.ContainsKey("Content-Length") && ctx.Request.RequestLine.Method != "GET") + { + //not a get request and has content-length + //so we must copy it + parser.WriteBody(ctx.Request.GetRequestStream()); + } + //we will write the response from HTTPClient to ServerContext + parser.ReceiveHeaders(); + ctx.Response.Headers.Clear(); + ctx.Response.StatusLine = parser.ReceivedHeaders.FirstLine; + + foreach(var hdr in parser.ReceivedHeaders) + { + foreach(var value in hdr.Value) + { + ctx.Response.Headers.Add(hdr.Key,value); + } + } + ctx.p.SendHeaders(); + if(ctx.Response.Headers.ContainsKey("Content-Type")) + { + ctx.p.WriteBody(parser.ReadBody()); + } + + } + + + public static HTTPClient Open(HTTPServer server,string method,string path) + { + string myUrl; + if(server.LocalEndPoint.Address.ToString()=="0.0.0.0") + { + //we can access via 127.0.0.1 + myUrl = $"http://127.0.0.1:{server.LocalEndPoint.Port}/{path.TrimStart('/')}"; + }else{ + //we can access via X.X.X.X + myUrl = $"http://{server.LocalEndPoint.Address.ToString()}:{server.LocalEndPoint.Port}/{path.TrimStart('/')}"; + } + + return HTTPClient.Open(method,myUrl); + } + } + + public class HTTPClientResponse + { + HttpParser p; + public HTTPClientResponse(HttpParser parser) + { + p=parser; + } + + public Dictionary> Headers {get{return p.ReceivedHeaders;}} + + public StatusLine StatusLine {get{return p.ReceivedHeaders.FirstLine;} set{p.ReceivedHeaders.FirstLine=value;}} + public void DownloadFile(string file) + { + using(var f = File.Create(file)) + { + DownloadFile(f); + } + } + public void DownloadFile(Stream strm) + { + var strm0=GetResponseStream(); + strm0.CopyTo(strm); + } + public Stream GetResponseStream() + { + return p.ReadBody(); + } + public string GetResponseString() + { + using(var sr=new StreamReader(GetResponseStream())) + { + return sr.ReadToEnd(); + } + } + public T GetResponseJson() + { + return JsonConvert.DeserializeObject(GetResponseString()); + } + + } + + public sealed class HTTPPassthroughReverseProxy + { + ServerContext ctx; + string host=""; + int port; + string hostHdr; + bool useSrcHost; + bool isSecure; + string path; + public HTTPPassthroughReverseProxy(ServerContext ctx,string url,bool useSrcHost) + { + Uri uri=new Uri(url); + hostHdr = uri.Host; + host=hostHdr; + this.useSrcHost = useSrcHost; + isSecure = uri.Scheme != "http" && uri.Scheme != "ws"; + if(((uri.Scheme == "http" || uri.Scheme == "ws") && uri.Port != 80 ) || ((uri.Scheme == "https" || uri.Scheme == "wss") && uri.Port != 443)) + { + hostHdr += $":{uri.Port}"; + port = uri.Port; + }else{ + if(uri.Scheme=="http" || uri.Scheme == "ws") + { + port=80; + } + else{ + port=443; + } + } + path = uri.PathAndQuery; + ctx.Request.RequestLine=new RequestLine(ctx.Request.RequestLine.Method,path,ctx.Request.RequestLine.HttpVersion); + this.ctx=ctx; + } + + public void Exchange(CancellationToken token=default(CancellationToken)) + { + using (TcpClient clt=new TcpClient()) + { + + if(!useSrcHost) + { + ctx.Request.Headers.Remove("Host"); + ctx.Request.Headers.Add("Host",hostHdr); + } + clt.Connect(host,port); + Stream strm; + + if(isSecure) + { + + var m=new SslStream(clt.GetStream()); + m.AuthenticateAsClient(host); + strm=m; + + }else{ + strm = clt.GetStream(); + } + + using(StreamPiper piper=new StreamPiper(ctx.GetRawStreamWithHeaders(),strm)){ + + + + piper.Pipe(token); + } + + } + + } + } +} \ No newline at end of file diff --git a/Tesses.Http/HttpServer.cs b/Tesses.Http/HttpServer.cs new file mode 100644 index 0000000..55881a3 --- /dev/null +++ b/Tesses.Http/HttpServer.cs @@ -0,0 +1,295 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; + +namespace Tesses.Http +{ + public static class RequestHandler + { + private class __IREQ : IRequestHandler + { + HandleRequestAsync a; + public __IREQ(HandleRequestAsync hra) + { + a=hra; + } + public async Task Handle(ServerContext ctx) + { + if(a!=null) + await a(ctx); + } + } + private static bool DefaultFileExists(VirtualStorage storage,string[] _defaultFileNames,string path,out string name) + { + foreach(var def in _defaultFileNames) + { + name = storage.PathCombine(path, def); + if(storage.FileExists(name)) + { + return true; + } + } + name = ""; + return false; + } + private static bool DefaultFileExists(string[] _defaultFileNames,string path,out string name) + { + foreach(var def in _defaultFileNames) + { + name = Path.Combine(path, def); + if(File.Exists(name)) + { + return true; + } + } + name = ""; + return false; + } + public static IRequestHandler FromVirtualStorage(VirtualStorage storage,string[] filenames=null,bool listDirectories=true,IRequestHandler _notFound=null) + { + if(filenames==null) + filenames = new string[]{ + "index.html", + "index.htm", + "default.html", + "default.htm" + }; + + if(_notFound == null) + _notFound=error; + + return FromDelegate(async(e)=>{ + string someUrl = WebUtility.UrlDecode(e.Request.CurrentUrl.Split(new char[]{'?'},2)[0].Substring(1)); + //Console.WriteLine(someUrl); + if (storage.DirectoryExists(someUrl)) + { + string name; + if(DefaultFileExists(storage,filenames,someUrl,out name)) + { + e.Response.SendFile(storage,name); + }else{ + if(listDirectories){ + + List items=new List(); + foreach(var item in storage.EnumerateDirectories(someUrl)) + { + items.Add(item + "/"); + } + foreach(var item in storage.EnumerateFiles(someUrl)) + { + items.Add(item); + } + + e.Response.SendFileListing($"Index of {e.Request.CurrentUrl.Split(new char[]{'?'},2)[0]}","Directory listing",items); + }else{ + e.Response.StatusLine=403; + await _notFound.Handle(e); + } + } + } + else if (storage.FileExists(someUrl)) + { + e.Response.SendFile(storage,someUrl); + } + else + { + e.Response.StatusLine=404; + await _notFound.Handle(e); + } + }); + } + public static IRequestHandler FromDirectory(string directory,string[] filenames=null,bool listDirectories=true,IRequestHandler _notFound=null) + { + if(filenames==null) + filenames = new string[]{ + "index.html", + "index.htm", + "default.html", + "default.htm" + }; + + if(_notFound == null) + _notFound=error; + + return FromDelegate(async(e)=>{ + string someUrl = Path.Combine(directory,WebUtility.UrlDecode(e.Request.CurrentUrl.Split(new char[]{'?'},2)[0].Substring(1)).Replace('/', Path.DirectorySeparatorChar)); + //Console.WriteLine(someUrl); + if (Directory.Exists(someUrl)) + { + string name; + if(DefaultFileExists(filenames,someUrl,out name)) + { + e.Response.SendFile(name); + }else{ + if(listDirectories){ + + List items=new List(); + foreach(var item in Directory.GetDirectories(someUrl)) + { + items.Add(Path.GetFileName(item) + "/"); + } + foreach(var item in Directory.GetFiles(someUrl)) + { + items.Add(Path.GetFileName(item)); + } + + e.Response.SendFileListing($"Index of {e.Request.CurrentUrl.Split(new char[]{'?'},2)[0]}","Directory listing",items); + }else{ + e.Response.StatusLine=403; + await _notFound.Handle(e); + } + } + } + else if (File.Exists(someUrl)) + { + e.Response.SendFile(someUrl); + } + else + { + e.Response.StatusLine=404; + await _notFound.Handle(e); + } + }); + } + public static IRequestHandler FromDelegate(HandleRequestAsync hra) + { + return new __IREQ(hra); + } + public static IRequestHandler FromDelegateSync(HandleRequest req) + { + return new __IREQ(async(e)=>{ + await Task.Run(()=>{ + if(req != null) + req(e); + }); + }); + } + internal static IRequestHandler error=new ErrorRequestHandler(); + public static IRequestHandler Guaranteed(ServerContext ctx,IRequestHandler value) + { + + if(value == null){ + ctx.Response.StatusLine =404; + return error; + + } + + return value; + } + } + public interface IRequestHandler + { + Task Handle(ServerContext ctx); + } + public delegate Task HandleRequestAsync(ServerContext ctx); + public delegate void HandleRequest(ServerContext ctx); + public sealed class HTTPServer + { + public IPEndPoint LocalEndPoint {get{return (IPEndPoint)_listener.LocalEndpoint;}} + IRequestHandler req; + public bool AllowMultipleRequestsOnOneConnection {get;set;} + public HTTPServer(HandleRequestAsync handler,TcpListener lstn) + { + req=RequestHandler.FromDelegate(handler); + _listener=lstn; + } + public HTTPServer(HandleRequest handler,TcpListener lstn) + { + req = RequestHandler.FromDelegateSync(handler); + } + public HTTPServer(IRequestHandler handler,TcpListener lstn) + { + req=handler; + _listener=lstn; + } + public Func FirstTime {get;set;}=null; + public bool CatchExceptions {get;set;} = true; + TcpListener _listener; + public void Listen(CancellationToken token=default(CancellationToken)) + { + ListenAsync(token).Wait(); + } + public async Task ListenAsync(CancellationToken token=default(CancellationToken)) + { + _listener.Start(); + using (var r = token.Register(() => _listener.Stop())) { + while (!token.IsCancellationRequested) + { + try{ + + var socket=await _listener.AcceptTcpClientAsync(); + Task.Factory.StartNew(async()=>{ + try{ + await HandleConnectionAsync(socket); + }catch(Exception ex) + { + _=ex; + if(!CatchExceptions) + { + throw ex; + } + } + }).Wait(0); + + }catch(Exception ex) + { + _=ex; + if(!CatchExceptions) + { + throw ex; + } + } + } + } + } + private async Task HandleConnectionAsync(TcpClient clt) + { + bool first=true; + bool allowMultipleRequests=AllowMultipleRequestsOnOneConnection; + while(clt.Connected) + { + var s=clt.GetStream(); + HttpParser parser=new HttpParser(s); + parser.ReceiveHeaders(); + parser.SentHeaders=new HeaderCollection(); + if(!allowMultipleRequests) + { + parser.SentHeaders.Add("Connection","close"); + }else{ + parser.SentHeaders.Add("Connection","keep-alive"); + } + var version = this.GetType().Assembly.GetName().Version; + parser.SentHeaders.Add("Server",$"Tesses.Http/{version.ToString()}"); + + + var ctx = new ServerContext(()=>{return clt.Connected;},parser,(IPEndPoint)clt.Client.LocalEndPoint,(IPEndPoint)clt.Client.RemoteEndPoint); + if(first && FirstTime != null) + { + if(!FirstTime(ctx)) + { + return; + } + } + await req.Handle(ctx); + + first=false; + if(parser.ReceivedHeaders.ContainsKey("Connection")) + { + if(parser.ReceivedHeaders["Connection"].Contains("close")) + { + break; + } + } + if(!allowMultipleRequests) break; + } + clt.Dispose(); + } + } + + +} diff --git a/Tesses.Http/MountableServer.cs b/Tesses.Http/MountableServer.cs new file mode 100644 index 0000000..2729f07 --- /dev/null +++ b/Tesses.Http/MountableServer.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Tesses.Http +{ + /// + /// mount multiple servers at different url paths + /// + public sealed class MountableServer : IRequestHandler + { + Dictionary _servers = new Dictionary(); + public MountableServer(IRequestHandler root) + { + _root = root; + } + IRequestHandler _root; + private (string Key,IRequestHandler Value) GetFromPath(ServerContext ctx) + { + string path = ctx.Request.GetQueryParameters(ctx.Request.CurrentUrl,new Dictionary>()); + //bool j = false; + foreach(var item in _servers.Reverse()) + { + if(path.StartsWith(item.Key,StringComparison.Ordinal)) + { + return (item.Key,RequestHandler.Guaranteed(ctx,item.Value)); + } + if (path == item.Key.TrimEnd('/')) + { + path += "/"; + return (item.Key,RequestHandler.Guaranteed(ctx,item.Value)); + } + } + //Console.WriteLine("HERE WE ARE"); + return ("/",RequestHandler.Guaranteed(ctx,_root)); + } + /// + /// Mount the specified url and server. + /// Must mount like this + /// /somePath0 + /// /somePath0/someSubPath0 + /// /somePath0/someSubPath0/someSubSubPath0 + /// /somePath0/someSubPath0/someSubSubPath1 + /// /somePath0/someSubPath1 + /// /somePath0/someSubPath1/someSubSubPath0 + /// /somePath0/someSubPath1/someSubSubPath1 + /// + /// URL. + /// Server. + public void Mount(string url,IRequestHandler server) + { + _servers.Add(url, server); + } + /// + /// Unmount a server + /// + /// Url + public void Unmount(string url) + { + _servers.Remove(url); + } + /// + /// Unmount all servers + /// + public void UnmountAll() + { + _servers.Clear(); + + } + + public async Task Handle(ServerContext ctx) + { + var v = GetFromPath(ctx); + string[] curUrl =ctx.Request.CurrentUrl.Split(new char[]{'?'},2,StringSplitOptions.RemoveEmptyEntries); + string url = '/' + curUrl[0].Substring(v.Key.Length).TrimStart('/'); + + if(curUrl.Length > 1) + { + url += $"?{curUrl[1]}"; + } + ctx.Request.CurrentUrl = url; + + await v.Value.Handle(ctx); + } + + + } + +} \ No newline at end of file diff --git a/Tesses.Http/MultipartParser.cs b/Tesses.Http/MultipartParser.cs new file mode 100644 index 0000000..c04dbab --- /dev/null +++ b/Tesses.Http/MultipartParser.cs @@ -0,0 +1,215 @@ +using System; +using System.IO; +using System.Net; +using System.Net.Sockets; +using System.Threading; +using System.Threading.Tasks; +using System.Collections.Generic; +using System.Text; +using System.Text.RegularExpressions; +using System.Net.Mime; + +namespace Tesses.Http +{ + public sealed class MultipartParser + { + string boundary=""; + HttpParser p; + public MultipartParser(HttpParser parser) + { + p=parser; + + + //boundary=----WebKitFormBoundaryyGTVag4OQVNjqdSl + string _bstr; + if(p.ReceivedHeaders.TryGetFirst("Content-Type",out _bstr)) + { + //multipart/*; boundary=somevalue + int offsetOfBoundary = _bstr.IndexOf("boundary="); + if(!_bstr.StartsWith("multipart/")) throw new Exception("not a multipart request/response"); + if(offsetOfBoundary < 0) throw new Exception("No \"boundary=\" in multipart header"); + offsetOfBoundary+=9; + int offsetOfSemiAfterBoundary = _bstr.IndexOf(';',offsetOfBoundary); + if(offsetOfSemiAfterBoundary < 0) + { + boundary=_bstr.Substring(offsetOfBoundary); + } + else + { + boundary=_bstr.Substring(offsetOfBoundary,offsetOfSemiAfterBoundary - offsetOfBoundary); + } + //we got the boundary str + + + }else{ + throw new Exception("No Content-Type found"); + } + } + #region DAJURIC_SIMPLE_HTTP_CODE + public IEnumerable Parse(OnFile onFile,bool disposeStream=true) + { + + + string bound = "--" + boundary; + //Console.WriteLine("BEFORE STREAM"); + var inputStream = new BufferedStream(p.ReadBody()); + //Print("Before ParseUntillBoundaryEnd"); + //Console.WriteLine("Before ParseUntilBoundaryEnd"); + + parseUntillBoundaryEnd(inputStream, new MemoryStream(), bound); + //Console.WriteLine("After ParseUntilBoundaryEnd"); + //Print("After ParseUntillBoundaryEnd"); + while (true) + { + //Print("Before ParseSection"); + var (n, v, fn, hdrs,ok) = parseSection(inputStream, "\r\n" + bound, onFile); + if(!ok) break; + //Print("After ParseSection"); + + + v.Position = 0; + yield return new MultipartEntry(n,hdrs,fn,v); + + if(disposeStream) + { + v.Dispose(); + } + + } + + + } + + //this region of code is somewhat modified from https://github.com/dajuric/simple-http/ + /// + /// Delegate executed when a file is about to be read from a body stream. + /// + /// Field name. + /// name of the file. + /// Content type. + /// Stream to be populated. + public delegate Stream OnFile(string fieldName, string fileName, string contentType); + + private static bool parseUntillBoundaryEnd(Stream source, Stream destination, string boundary) + { + var checkBuffer = new byte[boundary.Length]; //for boundary checking + + int b, i = 0; + while ((b = source.ReadByte()) != -1) + { + //Console.WriteLine(i); + if (i == boundary.Length) //boundary found -> go to the end of line + { + if (b == '\n') break; + if(b == '-') { + source.ReadByte(); + return false; + } + continue; + } + + if (b == boundary[i]) //start filling the check buffer + { + checkBuffer[i] = (byte)b; + i++; + } + else + { + var idx = 0; + while (idx < i) //write the buffer data to stream + { + destination.WriteByte(checkBuffer[idx]); + idx++; + } + + i = 0; + destination.WriteByte((byte)b); //write the current byte + } + } + return true; + } + + private static (string Name, Stream Value, string FileName, Dictionary> headers,bool isOk) parseSection(Stream source, string boundary, OnFile onFile) + { + //we must read two bytes + HeaderCollection coll=new HeaderCollection(source); + ContentDisposition disposition=new ContentDisposition(); + string ct="application/octet-stream"; + string n=""; + string fn=""; + if(coll.ContainsKey("Content-Disposition")) + { + disposition=new ContentDisposition(coll["Content-Disposition"][0]); + + n=disposition.Parameters["name"]; + fn=disposition.FileName; + + } + if(!coll.TryGetFirst("Content-Type",out ct)) + { + ct="application/octet-stream"; + } + //Print("Before ReadContentDisposition"); + //var (n, fn, ct) = readContentDisposition(source); + //Print("After ReadContentDisposition"); + //\r\n (empty row) + + + + var dst = String.IsNullOrEmpty(fn) ? new MemoryStream() : onFile(n, fn, ct); + if (dst == null) + throw new ArgumentException(nameof(onFile), "The on-file callback must return a stream."); + //Print("Before ParseUntillBodyEnd"); + bool isOk = parseUntillBoundaryEnd(source, dst, boundary); + //Print("Before ParseUntillBodyEnd"); + return (n, dst, fn, coll,isOk); + } + + + #endregion + public IEnumerable Parse(bool disposeStream=true) + { + return Parse((e,f,g)=>{return new MemoryStream();},disposeStream); + } + } + + public class MultipartEntry : IDisposable + { + internal MultipartEntry(string name,Dictionary> headers,string filename,Stream strm) + { + Name=name; + this.Stream=strm; + FileName = filename; + HasFileName=!string.IsNullOrWhiteSpace(filename); + Headers =headers; + string ct; + if(Headers.TryGetFirst("Content-Type",out ct)) + { + this.MimeType=ct; + } + } + public Dictionary> Headers {get;set;} + public bool HasFileName {get;private set;} + public string MimeType {get;private set;} + public string FileName {get;private set;} + + public string Name {get;private set;} + + public Stream Stream {get;private set;} + + public void Dispose() + { + Stream.Dispose(); + } + + public byte[] GetData() + { + return Stream.AsArray(); + } + + public string GetStringData() + { + return GetData().AsString(); + } + } +} \ No newline at end of file diff --git a/Tesses.Http/SendEvents.cs b/Tesses.Http/SendEvents.cs new file mode 100644 index 0000000..973d95f --- /dev/null +++ b/Tesses.Http/SendEvents.cs @@ -0,0 +1,30 @@ +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace Tesses.Http +{ + internal class SendEventArgs : EventArgs + { + public string Data {get;set;} + } + public class SendEvents + { + internal event EventHandler EventReceived; + + public void SendEvent(object data) + { + SendEvent(JsonConvert.SerializeObject(data)); + } + public void SendEvent(string e) + { + try{ + EventReceived?.Invoke(this,new SendEventArgs(){Data=e}); + }catch(Exception ex) + { + _=ex; + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http/ServerContext.cs b/Tesses.Http/ServerContext.cs new file mode 100644 index 0000000..8768ce1 --- /dev/null +++ b/Tesses.Http/ServerContext.cs @@ -0,0 +1,358 @@ +using System.Net; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Net.Http; +using System; +using System.Linq; +using System.Web; +using Newtonsoft.Json; +using System.Net.Mime; +using HeyRed.Mime; + +namespace Tesses.Http +{ + public class ServerContext + { + + public ServerRequest Request {get;private set;} + + public ServerResponse Response {get;private set;} + + internal HttpParser p; + public Stream GetRawStreamWithHeaders() + { + return new PrependStream(Encoding.UTF8.GetBytes(p.ReceivedHeaders.ToString()),p.GetRawStream()); + } + public Stream GetRawStream() + { + return p.GetRawStream(); + } + public bool IsConnected {get{ + if(_isConnected!=null) return _isConnected(); + + return false; + + }} + + Func _isConnected; + internal ServerContext(Func isConnected,HttpParser parser,IPEndPoint local,IPEndPoint remote) + { + _isConnected=isConnected; + p=parser; + Request=new ServerRequest(parser,remote); + + Response=new ServerResponse(isConnected,Request.RequestLine,parser,local); + + + } + + + + } + public class ServerResponse + { + RequestLine ln; + Func _isConnected; + string ogurl; + internal ServerResponse(Func isConnected,RequestLine line,HttpParser parser,IPEndPoint local) + { + + ln=line; + Address=local; + _isConnected=isConnected; + ogurl = ln.Path.Split('?')[0]; + this.parser=parser; + StatusLine=200; + } + HttpParser parser; + public IPEndPoint Address {get;set;} + public Dictionary> Headers {get {return parser.SentHeaders;}} + + public StatusLine StatusLine {get {return parser.SentHeaders.FirstLine;} set { parser.SentHeaders.FirstLine=value;}} + + public ServerResponse WithContentType(string contentType) + { + Headers.Add("Content-Type",contentType); + return this; + } + public void SendStatusCodeHtml() + { + StringBuilder builder=new StringBuilder(); + builder.AppendLine(""); + builder.AppendLine($"{StatusLine.StatusCode} {StatusLine.GetReasonPhrase()}"); + builder.AppendLine(""); + builder.AppendLine($"

{StatusLine.StatusCode} {StatusLine.GetReasonPhrase()}

"); + builder.AppendLine($"

{ogurl}

"); + builder.AppendLine("
Tesses.Http
"); + builder.AppendLine(""); + builder.AppendLine(""); + + WithContentType("text/html").SendText(builder); + + /* + +404 Not Found + +

404 Not Found

+
nginx/1.18.0 (Ubuntu)
+ + + + + + + + +*/ + } + public ServerResponse WithFileName(string filename,bool inline=false) + { + ContentDisposition contentDisposition=new ContentDisposition(); + contentDisposition.FileName=filename; + contentDisposition.Inline=inline; + Headers.Add("Content-Disposition",contentDisposition.ToString()); + return this; + } + public ServerResponse WithHeader(string key,string value) + { + Headers.Add(key,value); + return this; + } + public void ServerSentEvents(SendEvents evt) + { + bool __connected=true; + if(_isConnected == null) return; + WithContentType("text/event-stream").WithHeader("Cache-Control","no-cache").parser.SendHeaders(); + try{ + EventHandler cb= (sender,e0)=>{ + if(__connected) + parser.WriteBody($"data: {e0.Data}\n\n"); + }; + evt.EventReceived += cb; + while(_isConnected()); + evt.EventReceived -= cb; + __connected=false; + }catch(Exception ex) + { + _=ex; + } + } + public void SendText(StringBuilder b) + { + SendText(b.ToString()); + } + public void SendJson(object o) + { + WithContentType("application/json").SendText(JsonConvert.SerializeObject(o)); + } + public void SendText(string text) + { + MemoryStream strm=new MemoryStream(); + using(var sw=new StreamWriter(strm)) + { + + sw.Write(text); + sw.Flush(); + + + strm.Seek(0,SeekOrigin.Begin); + + SendResponseStream(strm); + } + } + private string _getFileNameWithoutQuery(string url) + { + int r = url.IndexOf('?'); + if(r > -1) + { + return Path.GetFileName(url.Remove(r).TrimEnd('/')) + (url.EndsWith("/") ? "/" : ""); + } + return Path.GetFileName(url.TrimEnd('/')) + (url.EndsWith("/") ? "/" : ""); + } + public ServerResponse WithContextTypeFromFileName(string filename) + { + return WithContentType(MimeTypesMap.GetMimeType(filename)); + } + public void SendRedirect(string redirectTo) + { + StatusLine=301; + + WithHeader("Location",redirectTo).WithHeader("Cache-Control","no-cache").parser.SendHeaders(); + + } + + public void SendFileListing(string title,string desc,IEnumerable entries) + { + if(!this.ln.Path.EndsWith("/")) + { + SendRedirect(this.ln.Path + '/'); + return; + } + StringBuilder b=new StringBuilder(); + b.Append($"{HttpUtility.HtmlEncode(title)}

{HttpUtility.HtmlEncode(title)}

{HttpUtility.HtmlEncode(desc)}

../
"); + foreach(var entry in entries) + { + //{HttpUtility.HtmlEncode(_getFileNameWithoutQuery(entry))}
"); + } + b.Append("

Tesses.Http
"); + + WithContentType("text/html").SendText(b); + } + public void SendFileAsDownload(string file) + { + WithFileName(Path.GetFileName(file)).SendFile(file); + } + public void SendFileAsDownload(VirtualStorage storage,string file) + { + WithFileName(Path.GetFileName(file)).SendFile(storage,file); + } + public void SendFile(string file) + { + using(var f = File.OpenRead(file)) + { + WithContextTypeFromFileName(file).SendRangableResponseStream(f); + } + } + public void SendFile(VirtualStorage storage,string file) + { + using(var f = storage.Open(file,FileMode.Open,FileAccess.Read,FileShare.Read)) + { + WithContextTypeFromFileName(file).SendRangableResponseStream(f); + } + } + public void SendResponseStream(Stream strm) + { + + + Headers.Add("Content-Length",strm.Length.ToString()); + parser.SendHeaders(); + if(ln.Method != "HEAD") + parser.WriteBody(strm); + + + } + + public void SendRangableResponseStream(Stream strm) + { + + + if(parser.ReceivedHeaders.ContainsKey("Range") && strm.CanSeek) + { + int start = 0, end = (int)strm.Length - 1; + if (parser.ReceivedHeaders["Range"].Count > 1) + { + throw new NotSupportedException("Multiple 'Range' headers are not supported."); + } + var range = parser.ReceivedHeaders["Range"][0].Replace("bytes=", String.Empty) + .Split(new string[] { "-" }, StringSplitOptions.RemoveEmptyEntries) + .Select(x => Int32.Parse(x)) + .ToArray(); + + start = (range.Length > 0) ? range[0] : 0; + end = (range.Length > 1) ? range[1] : (int)(strm.Length - 1); + + + var hdrs = parser.SentHeaders; + hdrs.Add("Accept-Ranges", "bytes"); + hdrs.Add("Content-Range", "bytes " + start + "-" + end + "/" + strm.Length); + hdrs.Add("Content-Length", (end - start + 1).ToString()); + StatusLine = 206; + + parser.SendHeaders(); + if(ln.Method != "HEAD") + parser.WriteBody(new RangeStream(strm,start,end-start+1)); + + + + }else{ + SendResponseStream(strm); + } + + + } + } + public class ServerRequest + { + public MultipartParser GetMultipartParser() + { + return new MultipartParser(this.parser); + } + public ServerRequest(HttpParser parser,IPEndPoint remote) + { + + + Address=remote; + + this.parser=parser; + OriginalUrl = RequestLine.Path; + } + HttpParser parser; + public IPEndPoint Address {get;set;} + + public string GetQueryParameters(string pathAndQuery,Dictionary> p) + { + string[] qParm = pathAndQuery.Split(new char[]{'?'},2,StringSplitOptions.RemoveEmptyEntries); + if(qParm.Length == 0) return ""; + if(qParm.Length == 1) + { + return qParm[0]; + }else{ + foreach(var kvp in qParm[1].Split(new char[]{'&'},StringSplitOptions.RemoveEmptyEntries)) + { + string[] _kvp = kvp.Split(new char[]{'='},2,StringSplitOptions.RemoveEmptyEntries); + if(_kvp.Length > 0) + { + if(_kvp.Length == 2) + { + p.Add(_kvp[0],HttpUtility.UrlEncode(_kvp[1])); + }else{ + p.Add(_kvp[0],""); + } + + } + } + + return qParm[0]; + } + + + + + } + public string OriginalUrl {get;private set;} + + public string CurrentUrl {get{return RequestLine.Path;} set{RequestLine=new RequestLine(RequestLine.Method,value,RequestLine.HttpVersion);}} + public string GetQueryParameters(Dictionary> p) + { + return GetQueryParameters(RequestLine.Path,p); + } + public RequestLine RequestLine {get{return parser.ReceivedHeaders.FirstLine;} set {parser.ReceivedHeaders.FirstLine=value;}} + + public Dictionary> Headers {get {return parser.ReceivedHeaders;}} + + public string GetRequestString() + { + using(var sr=new StreamReader(GetRequestStream())) + { + return sr.ReadToEnd(); + } + } + public T GetRequestJson() + { + return JsonConvert.DeserializeObject(GetRequestString()); + } + + public void GetUrlEncodedPost(Dictionary> p) + { + string urlData=$"{OriginalUrl}?{GetRequestString()}"; + GetQueryParameters(urlData,p); + } + + public Stream GetRequestStream() + { + return parser.ReadBody(); + } + } +} \ No newline at end of file diff --git a/Tesses.Http/ServerEntry.cs b/Tesses.Http/ServerEntry.cs new file mode 100644 index 0000000..f01418b --- /dev/null +++ b/Tesses.Http/ServerEntry.cs @@ -0,0 +1,30 @@ +using System.Net; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Net.Http; +using System; +using System.Linq; +using System.Web; +using Newtonsoft.Json; +using System.Net.Mime; +using HeyRed.Mime; +using System.Threading.Tasks; + +namespace Tesses.Http +{ + public abstract class Server : IRequestHandler,IDisposable + { + public abstract Task Handle(ServerContext ctx); + + public virtual void Close() + { + + } + public void Dispose() + { + Close(); + } + } + +} \ No newline at end of file diff --git a/Tesses.Http/StorageScope.cs b/Tesses.Http/StorageScope.cs new file mode 100644 index 0000000..e74c723 --- /dev/null +++ b/Tesses.Http/StorageScope.cs @@ -0,0 +1,515 @@ +using System.Net; +using System.Collections.Generic; +using System.IO; +using System.Text; +using System.Net.Http; +using System; +using System.Linq; +using System.Web; +using Newtonsoft.Json; +using System.Net.Mime; +using HeyRed.Mime; + +namespace Tesses.Http +{ + public class SubDirectoryVirtualStorage : VirtualStorage + { + public SubDirectoryVirtualStorage(VirtualStorage storage,string directory) + { + Storage=storage; + Directory = directory; + } + public VirtualStorage Storage {get;set;} + public string Directory {get;set;} + public override void CreateDirectory(string path) + { + Storage.CreateDirectory(PathCombine(Directory,path)); + } + + public override void Delete(string file) + { + Storage.Delete(PathCombine(Directory,file)); + } + + public override bool DirectoryExists(string filename) + { + return Storage.DirectoryExists(PathCombine(Directory,filename)); + } + + public override IEnumerable EnumerateDirectories(string dir) + { + return Storage.EnumerateDirectories(PathCombine(Directory,dir)); + } + + public override IEnumerable EnumerateFiles(string dir) + { + return Storage.EnumerateFiles(PathCombine(Directory,dir)); + } + + public override bool FileExists(string filename) + { + return Storage.FileExists(PathCombine(Directory,filename)); + } + + public override Stream Open(string file, FileMode mode, FileAccess access, FileShare share) + { + return Storage.Open(PathCombine(Directory,file),mode,access,share); + } + public override void CopyDirectory(string src, string dest, bool allowOverwrite = false) + { + Storage.CopyDirectory(PathCombine(Directory,src),PathCombine(Directory,dest)); + } + public override void CopyDirectoryTo(VirtualStorage storage, string src, string dest, bool allowOverwrite = false) + { + Storage.CopyDirectoryTo(storage,PathCombine(Directory,src),dest,allowOverwrite); + } + public override void CopyFile(string src, string dest) + { + Storage.CopyFile(PathCombine(Directory,src),PathCombine(Directory,dest)); + } + public override void CopyFileTo(string filename, Stream strm) + { + Storage.CopyFileTo(PathCombine(Directory,filename),strm); + } + public override void DeleteDirectory(string dir, bool recursive = false) + { + Storage.DeleteDirectory(PathCombine(Directory,dir),recursive); + } + public override DateTime GetCreationTime(string filename) + { + return Storage.GetCreationTime(PathCombine(Directory,filename)); + } + public override DateTime GetLastAccessTime(string filename) + { + return Storage.GetCreationTime(PathCombine(Directory,filename)); + } + public override DateTime GetLastWriteTime(string filename) + { + return Storage.GetCreationTime(PathCombine(Directory,filename)); + } + public override void MoveDirectory(string src, string dest, bool allowOverwrite = false) + { + Storage.MoveDirectory( PathCombine(Directory,src), PathCombine(Directory,dest), allowOverwrite); + } + public override void MoveDirectoryTo(VirtualStorage storage, string src, string dest, bool allowOverwrite = false) + { + Storage.MoveDirectoryTo(storage, PathCombine(Directory,src),dest,allowOverwrite); + } + public override void MoveFile(string src, string dest) + { + Storage.MoveFile(PathCombine(Directory,src),PathCombine(Directory,dest)); + } + public override void SetCreationTime(string filename, DateTime time) + { + Storage.SetCreationTime(PathCombine(Directory,filename),time); + } + public override void SetLastAccessTime(string filename, DateTime time) + { + Storage.SetLastAccessTime(PathCombine(Directory,filename),time); + } + public override void SetLastWriteTime(string filename, DateTime time) + { + Storage.SetLastWriteTime(PathCombine(Directory,filename),time); + } + public override string ActualPath => Path.Combine(Storage.ActualPath,Directory); + } + + + + public class DirectoryVirtualStorage : VirtualStorage + { + public DirectoryVirtualStorage(string working) + { + WorkingDirectory = working; + } + public DirectoryVirtualStorage() + { + WorkingDirectory=Environment.CurrentDirectory; + } + + public override string ActualPath => WorkingDirectory; + public override DateTime GetCreationTime(string filename) + { + if(FileExists(filename)) + { + return File.GetCreationTime(Path.Combine(WorkingDirectory,filename)); + } + else if(DirectoryExists(filename)) + { + return Directory.GetCreationTime(Path.Combine(WorkingDirectory,filename)); + } + else{ + return DateTime.Now; + } + + } + public override DateTime GetLastWriteTime(string filename) + { + if(FileExists(filename)) + { + return File.GetLastWriteTime(Path.Combine(WorkingDirectory,filename)); + } + else if(DirectoryExists(filename)) + { + return Directory.GetLastWriteTime(Path.Combine(WorkingDirectory,filename)); + } + else{ + return DateTime.Now; + } + + } + public override DateTime GetLastAccessTime(string filename) + { + if(FileExists(filename)) + { + return File.GetLastAccessTime(Path.Combine(WorkingDirectory,filename)); + } + else if(DirectoryExists(filename)) + { + return Directory.GetLastAccessTime(Path.Combine(WorkingDirectory,filename)); + } + else{ + return DateTime.Now; + } + + } + public override void SetCreationTime(string filename, DateTime time) + { + if(FileExists(filename)) + { + File.SetCreationTime(Path.Combine(WorkingDirectory,filename),time); + } + else if(DirectoryExists(filename)) + { + Directory.SetCreationTime(Path.Combine(WorkingDirectory,filename),time); + } + } + public override void SetLastWriteTime(string filename, DateTime time) + { + if(FileExists(filename)) + { + File.SetLastWriteTime(Path.Combine(WorkingDirectory,filename),time); + } + else if(DirectoryExists(filename)) + { + Directory.SetLastWriteTime(Path.Combine(WorkingDirectory,filename),time); + } + } + public override void SetLastAccessTime(string filename, DateTime time) + { + if(FileExists(filename)) + { + File.SetLastAccessTime(Path.Combine(WorkingDirectory,filename),time); + } + else if(DirectoryExists(filename)) + { + Directory.SetLastAccessTime(Path.Combine(WorkingDirectory,filename),time); + } + } + public override void DeleteDirectory(string dir, bool recursive = false) + { + Directory.Delete(Path.Combine(WorkingDirectory,dir),recursive); + } + public override void MoveDirectory(string src, string dest, bool allowOverwrite = false) + { + Directory.Move(Path.Combine(WorkingDirectory,src),Path.Combine(WorkingDirectory,dest)); + } + public override void MoveFile(string src, string dest) + { + File.Move(Path.Combine(WorkingDirectory,src),Path.Combine(WorkingDirectory,dest)); + } + public string WorkingDirectory {get;set;} + + public override void CreateDirectory(string path) + { + Directory.CreateDirectory(Path.Combine(WorkingDirectory,path)); + } + public override void CopyFile(string src, string dest) + { + File.Copy(Path.Combine(WorkingDirectory,src),Path.Combine(WorkingDirectory,dest)); + + } + public override void Delete(string file) + { + Delete(Path.Combine(WorkingDirectory,file)); + } + + public override bool DirectoryExists(string filename) + { + return Directory.Exists(Path.Combine(WorkingDirectory,filename)); + } + + public override IEnumerable EnumerateDirectories(string dir) + { + foreach(var directory in Directory.EnumerateDirectories(Path.Combine(WorkingDirectory,dir))) + { + yield return Path.GetFileName(directory); + } + } + + public override IEnumerable EnumerateFiles(string dir) + { + foreach(var file in Directory.EnumerateFiles(Path.Combine(WorkingDirectory,dir))) + { + yield return Path.GetFileName(file); + } + } + + public override bool FileExists(string filename) + { + return File.Exists(Path.Combine(WorkingDirectory,filename)); + } + + public override Stream Open(string file, FileMode mode, FileAccess access, FileShare share) + { + return File.Open(file,mode,access,share); + } + } + public abstract class VirtualStorage + { + public string GetActualPath(string path) + { + if(ActualPath.EndsWith("/")) + { + return $"{ActualPath}{path.TrimStart('/')}"; + }else{ + return $"{ActualPath}/{path.TrimStart('/')}"; + } + } + public virtual string ActualPath {get{return "vfs:///";}} + public void CopyFileTo(VirtualStorage storage,string src,string dest) + { + + using(var strm=storage.Open(dest,FileMode.Create,FileAccess.Write,FileShare.None)) + { + CopyFileTo(src,strm); + storage.SetCreationTime(dest,DateTime.Now); + storage.SetLastWriteTime(dest,GetLastWriteTime(src)); + storage.SetLastAccessTime(dest,DateTime.Now); + } + } + public virtual void CopyFile(string src,string dest) + { + CopyFileTo(this,src,dest); + } + public virtual void MoveFile(string src,string dest) + { + CopyFileTo(this,src,dest); + Delete(src); + } + public abstract void CreateDirectory(string path); + + public virtual void CopyDirectory(string src,string dest,bool allowOverwrite=false) + { + DateTime lastWrite=GetLastWriteTime(src); + + CreateDirectory(dest); + foreach(var item in EnumerateDirectories(src)) + { + CopyDirectory(PathCombine(src,item),PathCombine(dest,item),allowOverwrite); + } + foreach(var file in EnumerateFiles(src)) + { + if(FileExists(PathCombine(src,file)) && !allowOverwrite) + { + continue; + } + CopyFile(PathCombine(src,file),PathCombine(dest,file)); + } + SetCreationTime(dest,DateTime.Now); + SetLastWriteTime(dest,lastWrite); + SetLastAccessTime(dest,DateTime.Now); + } + public virtual void CopyDirectoryTo(VirtualStorage storage,string src,string dest,bool allowOverwrite=false) + { + DateTime lastWrite=GetLastWriteTime(src); + + storage.CreateDirectory(dest); + foreach(var item in EnumerateDirectories(src)) + { + CopyDirectoryTo(storage,PathCombine(src,item),PathCombine(dest,item),allowOverwrite); + } + foreach(var file in EnumerateFiles(src)) + { + if(storage.FileExists(PathCombine(src,file)) && !allowOverwrite) + { + continue; + } + CopyFileTo(storage,PathCombine(src,file),PathCombine(dest,file)); + } + storage.SetCreationTime(dest,DateTime.Now); + storage.SetLastWriteTime(dest,lastWrite); + storage.SetLastAccessTime(dest,DateTime.Now); + } + public virtual void MoveDirectory(string src,string dest,bool allowOverwrite=false) + { + DateTime lastWrite=GetLastWriteTime(src); + + CreateDirectory(dest); + foreach(var item in EnumerateDirectories(src)) + { + MoveDirectory(PathCombine(src,item),PathCombine(dest,item)); + } + foreach(var file in EnumerateFiles(src)) + { + if(FileExists(PathCombine(src,file)) && !allowOverwrite) + { + continue; + } + MoveFile(PathCombine(src,file),PathCombine(dest,file)); + } + SetCreationTime(dest,GetCreationTime(src)); + SetLastWriteTime(dest,lastWrite); + SetLastAccessTime(dest,DateTime.Now); + try{ + if(EnumerateDirectories(src).Count() > 0 || EnumerateFiles(src).Count() > 0) + { + return; + } + DeleteDirectory(src); + }catch(Exception ex) + { + _=ex; + } + } + public virtual void MoveDirectoryTo(VirtualStorage storage,string src,string dest,bool allowOverwrite=false) + { + DateTime lastWrite=GetLastWriteTime(src); + storage.CreateDirectory(dest); + foreach(var item in EnumerateDirectories(src)) + { + MoveDirectoryTo(storage,PathCombine(src,item),PathCombine(dest,item)); + } + foreach(var file in EnumerateFiles(src)) + { + if(FileExists(PathCombine(src,file)) && !allowOverwrite) + { + continue; + } + CopyFileTo(storage,PathCombine(src,file),PathCombine(dest,file)); + storage.SetCreationTime(PathCombine(dest,file),GetCreationTime(PathCombine(src,file))); + storage.SetLastWriteTime(PathCombine(dest,file),GetLastWriteTime(PathCombine(src,file))); + storage.SetLastAccessTime(PathCombine(dest,file),DateTime.Now); + Delete(PathCombine(src,file)); + } + storage.SetCreationTime(dest,GetCreationTime(src)); + storage.SetLastWriteTime(dest,lastWrite); + storage.SetLastAccessTime(dest,DateTime.Now); + try{ + if(EnumerateDirectories(src).Count() > 0 || EnumerateFiles(src).Count() > 0) + { + return; + } + DeleteDirectory(src); + }catch(Exception ex) + { + _=ex; + } + } + + + private void WARNING(string txt) + { + var col=Console.ForegroundColor; + Console.ForegroundColor=ConsoleColor.Yellow; + Console.WriteLine($"WARNING: {txt}"); + Console.ForegroundColor=col; + } + public virtual DateTime GetCreationTime(string filename) + { + WARNING("GetCreationTime Not Implemented"); + return DateTime.Now; + } + public virtual DateTime GetLastAccessTime(string filename) + { + + WARNING("GetLastAccessTime Not Implemented"); + return DateTime.Now; + } + public virtual DateTime GetLastWriteTime(string filename) + { + + WARNING("GetLastWriteTime Not Implemented"); + return DateTime.Now; + } + public virtual void SetCreationTime(string filename,DateTime time) + { + WARNING("SetCreationTime Not Implemented"); + + } + public virtual void SetLastWriteTime(string filename,DateTime time) + { + WARNING("SetLastWriteTime Not Implemented"); + + } + public virtual void SetLastAccessTime(string filename,DateTime time) + { + WARNING("SetLastAccessTime Not Implemented"); + + } + + public abstract bool FileExists(string filename); + public abstract bool DirectoryExists(string filename); + public virtual void CopyFileTo(string filename,Stream strm) + { + using(var strmIn = Open(filename,FileMode.Open,FileAccess.Read,FileShare.Read)) + { + strmIn.CopyTo(strm); + } + } + public abstract void Delete(string file); + + protected virtual void DeleteEmptyDirectory(string dir) + { + + } + public string PathCombine(string p1,string p2) + { + return p1.TrimEnd('/') + '/' + p2.TrimStart('/'); + } + public string PathCombine(IEnumerable args) + { + string s=""; + + var enumerator = args.GetEnumerator(); + if(!enumerator.MoveNext()) + { + return ""; + } + s=enumerator.Current.ToString(); + while(enumerator.MoveNext()) + { + s=PathCombine(s,enumerator.Current); + } + return s; + } + public string PathCombine(params string[] path) + { + return PathCombine((IEnumerable)path); + } + public abstract IEnumerable EnumerateFiles(string dir); + + public abstract IEnumerable EnumerateDirectories(string dir); + public virtual void DeleteDirectory(string dir,bool recursive=false) + { + if(recursive) + { + foreach(var dirname in EnumerateDirectories(dir)) + { + DeleteDirectory(PathCombine(dir,dirname),true); + } + foreach(var file in EnumerateFiles(dir)) + { + Delete(PathCombine(dir,file)); + } + } + DeleteEmptyDirectory(dir); + + } + + + + + public abstract Stream Open(string file,FileMode mode,FileAccess access,FileShare share); + } +} \ No newline at end of file diff --git a/Tesses.Http/Streams.cs b/Tesses.Http/Streams.cs new file mode 100644 index 0000000..fab399e --- /dev/null +++ b/Tesses.Http/Streams.cs @@ -0,0 +1,210 @@ +using System.Net; +using System.Collections.Generic; +using System.IO; +using System.Threading; +using System; +using System.Threading.Tasks; + +namespace Tesses.Http +{ + public class PrependStream : Stream + { + int offsetInSpecialInfo=0; + byte[] specialInfo; + Stream actualStream; + public PrependStream(byte[] specialInfo,Stream outerStrm) + { + this.specialInfo=specialInfo; + actualStream=outerStrm; + } + + public override bool CanRead => actualStream.CanRead; + + public override bool CanSeek => false; + + public override bool CanWrite => actualStream.CanWrite; + + public override long Length => throw new NotImplementedException(); + + public override long Position { get => throw new NotImplementedException(); set => throw new NotImplementedException(); } + + public override void Flush() + { + actualStream.Flush(); + } + public override async Task ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + if(offsetInSpecialInfo < specialInfo.Length) + { + //we are in special info header + int read=Math.Min(count,specialInfo.Length-offsetInSpecialInfo); + Array.Copy(specialInfo,offsetInSpecialInfo,buffer,offset,read); + offsetInSpecialInfo += read; + return read; + } + else + { + return await actualStream.ReadAsync(buffer,offset,count,cancellationToken); + } + } + public override int Read(byte[] buffer, int offset, int count) + { + if(offsetInSpecialInfo < specialInfo.Length) + { + //we are in special info header + int read=Math.Min(count,specialInfo.Length-offsetInSpecialInfo); + Array.Copy(specialInfo,offsetInSpecialInfo,buffer,offset,read); + offsetInSpecialInfo += read; + return read; + } + else + { + return actualStream.Read(buffer,offset,count); + } + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + actualStream.Write(buffer,offset,count); + } + public override async Task WriteAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken) + { + await actualStream.WriteAsync(buffer, offset, count, cancellationToken); + } + } + + public class StreamPiper : IDisposable + { + CancellationTokenSource token=new CancellationTokenSource(); + Thread _t1,_t2; + Stream _s1,_s2; + bool ownStrm; + public StreamPiper(Stream s1,Stream s2,bool ownStrm=true) + { + + _s1=s1; + _s2=s2; + _t1=new Thread(CopyStream1To2); + _t2=new Thread(CopyStream2To1); + this.ownStrm=ownStrm; + } + private void CopyStream1To2() + { + try{ + _s1.CopyToAsync(_s2,1024,token.Token).Wait(); + }catch(System.AggregateException ex) + { + _=ex; + token.Cancel(); + } + } + private void CopyStream2To1() + { + try{ + _s2.CopyToAsync(_s1,1024,token.Token).Wait(); + }catch(System.AggregateException ex) + { + _=ex; + token.Cancel(); + } + } + public void Dispose() + { + token.Cancel(); + token.Dispose(); + _t1.Abort(); + _t2.Abort(); + if(ownStrm) + { + _s1.Dispose(); + _s2.Dispose(); + } + } + + public void Pipe(CancellationToken token=default(CancellationToken)) + { + token.Register(()=>{ + this.token.Cancel(); + }); + _t1.Start(); + _t2.Start(); + _t1.Join(); + _t2.Join(); + } + } + + public class RangeStream : Stream + { + Stream _strm; + long _len; + long _read=0; + public RangeStream(Stream strm,long? pos,long? len) + { + long _pos=0; + if(pos.HasValue) + { + _pos=pos.Value; + strm.Seek(pos.Value,SeekOrigin.Begin); + } + if(len.HasValue) + { + _len=len.Value; + }else{ + _len=strm.Length; + } + _len=Math.Min(_len,strm.Length - _pos); + _strm=strm; + } + + public override bool CanRead => _strm.CanRead; + + public override bool CanSeek => false; + + public override bool CanWrite => false; + + public override long Length => _len; + + public override long Position { get => _read; set => throw new NotImplementedException(); } + + public override void Flush() + { + _strm.Flush(); + } + + public override int Read(byte[] buffer, int offset, int count) + { + int read=(int)Math.Min(_len-_read,count); + if(read == 0) return 0; + + read=_strm.Read(buffer,offset,count); + _read+= read; + + return read; + } + + public override long Seek(long offset, SeekOrigin origin) + { + throw new NotImplementedException(); + } + + public override void SetLength(long value) + { + throw new NotImplementedException(); + } + + public override void Write(byte[] buffer, int offset, int count) + { + throw new NotImplementedException(); + } + } +} \ No newline at end of file diff --git a/Tesses.Http/Tesses.Http.csproj b/Tesses.Http/Tesses.Http.csproj new file mode 100644 index 0000000..c6e39d5 --- /dev/null +++ b/Tesses.Http/Tesses.Http.csproj @@ -0,0 +1,23 @@ + + + + netstandard2.0 + true + Tesses.Http + Mike Nolan + Tesses + 1.0.0 + 1.0.0 + 1.0.0 + A Web Server/Client + HTTP, WebServer, WebClient + https://gitlab.tesses.cf/tesses50/tesses.http + MIT + + + + + + + + diff --git a/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.deps.json b/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.deps.json new file mode 100644 index 0000000..2752709 --- /dev/null +++ b/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.deps.json @@ -0,0 +1,79 @@ +{ + "runtimeTarget": { + "name": ".NETStandard,Version=v2.0/", + "signature": "" + }, + "compilationOptions": {}, + "targets": { + ".NETStandard,Version=v2.0": {}, + ".NETStandard,Version=v2.0/": { + "Tesses.Http/1.0.0": { + "dependencies": { + "MimeTypesMap": "1.0.8", + "NETStandard.Library": "2.0.3", + "Newtonsoft.Json": "13.0.1" + }, + "runtime": { + "Tesses.Http.dll": {} + } + }, + "Microsoft.NETCore.Platforms/1.1.0": {}, + "MimeTypesMap/1.0.8": { + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": { + "assemblyVersion": "1.0.8.0", + "fileVersion": "1.0.8.0" + } + } + }, + "NETStandard.Library/2.0.3": { + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + } + }, + "Newtonsoft.Json/13.0.1": { + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "assemblyVersion": "13.0.0.0", + "fileVersion": "13.0.1.25517" + } + } + } + } + }, + "libraries": { + "Tesses.Http/1.0.0": { + "type": "project", + "serviceable": false, + "sha512": "" + }, + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "serviceable": true, + "sha512": "sha512-kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "path": "microsoft.netcore.platforms/1.1.0", + "hashPath": "microsoft.netcore.platforms.1.1.0.nupkg.sha512" + }, + "MimeTypesMap/1.0.8": { + "type": "package", + "serviceable": true, + "sha512": "sha512-iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "path": "mimetypesmap/1.0.8", + "hashPath": "mimetypesmap.1.0.8.nupkg.sha512" + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "serviceable": true, + "sha512": "sha512-st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "path": "netstandard.library/2.0.3", + "hashPath": "netstandard.library.2.0.3.nupkg.sha512" + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "serviceable": true, + "sha512": "sha512-ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "path": "newtonsoft.json/13.0.1", + "hashPath": "newtonsoft.json.13.0.1.nupkg.sha512" + } + } +} \ No newline at end of file diff --git a/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.dll b/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.dll new file mode 100644 index 0000000..7b73abb Binary files /dev/null and b/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.dll differ diff --git a/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.pdb b/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.pdb new file mode 100644 index 0000000..291b368 Binary files /dev/null and b/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.pdb differ diff --git a/Tesses.Http/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs b/Tesses.Http/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs new file mode 100644 index 0000000..4c9a2c1 --- /dev/null +++ b/Tesses.Http/obj/Debug/netstandard2.0/.NETStandard,Version=v2.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETStandard,Version=v2.0", FrameworkDisplayName = "")] diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfo.cs b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfo.cs new file mode 100644 index 0000000..e408480 --- /dev/null +++ b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfo.cs @@ -0,0 +1,24 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +using System; +using System.Reflection; + +[assembly: System.Reflection.AssemblyCompanyAttribute("Tesses")] +[assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] +[assembly: System.Reflection.AssemblyDescriptionAttribute("A Web Server/Client")] +[assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyProductAttribute("Tesses.Http")] +[assembly: System.Reflection.AssemblyTitleAttribute("Tesses.Http")] +[assembly: System.Reflection.AssemblyVersionAttribute("1.0.0")] +[assembly: System.Reflection.AssemblyMetadataAttribute("RepositoryUrl", "https://gitlab.tesses.cf/tesses50/tesses.http")] + +// Generated by the MSBuild WriteCodeFragment class. + diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfoInputs.cache b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfoInputs.cache new file mode 100644 index 0000000..19f25bb --- /dev/null +++ b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfoInputs.cache @@ -0,0 +1 @@ +ea81f4c5aa36132a8d98fd8f84bd055ee8efd423 diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.GeneratedMSBuildEditorConfig.editorconfig b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.GeneratedMSBuildEditorConfig.editorconfig new file mode 100644 index 0000000..91351a2 --- /dev/null +++ b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.GeneratedMSBuildEditorConfig.editorconfig @@ -0,0 +1,3 @@ +is_global = true +build_property.RootNamespace = Tesses.Http +build_property.ProjectDir = /home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/ diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.assets.cache b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.assets.cache new file mode 100644 index 0000000..1a7df5d Binary files /dev/null and b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.assets.cache differ diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.AssemblyReference.cache b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.AssemblyReference.cache new file mode 100644 index 0000000..5cf1319 Binary files /dev/null and b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.AssemblyReference.cache differ diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.CoreCompileInputs.cache b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.CoreCompileInputs.cache new file mode 100644 index 0000000..f96b2e8 --- /dev/null +++ b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.CoreCompileInputs.cache @@ -0,0 +1 @@ +6ac073b0afc1b3fc2934cc42feca1de8e80d19d3 diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.FileListAbsolute.txt b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.FileListAbsolute.txt new file mode 100644 index 0000000..8bb2386 --- /dev/null +++ b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.FileListAbsolute.txt @@ -0,0 +1,20 @@ +/home/mike/Documents/Tesses.Http/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.deps.json +/home/mike/Documents/Tesses.Http/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.dll +/home/mike/Documents/Tesses.Http/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.pdb +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.AssemblyReference.cache +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.GeneratedMSBuildEditorConfig.editorconfig +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfoInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfo.cs +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.CoreCompileInputs.cache +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.dll +/home/mike/Documents/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.pdb +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.deps.json +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.dll +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/bin/Debug/netstandard2.0/Tesses.Http.pdb +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.AssemblyReference.cache +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.GeneratedMSBuildEditorConfig.editorconfig +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfoInputs.cache +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.AssemblyInfo.cs +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.csproj.CoreCompileInputs.cache +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.dll +/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.pdb diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.dll b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.dll new file mode 100644 index 0000000..7b73abb Binary files /dev/null and b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.dll differ diff --git a/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.pdb b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.pdb new file mode 100644 index 0000000..291b368 Binary files /dev/null and b/Tesses.Http/obj/Debug/netstandard2.0/Tesses.Http.pdb differ diff --git a/Tesses.Http/obj/Tesses.Http.csproj.nuget.dgspec.json b/Tesses.Http/obj/Tesses.Http.csproj.nuget.dgspec.json new file mode 100644 index 0000000..e86430a --- /dev/null +++ b/Tesses.Http/obj/Tesses.Http.csproj.nuget.dgspec.json @@ -0,0 +1,72 @@ +{ + "format": 1, + "restore": { + "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj": {} + }, + "projects": { + "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "projectName": "Tesses.Http", + "projectPath": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + }, + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.400/RuntimeIdentifierGraph.json" + } + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http/obj/Tesses.Http.csproj.nuget.g.props b/Tesses.Http/obj/Tesses.Http.csproj.nuget.g.props new file mode 100644 index 0000000..9b8442f --- /dev/null +++ b/Tesses.Http/obj/Tesses.Http.csproj.nuget.g.props @@ -0,0 +1,15 @@ + + + + True + NuGet + $(MSBuildThisFileDirectory)project.assets.json + /home/mike/.nuget/packages/ + /home/mike/.nuget/packages/ + PackageReference + 6.3.0 + + + + + \ No newline at end of file diff --git a/Tesses.Http/obj/Tesses.Http.csproj.nuget.g.targets b/Tesses.Http/obj/Tesses.Http.csproj.nuget.g.targets new file mode 100644 index 0000000..8284cdf --- /dev/null +++ b/Tesses.Http/obj/Tesses.Http.csproj.nuget.g.targets @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Tesses.Http/obj/project.assets.json b/Tesses.Http/obj/project.assets.json new file mode 100644 index 0000000..b14f9d6 --- /dev/null +++ b/Tesses.Http/obj/project.assets.json @@ -0,0 +1,314 @@ +{ + "version": 3, + "targets": { + ".NETStandard,Version=v2.0": { + "Microsoft.NETCore.Platforms/1.1.0": { + "type": "package", + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + } + }, + "MimeTypesMap/1.0.8": { + "type": "package", + "compile": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + }, + "runtime": { + "lib/netstandard2.0/MimeTypesMap.dll": {} + } + }, + "NETStandard.Library/2.0.3": { + "type": "package", + "dependencies": { + "Microsoft.NETCore.Platforms": "1.1.0" + }, + "compile": { + "lib/netstandard1.0/_._": {} + }, + "runtime": { + "lib/netstandard1.0/_._": {} + }, + "build": { + "build/netstandard2.0/NETStandard.Library.targets": {} + } + }, + "Newtonsoft.Json/13.0.1": { + "type": "package", + "compile": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + }, + "runtime": { + "lib/netstandard2.0/Newtonsoft.Json.dll": { + "related": ".xml" + } + } + } + } + }, + "libraries": { + "Microsoft.NETCore.Platforms/1.1.0": { + "sha512": "kz0PEW2lhqygehI/d6XsPCQzD7ff7gUJaVGPVETX611eadGsA3A877GdSlU0LRVMCTH/+P3o2iDTak+S08V2+A==", + "type": "package", + "path": "microsoft.netcore.platforms/1.1.0", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "ThirdPartyNotices.txt", + "dotnet_library_license.txt", + "lib/netstandard1.0/_._", + "microsoft.netcore.platforms.1.1.0.nupkg.sha512", + "microsoft.netcore.platforms.nuspec", + "runtime.json" + ] + }, + "MimeTypesMap/1.0.8": { + "sha512": "iOm6Zar+yVROhlyrGGSJTfThvNoHLUeYeQQND9YD/ot/nA2qsWUp9kP2MHTdF9P7I8afW6eCf8vdELLZjDFdSQ==", + "type": "package", + "path": "mimetypesmap/1.0.8", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "lib/net452/MimeTypesMap.dll", + "lib/netstandard1.1/MimeTypesMap.dll", + "lib/netstandard2.0/MimeTypesMap.dll", + "mimetypesmap.1.0.8.nupkg.sha512", + "mimetypesmap.nuspec" + ] + }, + "NETStandard.Library/2.0.3": { + "sha512": "st47PosZSHrjECdjeIzZQbzivYBJFv6P2nv4cj2ypdI204DO+vZ7l5raGMiX4eXMJ53RfOIg+/s4DHVZ54Nu2A==", + "type": "package", + "path": "netstandard.library/2.0.3", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.TXT", + "THIRD-PARTY-NOTICES.TXT", + "build/netstandard2.0/NETStandard.Library.targets", + "build/netstandard2.0/ref/Microsoft.Win32.Primitives.dll", + "build/netstandard2.0/ref/System.AppContext.dll", + "build/netstandard2.0/ref/System.Collections.Concurrent.dll", + "build/netstandard2.0/ref/System.Collections.NonGeneric.dll", + "build/netstandard2.0/ref/System.Collections.Specialized.dll", + "build/netstandard2.0/ref/System.Collections.dll", + "build/netstandard2.0/ref/System.ComponentModel.Composition.dll", + "build/netstandard2.0/ref/System.ComponentModel.EventBasedAsync.dll", + "build/netstandard2.0/ref/System.ComponentModel.Primitives.dll", + "build/netstandard2.0/ref/System.ComponentModel.TypeConverter.dll", + "build/netstandard2.0/ref/System.ComponentModel.dll", + "build/netstandard2.0/ref/System.Console.dll", + "build/netstandard2.0/ref/System.Core.dll", + "build/netstandard2.0/ref/System.Data.Common.dll", + "build/netstandard2.0/ref/System.Data.dll", + "build/netstandard2.0/ref/System.Diagnostics.Contracts.dll", + "build/netstandard2.0/ref/System.Diagnostics.Debug.dll", + "build/netstandard2.0/ref/System.Diagnostics.FileVersionInfo.dll", + "build/netstandard2.0/ref/System.Diagnostics.Process.dll", + "build/netstandard2.0/ref/System.Diagnostics.StackTrace.dll", + "build/netstandard2.0/ref/System.Diagnostics.TextWriterTraceListener.dll", + "build/netstandard2.0/ref/System.Diagnostics.Tools.dll", + "build/netstandard2.0/ref/System.Diagnostics.TraceSource.dll", + "build/netstandard2.0/ref/System.Diagnostics.Tracing.dll", + "build/netstandard2.0/ref/System.Drawing.Primitives.dll", + "build/netstandard2.0/ref/System.Drawing.dll", + "build/netstandard2.0/ref/System.Dynamic.Runtime.dll", + "build/netstandard2.0/ref/System.Globalization.Calendars.dll", + "build/netstandard2.0/ref/System.Globalization.Extensions.dll", + "build/netstandard2.0/ref/System.Globalization.dll", + "build/netstandard2.0/ref/System.IO.Compression.FileSystem.dll", + "build/netstandard2.0/ref/System.IO.Compression.ZipFile.dll", + "build/netstandard2.0/ref/System.IO.Compression.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.DriveInfo.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.Primitives.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.Watcher.dll", + "build/netstandard2.0/ref/System.IO.FileSystem.dll", + "build/netstandard2.0/ref/System.IO.IsolatedStorage.dll", + "build/netstandard2.0/ref/System.IO.MemoryMappedFiles.dll", + "build/netstandard2.0/ref/System.IO.Pipes.dll", + "build/netstandard2.0/ref/System.IO.UnmanagedMemoryStream.dll", + "build/netstandard2.0/ref/System.IO.dll", + "build/netstandard2.0/ref/System.Linq.Expressions.dll", + "build/netstandard2.0/ref/System.Linq.Parallel.dll", + "build/netstandard2.0/ref/System.Linq.Queryable.dll", + "build/netstandard2.0/ref/System.Linq.dll", + "build/netstandard2.0/ref/System.Net.Http.dll", + "build/netstandard2.0/ref/System.Net.NameResolution.dll", + "build/netstandard2.0/ref/System.Net.NetworkInformation.dll", + "build/netstandard2.0/ref/System.Net.Ping.dll", + "build/netstandard2.0/ref/System.Net.Primitives.dll", + "build/netstandard2.0/ref/System.Net.Requests.dll", + "build/netstandard2.0/ref/System.Net.Security.dll", + "build/netstandard2.0/ref/System.Net.Sockets.dll", + "build/netstandard2.0/ref/System.Net.WebHeaderCollection.dll", + "build/netstandard2.0/ref/System.Net.WebSockets.Client.dll", + "build/netstandard2.0/ref/System.Net.WebSockets.dll", + "build/netstandard2.0/ref/System.Net.dll", + "build/netstandard2.0/ref/System.Numerics.dll", + "build/netstandard2.0/ref/System.ObjectModel.dll", + "build/netstandard2.0/ref/System.Reflection.Extensions.dll", + "build/netstandard2.0/ref/System.Reflection.Primitives.dll", + "build/netstandard2.0/ref/System.Reflection.dll", + "build/netstandard2.0/ref/System.Resources.Reader.dll", + "build/netstandard2.0/ref/System.Resources.ResourceManager.dll", + "build/netstandard2.0/ref/System.Resources.Writer.dll", + "build/netstandard2.0/ref/System.Runtime.CompilerServices.VisualC.dll", + "build/netstandard2.0/ref/System.Runtime.Extensions.dll", + "build/netstandard2.0/ref/System.Runtime.Handles.dll", + "build/netstandard2.0/ref/System.Runtime.InteropServices.RuntimeInformation.dll", + "build/netstandard2.0/ref/System.Runtime.InteropServices.dll", + "build/netstandard2.0/ref/System.Runtime.Numerics.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Formatters.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Json.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Primitives.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.Xml.dll", + "build/netstandard2.0/ref/System.Runtime.Serialization.dll", + "build/netstandard2.0/ref/System.Runtime.dll", + "build/netstandard2.0/ref/System.Security.Claims.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Algorithms.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Csp.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Encoding.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.Primitives.dll", + "build/netstandard2.0/ref/System.Security.Cryptography.X509Certificates.dll", + "build/netstandard2.0/ref/System.Security.Principal.dll", + "build/netstandard2.0/ref/System.Security.SecureString.dll", + "build/netstandard2.0/ref/System.ServiceModel.Web.dll", + "build/netstandard2.0/ref/System.Text.Encoding.Extensions.dll", + "build/netstandard2.0/ref/System.Text.Encoding.dll", + "build/netstandard2.0/ref/System.Text.RegularExpressions.dll", + "build/netstandard2.0/ref/System.Threading.Overlapped.dll", + "build/netstandard2.0/ref/System.Threading.Tasks.Parallel.dll", + "build/netstandard2.0/ref/System.Threading.Tasks.dll", + "build/netstandard2.0/ref/System.Threading.Thread.dll", + "build/netstandard2.0/ref/System.Threading.ThreadPool.dll", + "build/netstandard2.0/ref/System.Threading.Timer.dll", + "build/netstandard2.0/ref/System.Threading.dll", + "build/netstandard2.0/ref/System.Transactions.dll", + "build/netstandard2.0/ref/System.ValueTuple.dll", + "build/netstandard2.0/ref/System.Web.dll", + "build/netstandard2.0/ref/System.Windows.dll", + "build/netstandard2.0/ref/System.Xml.Linq.dll", + "build/netstandard2.0/ref/System.Xml.ReaderWriter.dll", + "build/netstandard2.0/ref/System.Xml.Serialization.dll", + "build/netstandard2.0/ref/System.Xml.XDocument.dll", + "build/netstandard2.0/ref/System.Xml.XPath.XDocument.dll", + "build/netstandard2.0/ref/System.Xml.XPath.dll", + "build/netstandard2.0/ref/System.Xml.XmlDocument.dll", + "build/netstandard2.0/ref/System.Xml.XmlSerializer.dll", + "build/netstandard2.0/ref/System.Xml.dll", + "build/netstandard2.0/ref/System.dll", + "build/netstandard2.0/ref/mscorlib.dll", + "build/netstandard2.0/ref/netstandard.dll", + "build/netstandard2.0/ref/netstandard.xml", + "lib/netstandard1.0/_._", + "netstandard.library.2.0.3.nupkg.sha512", + "netstandard.library.nuspec" + ] + }, + "Newtonsoft.Json/13.0.1": { + "sha512": "ppPFpBcvxdsfUonNcvITKqLl3bqxWbDCZIzDWHzjpdAHRFfZe0Dw9HmA0+za13IdyrgJwpkDTDA9fHaxOrt20A==", + "type": "package", + "path": "newtonsoft.json/13.0.1", + "files": [ + ".nupkg.metadata", + ".signature.p7s", + "LICENSE.md", + "lib/net20/Newtonsoft.Json.dll", + "lib/net20/Newtonsoft.Json.xml", + "lib/net35/Newtonsoft.Json.dll", + "lib/net35/Newtonsoft.Json.xml", + "lib/net40/Newtonsoft.Json.dll", + "lib/net40/Newtonsoft.Json.xml", + "lib/net45/Newtonsoft.Json.dll", + "lib/net45/Newtonsoft.Json.xml", + "lib/netstandard1.0/Newtonsoft.Json.dll", + "lib/netstandard1.0/Newtonsoft.Json.xml", + "lib/netstandard1.3/Newtonsoft.Json.dll", + "lib/netstandard1.3/Newtonsoft.Json.xml", + "lib/netstandard2.0/Newtonsoft.Json.dll", + "lib/netstandard2.0/Newtonsoft.Json.xml", + "newtonsoft.json.13.0.1.nupkg.sha512", + "newtonsoft.json.nuspec", + "packageIcon.png" + ] + } + }, + "projectFileDependencyGroups": { + ".NETStandard,Version=v2.0": [ + "MimeTypesMap >= 1.0.8", + "NETStandard.Library >= 2.0.3", + "Newtonsoft.Json >= 13.0.1" + ] + }, + "packageFolders": { + "/home/mike/.nuget/packages/": {} + }, + "project": { + "version": "1.0.0", + "restore": { + "projectUniqueName": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "projectName": "Tesses.Http", + "projectPath": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "packagesPath": "/home/mike/.nuget/packages/", + "outputPath": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/obj/", + "projectStyle": "PackageReference", + "configFilePaths": [ + "/home/mike/.nuget/NuGet/NuGet.Config" + ], + "originalTargetFrameworks": [ + "netstandard2.0" + ], + "sources": { + "https://api.nuget.org/v3/index.json": {} + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "projectReferences": {} + } + }, + "warningProperties": { + "warnAsError": [ + "NU1605" + ] + } + }, + "frameworks": { + "netstandard2.0": { + "targetAlias": "netstandard2.0", + "dependencies": { + "MimeTypesMap": { + "target": "Package", + "version": "[1.0.8, )" + }, + "NETStandard.Library": { + "suppressParent": "All", + "target": "Package", + "version": "[2.0.3, )", + "autoReferenced": true + }, + "Newtonsoft.Json": { + "target": "Package", + "version": "[13.0.1, )" + } + }, + "imports": [ + "net461", + "net462", + "net47", + "net471", + "net472", + "net48", + "net481" + ], + "assetTargetFallback": true, + "warn": true, + "runtimeIdentifierGraphPath": "/usr/share/dotnet/sdk/6.0.400/RuntimeIdentifierGraph.json" + } + } + } +} \ No newline at end of file diff --git a/Tesses.Http/obj/project.nuget.cache b/Tesses.Http/obj/project.nuget.cache new file mode 100644 index 0000000..31a0bf5 --- /dev/null +++ b/Tesses.Http/obj/project.nuget.cache @@ -0,0 +1,13 @@ +{ + "version": 2, + "dgSpecHash": "84jwmFi3zgfL/NYUasnrlgO3RTp2WPp/ajWPJmaNlfWrGU2rVvy6VKS31rxuK4/5hdeSawlUwyMkVnhaXJzBIQ==", + "success": true, + "projectFilePath": "/home/mike/Documents/Code/WorkingOn/Tesses.Http/Tesses.Http/Tesses.Http.csproj", + "expectedPackageFiles": [ + "/home/mike/.nuget/packages/microsoft.netcore.platforms/1.1.0/microsoft.netcore.platforms.1.1.0.nupkg.sha512", + "/home/mike/.nuget/packages/mimetypesmap/1.0.8/mimetypesmap.1.0.8.nupkg.sha512", + "/home/mike/.nuget/packages/netstandard.library/2.0.3/netstandard.library.2.0.3.nupkg.sha512", + "/home/mike/.nuget/packages/newtonsoft.json/13.0.1/newtonsoft.json.13.0.1.nupkg.sha512" + ], + "logs": [] +} \ No newline at end of file