aboutsummaryrefslogtreecommitdiff
path: root/captain/gemini.f90
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2021-03-27 16:50:20 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2021-03-27 16:50:20 -0400
commitfd9077056f7f33c60b218636ead0644d42e75a09 (patch)
tree9010b2d5ed8d22fa1e571cdec79f8a6f0c30d66c /captain/gemini.f90
parent0b8ec300ca4f2f2c3ce09d14ac1eed5478ea6420 (diff)
downloadlevitating-fd9077056f7f33c60b218636ead0644d42e75a09.tar.gz
levitating-fd9077056f7f33c60b218636ead0644d42e75a09.zip
Minor cleanup of the template code. Started on main program handling requests.
Diffstat (limited to 'captain/gemini.f90')
-rw-r--r--captain/gemini.f90131
1 files changed, 131 insertions, 0 deletions
diff --git a/captain/gemini.f90 b/captain/gemini.f90
new file mode 100644
index 0000000..ce7b984
--- /dev/null
+++ b/captain/gemini.f90
@@ -0,0 +1,131 @@
+module gemini
+implicit none
+
+contains
+
+ subroutine read_request(ssl, req)
+ use jessl, only: ssl_read
+ use iso_c_binding
+ implicit none
+
+ type(c_ptr)::ssl
+ character(*), intent(out)::req
+
+ character, dimension(64)::buf
+ integer::bufread
+
+ integer::i, j
+
+ req = " "
+ i = 1
+
+ bufread = ssl_read(ssl, buf)
+ do while(bufread > 0)
+
+ do j = 1, bufread
+ if(buf(j) == c_new_line) then
+ exit
+ end if
+
+ if(buf(j) /= c_carriage_return) then
+ req(i:i) = buf(j)
+ i = i + 1
+ end if
+
+ end do
+
+ if(buf(j) == c_new_line) then
+ exit
+ end if
+
+ bufread = ssl_read(ssl, buf)
+ end do
+
+ end subroutine read_request
+
+ subroutine handle_request()
+ use jessl
+ use iso_c_binding
+ use config
+ use iso_fortran_env
+ implicit none
+
+ ! For our TLS connection
+ type(c_ptr)::ctx
+ type(c_ptr)::method
+ type(c_ptr)::ssl
+ integer(kind=c_long)::res
+
+ ! Requested file
+ character(1024)::request
+ character(512)::mimetype
+
+ call library_init()
+
+ method = tls_server_method()
+ ctx = ctx_new(method)
+
+ if(.not. C_ASSOCIATED(ctx)) then
+ call write_log("Context failed")
+ return
+ end if
+
+ ! Seems to be a dummy now...
+ !res = ctx_set_ecdh_auto(ctx, 1)
+
+ if(.not. ctx_use_certificate_file(ctx, trim(pubcert), SSL_FILETYPE_PEM)) then
+ call write_log("Cert file failed")
+ call write_log("Public: "//trim(pubcert))
+ !call print_error()
+ return
+ end if
+
+ if(.not. ctx_use_private_key_file(ctx, trim(privcert), SSL_FILETYPE_PEM)) then
+ call write_log("Cert file failed")
+ call write_log("Private: "//trim(privcert))
+ !call print_error()
+ return
+ end if
+
+ ssl = ssl_new(ctx)
+
+ call write_log("Initiating connection")
+
+ ! So this is a GNU Extension...
+ res = set_read_fd(ssl, fnum(input_unit))
+ if(res /= 1) then
+ call write_log("set rfd failed")
+ !call print_error()
+ return
+ end if
+
+ res = set_write_fd(ssl, fnum(output_unit))
+ if(res /= 1) then
+ call write_log("set wfd failed")
+ !call print_error()
+ return
+ end if
+
+ res = ssl_accept(ssl)
+ if(res <= 0) then
+ call write_log("ssl_accept failed")
+ !call print_error()
+ return
+ end if
+
+ call write_log("Handling read_request")
+
+ ! Do the actual protocol nonsense
+ call read_request(ssl, request)
+
+ call write_log("Request is "//trim(request))
+
+ ! If it ends in a slash, let's manually and silently add "index.gmi"
+ if(request(len_trim(request):len_trim(request)) == "/") then
+ request = trim(request)//"index.gmi"
+ end if
+
+
+ end subroutine handle_request
+
+end module gemini \ No newline at end of file