summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoralekseiplusplus <alekseijeaves@protonmail.com>2024-06-30 21:57:33 +1000
committeralekseiplusplus <alekseijeaves@protonmail.com>2024-06-30 21:57:33 +1000
commita3bdaf37b72013fe581f108c4798137e1ea267cd (patch)
tree5200d85e5b923499a7c93ba5e4278613f3c053cf
parentd5cc926ec6c3020d2d51cacc7d14e59c558c4167 (diff)
last commit of today; expanding on configuration and modules
-rwxr-xr-xconfigure.tcl92
-rwxr-xr-xhttp-cache.tcl6
-rwxr-xr-xhttp.tcl10
-rwxr-xr-xmodules/document-viewer.tcl54
-rwxr-xr-xtcl-httpd1
-rw-r--r--tcl-httpd.conf3
-rwxr-xr-xtest.tcl22
7 files changed, 166 insertions, 22 deletions
diff --git a/configure.tcl b/configure.tcl
index 3c3a426..76fd37e 100755
--- a/configure.tcl
+++ b/configure.tcl
@@ -3,35 +3,99 @@
namespace eval http {
# The directory which files are searched for.
variable srv {/home/aleksei/www/files/}
- # hook_namespace refers to a user-created namespace.
- # It must have some things such as
- # A proc 'main' which is what the server will execute to get information.
- # A list $targets which have all the valid targets.
- variable hook_namespace {}
- namespace eval cache {
+ namespace eval cache {
variable precache {
{/fonts/}
}
}
namespace eval module {
- #variable directory {}
+ variable targets {};
source modules/template.tcl
}
}
-
+proc temp {} {
+ # Run through and bring in all targets
+ foreach i [namespace children ::http::module] {
+ set ::http::module::targets [concat $::http::module::targets $i::targets]
+ # If there are duplicate elements, then error.
+ if [expr [llength [lsort -unique $::http::module::targets]] != [llength $::http::module::targets]] {
+ error "A duplicate target coming from $i."
+ }
+ }
+}
## Validate configuration variables.
## Especially file exists content
## Especially validate the existence of necessary components in $content
-proc validate {} {
- # Two types of rules
- # The VARIABLE=value
- # For instance, SRV=/ and whatnot
- # The @ACTION Etc
- # For instance, @MODULE and @PRECACHE
+
+set config [open /etc/tcl-httpd.conf]
+
+
+## Configure the server, whilst verifying options.
+
+namespace eval temp {
+ set error_state 0;
+ set error_message "Invalid lines:";
+ set line_number 1;
+
+
+ namespace eval verify {
+ proc srv {s} {
+
+ }
+
+ proc module_path
+ }
+
+ namespace eval actions {
+ proc @MODULE {v} {
+ if [info exists ::http::configure::module_path] {
+ set path [string cat $::http::configure::module_path $v ".tcl"]
+ if { [file exists $path] && [file isFile $path] } {
+ namespace eval [string cat "::http::module::" $v] {
+ source $path
+ }
+ } else {
+ error "Fatal Error: While trying to import module '$b', file $path' doesn't exist."
+ }
+ } else {
+ error "Fatal Error: Tried to import module '$b' without a module_path"
+ }
+ }
+
+ proc @PRECACHE {a b} {
+ ::http::cache::add $b
+ }
+ }
+
+ while {[gets $config line] != -1} {
+ if [regexp {^[[:lower:]_]+=[[:alnum:][:punct:]]+$} $line] {
+ set n [string first "=" $line]
+ set a [string range start [expr n-1]]
+ set b [string range [expr n+1] end]
+ # RUN VERIFICATION
+ namespace eval ::http::configure "variable $a $b"
+ } elseif [regexp {^@[[:upper:]]+ [[:alnum:][:punct:]]+$} $line] {
+ set n [string first " " $line]
+ set a [string range start [expr n-1]]
+ set b [string range [expr n+1] end]
+ # PERFORM ACTION
+ } else {
+ append error_message " $line_number"
+ set error_state 1;
+ }
+ incr line_number;
+ }
+
+ if $error_state {
+ error "ERROR: There were multiple errors in your configuration.\n$error_message"
+ }
}
+
+## Delete the namespace afterwards.
+namespace delete temp;
diff --git a/http-cache.tcl b/http-cache.tcl
index 25e5f0d..f377770 100755
--- a/http-cache.tcl
+++ b/http-cache.tcl
@@ -27,9 +27,9 @@ namespace eval cache {
}
}
- #TODO: Pre-cache all precache files.
- foreach i $precache {
- add [string cat $::http::root $i]
+ # Process the precache
+ foreach i $::http::configure::precache {
+ add [string cat $::http::configure::srv $i]
}
}
diff --git a/http.tcl b/http.tcl
index 3995c80..7dc6dbb 100755
--- a/http.tcl
+++ b/http.tcl
@@ -40,8 +40,8 @@ namespace eval http {
]
proc server {channel address port} {
- variable hook_namespace;
- variable srv;
+ #variable hook_namespace;
+ #variable srv;
## (1) Handle first line
puts "(1)"
@@ -51,6 +51,7 @@ namespace eval http {
## (2) Get rest of packet.
set packet {}
+
while { [gets $channel line] } {
puts $line
## Check if field-line is in correct form.
@@ -80,7 +81,7 @@ namespace eval http {
## (3) Find if the file exists, or there is a hooked application.
# If file exists, then 200 OK!
- set filename [string cat $srv [request_target::file $request_target]]
+ set filename [string cat $configure::srv [request_target::file $request_target]]
if [expr [file exists $filename] && [file isfile $filename]] {
respond $channel 200 $filename
} elseif [expr [file exists [string cat $filename "index.html"]] && [file isfile [string cat $filename "index.html"]]] {
@@ -121,9 +122,8 @@ namespace eval http {
proc respond {channel status {optional {}}} {
## Import Variables
- variable srv;
variable status_codes;
- variable hook_namespace;
+
## New Variables
variable content {};
variable response {};
diff --git a/modules/document-viewer.tcl b/modules/document-viewer.tcl
new file mode 100755
index 0000000..de8f0e7
--- /dev/null
+++ b/modules/document-viewer.tcl
@@ -0,0 +1,54 @@
+## Note that this code is leftover from the beginning of this project,
+## which was originally a CGI document viewer that grew into a HTTP
+## server instead, but I plan to implement this as a module.
+## This is not at all supposed to be used right now.
+
+variable directories {articles test-one}
+
+
+
+### Content
+
+proc run {request_target} {
+
+}
+
+
+
+
+append http::content [html::start Lame!]
+
+## If directory is not queried,
+if { ([lsearch -exact [dict keys $query] "directory"] eq -1) || ([lsearch -exact $directories [dict get $query directory]] eq -1 )} {
+ append http::content "Utter failure."
+ append http::content [html::end]
+ http::respond
+ exit
+}
+
+set directory [dict get $query directory]
+
+
+
+## If document is not queried, or does not exist in our directory,
+set documents [exec ls -Q $directory]
+if { ([lsearch -exact [dict keys $query] "document"] eq -1) || ([lsearch -exact $documents [dict get $query document]] eq -1 ) } {
+ foreach a $documents {
+ append http::content [html::link $a "?directory=$directory&document=$a"]
+ }
+ append http::content [html::end]
+ http::respond
+ exit
+}
+
+
+
+## Open file
+set file [open "$directory/[dict get $query document]" r]
+
+## Output lines
+while {[gets $file line] != -1} {
+ append http::content "$line <br> "
+}
+
+append http::content [html::end]
diff --git a/tcl-httpd b/tcl-httpd
index ade8359..575a3fa 100755
--- a/tcl-httpd
+++ b/tcl-httpd
@@ -1,5 +1,6 @@
#!/bin/tclsh
+
source configure.tcl
source http.tcl
diff --git a/tcl-httpd.conf b/tcl-httpd.conf
new file mode 100644
index 0000000..efd3030
--- /dev/null
+++ b/tcl-httpd.conf
@@ -0,0 +1,3 @@
+srv=/home/aleksei/www/files/
+@MODULE template
+@PRECACHE /style.css
diff --git a/test.tcl b/test.tcl
new file mode 100755
index 0000000..290994c
--- /dev/null
+++ b/test.tcl
@@ -0,0 +1,22 @@
+#!/bin/tclsh
+
+set tests {
+ {exec curl -i http://localhost:8000}
+ {exec curl -i http://localhost:8000/style.css}
+ {exec curl -i http://localhost:8000/index.html}
+}
+
+if [expr ($argc == 0)] {
+ set j 0;
+ foreach i $tests {
+ puts "($j) : [string range $i 13 end]"
+ incr j
+ }
+} elseif [expr ($argc == 1)] {
+ set a [lindex $argv 0];
+ if { ($a >= 0) && ($a < [llength $tests]) } {
+ puts [eval [lindex $tests $a]]
+ } else {
+ puts "Argument not in range."
+ }
+}