|
@@ -10,8 +10,10 @@ using Invercargill.DataStructures;
|
|
|
*/
|
|
*/
|
|
|
|
|
|
|
|
// Display all request headers
|
|
// Display all request headers
|
|
|
-class HeadersHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class HeadersEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/headers"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var parts = new Series<string>();
|
|
var parts = new Series<string>();
|
|
|
parts.add("Request Headers:\n");
|
|
parts.add("Request Headers:\n");
|
|
|
parts.add("================\n\n");
|
|
parts.add("================\n\n");
|
|
@@ -31,8 +33,10 @@ class HeadersHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Check for user-agent header
|
|
// Check for user-agent header
|
|
|
-class UserAgentHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class UserAgentEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/user-agent"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var user_agent = http_context.request.user_agent ?? "Unknown";
|
|
var user_agent = http_context.request.user_agent ?? "Unknown";
|
|
|
|
|
|
|
|
return new HttpStringResult(@"Your User-Agent is: $user_agent");
|
|
return new HttpStringResult(@"Your User-Agent is: $user_agent");
|
|
@@ -40,8 +44,10 @@ class UserAgentHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Check content type and content length
|
|
// Check content type and content length
|
|
|
-class ContentInfoHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class ContentInfoEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/content-info"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var parts = new Series<string>();
|
|
var parts = new Series<string>();
|
|
|
parts.add("Content Information:\n");
|
|
parts.add("Content Information:\n");
|
|
|
parts.add("===================\n\n");
|
|
parts.add("===================\n\n");
|
|
@@ -57,8 +63,10 @@ class ContentInfoHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Check if header exists
|
|
// Check if header exists
|
|
|
-class CheckHeaderHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class CheckHeaderEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/check-header"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var header_name = http_context.request.get_query_or_default("name", "Accept");
|
|
var header_name = http_context.request.get_query_or_default("name", "Accept");
|
|
|
var exists = http_context.request.has_header(header_name);
|
|
var exists = http_context.request.has_header(header_name);
|
|
|
var value = http_context.request.get_header(header_name);
|
|
var value = http_context.request.get_header(header_name);
|
|
@@ -68,8 +76,10 @@ class CheckHeaderHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Set custom response headers
|
|
// Set custom response headers
|
|
|
-class CustomHeadersHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class CustomHeadersEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/custom-headers"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
return new HttpStringResult("Response with custom headers!")
|
|
return new HttpStringResult("Response with custom headers!")
|
|
|
.set_header("X-Custom-Header", "Custom-Value")
|
|
.set_header("X-Custom-Header", "Custom-Value")
|
|
|
.set_header("X-Request-Id", generate_request_id())
|
|
.set_header("X-Request-Id", generate_request_id())
|
|
@@ -79,8 +89,10 @@ class CustomHeadersHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Display all cookies
|
|
// Display all cookies
|
|
|
-class CookiesHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class CookiesEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/cookies"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var parts = new Series<string>();
|
|
var parts = new Series<string>();
|
|
|
parts.add("Request Cookies:\n");
|
|
parts.add("Request Cookies:\n");
|
|
|
parts.add("================\n\n");
|
|
parts.add("================\n\n");
|
|
@@ -105,8 +117,10 @@ class CookiesHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Get specific cookie
|
|
// Get specific cookie
|
|
|
-class GetCookieHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class GetCookieEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/get-cookie"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var name = http_context.request.get_query_or_default("name", "session");
|
|
var name = http_context.request.get_query_or_default("name", "session");
|
|
|
var value = http_context.request.get_cookie(name);
|
|
var value = http_context.request.get_cookie(name);
|
|
|
|
|
|
|
@@ -119,8 +133,10 @@ class GetCookieHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Set a cookie (via Set-Cookie header)
|
|
// Set a cookie (via Set-Cookie header)
|
|
|
-class SetCookieHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class SetCookieEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/set-cookie"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var name = http_context.request.get_query_or_default("name", "test");
|
|
var name = http_context.request.get_query_or_default("name", "test");
|
|
|
var value = http_context.request.get_query_or_default("value", "123");
|
|
var value = http_context.request.get_query_or_default("value", "123");
|
|
|
var max_age = http_context.request.get_query_or_default("max_age", "3600");
|
|
var max_age = http_context.request.get_query_or_default("max_age", "3600");
|
|
@@ -131,8 +147,10 @@ class SetCookieHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Set multiple cookies
|
|
// Set multiple cookies
|
|
|
-class SetCookiesHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class SetCookiesEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/set-cookies"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
// Note: Setting multiple cookies with the same header name requires
|
|
// Note: Setting multiple cookies with the same header name requires
|
|
|
// special handling - this example shows the approach
|
|
// special handling - this example shows the approach
|
|
|
return new HttpStringResult("Multiple cookies set!")
|
|
return new HttpStringResult("Multiple cookies set!")
|
|
@@ -143,8 +161,10 @@ class SetCookiesHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Delete a cookie
|
|
// Delete a cookie
|
|
|
-class DeleteCookieHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class DeleteCookieEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/delete-cookie"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var name = http_context.request.get_query_or_default("name", "test");
|
|
var name = http_context.request.get_query_or_default("name", "test");
|
|
|
|
|
|
|
|
return new HttpStringResult(@"Cookie '$name' deleted")
|
|
return new HttpStringResult(@"Cookie '$name' deleted")
|
|
@@ -153,8 +173,10 @@ class DeleteCookieHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Check if cookie exists
|
|
// Check if cookie exists
|
|
|
-class HasCookieHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class HasCookieEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/has-cookie"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var name = http_context.request.get_query_or_default("name", "session");
|
|
var name = http_context.request.get_query_or_default("name", "session");
|
|
|
var exists = http_context.request.has_cookie(name);
|
|
var exists = http_context.request.has_cookie(name);
|
|
|
|
|
|
|
@@ -163,8 +185,10 @@ class HasCookieHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Cookie-based session simulation
|
|
// Cookie-based session simulation
|
|
|
-class SessionHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class SessionEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/session"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var session_id = http_context.request.get_cookie("session_id");
|
|
var session_id = http_context.request.get_cookie("session_id");
|
|
|
|
|
|
|
|
if (session_id == null) {
|
|
if (session_id == null) {
|
|
@@ -187,8 +211,10 @@ Your session is active.");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// CORS headers example
|
|
// CORS headers example
|
|
|
-class CorsHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class CorsEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/cors"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var origin = http_context.request.get_header("Origin") ?? "*";
|
|
var origin = http_context.request.get_header("Origin") ?? "*";
|
|
|
|
|
|
|
|
return new HttpStringResult(@"CORS enabled for origin: $origin")
|
|
return new HttpStringResult(@"CORS enabled for origin: $origin")
|
|
@@ -200,8 +226,10 @@ class CorsHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Cache control headers
|
|
// Cache control headers
|
|
|
-class CacheHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class CacheEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/cache"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var cache_type = http_context.request.get_query_or_default("type", "public");
|
|
var cache_type = http_context.request.get_query_or_default("type", "public");
|
|
|
|
|
|
|
|
return new HttpStringResult(@"This response is cached ($cache_type cache, 1 hour)")
|
|
return new HttpStringResult(@"This response is cached ($cache_type cache, 1 hour)")
|
|
@@ -212,8 +240,10 @@ class CacheHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Content negotiation
|
|
// Content negotiation
|
|
|
-class NegotiateHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class NegotiateEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/negotiate"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
var accept = http_context.request.get_header("Accept") ?? "*/*";
|
|
var accept = http_context.request.get_header("Accept") ?? "*/*";
|
|
|
|
|
|
|
|
if (accept.contains("application/json")) {
|
|
if (accept.contains("application/json")) {
|
|
@@ -230,8 +260,10 @@ class NegotiateHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Security headers
|
|
// Security headers
|
|
|
-class SecureHandler : Object, RouteHandler {
|
|
|
|
|
- public async HttpResult handle_route(HttpContext http_context, RouteContext route_context) throws Error {
|
|
|
|
|
|
|
+class SecureEndpoint : Object, Endpoint {
|
|
|
|
|
+ public string route { get { return "/secure"; } }
|
|
|
|
|
+ public Method[] methods { owned get { return { Method.GET }; } }
|
|
|
|
|
+ public async HttpResult handle_request(HttpContext http_context, RouteInformation route) throws Error {
|
|
|
return new HttpStringResult("Response with security headers!")
|
|
return new HttpStringResult("Response with security headers!")
|
|
|
.set_header("X-Content-Type-Options", "nosniff")
|
|
.set_header("X-Content-Type-Options", "nosniff")
|
|
|
.set_header("X-Frame-Options", "DENY")
|
|
.set_header("X-Frame-Options", "DENY")
|
|
@@ -243,26 +275,28 @@ class SecureHandler : Object, RouteHandler {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void main() {
|
|
void main() {
|
|
|
- var router = new Router();
|
|
|
|
|
- var server = new Server(8083, router);
|
|
|
|
|
|
|
+ var router = new EndpointRouter()
|
|
|
|
|
+ .add_endpoint(new HeadersEndpoint())
|
|
|
|
|
+ .add_endpoint(new UserAgentEndpoint())
|
|
|
|
|
+ .add_endpoint(new ContentInfoEndpoint())
|
|
|
|
|
+ .add_endpoint(new CheckHeaderEndpoint())
|
|
|
|
|
+ .add_endpoint(new CustomHeadersEndpoint())
|
|
|
|
|
+ .add_endpoint(new CookiesEndpoint())
|
|
|
|
|
+ .add_endpoint(new GetCookieEndpoint())
|
|
|
|
|
+ .add_endpoint(new SetCookieEndpoint())
|
|
|
|
|
+ .add_endpoint(new SetCookiesEndpoint())
|
|
|
|
|
+ .add_endpoint(new DeleteCookieEndpoint())
|
|
|
|
|
+ .add_endpoint(new HasCookieEndpoint())
|
|
|
|
|
+ .add_endpoint(new SessionEndpoint())
|
|
|
|
|
+ .add_endpoint(new CorsEndpoint())
|
|
|
|
|
+ .add_endpoint(new CacheEndpoint())
|
|
|
|
|
+ .add_endpoint(new NegotiateEndpoint())
|
|
|
|
|
+ .add_endpoint(new SecureEndpoint());
|
|
|
|
|
|
|
|
- // Register routes
|
|
|
|
|
- router.get("/headers", new HeadersHandler());
|
|
|
|
|
- router.get("/user-agent", new UserAgentHandler());
|
|
|
|
|
- router.get("/content-info", new ContentInfoHandler());
|
|
|
|
|
- router.get("/check-header", new CheckHeaderHandler());
|
|
|
|
|
- router.get("/custom-headers", new CustomHeadersHandler());
|
|
|
|
|
- router.get("/cookies", new CookiesHandler());
|
|
|
|
|
- router.get("/get-cookie", new GetCookieHandler());
|
|
|
|
|
- router.get("/set-cookie", new SetCookieHandler());
|
|
|
|
|
- router.get("/set-cookies", new SetCookiesHandler());
|
|
|
|
|
- router.get("/delete-cookie", new DeleteCookieHandler());
|
|
|
|
|
- router.get("/has-cookie", new HasCookieHandler());
|
|
|
|
|
- router.get("/session", new SessionHandler());
|
|
|
|
|
- router.get("/cors", new CorsHandler());
|
|
|
|
|
- router.get("/cache", new CacheHandler());
|
|
|
|
|
- router.get("/negotiate", new NegotiateHandler());
|
|
|
|
|
- router.get("/secure", new SecureHandler());
|
|
|
|
|
|
|
+ var pipeline = new Pipeline()
|
|
|
|
|
+ .add_component(router);
|
|
|
|
|
+
|
|
|
|
|
+ var server = new Server(8083, pipeline);
|
|
|
|
|
|
|
|
print("Headers and Cookies Example Server running on port 8083\n");
|
|
print("Headers and Cookies Example Server running on port 8083\n");
|
|
|
print("Try these endpoints:\n");
|
|
print("Try these endpoints:\n");
|