Skip to content

Commit

Permalink
Embedio CLI
Browse files Browse the repository at this point in the history
  • Loading branch information
geoperez committed Apr 29, 2015
1 parent 1e62b89 commit f784a3d
Show file tree
Hide file tree
Showing 14 changed files with 226 additions and 42 deletions.
3 changes: 0 additions & 3 deletions Unosquare.Labs.EmbedIO.Command/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,6 @@
<setting name="ServerAddress" serializeAs="String">
<value>http://localhost:9696/</value>
</setting>
<setting name="HtmlRootPath" serializeAs="String">
<value>C:\unosquare\embedio\Unosquare.Labs.EmbedIO.Samples\html</value>
</setting>
<setting name="HtmlDefaultDocument" serializeAs="String">
<value>index.html</value>
</setting>
Expand Down
28 changes: 28 additions & 0 deletions Unosquare.Labs.EmbedIO.Command/Options.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using CommandLine;
using CommandLine.Text;
using System.Collections.Generic;

namespace Unosquare.Labs.EmbedIO.Command
{
internal class Options
{
// TODO: Get a JSON file?
//[ValueList(typeof (List<string>), MaximumElements = 1)]
//public IList<string> Items { get; set; }

[Option('p', "path", Required = true, HelpText = "WWW-root path.")]
public string RootPath { get; set; }

[OptionList('a', "api", Separator = ',', HelpText = "Specify assemblies to load, separated by a comma.")]
public IList<string> ApiAssemblies { get; set; }

// TODO: Add url

[HelpOption]
public string GetUsage()
{
return HelpText.AutoBuild(this,
(HelpText current) => HelpText.DefaultParsingErrorsHandler(this, current));
}
}
}
85 changes: 79 additions & 6 deletions Unosquare.Labs.EmbedIO.Command/Program.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,32 @@
namespace Unosquare.Labs.EmbedIO.Command
{
using CommandLine;
using System;
using System.Linq;
using System.Reflection;
using Unosquare.Labs.EmbedIO.Log;
using Unosquare.Labs.EmbedIO.Modules;

class Program
internal class Program
{
static void Main(string[] args)
private static readonly SimpleConsoleLog Log = new SimpleConsoleLog();

private static void Main(string[] args)
{
var options = new Options();

Console.WriteLine("Unosquare.Labs.EmbedIO Web Server");

if (!Parser.Default.ParseArguments(args, options)) return;

Console.WriteLine(" Command-Line Utility: Press any key to stop the server.");

using (var server = new WebServer(Properties.Settings.Default.ServerAddress, new SimpleConsoleLog()))
using (var server = new WebServer(Properties.Settings.Default.ServerAddress, Log))
{
if (Properties.Settings.Default.UseLocalSessionModule)
server.RegisterModule(new Modules.LocalSessionModule());
server.RegisterModule(new LocalSessionModule());

var staticFilesModule = new Modules.StaticFilesModule(Properties.Settings.Default.HtmlRootPath)
var staticFilesModule = new StaticFilesModule(options.RootPath)
{
DefaultDocument = Properties.Settings.Default.HtmlDefaultDocument,
DefaultExtension = Properties.Settings.Default.HtmlDefaultExtension,
Expand All @@ -24,10 +35,72 @@ static void Main(string[] args)

server.RegisterModule(staticFilesModule);

if (options.ApiAssemblies != null && options.ApiAssemblies.Count > 0)
{
foreach (var api in options.ApiAssemblies)
{
Log.DebugFormat("Checking API {0}", api);
LoadApi(api, server);
}
}

// start the server
server.RunAsync();
Console.ReadKey(true);
}
}

private static void LoadApi(string apiPath, WebServer server)
{
try
{
var assembly = Assembly.LoadFile(apiPath);

if (assembly == null) return;

var types = assembly.GetTypes();

// Load WebApiModules
var apiControllers =
types.Where(x => x.IsClass && !x.IsAbstract && x.IsSubclassOf(typeof (WebApiController))).ToArray();

if (apiControllers.Any())
{
server.RegisterModule(new WebApiModule());

foreach (var apiController in apiControllers)
{
server.Module<WebApiModule>().RegisterController(apiController);
Log.DebugFormat("Registering {0} WebAPI", apiController.Name);
}
}
else
{
Log.DebugFormat("{0} does not have any WebAPI", apiPath);
}

// Load WebSocketsModules
var sockerServers = types.Where(x => x.BaseType == typeof (WebSocketsServer)).ToArray();

if (sockerServers.Any())
{
server.RegisterModule(new WebSocketsModule());

foreach (var socketServer in sockerServers)
{
server.Module<WebSocketsModule>().RegisterWebSocketsServer(socketServer);
Log.DebugFormat("Registering {0} WebSocket", socketServer.Name);
}
}
else
{
Log.DebugFormat("{0} does not have any WebSocket", apiPath);
}
}
catch (Exception ex)
{
Log.Error(ex.Message);
}
}
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 0 additions & 3 deletions Unosquare.Labs.EmbedIO.Command/Properties/Settings.settings
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,6 @@
<Setting Name="ServerAddress" Type="System.String" Scope="Application">
<Value Profile="(Default)">http://localhost:9696/</Value>
</Setting>
<Setting Name="HtmlRootPath" Type="System.String" Scope="Application">
<Value Profile="(Default)">C:\unosquare\embedio\Unosquare.Labs.EmbedIO.Samples\html</Value>
</Setting>
<Setting Name="HtmlDefaultDocument" Type="System.String" Scope="Application">
<Value Profile="(Default)">index.html</Value>
</Setting>
Expand Down
15 changes: 15 additions & 0 deletions Unosquare.Labs.EmbedIO.Command/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
## EmbedIO CLI

Start any web folder or EmbedIO-enabled DLL from command line.

### Run web folder (static content only)

```
$ embediocli -p c:\wwwroot
```

### Run web folder with WebAPI or WebSocket Assembly

```
$ embediocli -p c:\wwwroot --api mywebapi.dll
```
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Unosquare.Labs.EmbedIO.Command</RootNamespace>
<AssemblyName>Unosquare.Labs.EmbedIO.Command</AssemblyName>
<AssemblyName>embediocli</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
Expand All @@ -33,7 +33,14 @@
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>favicon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="CommandLine, Version=1.9.71.2, Culture=neutral, PublicKeyToken=de6f01bd326f8c32, processorArchitecture=MSIL">
<HintPath>..\packages\CommandLineParser.1.9.71\lib\net45\CommandLine.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
Expand All @@ -43,6 +50,7 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Options.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Properties\Settings.Designer.cs">
Expand All @@ -53,17 +61,22 @@
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Unosquare.Labs.EmbedIO\Unosquare.Labs.EmbedIO.csproj">
<Project>{7d7c29b4-9493-4ebd-8f20-6fac1e7161ee}</Project>
<Name>Unosquare.Labs.EmbedIO</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="favicon.ico" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Expand Down
Binary file added Unosquare.Labs.EmbedIO.Command/favicon.ico
Binary file not shown.
4 changes: 4 additions & 0 deletions Unosquare.Labs.EmbedIO.Command/packages.config
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="CommandLineParser" version="1.9.71" targetFramework="net45" />
</packages>
26 changes: 13 additions & 13 deletions Unosquare.Labs.EmbedIO.Samples/RestApiSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,13 @@
public static class RestApiSample
{
private const string RelativePath = "/api/";
public static List<Person> People { get; private set; }

public static List<Person> People = new List<Person>
{
new Person() {Key = 1, Name = "Mario Di Vece", Age = 31, EmailAddress = "[email protected]"},
new Person() {Key = 2, Name = "Geovanni Perez", Age = 32, EmailAddress = "[email protected]"},
new Person() {Key = 3, Name = "Luis Gonzalez", Age = 29, EmailAddress = "[email protected]"},
};

/// <summary>
/// Here we add the WebApiModule to our Web Server and register our controller classes.
Expand All @@ -23,13 +29,6 @@ public static class RestApiSample
/// <param name="server">The server.</param>
public static void Setup(WebServer server)
{
People = new List<Person>()
{
new Person() {Key = 1, Name = "Mario Di Vece", Age = 31, EmailAddress = "[email protected]"},
new Person() {Key = 2, Name = "Geovanni Perez", Age = 32, EmailAddress = "[email protected]"},
new Person() {Key = 3, Name = "Luis Gonzalez", Age = 29, EmailAddress = "[email protected]"},
};

foreach (var person in People)
{
person.PhotoUrl = GetGravatarUrl(person.EmailAddress);
Expand All @@ -41,22 +40,23 @@ public static void Setup(WebServer server)

private static string GetGravatarUrl(string emailAddress)
{
return string.Format("http://www.gravatar.com/avatar/{0}.png?s=100", HashMD5(emailAddress));
return string.Format("http://www.gravatar.com/avatar/{0}.png?s=100", HashMd5(emailAddress));
}

private static string HashMD5(string input)
private static string HashMd5(string input)
{
// step 1, calculate MD5 hash from input
MD5 md5 = System.Security.Cryptography.MD5.Create();
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(input);
MD5 md5 = MD5.Create();
byte[] inputBytes = Encoding.ASCII.GetBytes(input);
byte[] hash = md5.ComputeHash(inputBytes);

// step 2, convert byte array to hex string
StringBuilder sb = new StringBuilder();
var sb = new StringBuilder();
for (int i = 0; i < hash.Length; i++)
{
sb.Append(hash[i].ToString("x2"));
}

return sb.ToString();
}

Expand Down
3 changes: 2 additions & 1 deletion Unosquare.Labs.EmbedIO.Samples/WebSocketsSample.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,15 @@ public static class WebSocketsSample
public static void Setup(WebServer server)
{
server.RegisterModule(new WebSocketsModule());
server.Module<WebSocketsModule>().RegisterWebSocketsServer<WebSocketsChatServer>("/chat");
server.Module<WebSocketsModule>().RegisterWebSocketsServer<WebSocketsChatServer>();
server.Module<WebSocketsModule>().RegisterWebSocketsServer<WebSocketsTerminalServer>("/terminal");
}
}

/// <summary>
/// Defines a very simple chat server
/// </summary>
[WebSocketHandler("/chat")]
public class WebSocketsChatServer : WebSocketsServer
{

Expand Down
17 changes: 11 additions & 6 deletions Unosquare.Labs.EmbedIO/Modules/WebApiModule.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,17 @@ public void RegisterController<T>()
if (ControllerTypes.Contains(typeof (T)))
throw new ArgumentException("Controller types must be unique within the module");

RegisterController(typeof (T));
}

/// <summary>
/// Registers the controller.
/// </summary>
public void RegisterController(Type controllerType)
{
var protoDelegate = new ResponseHandler((server, context) => true);

var methods = typeof (T).GetMethods(System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.Public)
var methods = controllerType.GetMethods(BindingFlags.Instance | BindingFlags.Public)
.Where(m => m.ReturnType == protoDelegate.Method.ReturnType
&& m.GetParameters().Select(pi => pi.ParameterType)
.SequenceEqual(protoDelegate.Method.GetParameters()
Expand All @@ -114,18 +121,16 @@ public void RegisterController<T>()
else
DelegateMap.Add(path, delegatePath); // add

var delegatePair = new Tuple<Type, MethodInfo>(typeof (T), method);
var delegatePair = new Tuple<Type, MethodInfo>(controllerType, method);
if (DelegateMap[path].ContainsKey(attribute.Verb))
DelegateMap[path][attribute.Verb] = delegatePair; // update
else
DelegateMap[path].Add(attribute.Verb, delegatePair); // add
}
}

ControllerTypes.Add(typeof (T));

ControllerTypes.Add(controllerType);
}

}

/// <summary>
Expand Down
Loading

0 comments on commit f784a3d

Please sign in to comment.