Skip to content

Commit

Permalink
Adjust WebServer samples to support new FileSystem nuget (#330)
Browse files Browse the repository at this point in the history
  • Loading branch information
Ellerbach authored Nov 2, 2023
1 parent 6a53ee0 commit 60e7cc1
Show file tree
Hide file tree
Showing 23 changed files with 418 additions and 96 deletions.
52 changes: 33 additions & 19 deletions samples/Webserver/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ Shows how to use .NET **nanoFramework** Webserver library in common usage scenar
## Samples

- [🌶️ - REST and GPIO](./WebServer.GpioRest/)
- [🌶️🌶️ - HTTP server](./WebServer.Sample/)
- [🌶️🌶️ - HTTP server](./WebServer.Sample/WebServer.Sample/)
- [🌶️🌶️ - HTTP server with file system](./WebServer.Sample/WebServer.Sample.FileSystem/)
- [🌶️🌶️ - Dependency Injection](./WebServer.DI/)

## Usage
Expand Down Expand Up @@ -68,9 +69,10 @@ The `RouteAnyTest`is called whenever the url is `test/any` whatever the method i

There is a more advance example with simple REST API to get a list of Person and add a Person. Check it in the [sample](./WebServer.Sample/ControllerPerson.cs).

**Important**
* By default the routes are not case sensitive and the attribute **must** be lowercase
* If you want to use case sensitive routes like in the previous example, use the attribute `CaseSensitive`. As in the previous example, you **must** write the route as you want it to be responded to.
> ![Important]
>
> - By default the routes are not case sensitive and the attribute **must** be lowercase
> - If you want to use case sensitive routes like in the previous example, use the attribute `CaseSensitive`. As in the previous example, you **must** write the route as you want it to be responded to.
## A simple GPIO controller REST API

Expand All @@ -84,6 +86,7 @@ You will find in simple [GPIO controller sample](./WebServer.GpioRest) REST API.
- To read the pin 4: http://yoururl/read/4, you will get as a raw text `high`or `low`depending on the state

## DI integration with controllers

Check [WebServer.DI sample](./WebServer.DI) if you want to use controllers with automatically injecting services from [nanoFramework.DependencyInjection](https://github.com/nanoframework/nanoFramework.DependencyInjection).

- Type you credentials in Program.cs files
Expand All @@ -95,13 +98,13 @@ Check [WebServer.DI sample](./WebServer.DI) if you want to use controllers with
Controllers support authentication. 3 types of authentications are currently implemented on controllers only:

- Basic: the classic user and password following the HTTP standard. Usage:
- `[Authentication("Basic")]` will use the default credential of the webserver
- `[Authentication("Basic:myuser mypassword")]` will use myuser as a user and my password as a password. Note: the user cannot contains spaces.
- `[Authentication("Basic")]` will use the default credential of the webserver
- `[Authentication("Basic:myuser mypassword")]` will use myuser as a user and my password as a password. Note: the user cannot contains spaces.
- APiKey in header: add ApiKey in headers with the API key. Usage:
- `[Authentication("ApiKey")]` will use the default credential of the webserver
- `[Authentication("ApiKeyc:akey")]` will use akey as ApiKey.
- `[Authentication("ApiKey")]` will use the default credential of the webserver
- `[Authentication("ApiKeyc:akey")]` will use akey as ApiKey.
- None: no authentication required. Usage:
- `[Authentication("None")]` will use the default credential of the webserver
- `[Authentication("None")]` will use the default credential of the webserver

The Authentication attribute applies to both public Classes an public Methods.

Expand Down Expand Up @@ -166,16 +169,15 @@ using (WebServer server = new WebServer(80, HttpProtocol.Http, new Type[] { type
With the previous example the following happens:

- All the controller by default, even when nothing is specified will use the controller credentials. In our case, the Basic authentication with the default user (topuser) and password (topPassword) will be used.
- When calling http://yoururl/authbasic from a browser, you will be prompted for the user and password, use the default one topuser and topPassword to get access
- When calling http://yoururl/authnone, you won't be prompted because the authentication has been overridden for no authentication
- When calling http://yoururl/authbasicspecial, the user and password are different from the defautl ones, user2 and password is the right couple here
- When calling http://yoururl/authbasic from a browser, you will be prompted for the user and password, use the default one topuser and topPassword to get access
- When calling http://yoururl/authnone, you won't be prompted because the authentication has been overridden for no authentication
- When calling http://yoururl/authbasicspecial, the user and password are different from the defautl ones, user2 and password is the right couple here
- If you would have define in the controller a specific user and password like `[Authentication("Basic:myuser mypassword")]`, then the default one for all the controller would have been myuser and mypassword
- When calling http://yoururl/authapi, you must pass the header `ApiKey` (case sensitive) with the value `superKey1234` to get authorized, this is overridden the default Basic authentication
- When calling http://yoururl/authdefaultapi, the default key `ATopSecretAPIKey1234` will be used so you have to pass it in the headers of the request

All up, this is an example to show how to use authentication, it's been defined to allow flexibility.


## Managing incoming queries thru events

Very basic usage is the following:
Expand Down Expand Up @@ -225,15 +227,27 @@ if (url.ToLower().IndexOf("/param.htm") == 0)
}
```

And server static files:
To serve static files, you have to use the `nanoFramework.WebServer.FileSystem` nuget. This is only supported on devices having the `System.IO.FileSystem` capability.

```csharp
var files = storage.GetFiles();
foreach (var file in files)
// Gets the list of all files in a specific directory
// See the MountExample for more details if you need to mount an SD card and adjust here
// https://github.com/nanoframework/Samples/blob/main/samples/System.IO.FileSystem/MountExample/Program.cs
_listFiles = Directory.GetFiles(DirectoryPath);
// Remove the root directory
for (int i = 0; i < _listFiles.Length; i++)
{
_listFiles[i] = _listFiles[i].Substring(DirectoryPath.Length);
}

var fileName = url.Substring(1);
// Note that the file name is case sensitive
// Very simple example serving a static file on an SD card
foreach (var file in _listFiles)
{
if (file.Name == url)
if (file == fileName)
{
WebServer.SendFileOverHTTP(e.Context.Response, file);
WebServer.SendFileOverHTTP(e.Context.Response, DirectoryPath + file);
return;
}
}
Expand Down Expand Up @@ -345,7 +359,7 @@ using (WebServer server = new WebServer(443, HttpProtocol.Https)
}
```

> IMPORTANT: because the certificate above is not issued from a Certificate Authority it won't be recognized as a valid certificate. If you want to access the nanoFramework device with your browser, for example, you'll have to add the (CRT file)[WebServer.Sample\webserver-cert.crt] as a trusted one. On Windows, you just have to double click on the CRT file and then click "Install Certificate...".
> IMPORTANT: because the certificate above is not issued from a Certificate Authority it won't be recognized as a valid certificate. If you want to access the nanoFramework device with your browser, for example, you'll have to add the [CRT file](WebServer.Sample\WebServer.Sample\webserver-cert.crt) as a trusted one. On Windows, you just have to double click on the CRT file and then click "Install Certificate...".

You can of course use the routes as defined earlier. Both will work, event or route with the notion of controller.

Expand Down
13 changes: 2 additions & 11 deletions samples/Webserver/WebServer.DI/WebServer.Sample.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,8 @@
<HintPath>packages\nanoFramework.System.Text.1.2.37\lib\nanoFramework.System.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.WebServer, Version=1.2.0.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.WebServer.1.2.1\lib\nanoFramework.WebServer.dll</HintPath>
<Private>True</Private>
<Reference Include="nanoFramework.WebServer">
<HintPath>packages\nanoFramework.WebServer.1.2.3\lib\nanoFramework.WebServer.dll</HintPath>
</Reference>
<Reference Include="System.Device.Wifi, Version=1.5.65.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.System.Device.Wifi.1.5.65\lib\System.Device.Wifi.dll</HintPath>
Expand All @@ -75,14 +74,6 @@
<HintPath>packages\nanoFramework.System.Threading.1.1.19\lib\System.Threading.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Windows.Storage, Version=1.5.33.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.Windows.Storage.1.5.33\lib\Windows.Storage.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Windows.Storage.Streams, Version=1.14.24.46541, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.Windows.Storage.Streams.1.14.24\lib\Windows.Storage.Streams.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
<ProjectExtensions>
Expand Down
4 changes: 1 addition & 3 deletions samples/Webserver/WebServer.DI/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,5 @@
<package id="nanoFramework.System.Net.Http.Server" version="1.5.104" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Text" version="1.2.37" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Threading" version="1.1.19" targetFramework="netnano1.0" />
<package id="nanoFramework.WebServer" version="1.2.1" targetFramework="netnano1.0" />
<package id="nanoFramework.Windows.Storage" version="1.5.33" targetFramework="netnano1.0" />
<package id="nanoFramework.Windows.Storage.Streams" version="1.14.24" targetFramework="netnano1.0" />
<package id="nanoFramework.WebServer" version="1.2.3" targetFramework="netnano1.0" />
</packages>
13 changes: 2 additions & 11 deletions samples/Webserver/WebServer.GpioRest/WebServer.GpioRest.nfproj
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,8 @@
<HintPath>packages\nanoFramework.System.Text.1.2.37\lib\nanoFramework.System.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.WebServer, Version=1.2.0.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.WebServer.1.2.1\lib\nanoFramework.WebServer.dll</HintPath>
<Private>True</Private>
<Reference Include="nanoFramework.WebServer">
<HintPath>packages\nanoFramework.WebServer.1.2.3\lib\nanoFramework.WebServer.dll</HintPath>
</Reference>
<Reference Include="System.Device.Gpio, Version=1.1.28.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.System.Device.Gpio.1.1.28\lib\System.Device.Gpio.dll</HintPath>
Expand Down Expand Up @@ -75,14 +74,6 @@
<HintPath>packages\nanoFramework.System.Threading.1.1.19\lib\System.Threading.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Windows.Storage, Version=1.5.33.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.Windows.Storage.1.5.33\lib\Windows.Storage.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Windows.Storage.Streams, Version=1.14.24.46541, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>packages\nanoFramework.Windows.Storage.Streams.1.14.24\lib\Windows.Storage.Streams.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
<ProjectExtensions>
Expand Down
4 changes: 1 addition & 3 deletions samples/Webserver/WebServer.GpioRest/packages.config
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,5 @@
<package id="nanoFramework.System.Net.Http.Server" version="1.5.104" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Text" version="1.2.37" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Threading" version="1.1.19" targetFramework="netnanoframework10" />
<package id="nanoFramework.WebServer" version="1.2.1" targetFramework="netnano1.0" />
<package id="nanoFramework.Windows.Storage" version="1.5.33" targetFramework="netnano1.0" />
<package id="nanoFramework.Windows.Storage.Streams" version="1.14.24" targetFramework="netnano1.0" />
<package id="nanoFramework.WebServer" version="1.2.3" targetFramework="netnano1.0" />
</packages>
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="Current" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Label="Globals">
<NanoFrameworkProjectSystemPath>$(MSBuildExtensionsPath)\nanoFramework\v1.0\</NanoFrameworkProjectSystemPath>
</PropertyGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.Default.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectTypeGuids>{11A8DD76-328B-46DF-9F39-F559912D0360};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<ProjectGuid>{129CD942-C541-4E30-A605-9AB688E92800}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<FileAlignment>512</FileAlignment>
<RootNamespace>WebServer.Sample</RootNamespace>
<AssemblyName>WebServer.Sample</AssemblyName>
<TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants);HAS_WIFI;HAS_STORAGE;</DefineConstants>
</PropertyGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.props" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.props')" />
<ItemGroup>
<Compile Include="..\WebServer.Sample\ControllerAuth.cs" >
<Link>ControllerAuth.cs</Link>
</Compile>
<Compile Include="..\WebServer.Sample\ControllerPerson.cs" >
<Link>ControllerPerson.cs</Link>
</Compile>
<Compile Include="..\WebServer.Sample\ControllerTest.cs" >
<Link>ControllerTest.cs</Link>
</Compile>
<Compile Include="..\WebServer.Sample\Program.cs" >
<Link>Program.cs</Link>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Resources.resx">
<Generator>nFResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="Resources\favicon.ico" />
</ItemGroup>
<ItemGroup>
<Reference Include="mscorlib, Version=1.14.3.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.CoreLibrary.1.14.2\lib\mscorlib.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.ResourceManager, Version=1.2.13.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.ResourceManager.1.2.13\lib\nanoFramework.ResourceManager.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.Runtime.Events, Version=1.11.6.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.Runtime.Events.1.11.6\lib\nanoFramework.Runtime.Events.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.System.Collections, Version=1.5.18.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Collections.1.5.18\lib\nanoFramework.System.Collections.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.System.Text, Version=1.2.37.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Text.1.2.37\lib\nanoFramework.System.Text.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nanoFramework.WebServer">
<HintPath>..\packages\nanoFramework.WebServer.FileSystem.1.2.3\lib\nanoFramework.WebServer.dll</HintPath>
</Reference>
<Reference Include="System.Device.Gpio, Version=1.1.28.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Device.Gpio.1.1.28\lib\System.Device.Gpio.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Device.Wifi">
<HintPath>..\packages\nanoFramework.System.Device.Wifi.1.5.65\lib\System.Device.Wifi.dll</HintPath>
</Reference>
<Reference Include="System.IO.FileSystem">
<HintPath>..\packages\nanoFramework.System.IO.FileSystem.1.1.23\lib\System.IO.FileSystem.dll</HintPath>
</Reference>
<Reference Include="System.IO.Streams, Version=1.1.38.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.IO.Streams.1.1.38\lib\System.IO.Streams.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net, Version=1.10.62.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Net.1.10.62\lib\System.Net.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Net.Http, Version=1.5.104.0, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Net.Http.Server.1.5.104\lib\System.Net.Http.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Threading, Version=1.1.19.33722, Culture=neutral, PublicKeyToken=c07d481e9758c731">
<HintPath>..\packages\nanoFramework.System.Threading.1.1.19\lib\System.Threading.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Import Project="$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets" Condition="Exists('$(NanoFrameworkProjectSystemPath)NFProjectSystem.CSharp.targets')" />
<ProjectExtensions>
<ProjectCapabilities>
<ProjectConfigurationsDeclaredAsItems />
</ProjectCapabilities>
</ProjectExtensions>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,5 @@
<package id="nanoFramework.System.Net.Http.Server" version="1.5.104" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Text" version="1.2.37" targetFramework="netnano1.0" />
<package id="nanoFramework.System.Threading" version="1.1.19" targetFramework="netnano1.0" />
<package id="nanoFramework.WebServer" version="1.2.1" targetFramework="netnano1.0" />
<package id="nanoFramework.Windows.Storage" version="1.5.33" targetFramework="netnano1.0" />
<package id="nanoFramework.Windows.Storage.Streams" version="1.14.24" targetFramework="netnano1.0" />
<package id="nanoFramework.WebServer.FileSystem" version="1.2.3" targetFramework="netnano1.0" />
</packages>
Loading

0 comments on commit 60e7cc1

Please sign in to comment.