A web server written entirely in PowerShell. Also the beginning of a framework for developing web applications in PowerShell.
A web server written entirely in the PowerShell scripting language and the .NET framework. The entirety of the project has no external dependencies or installation requirements. PAWS is designed to be runnable wherever PowerShell can run. There is no configuration apart from a few startup parameters and all custom application functionality is done by overriding existing methods.What is it not?
PAWS is not a production web server. It is very much a single-threaded thing (a current PowerShell limitation) and should not be expected to perform on par to (or even close to) other well-known web servers.What is it good for?
PAWS is simple to understand and easy to use. At its core, a web server is a rather simple beast and much of the complexity of "web-magic" lies in the implementation of the browser. Similarly, PAWS is also a simple beast which does little more than receive resource requests and respond to them. By overriding the default functionality, browser based applications can be developed quickly and easily. PAWS can be used to provide a user interface to your PowerShell based projects and satisfy the needs of ad-hoc presentation requirements.How does it work?
PAWS accepts incoming TCP requests on a specified port (usually 80) and currently implements a subset of the HTTP protocol (ie. GET requests). By default, PAWS will act as a normal web server and satisfy GET requests for things like html pages and images. The fun starts when you override the default behavior and have PAWS begin staisfying requests for virtual resources, like Sql databases or reports.What is needed?
A lot of stuff. There is much room for improvement and innovation. All suggestions and assistance will be welcome.
About PowerShell Ad-hoc Web Server
The Web Server
This project consists of a set of PowerShell scripts which implement basic web server behavior. Lib.WebServer.ps1 contains the function Run-WebServer which listens for and accepts incoming connections on a specified port. Each time a new connection is established, Run-WebServer will call the Process-Web-GET function which interprets the incoming request and sends back an appropriate response.
The default web server behavior is to map requests into a file system folder. For example, if the uri 'http://mydomain.com/index.htm' is requested, the web server will attempt to find the 'index.htm' file within the file system folder determined to be the root folder for 'mydomain.com'. If 'index.htm' is found, the server sends the contents of the file (resource) back to the requestor. The contents of this html are then interpreted and rendered by the requestor's browser (or whatever client).
Running the Web Server
The paws.ps1 file a general script which accepts arguments for the Run-WebServer function and then invokes with those arguments. Default values exist for these arguments which will run a normal web server.Arguments for paws.ps1:
- string $RootFolder : Root file system folder to use.
- int $ServerPort : Port to listen for incoming connections (defaults to port 80)
- string $RunEnvironment : Can be 'development', 'debug', 'test', or (default) 'production'.
- string $ApplicationFile : A script filename which implements a Process-Web-GET function.
- string $ServerName : A name or address to use for the server (defaults to 'localhost').
Using 'development' or 'debug' for the $RunEnvironment argument will set some debugging flags and is intended to allow the codebase to display more detailed status and diagnostic information than would be desired in 'test' or 'production' modes. 'development' and 'debug' modes will also force any $ApplicationFile specified to be reloaded for each request. Each time the application file is loaded, it overwrites the existing version of Process-Web-GET in memory with the version found in the application file. This is very convenient for being able to edit your application's implementation of Process-Web-GET without having to restart the web server for each change. Simply save your changes and the file will be reloaded on the next request.
You can also use the run-*-server.ps1 scripts to start the web server with a particular configuration and application.
Once the web server is running, open a browser window and navigate to the address specified in $ServerName.
For example, running paws.ps1 with no parameters will start a web server listening on 'localhost', port 80, and using the current folder as the root folder for the website. Opening a browser and navigating to the uri 'http://localhost/readme.txt' should display this readme file in your browser window.
If you get an error like 'Only one usage of each socket address (protocol/network address/port) is normally permitted', then you already have some other service on your machine which has that $ServerPort already open and you need to specify another one. You could specify a different port with '.\paws.ps1 -ServerPort 8000' and then navigate to 'http://localhost:8000/readme.txt'.
Implementing Custom Web Applications
In order to customize the web server to generate customized content, you simply need to override/overwrite the Process-Web-GET function to respond to your requests and generate whatever dynamic content in response. The WebApp.*.ps1 files all have their own Process-Web-GET function which establish a particular uri scheme and content specific to that application.
A WebApp.*.ps1 file is loaded and executed (dot-sourced/included) by the Run-WebServer function as determined by the function's $ApplicationFile parameter. If no application file is provided, a default version of Process-Web-GET is invoked which implements standard web server behavior. If an application file is specified, it will contain a different implementation of the Process-Web-GET function which will, when loaded, will overwrite and redefine the default version of Process-Web-GET. When Run-WebServer calls Process-Web-GET to handle incoming requests, it will be calling the application's version of Process-Web-GET rather than the default one.
Error trapping is installed in the Run-WebServer function, prior to the call to Process-Web-GET. When an error occurs the error text is written to the console and the existing connection is closed.
- Lib.Imaging.ps1 : Image sizing and serialization.
- Lib.MimeType.ps1 : Determine mime-type from file extension.
- Lib.Resource.ps1 : The Resource object (ie. a file)
- Lib.Strings.ps1 : String encoding (ascii/unicode/byte array/base64).
- Lib.WebPage.ps1 : Common web page header, footer, and navigation menu.
- Lib.WebRequest.ps1 : The WebRequest object.
- Lib.WebResponse.ps1 : The WebResponse object.
- Lib.WebServer.ps1 : Main server code.
- paws.ps1 : A general server startup script.
- run-file-server.ps1 : Starts a server running the WebApp.FileBrowser.ps1 application.
- run-image-server.ps1 : Starts a server running the WebApp.ImageBrowser.ps1 application.
- run-psdoc-server.ps1 : Starts a server running the WebApp.PSDoc.ps1 application.
- run-sqladmin-server.ps1 : Starts a server running the WebApp.SqlAdmin.ps1 application.
- run-test-form.ps1 : Starts a server running the WebApp.TestForm.ps1 application.
- Test.Imaging.ps1 : Test image functions.
- Test.MimeType.ps1 : Test mime-type functions.
- Test.Resource.ps1 : Test resource functions.
- Test.Strings.ps1 : Test string functions.
- WebApp.FileBrowser.ps1 : Implements a file browser application.
- WebApp.ImageBrowser.ps1 : Implements an image file browser application.
- WebApp.PSDoc.ps1 : Implements a PowerShell documentation browser (broken).
- WebApp.SqlAdmin.ps1 : Implements an administrative interface to an Sql Server (very rough).
- WebApp.TestForm.ps1 : Implements a simple submittable form.
- WebApp.WebServer.ps1 : Implements default web server behavior.