From 1ffe5fffb44e60abcd9600943ef2fef2e7b6c4b0 Mon Sep 17 00:00:00 2001 From: mrkubax10 Date: Wed, 6 Sep 2023 20:09:20 +0200 Subject: [PATCH] Frontend: Add support for HTML templates --- frontend.pl | 152 ++++++++++++++++++++++++++++++++++++++----- static/index.html | 1 + templates/index.html | 2 +- 3 files changed, 138 insertions(+), 17 deletions(-) create mode 100644 static/index.html diff --git a/frontend.pl b/frontend.pl index 7d6e9c3..3e8b3b4 100644 --- a/frontend.pl +++ b/frontend.pl @@ -25,6 +25,16 @@ use feature qw(switch); use strict; use warnings; +sub readFullFile { + my $aFile = $_[0]; + + my $content = ""; + while(!eof($aFile)) { + $content.=readline($aFile); + } + return $content; +} + use constant { HTTP_METHOD_UNKNOWN => 0, HTTP_METHOD_GET => 1, @@ -132,6 +142,123 @@ sub sendNotImplemented { $aClient->send($response); } +sub sendNotFound { + my $aClient = $_[0]; + + my $content = "

404 Not Found

irclogger_web
"; + my $response = getBaseResponse(404, "Not Found"); + $response.="Content-Type: text/html, charset=utf-8\r\n"; + $response.="Content-Length: ".length($content)."\r\n\r\n"; + $response.=$content; + $aClient->send($response); +} + +use constant { + PREPROCESSOR_STATE_TEXT => 0, + PREPROCESSOR_STATE_VAR => 1, + PREPROCESSOR_STATE_INC => 2 +}; +sub preprocessHTML { + my $aContent = $_[0]; + my $aVariables = $_[1]; + + my $contentLength = length($aContent); + my $state = PREPROCESSOR_STATE_TEXT; + my $currentString = ""; + my $index = 0; + my $output = ""; + while($index<$contentLength) { + my $char = substr($aContent, $index++, 1); + given($state) { + when(PREPROCESSOR_STATE_TEXT) { + if($char eq "{" && $index<$contentLength) { + my $nextChar = substr($aContent, $index, 1); + if($nextChar eq "{") { + $index++; + $state = PREPROCESSOR_STATE_VAR; + next; + } + } + if($char eq "[" && $index<$contentLength) { + my $nextChar = substr($aContent, $index, 1); + if($nextChar eq "[") { + $index++; + $state = PREPROCESSOR_STATE_INC; + next; + } + } + $output.=$char; + } + when(PREPROCESSOR_STATE_VAR) { + if($char eq "}" && $index<$contentLength) { + my $nextChar = substr($aContent, $index, 1); + if($nextChar eq "}") { + $index++; + $output.=$aVariables->{$currentString}; + $currentString = ""; + $state = PREPROCESSOR_STATE_TEXT; + next; + } + } + $currentString.=$char; + } + when(PREPROCESSOR_STATE_INC) { + if($char eq "]" && $index<$contentLength) { + my $nextChar = substr($aContent, $index, 1); + if($nextChar eq "]") { + $index++; + if(open(my $file, "<", $currentString)) { + $output.=readFullFile($file); + close($file); + } + else { + $output.="[[Include file not found]"; + } + $currentString = ""; + $state = PREPROCESSOR_STATE_TEXT; + next; + } + } + $currentString.=$char; + } + } + } + return $output; +} + +sub sendTemplate { + my $aFilePath = $_[0]; + my $aClient = $_[1]; + my $aVariables = $_[2]; + + my $result = open(my $file, "<", $aFilePath); + if(!$result) { + sendNotFound($aClient); + return 0; + } + my $content = preprocessHTML(readFullFile($file), $aVariables); + close($file); + my $length = length($content); + my $response = getBaseResponse(200, "OK"); + $response.="Content-Length: $length\r\n\r\n"; + $response.=$content; + $aClient->send($response); +} + +sub handlePath { + my $aClient = $_[0]; + my $aPath = $_[1]; + my $aRequest = $_[2]; + + given($aPath) { + when("/") { + sendTemplate("templates/index.html", $aClient, {"var"=>"value"}); + return 1; + } + } + return 0; +} + sub sendResponse { my $aClient = $_[0]; my $aRequest = $_[1]; @@ -144,25 +271,19 @@ sub sendResponse { given($aRequest->{"method"}) { when(HTTP_METHOD_GET) { my $path = File::Spec->canonpath($aRequest->{"path"}); - if($path eq "/") { - $path = "/index.html"; + if($path eq "/index.html" || $path eq "/index.htm") { + $path = "/"; } - my $filePath = "templates".$path; - my $result = open(my $file, "<", $filePath); - print($filePath); - if(!$result) { - my $content = "

404 Not Found

irclogger_web
"; - my $response = getBaseResponse(404, "Not Found"); - $response.="Content-Type: text/html, charset=utf-8\r\n"; - $response.="Content-Length: ".length($content)."\r\n\r\n"; - $response.=$content; - $aClient->send($response); + if(handlePath($aClient, $path, $aRequest)) { return; } - my $content = ""; - while(!eof($file)) { - $content.=readline($file); + my $filePath = "static".$path; + my $result = open(my $file, "<", $filePath); + if(!$result) { + sendNotFound($aClient); + return; } + my $content = readFullFile($file); close($file); my $response = getBaseResponse(200, "OK"); # TODO @@ -170,7 +291,6 @@ sub sendResponse { #$response.="Content-Type: $mime\r\n"; $response.="Content-Length: ".length($content)."\r\n\r\n"; $response.=$content; - print($response); $aClient->send($response); } default { diff --git a/static/index.html b/static/index.html new file mode 100644 index 0000000..32f7201 --- /dev/null +++ b/static/index.html @@ -0,0 +1 @@ +

Hi!

diff --git a/templates/index.html b/templates/index.html index 32f7201..b12ef73 100644 --- a/templates/index.html +++ b/templates/index.html @@ -1 +1 @@ -

Hi!

+

{{var}}