A => access.log +0 -0
A => readme.txt +16 -0
@@ 1,16 @@
+25.11.2020
+----------
+
+simple http server written in Tcl just for experimental purposes.
+it doesn't have any advantages over thttpd or darkhttpd (i highly recommend this to use).
+nearly 100 lines
+
+features
+-html serve (wow)
+-route designing
+-directory viewing
+-404 page
+-access logging
+
+TODO (maybe)
+-image and other mime types support<
\ No newline at end of file
A => server.tcl +107 -0
@@ 1,107 @@
+# simple web server attempt
+# 18.11.2020
+# with tcl 8.6.9
+
+# this is main root holder
+# when something is read on server, ::route changes
+set ::route ""
+set ::okHeader {
+ HTTP/1.1 200 OK
+ Content-Type: text/html; charset=UTF-8\r\n\r\n
+}
+proc ::svStart {channel addr port} {
+ # this is for async socket read
+ fconfigure $channel -blocking 0
+ set logFile [open "access.log" "a+"]
+ # logging accesses
+ puts $logFile "[fconfigure $channel -sockname] /$::route"
+ close $logFile
+ ::svRead $channel
+ ::svWrite $channel
+}
+proc ::svRead {channel} {
+ set input [gets $channel]
+ # if you really want an icon you can change this
+ if [string match "*favicon*" $input] {
+ return 0
+ # parsing request
+ } elseif [string match "GET /* HTTP/1.1" $input] {
+ regexp "/(.*) HTTP/1.1" $input temp ::route
+ }
+}
+proc ::svWrite {channel} {
+ puts $channel $::okHeader
+ # index route "/"
+ if {$::route eq ""} {
+ set st [::returnDir]
+ puts $channel $st
+ # for directories
+ # in directories i didn't want to show folders
+ # glob -type f(ile) means that
+ } elseif [string match "*/" $::route] {
+ set st [::returnDir $::route]
+ puts $channel $st
+ # for returning file
+ # just for text files
+ # it doesn't read image or etc.
+ } elseif [string match "*\.*" $::route] {
+ set st [::returnFile $::route]
+ puts $channel $st
+ # if requested route is in user generated ::paths
+ # it returns it
+ # if it isn't there
+ # returns 404
+ } else {
+ if [info exists ::paths($::route)] {
+ puts $channel $::paths($::route)
+ } else {
+ puts $channel $::fourofour
+ }
+ }
+ # you know we always need to flush
+ flush $channel
+ after 2000 [list close $channel]
+}
+proc ::returnDir {{dir ""}} {
+ # for memoizing index.html
+ # we need to call twice
+ set index [format "%sindex.html" $dir]
+ if {[glob -nocomplain "$dir*"] eq ""} {
+ return $::fourofour
+ } elseif {[glob -nocomplain $index] ne ""} {
+ set indexFile [open $index "r"]
+ return [read $indexFile]
+ }
+ # little template engine here
+ # it's quite pathetic and hard to read
+ set pContent [string map [list {#dizin#} $dir {#dosyalar#} "[join [lmap ex [glob -type f "$dir*"] {format {<a href='/%s'>%s</a><br>} $ex $ex}] " "]"] $::dirContent]
+ return $pContent
+}
+proc ::readFile {path} {
+ # just for html files
+ # it doesn't read binary
+ set temp [open "$path" "r"]
+ return [read $temp]
+}
+proc ::returnFile {file} {
+ if [file exists $file] {
+ set file [open "$file" "rb"]
+ return [string map [list {#ic#} [read $file]] $::fileContent]
+ } else {
+ return $::fourofour
+ }
+}
+proc ::main {{port 80}} {
+ set skt [socket -server ::svStart $port]
+ vwait forever
+}
+# those three are necessary
+# if you want to add
+# just change ::paths array
+set ::dirContent [::readFile "views/dir.html"]
+set ::fourofour [::readFile "views/404.html"]
+set ::fileContent [::readFile "views/file.html"]
+array set ::paths {}
+
+# here we go again
+::main 80<
\ No newline at end of file
A => views/404.html +16 -0
@@ 1,16 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>404</title>
+</head>
+<body>
+<h1>Kardeşim sen hele nerelerde gezersin öyle</h1>
+<p>Hele Geri Dön Sen</p>
+<hr>
+<i>Tsv<br>
+Kaynak kodlarını bulabilirsiniz
+</i>
+</body>
+</html><
\ No newline at end of file
A => views/dir.html +13 -0
@@ 1,13 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>#dizin#</title>
+</head>
+ <body>
+ <p style="font-family:monospace;">
+ #dosyalar#
+ </p>
+</body>
+</html><
\ No newline at end of file
A => views/file.html +16 -0
@@ 1,16 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ </head>
+ <body>
+ <pre>
+#ic#
+ </pre>
+ <hr>
+ <i>Tsv<br>
+ Kaynak kodlarını bulabilirsiniz
+ </i>
+ </body>
+</html>