Giter VIP home page Giter VIP logo

polaris's Introduction

Polaris

Join the chat at https://gitter.im/PowerShell/Polaris Build Status PowerShell Gallery

A cross-platform, minimalist web framework for PowerShell.

Disclaimer

Polaris is currently an unsupported, experimental, proof-of-concept. There is no current plan to turn it into a supported Microsoft product.

That being said, we do plan on continuing to experiment within this repository for the foreseeable future.

Example

New-PolarisGetRoute -Path "/helloworld" -Scriptblock {
    $Response.Send('Hello World!')
}

Start-Polaris

Why yet another web framework for PowerShell?

There have been a great list of other micro web frameworks written over the years (Thanks @jaykul for the list!).

Polaris' differentiation is that it is cross-platform and uses the .NET HttpListener class.

Getting Started

Prerequisites

Steps

PS > Install-Module -Name Polaris -Scope CurrentUser -Force

You can now try out the example above or checkout the site for more usage information!

From source

  1. Clone or download the zip of the repo
  2. Open PowerShell
  3. At this point, you can now run Import-Module ./Polaris.psd1

You can now try out the example above or checkout the site for more usage!

You can also run all the Pester tests by running Invoke-Pester in the test directory. You will need Pester version 4.1.0 or higher to run the tests on Linux or MacOS.

Documentation

Check out the docs folder or the site for a full API reference.

Troubleshooting / Questions

  • Twitter: #PSPolaris
  • Slack: See us in the #Polaris channel of the PowerShell Slack
  • GitHub Issues: Submit a bug / new feature idea / or just a question as a new GitHub issue

Roadmap

We have a few paths we are interested in taking. We hope the community helps direct us.

  • Expanding on the current implementation using HttpListener to deliver features you'd expect from projects ASP.NET or Expressjs (route parameters, query parameters, middleware, auth etc)
  • Investigating the use of Kestrel/ASP.NET Routing instead of HttpListener
  • Creating a routing domain-specific language (DSL) for isolating and running script blocks as routes. Drawing inspiration from Pester.

Feedback

This project is an experiment that has the possibility to grow into something great. We can't do that without great feedback from you.

If you have an idea or find a bug, join the discussions in the issues or create a new issue.

License

Polaris is licensed under the MIT License.

Maintainers

Code of Conduct

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

polaris's People

Contributors

affieuk avatar bateskevin avatar bergmeister avatar bgelens avatar bladefirelight avatar chendrayanv avatar csandfeld avatar doug-reimer avatar gitter-badger avatar hvid avatar jeremymcgee73 avatar joeyaiello avatar pcgeek86 avatar stephanevg avatar stevel-msft avatar tiberriver256 avatar timcurwick avatar tylerleonhardt avatar vors avatar xtqqczze avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

polaris's Issues

Investigate use or pure powershell

Considering powershell can natively instantiate .NET classes, it would simplify development (no builds, better intellisense) and maintainability of the code base if Polaris was implemented in pure Powershell

Verify or Support Functionality on Windows IoT Core

One major use case I personally see is as a minimalistic way to give Windows IoT Core a PowerShell based alternative to Node.js for web server.

I have not yet had a chance to test Polaris on IoT Core, I will add feedback when I do.

Why is it on the PowerShell project?

Polaris is currently an unsupported, experimental, proof-of-concept. There is no current plan to turn it into a supported Microsoft product.

Does having it inside the PowerShell organization not imply some form of endorsement?

Is there some latent need you perceive that's not being met by the many other micro web frameworks written over the years for PowerShell?

Consider support for pluggable authentication

Hiyo!

This is outside my wheelhouse, but it would be quite valuable to have some sort of authentication, preferably pluggable so that folks could implement different mechanisms. Apologies if this is already included and I missed it

Cheers!

Hellow world example for new-GetRoute gives 404

New-GetRoute -Path "/helloworld" -ScriptBlock {
param($request,$response);
$response.Send('Hello World');
}

and I get

Server Error in '/' Application.
The resource cannot be found.

         Description: HTTP 404. The resource you are looking for (or one of its dependencies) could have been

removed, had its name changed, or is temporarily unavailable.  Please review the following URL and make sure that
it is spelled correctly.

         Requested URL: /helloworld

Stoping and Starting on the same port throws prefix error

Polaris receives the following error when starting after stopping on a particular port in the same PowerShell session. In this example, it was the default 8080 port.

PS C:\Users\tyleonha\Polaris\example> $app = Start-Polaris
PS C:\Users\tyleonha\Polaris\example> Stop-Polaris
Server Stopped.
PS C:\Users\tyleonha\Polaris\example> Start-Polaris
Exception calling "Start" with "3" argument(s): "Failed to listen on prefix 'http://localhost:8080/' because it conflicts with an existing
registration on the machine."
At C:\Users\tyleonha\Polaris\Polaris.psm1:115 char:5
+     $global:Polaris.Start($Port, $MinRunspaces, $MaxRunspaces);
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : HttpListenerException

Serving a static folder should create a default route to an index.html file

Consider the following:

New-StaticRoute -FolderPath "./static" -RoutePath "/public"

if there's an index.html located in ./staticwe should register that as a route to: /public. In other words, navigating to /public should send the index.html file back.

Also, I believe there are a few other defaults out there like default.html or index.htm we should check for these as well and pick one to become the default if there are multiple options.

cmdlet parser

What's the possibility of having a cmdlet parser from an allowed list that Polaris read's those cmdlets, figures out the parameters and output of said cmdlet and then auto-creates a route with the relevant method.

e.g.

Get-Item
Parses that as:
Method: Get
Query Params: [string]$Path, [string]$Filter, [string[]]Include, etc
Output: one of the following as JSON
  System.IO.FileInfo
  System.Boolean
  System.String
  System.IO.FileInfo
  System.IO.DirectoryInfo

Failed to do 'dotnet build'

Windows 10 1607 - PowerShell Core 6 Beta 8. Failed to before build with 1 warning and 3 errors. This is after installing DotNet SDK 2.0. This was after a successful 'dotnet restore'

PS C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore> dotnet build
C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj : warning NU1603: Polaris depends on System.Management.Automation (>= 6.0.0-alpha17) but System.Management.Automation 6.0.0-alpha17 was not found. An approximate best match of System.Management.Automation 6.1.7601.17514 was resolved.
Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj : warning NU1603: Polaris depends on System.Management.Automation (>= 6.0.0-alpha17) but System.Management.Automation 6.0.0-alpha17 was not found. An approximate best match of System.Management.Automation 6.1.7601.17514 was resolved.
Polaris.cs(4,14): error CS0234: The type or namespace name 'Management' does not exist in the namespace 'System' (are you missing an assembly reference?) [C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj]
Polaris.cs(6,14): error CS0234: The type or namespace name 'Management' does not exist in the namespace 'System' (are you missing an assembly reference?) [C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj]
Polaris.cs(24,9): error CS0246: The type or namespace name 'RunspacePool' could not be found (are you missing a using directive or an assembly reference?) [C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj]

Build FAILED.

C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj : warning NU1603: Polaris depends on System.Management.Automation (>= 6.0.0-alpha17) but System.Management.Automation 6.0.0-alpha17 was not found. An approximate best match of System.Management.Automation 6.1.7601.17514 was resolved.
Polaris.cs(4,14): error CS0234: The type or namespace name 'Management' does not exist in the namespace 'System' (are you missing an assembly reference?) [C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj]
Polaris.cs(6,14): error CS0234: The type or namespace name 'Management' does not exist in the namespace 'System' (are you missing an assembly reference?) [C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj]
Polaris.cs(24,9): error CS0246: The type or namespace name 'RunspacePool' could not be found (are you missing a using directive or an assembly reference?) [C:\Program Files\PowerShell\6.0.0-beta.8\Modules\Polaris\PolarisCore\Polaris.csproj]
1 Warning(s)
3 Error(s)

Cached data being return?

I called a route incorrectly passing it hashtable instead of a json object and it return the output from the last command. I don't think this should be expected behaviour.

# The following shows the two route definitions
PS C:\> (Get-WebRoute)['Get-User']['GET']
    $params = @{}
    $request.Query | ForEach-Object { $params[$_] = $request.Query[$_] }
    $result = Get-User @params | ConvertTo-Json
    $response.Send($result)

PS C:\> (Get-WebRoute)['Remove-User']['DELETE']
    $params = @{}
    $request.body.psobject.properties | ForEach-Object { $params[$_.Name] = $_.Value }
    $result = Remove-User @params
    $response.Send($result)

# incorrectly creating a hashtable instead of a json object
PS C:\> $remove = @{UserName='[email protected]'}

# Create a user
PS C:\> Invoke-RestMethod -Method POST -Uri http://localhost:8080/New-User -Body $body -ContentType application/json
# Note: nothing is returned from this call, as expected

# Try to remove the user with the hashtable being sent
PS C:\> Invoke-RestMethod -Method DELETE -Uri http://localhost:8080/Remove-User -Body $remove -ContentType application/json
# No output, this I think is simply returning the same output from the New-User call, which is nothing, to prove see below

# Make call which returns output
PS C:\> Invoke-RestMethod -Method GET -Uri 'http://localhost:8080/[email protected]'
DisplayName         : Joe Bloggs
Enabled             : True
LockedOut           : False
PasswordLastSet     : 09/11/2017 12:59:25
LastLogonDate       :

# call again with incorrect hashtable being sent
PS C:\> Invoke-RestMethod -Method DELETE -Uri http://localhost:8080/Remove-User -Body $remove -ContentType application/json

DisplayName         : Joe Bloggs
Enabled             : True
LockedOut           : False
PasswordLastSet     : 09/11/2017 12:59:25
LastLogonDate       :
# As you can see  the output from Get-User is returned, to prove see the output when Remove-User is provided with a json object
PS C:\> $remove = @{UserName='[email protected]'} | ConvertTo-Json
PS C:\> Invoke-RestMethod -Method DELETE -Uri http://localhost:8080/Remove-User -Body $remove -ContentType application/json

PS C:\> Get-ADUser joe.bloggs
Get-ADUser : Cannot find an object with identity: <snip>
At line:1 char:1
+ Get-ADUser joe.bloggs
+ ~~~~~~~~~~~~~~~~~~~~~

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.14393.1770
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.14393.1770
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

When serving a static folder, there is no response for folders

Consider the example:

New-StaticRoute -FolderPath "./static" -RoutePath "/public"

./static contains:
index.html
image/

and ./static/image/ contains:
hello.png

we can make requests to:
/public/index.html
/public/image/hello.png
just fine...
but /public/image hangs.

This is because Polaris can't handle navigating to directories yet. Polaris should support this at the very least by returning the list of things in that directory... ideally links that navigate to that item.

DotNet SDK Requirement

On a new Win10 Enterprise (1607), using PowerShell 6 beta 8, the default dotnet SDK that is being used errors out when you try to do a 'dotnet restore' or 'dotnet build':
C:\Program Files\dotnet\sdk\1.1.0\Sdks\Microsoft.NET.Sdk\build\Microsoft.NET.TargetFrameworkInference.targets(126,5): error : The current .NET SDK does not support targeting .NET Standard 2.0. Either target .NET Standard 1.6 or lower, or use a version of the .NET SDK that supports .NET Standard 2.0. [C:\PowerShell\Modules\Polaris\PolarisCore\Polaris.csproj]

Did I miss a requirement, or should it be listed in the "Getting Started" guide to use a higher level SDK?

Building on Windows fails if you don't have .NET 4.5.1 installed

on fresh server 1709, with updates installed
I installed .net 2.0 SDK and powershell 6.0 beta 9
ran pwsh and invoke-build build
I got this error


PS C:\Users\Blade\Downloads\Polaris-master\Polaris-master> invoke-build build
Build build C:\Users\Blade\Downloads\Polaris-master\Polaris-master\Polaris.build.ps1
Task /Build/SetupDotNet

### Installing .NET CLI 2.0.0...

dotnet-install: .NET SDK version 2.0.0 is already installed.
dotnet-install: Adding to current process PATH: "C:\Users\Blade\Downloads\Polaris-master\Polaris-master\.dotnet\". Note: This change will not be visible if PowerShell was run as a child process.

### Installation complete.

### Using dotnet v2.0.0 at path C:\Users\Blade\Downloads\Polaris-master\Polaris-master\.dotnet\dotnet.exe

Done /Build/SetupDotNet 00:00:03.6535980
Done /Build/Restore/SetupDotNet
Task /Build/Restore
  Restore completed in 751.42 ms for C:\Users\Blade\Downloads\Polaris-master\Polaris-master\PolarisCore\Polaris.csproj.
Done /Build/Restore 00:00:07.3507350
Task /Build
Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

C:\Program Files\dotnet\sdk\2.0.2\Sdks\Microsoft.NET.Sdk\build\Microsoft.PackageDependencyResolution.targets(165,5): error : Assets file 'C:\Users\Blade\Downloads\Polaris-master\Polaris-master\PolarisCore\obj\project.assets.json' doesn't have a target for '.NETFramework,Version=v4.5.1'. Ensure that restore has run and that you have included 'net451' in the TargetFrameworks for your project. [C:\Users\Blade\Downloads\Polaris-master\Polaris-master\PolarisCore\Polaris.csproj]

Build FAILED.

C:\Program Files\dotnet\sdk\2.0.2\Sdks\Microsoft.NET.Sdk\build\Microsoft.PackageDependencyResolution.targets(165,5): error : Assets file 'C:\Users\Blade\Downloads\Polaris-master\Polaris-master\PolarisCore\obj\project.assets.json' doesn't have a target for '.NETFramework,Version=v4.5.1'. Ensure that restore has run and that you have included 'net451' in the TargetFrameworks for your project. [C:\Users\Blade\Downloads\Polaris-master\Polaris-master\PolarisCore\Polaris.csproj]
    0 Warning(s)
    1 Error(s)

Time Elapsed 00:00:01.06
At C:\Users\Blade\Downloads\Polaris-master\Polaris-master\Polaris.build.ps1:90 char:1
+ task Build {
+ ~~~~~~~~~~~~
Build FAILED. 3 tasks, 1 errors, 0 warnings 00:00:13.4870544
exec : Command { & $script:dotnetExe build .\PolarisCore\Polaris.csproj -f net451 } exited with code 1.
At C:\Users\Blade\Downloads\Polaris-master\Polaris-master\Polaris.build.ps1:92 char:9
+         exec { & $script:dotnetExe build .\PolarisCore\Polaris.csproj ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidResult: (:) [Invoke-BuildExec], Exception
    + FullyQualifiedErrorId : Invoke-BuildExec

Is there support for POSTing data

I've gone through the wiki, can't find examples of post a $body variable, maybe json with convertTo / convertFrom?

Something like

New-WebRoute -Path "/" -Method "POST" -ScriptBlock {
    New-Item -Path $body.Path -ItemType Directory
    $response.Send($(Get-Item -Path $body.Path));
}
Start-Polaris -Port 80

###
$body = @{'Path'='C:\Test'}
Invoke-WebRequest -Method Post -Uri http://localhost -Body $body

start stop start doesn't work

Try start and stop and start polatis again

PS /Users/vors/dev/polaris> Start-Polaris                                                                                                                                                                                                 Port ScriptBlockRoutes                                                                                               ---- -----------------                                                                                               8080 {[qwert, System.Collections.Generic.Dictionary`2[System.String,System.String]]}                                                                                                                                                      

PS /Users/vors/dev/polaris> Stop-Polaris -Verbose                                                                    VERBOSE: Server Stopped.                                                                                             
PS /Users/vors/dev/polaris> Start-Polaris                                                                            Exception calling "Start" with "3" argument(s): "Failed to listen on prefix 'http://+:8080/' because it conflicts    
with an existing registration on the machine."
At /Users/vors/dev/polaris/Polaris.psm1:154 char:5
+     $global:Polaris.Start($Port, $MinRunspaces, $MaxRunspaces)
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : HttpListenerException
 

Port ScriptBlockRoutes                                                              
---- -----------------                                                              
8080 {[qwert, System.Collections.Generic.Dictionary`2[System.String,System.String]]}


Unloading the module leaks a RunspacePool

Due to #34 , unloading the module with remove-module polaris will leave the global variable $polaris and associated disposable RunspacePool field in memory. The Polaris class would be better modeled as a singleton, and be made disposable. Consider adding a hook for module removal to dispose the singleton; here's an interactive example:

PS C:\> new-module -Name foo {
    $m = $ExecutionContext.SessionState.Module;
    $m.OnRemove = {
        # [polaris]::cleanup()
        write-host "bye from $($m.Name)"
        }.GetNewClosure()
} | import-module

PS> remove-module foo
bye from foo

Support for Windows PowerShell 3 and 4

As it turns out:

[PolarisCore.Polaris]::new() is PowerShell 5 syntax.

We should use a syntax that's more supported.

Maybe something like:
New-Object PolarisCore.Polaris if possible.

Support for Windows PowerShell (5.x and lower)

Right now, Polaris only supports PowerShell 6. Polaris should work with Windows PowerShell to support those that have scripts that aren't using PowerShell 6 that they'd like to use with Polaris.

Out of memory error using static route

It would seem get-content does not like large files

[0]:
System.OutOfMemoryException: Array dimensions exceeded supported range.
   at System.Collections.ArrayList.set_Capacity(Int32 value)
   at System.Collections.ArrayList.EnsureCapacity(Int32 min)
   at System.Collections.ArrayList.Add(Object value)
   at Microsoft.PowerShell.Commands.FileSystemContentReaderWriter.ReadByteEncoded(Boolean waitChanges, ArrayList blocks, Boolean readBack)
   at Microsoft.PowerShell.Commands.FileSystemContentReaderWriter.Read(Int64 readCount)
   at Microsoft.PowerShell.Commands.GetContentCommand.ProcessRecord()At line:4 char:14
+ ...    $bytes = Get-Content "C:\WIM\Srv1709.wim" -Encoding Byte -ReadCoun ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Errors in PowerShell Scripts are not returning 500s

This was discovered in #67
Here's a snippet from that:

Ok so,

When you do Invoke-RestMethod without converting the body to json, it sends over that hashtable as a string:

Take a look at the string in the middle of this image:
screen shot 2017-11-09 at 11 10 08 pm

That is how Invoke-RestMethod works, so we must play with that. Now, I'm pretty sure, there was an error in my Json parsing middleware so I wrapped that in a try/catch to catch when strings don't parse correctly. That said, 2 errors get thrown in your script block:

$bodyBlock = '
            $params = @{{}}
            $request.body.psobject.properties | ForEach-Object {{ $params[$_.Name] = $_.Value }}
            $result = {0} @params
            $response.Send($result)
        ' -f $Name

$request.body.psobject.properties | ForEach-Object { $params[$_.Name] = $_.Value }
with a Index operation failed; the array index evaluated to null. I'm guessing because $request.body is null

and $result = Remove-Item @params
because it's expecting the -Path

I thought that Polaris was throwing errors (returning 500 InternalServerError) when this happened but I guess that's not true. I'll open an issue to fix error reporting.

I think we're only throwing 500s if actual PowerShell crashes - like the script stops being executed.

Investigate other implementations of Polaris

When working on the Azure IoT SDK Direct Methods, I got some great feedback regarding script blocks and scope.

Rather than passing in arbitrary script blocks, we could pass in a module that has a function we want to run for a given route.

This way, the module contains the scope of the executing route.

We should enable this for Polaris.

Build has one warning: MSB3277

The build currently has one warning:

/usr/local/share/dotnet/sdk/2.0.0/Microsoft.Common.CurrentVersion.targets(1987,5): warning MSB3277: Found conflicts between different versions of the same dependent assembly that could not be resolved.  These reference conflicts are listed in the build log when log verbosity is set to detailed. [/Users/tylerleonhardt/Desktop/CompSci/DotNET/Core/Polaris/PolarisCore/Polaris.csproj]
  Polaris -> /Users/tylerleonhardt/Desktop/CompSci/DotNET/Core/Polaris/PolarisCore/bin/Debug/netstandard2.0/Polaris.dll

Build succeeded.

Usually this is fixable by updating a dependency or adding a binding redirect. This is likely because we are using:
<PackageReference Include="System.Management.Automation" Version="6.0.0-alpha17" />
from myget which supported .NET Standard 1.6.

Add Cmdlet prefixes

It's best practice to change:

Get-WebRoute

To

Get-PolarisWebRoute

That prefix helps user know what module the cmdlet comes from.

Add-Type cannot find Polaris.dll

Hello,

Seems that there's no folder bin under Polaris\PolarisCore\.

OS: Windows 10.0.15063
Powershell: 6.0.0-beta.8
dotnet: 2.0.2

PS D:\Git\Polaris> ipmo .\Polaris.psm1
Add-Type : Cannot bind parameter 'Path' to the target. Exception
setting "Path": "Cannot find path 'D:\Git\Polaris\PolarisCore\bin\Debug\netstandard2.0\Polaris.dll' because it does not
exist."
At D:\Git\Polaris\Polaris.psm1:1 char:16
+ ... -Type -Path
"$PSScriptRoot/PolarisCore/bin/Debug/netstandard2.0/Polar ...
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (:) [Add-Type], Paramete
   rBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.Pow
   erShell.Commands.AddTypeCommand

Start-Polaris when there are no routes registered calls some mandatory parameters

Start polaris without registering any routes.
It runs into a confusing mandatory parameters supply prompt

PS /Users/vors/dev/polaris> import-module ./Polaris.psd1                                                             
PS /Users/vors/dev/polaris> Start-Polaris -Verbose                                                                   

cmdlet ThrowError at command pipeline position 1
Supply values for the following parameters:
errorId: 213
errorCategory: 1

Better VS Code/PSScriptAnalyzer integration

PSScriptAnalyzer can be a manual build step to ensure code quality. For example, PSScriptAnalyzer can enforce help comments on exported module functions. VS Code's PowerShell linting supports configuration through PSScriptAnalyzer's settings file. Following migration to PSScriptAnalyzer/VS Code, we would probably want to standardize code with the style used by VS Code's snippets and PSScriptAnalyzer-driven autoformatting.

$respoinse.SetHeader fails

a call to $response.SetHeader("test","test");

Gives this error, no mater the header name or value

Invoke-WebRequest :
[0]:
System.Management.Automation.MethodInvocationException: Exception calling "SetHeader" with "2" argument(s): "Object
reference not set to an instance of an object." ---> System.NullReferenceException: Object reference not set to an
instance of an object.
at PolarisCore.PolarisResponse.SetHeader(String headerName, String headerValue) in
C:\Polaris-master\PolarisCore\PolarisResponse.cs:line 23
at CallSite.Target(Closure , CallSite , Object , String , String )
--- End of inner exception stack trace ---
at System.Management.Automation.ExceptionHandlingOps.ConvertToMethodInvocationException(Exception exception, Type
typeToThrow, String methodName, Int32 numArgs, MemberInfo memberInfo)
at CallSite.Target(Closure , CallSite , Object , String , String )
at System.Dynamic.UpdateDelegates.UpdateAndExecute3[T0,T1,T2,TRet](CallSite site, T0 arg0, T1 arg1, T2 arg2)
at System.Management.Automation.Interpreter.DynamicInstruction`4.Run(InterpretedFrame frame)
at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(InterpretedFrame frame)At line:4
char:13

  •         $response.SetHeader('test','test');
    
  •         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

At line:1 char:1

  • Invoke-WebRequest -UseBasicParsing -Uri http://localhost:8080/3?scrip ...
  •   + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebExc
     eption
      + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
    

Currently only running with Prefix localhost - should run with any hostname for hosting outside

right now, we only register:

http://localhost:(Port)/

this is fine for local testing but what doesn't work is when we want to expose it externally. If I want to use ngrok to tunnel my web server running on my machine, I need web server to be able to handle any host:
http://8a3f3451.ngrok.io
for example.

We will also need this if we want to run Polaris in a container. Same reasons above.

  1. Figure out what set of prefixes solve this for Windows, MacOS, and Linux (via container)
  2. figure out if admin is needed

For Windows, a prefix of: http://+:(port)/ did the trick. It DID require admin. A solution that doesn't require admin that I think is out of scope of this issue is the following complete prefix: http://+:80/Temporary_Listen_Addresses/ If there's enough want of a way to host without admin, I'll open a bug to support this prefix.

I have a branch that contains some code that checks if the OS is Windows and if so, it checks if the process has admin permissions. If so, then we're good to go to add the + prefix. Now I need to look at a solution for MacOS and Linux (docker).

Support query parameters

They're absolutely necessary.

localhost:8080/hello?name=Tyler

There's a bug to track the investigation of ASP.NET Routing in #13

but potentially in the meantime we can add on to the additional routing logic to support query parameters.

Should be simple:

  1. get the query parameters from the url
  2. put them in the PolarisRequest object that gets sent down to the executing PowerShell

Error on import

Just cloned on macOS and copied the first command from the README

PS /Users/vors/dev/polaris> Import-Module –Name .\Polaris.psm1                                                       
Add-Type : Cannot bind parameter 'Path' to the target. Exception setting "Path": "Cannot find path 
'/Users/vors/dev/polaris/PolarisCore/bin/Debug/netstandard2.0/Polaris.dll' because it does not exist."
At /Users/vors/dev/polaris/Polaris.psm1:1 char:16
+ ... -Type -Path "$PSScriptRoot/PolarisCore/bin/Debug/netstandard2.0/Polar ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : WriteError: (:) [Add-Type], ParameterBindingException
    + FullyQualifiedErrorId : ParameterBindingFailed,Microsoft.PowerShell.Commands.AddTypeCommand

Workaround: this works fine

Import-Module –Name ./Polaris.psm1                

Query Parameters Documentation Incorrect

I think the documentation for query parameters needs to be updated to something like:

$response.QueryParameters changed to $response.Query

New-WebRoute -Path "/hellome" -Method "GET" -ScriptBlock { if ($request.Query['name']) { $response.Send('Hello ' + $request.Query['name']); } else { $response.Send('Hello World'); } }

Support for starting and stopping multiple servers in the same PS session

We should be able to do:

$app1 = Start-Polaris -Port 8080

New-Polaris

$app2 = Start-Polaris -Port 8081

Stop-Polaris $app2
Stop-Polaris $app1

Where New-Polaris creates a new Polaris object and puts it in the existing global $Polaris variable.

This also means that all New-*Route cmdlets should allow a -ServerContext param where you can pass in the server you want to add a route to.

Example:

$app = Start-Polaris -Port 8080

$sb = { $response.Send("atlas") }
New-GetRoute /hello $sb -ServerContext $app

This is actually almost done. Work remaining is:

  • create the New-Polaris cmdlet that creates a new Polaris object and stores it in $global:Polaris
  • add -ServerContext to New-*Route

Use InvokeBuild to build

all the dotnet sdk calls should be wrapped in InvokeBuild.

That way everyone runs Invoke-Build and the build script builds the correctly targeted versions

Any way to share state between route handlers?

I'm looking for a way to create few related endpoints.
I would be good to be able to share some objects between them.

For example, that could work in theory

$global:foo = 444
New-PostRoute -Path "/foo" -ScriptBlock {
    param($request,$response)                                                                        $response.Send("foo = " +  $global:foo)
}

Console.WriteLine usage

There are a bunch of places where Console.WriteLine is used:

PolarisCore/Polaris.cs
57:            Console.WriteLine("App listening on Port: " + port + "!");
63:            Console.WriteLine("Server Stopped.");
101:                Console.WriteLine("request came in: " + rawRequest.HttpMethod + " " + rawRequest.RawUrl);
119:                            Console.WriteLine(PowerShellInstance.InvocationStateInfo.Reason);
132:                        Console.WriteLine("404 Not Found");
136:                        Console.WriteLine(e.Message);

This is not a very PowerShell way to achieve the debug output.
That leads to things like

> $q = Invoke-RestMethod http://127.0.0.1:8080/get                                       
request came in: GET /get

A better one, for example, would be to take a log function callback in the core C# dll and pass Write-Verbose from the powershell wrapper.

Middleware in Polaris

something like app.use in Express. Where every request that meets a certain criteria will run against some middleware code before running the defined logic. That way apps can be more modular.

This includes plugging in different authentication methods.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.