using System;
using System.Collections.Generic;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Crestron.SimplSharp.WebScripting
{
/// Mock HttpCwsServer class for HTTP web server functionality
public class HttpCwsServer : IDisposable
{
private HttpListener? _httpListener;
private bool _listening;
private readonly Dictionary _routes = new Dictionary();
/// Gets or sets the port number
public int Port { get; set; }
/// Gets whether the server is listening
public bool Listening => _listening;
/// Initializes a new instance of HttpCwsServer
public HttpCwsServer()
{
Port = 80;
}
/// Initializes a new instance of HttpCwsServer
/// Port number to listen on
public HttpCwsServer(int port)
{
Port = port;
}
/// Starts the HTTP server
/// True if started successfully
public bool Start()
{
if (_listening)
return true;
try
{
_httpListener = new HttpListener();
_httpListener.Prefixes.Add($"http://+:{Port}/");
_httpListener.Start();
_listening = true;
_ = Task.Run(ProcessRequestsAsync);
return true;
}
catch (Exception)
{
return false;
}
}
/// Stops the HTTP server
/// True if stopped successfully
public bool Stop()
{
if (!_listening)
return true;
try
{
_listening = false;
_httpListener?.Stop();
_httpListener?.Close();
return true;
}
catch (Exception)
{
return false;
}
}
/// Adds a route handler
/// Route path
/// Handler for the route
public void AddRoute(string route, IHttpCwsHandler handler)
{
_routes[route.ToLowerInvariant()] = handler;
}
/// Removes a route handler
/// Route path to remove
public void RemoveRoute(string route)
{
_routes.Remove(route.ToLowerInvariant());
}
/// Unregisters a route handler
/// Route path to unregister
public void Unregister(string route)
{
RemoveRoute(route);
}
private async Task ProcessRequestsAsync()
{
while (_listening && _httpListener != null)
{
try
{
var context = await _httpListener.GetContextAsync();
_ = Task.Run(() => HandleRequest(context));
}
catch (HttpListenerException)
{
// Listener was stopped
break;
}
catch (ObjectDisposedException)
{
// Listener was disposed
break;
}
catch (Exception)
{
// Handle other exceptions
continue;
}
}
}
private void HandleRequest(HttpListenerContext context)
{
try
{
var request = context.Request;
var response = context.Response;
var path = request.Url?.AbsolutePath?.ToLowerInvariant() ?? "/";
var cwsContext = new HttpCwsContext(context);
if (_routes.TryGetValue(path, out var handler))
{
handler.ProcessRequest(cwsContext);
}
else
{
// Default 404 response
response.StatusCode = 404;
var buffer = Encoding.UTF8.GetBytes("Not Found");
response.ContentLength64 = buffer.Length;
response.OutputStream.Write(buffer, 0, buffer.Length);
}
response.Close();
}
catch (Exception)
{
// Handle request processing errors
try
{
context.Response.StatusCode = 500;
context.Response.Close();
}
catch
{
// Ignore errors when closing response
}
}
}
/// Disposes the HttpCwsServer
public void Dispose()
{
Stop();
_httpListener?.Close();
}
}
/// Mock HttpCwsContext class representing an HTTP request/response context
public class HttpCwsContext
{
private readonly HttpListenerContext _context;
/// Gets the HTTP request
public HttpCwsRequest Request { get; }
/// Gets the HTTP response
public HttpCwsResponse Response { get; }
/// Initializes a new instance of HttpCwsContext
/// Underlying HttpListenerContext
public HttpCwsContext(HttpListenerContext context)
{
_context = context;
Request = new HttpCwsRequest(context.Request);
Response = new HttpCwsResponse(context.Response);
}
}
/// Mock HttpCwsRequest class representing an HTTP request
public class HttpCwsRequest
{
private readonly HttpListenerRequest _request;
/// Gets the HTTP method
public string HttpMethod => _request.HttpMethod;
/// Gets the request URL
public Uri? Url => _request.Url;
/// Gets the request headers
public System.Collections.Specialized.NameValueCollection Headers => _request.Headers;
/// Gets the query string
public System.Collections.Specialized.NameValueCollection QueryString => _request.QueryString;
/// Gets the content type
public string? ContentType => _request.ContentType;
/// Gets the content length
public long ContentLength => _request.ContentLength64;
/// Gets the input stream
public Stream InputStream => _request.InputStream;
/// Initializes a new instance of HttpCwsRequest
/// Underlying HttpListenerRequest
public HttpCwsRequest(HttpListenerRequest request)
{
_request = request;
}
/// Gets the request body as a string
/// Request body content
public string GetRequestBodyAsString()
{
using var reader = new StreamReader(InputStream, Encoding.UTF8);
return reader.ReadToEnd();
}
}
/// Mock HttpCwsResponse class representing an HTTP response
public class HttpCwsResponse
{
private readonly HttpListenerResponse _response;
/// Gets or sets the status code
public int StatusCode
{
get => _response.StatusCode;
set => _response.StatusCode = value;
}
/// Gets or sets the status description
public string StatusDescription
{
get => _response.StatusDescription;
set => _response.StatusDescription = value;
}
/// Gets or sets the content type
public string? ContentType
{
get => _response.ContentType;
set => _response.ContentType = value;
}
/// Gets or sets the content length
public long ContentLength
{
get => _response.ContentLength64;
set => _response.ContentLength64 = value;
}
/// Gets the response headers
public WebHeaderCollection Headers => _response.Headers;
/// Gets the output stream
public Stream OutputStream => _response.OutputStream;
/// Initializes a new instance of HttpCwsResponse
/// Underlying HttpListenerResponse
public HttpCwsResponse(HttpListenerResponse response)
{
_response = response;
}
/// Writes a string to the response
/// Content to write
public void Write(string content)
{
var buffer = Encoding.UTF8.GetBytes(content);
ContentLength = buffer.Length;
OutputStream.Write(buffer, 0, buffer.Length);
}
/// Writes bytes to the response
/// Buffer to write
/// Offset in buffer
/// Number of bytes to write
public void Write(byte[] buffer, int offset, int count)
{
OutputStream.Write(buffer, offset, count);
}
/// Ends the response
public void End()
{
try
{
_response.Close();
}
catch (Exception)
{
// Ignore exceptions during close
}
}
}
/// Interface for HTTP request handlers
public interface IHttpCwsHandler
{
/// Processes an HTTP request
/// HTTP context
void ProcessRequest(HttpCwsContext context);
}
/// Mock HttpCwsRoute class for route management
public class HttpCwsRoute
{
/// Gets or sets the route path
public string Path { get; set; } = string.Empty;
/// Gets or sets the HTTP method
public string Method { get; set; } = "GET";
/// Gets or sets the route handler
public IHttpCwsHandler? Handler { get; set; }
/// Initializes a new instance of HttpCwsRoute
public HttpCwsRoute()
{
}
/// Initializes a new instance of HttpCwsRoute
/// Route path
/// Route handler
public HttpCwsRoute(string path, IHttpCwsHandler handler)
{
Path = path;
Handler = handler;
}
/// Initializes a new instance of HttpCwsRoute
/// Route path
/// HTTP method
/// Route handler
public HttpCwsRoute(string path, string method, IHttpCwsHandler handler)
{
Path = path;
Method = method;
Handler = handler;
}
}
/// Mock HTTP CWS route collection
public class HttpCwsRouteCollection
{
private readonly List _routes = new List();
/// Adds a route
/// Route to add
public void Add(HttpCwsRoute route)
{
_routes.Add(route);
}
/// Removes a route
/// Route to remove
public void Remove(HttpCwsRoute route)
{
_routes.Remove(route);
}
/// Clears all routes
public void Clear()
{
_routes.Clear();
}
/// Gets route count
public int Count => _routes.Count;
}
/// Mock HTTP CWS request event args
public class HttpCwsRequestEventArgs : EventArgs
{
/// Gets the HTTP context
public HttpCwsContext Context { get; private set; }
/// Initializes new instance
/// HTTP context
public HttpCwsRequestEventArgs(HttpCwsContext context)
{
Context = context;
}
}
}