aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2021-03-29 16:38:00 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2021-03-29 16:38:00 -0400
commitbe976a38f1d95258f19d94f4cf5dc4c677041ed9 (patch)
treedf8557c3d44c6dc41a29f34646d5d231d6075270
parent7614a6244d080b8c0f82da8c34ccf7a4a88fe72a (diff)
downloadlevitating-be976a38f1d95258f19d94f4cf5dc4c677041ed9.tar.gz
levitating-be976a38f1d95258f19d94f4cf5dc4c677041ed9.zip
Changed how temp files work on UNIX-y stuff. Fixed templates, which were quite broken.
-rw-r--r--captain/captian.f901
-rw-r--r--captain/config.f905
-rw-r--r--captain/external.f9017
-rw-r--r--captain/gemini.f9083
-rw-r--r--captain/template.f9091
-rw-r--r--common/utilities.F9032
6 files changed, 160 insertions, 69 deletions
diff --git a/captain/captian.f90 b/captain/captian.f90
index 24fc34c..2c3cab4 100644
--- a/captain/captian.f90
+++ b/captain/captian.f90
@@ -2,6 +2,7 @@ program captain
use captain_db
use config
use logging, only: initialize_log => initialize, logunit
+use gemini, only: handle_gemini => handle_request
implicit none
integer::mode
diff --git a/captain/config.f90 b/captain/config.f90
index 338dc4d..dc26ef4 100644
--- a/captain/config.f90
+++ b/captain/config.f90
@@ -36,6 +36,7 @@ contains
i = index(str, '=')
if(i > 0) then
+ i = i - 1 ! Remove the equal sign
v = adjustl(str(1:i))
end if
@@ -107,6 +108,10 @@ contains
call get_variable(line, cvariable)
call get_value(line, cvalue)
+
+ ! Debugging
+ ! Print *, trim(cvariable)//" => "//trim(cvalue)
+
call assign_config(trim(cvariable), trim(cvalue))
end if
diff --git a/captain/external.f90 b/captain/external.f90
index 86efe94..aa65e71 100644
--- a/captain/external.f90
+++ b/captain/external.f90
@@ -4,18 +4,23 @@ implicit none
contains
- function external_request_gemini(request) result(renderunit)
+ function external_request_gemini(request) result(disk_filename)
use page_template
+ use config, only: template_filepath
+ use logging, only: write_log
implicit none
character(*), intent(in)::request
+ character(len=:), pointer::disk_filename
integer::renderunit
character(1024)::template_file
type(template)::page
+ character(16)::log_tmp
! Open the base template
call template_filepath("index.gmi", template_file)
- call page%init(template_file)
+
+ call page%init(trim(template_file))
if(trim(request) == "/" .or. trim(request) == "/index.gmi") then
@@ -42,11 +47,11 @@ contains
call page%assign('title', 'Not Found')
end if
-
- open(newunit=renderunit, form="formatted", status="scratch", access='stream')
-
- call page%render(renderunit)
+
+ call page%render()
+ disk_filename => page%output_filename
+
end function external_request_gemini
end module external_handling \ No newline at end of file
diff --git a/captain/gemini.f90 b/captain/gemini.f90
index 31b1deb..841bcc4 100644
--- a/captain/gemini.f90
+++ b/captain/gemini.f90
@@ -1,8 +1,34 @@
module gemini
implicit none
+ private
+
+ public :: handle_request
+
contains
+ subroutine simplify_request(full_request, local_request)
+ use logging, only: write_log
+ implicit none
+
+ character(*), intent(in)::full_request
+ character(*), intent(out)::local_request
+
+ integer::i, j
+
+ ! Get the file of interest
+ i = index(full_request, "://")
+ if(i <= 0) then
+ local_request = full_request
+ else
+ j = index(full_request(i+3:len_trim(full_request)), "/")
+ local_request = full_request((i+j+2):len_trim(full_request))
+ end if
+
+ call write_log("Simplified Local Request: "//trim(local_request))
+
+ end subroutine simplify_request
+
subroutine read_request(ssl, req)
use jessl, only: ssl_read
use iso_c_binding
@@ -70,6 +96,7 @@ contains
subroutine write_file(ssl, unit_number, mimetype)
use iso_c_binding, only: c_ptr, c_carriage_return, c_new_line
use jessl, only: ssl_write
+ use logging
implicit none
type(c_ptr)::ssl
@@ -87,6 +114,28 @@ contains
end do
end subroutine write_file
+
+ subroutine write_string(ssl, string)
+ use jessl, only: ssl_write
+ use iso_c_binding, only: c_ptr
+ implicit none
+
+ type(c_ptr)::ssl
+ character(*)::string
+ character, dimension(:), allocatable::buf
+ integer::i
+
+ allocate(buf(len(string)))
+
+ do i = 1, len(string)
+ buf(i) = string(i:i)
+ end do
+
+ i = ssl_write(ssl, buf)
+
+ deallocate(buf)
+
+ end subroutine write_string
subroutine handle_request()
use jessl
@@ -94,6 +143,7 @@ contains
use config
use iso_fortran_env
use external_handling, only: external_request_gemini
+ use logging, only: write_log
implicit none
! For our TLS connection
@@ -103,13 +153,17 @@ contains
integer(kind=c_long)::res
! Requested file
- character(1024)::request
+ character(1024)::request, local_request
character(512)::mimetype
+
+ character(len=:), pointer::filename_ptr
- integer::rendered_unit
+ integer::rendered_unit, ioerror
call library_init()
+ filename_ptr => null()
+
method = tls_server_method()
ctx = ctx_new(method)
@@ -167,20 +221,33 @@ contains
call read_request(ssl, request)
call write_log("Request is "//trim(request))
+
+ call simplify_request(request, local_request)
- if(len_trim(request) .ge. 4) then
- if(request(1:4) == '/api') then
+ if(len_trim(local_request) .ge. 4) then
+ if(local_request(1:4) == '/api') then
!call handle_api_request(request)
else
- rendered_unit = external_request_gemini(request)
+ filename_ptr => external_request_gemini(local_request)
end if
else
- rendered_unit = external_request_gemini(request)
+ filename_ptr => external_request_gemini(local_request)
end if
- call write_file(ssl, rendered_unit, "text/gemini")
+ if(associated(filename_ptr)) then
+ open(newunit=rendered_unit, file=trim(filename_ptr), status="old", &
+ form="unformatted", iostat=ioerror, access="stream")
+
+ call write_log("transferring "//trim(filename_ptr))
+ call write_file(ssl, rendered_unit, "text/gemini")
- close(rendered_unit)
+ close(rendered_unit)
+
+ if(filename_ptr(1:5) == '/tmp/') then
+ call unlink(filename_ptr)
+ end if
+ deallocate(filename_ptr)
+ end if
end subroutine handle_request
diff --git a/captain/template.f90 b/captain/template.f90
index 6b5429d..f8a6625 100644
--- a/captain/template.f90
+++ b/captain/template.f90
@@ -31,6 +31,7 @@ implicit none
character(len=:), pointer::base_filename
type(variable), dimension(:), pointer::variables
+ character(len=:), pointer::output_filename
contains
@@ -39,11 +40,10 @@ implicit none
procedure :: assign_integer => template_assign_integer
procedure :: assign_string => template_assign_string
procedure :: assign_logical => template_assign_logical
- procedure :: render_unit => template_render_unit
- procedure :: render_filename => template_render_filename
+ procedure :: render => template_render
procedure :: evaluate => template_evaluate
+ procedure :: generate_output_filename => template_generate_output_filename
- generic :: render => render_unit, render_filename
generic :: assign => assign_integer, assign_string, assign_logical
end type
@@ -84,15 +84,12 @@ contains
end subroutine variable_shallow_copy
subroutine variable_set_name(self, name)
+ use logging
implicit none
class(variable)::self
character(*), intent(in)::name
-
- if(associated(self%vname)) then
- deallocate(self%vname)
- end if
-
+
allocate(character(len=max(len_trim(name), 1)) :: self%vname)
if(len_trim(name) == 0) then
self%vname = " "
@@ -140,15 +137,16 @@ contains
end subroutine variable_assign_integer
subroutine variable_assign_string(self, name, str)
+ use logging
implicit none
class(variable)::self
character(*), intent(in)::name, str
- call self%set_name(name)
+ call self%set_name(name)
self%vtype = VTYPE_STRING
call self%set_string_value(str)
-
+
end subroutine variable_assign_string
subroutine variable_assign_logical(self, name, lg)
@@ -182,6 +180,8 @@ contains
allocate(self%variables(32))
self%variables%vtype = VTYPE_NONE
+ self%output_filename => null()
+
end subroutine template_init
subroutine template_destroy(self)
@@ -196,6 +196,17 @@ contains
end subroutine template_destroy
+ subroutine template_generate_output_filename(self)
+ use utilities, only: generate_temporary_filename
+ use logging
+ implicit none
+
+ class(template)::self
+
+ self%output_filename => generate_temporary_filename()
+
+ end subroutine template_generate_output_filename
+
function template_available_variable_index(self) result(i)
implicit none
@@ -212,6 +223,9 @@ contains
! Need to expand
if(i > size(self%variables)) then
allocate(tmp(size(self%variables)+32))
+
+ tmp%vtype = VTYPE_NONE
+
do j=1, i-1
call tmp(j)%shallow_copy(self%variables(j))
end do
@@ -239,6 +253,7 @@ contains
end subroutine template_assign_integer
subroutine template_assign_string(self, name, value)
+ use logging
implicit none
class(template)::self
@@ -246,6 +261,7 @@ contains
integer::i
i = template_available_variable_index(self)
+
call self%variables(i)%assign(name, value)
end subroutine template_assign_string
@@ -259,30 +275,17 @@ contains
integer::i
i = template_available_variable_index(self)
+
call self%variables(i)%assign(name, value)
end subroutine template_assign_logical
-
- subroutine template_render_filename(self, filename)
- implicit none
-
- class(template)::self
- character(*), intent(in)::filename
- integer::unit_number
-
- open(file=filename, newunit=unit_number, status="unknown", form="formatted", action="write")
- call self%render_unit(unit_number)
-
- close(unit_number)
-
- end subroutine template_render_filename
-
- subroutine template_render_unit(self, unum)
+ subroutine template_render(self, filename)
+ use logging
implicit none
class(template)::self
- integer, intent(in)::unum
+ character(*), intent(in), optional::filename
character::this_char, last_char
character(len=2)::running_pair, closing_pair
@@ -293,14 +296,22 @@ contains
logical::writing_now
- integer::input, istat, i
-
- open(newunit=input, file=self%base_filename, status="old", form="formatted", action="read")
+ integer::input, istat, i, unum
+
+ if(present(filename)) then
+ allocate(character(len=len_trim(filename)) :: self%output_filename)
+ self%output_filename = trim(filename)
+ else
+ call self%generate_output_filename()
+ end if
+
+ open(newunit=unum, file=trim(self%output_filename), status="new", form="formatted", access="stream", action="write")
+ open(newunit=input, file=trim(self%base_filename), status="old", form="unformatted", access="stream")
writing_now = .true.
last_char = ' '
- read(input, '(A1)', iostat=istat) this_char
+ read(input, iostat=istat) this_char
do while(istat == 0)
running_pair = last_char//this_char
@@ -314,17 +325,17 @@ contains
brace_internals = ' '
- read(input, '(A1)', iostat=istat) this_char
+ read(input, iostat=istat) this_char
i = 1
- do while(istat == 0 .and. .not. (running_pair /= closing_pair))
+ do while(istat == 0 .and. (running_pair /= closing_pair))
brace_internals(i:i) = this_char
i = i + 1
last_char = this_char
- read(input, '(A1)', iostat=istat) this_char
+ read(input, iostat=istat) this_char
running_pair = last_char//this_char
end do
- brace_internals(i:i) = ' ' ! Remove trailing bracket
+ brace_internals(i-1:i-1) = ' ' ! Remove trailing bracket
brace_internals = adjustl(brace_internals)
! Simple variable
@@ -333,7 +344,7 @@ contains
if(associated(replacement)) then
do i=1, len_trim(replacement)
- write(unum, '(A1)', advance='no') replacement(i:i)
+ write(unum, '(A1)', advance='no') replacement(i:i)
end do
replacement => null() ! do not free - internal strings
end if
@@ -348,18 +359,18 @@ contains
write(unum, '(A1)', advance='no') last_char
write(unum, '(A1)', advance='no') this_char
- else
+ else if(this_char /= '{') then
write(unum, '(A1)', advance='no') this_char
-
end if
last_char = this_char
- read(input, '(A1)', iostat=istat) this_char
+ read(input, iostat=istat) this_char
end do
+ close(unum)
close(input)
- end subroutine template_render_unit
+ end subroutine template_render
function template_evaluate(self, txt) result(res)
implicit none
diff --git a/common/utilities.F90 b/common/utilities.F90
index 2e19031..3ce3363 100644
--- a/common/utilities.F90
+++ b/common/utilities.F90
@@ -122,6 +122,7 @@ contains
function generate_temporary_filename() result(fullpath)
use iso_c_binding
+ use logging
implicit none
character(len=:), pointer::fullpath
@@ -177,24 +178,13 @@ contains
res = GetTempFileName(tmp_path, c_null_ptr, 0, tmp_name)
call c_free(tmp_path)
-#else
- interface
- function tmpnam(p) bind(c, name='tmpnam')
- use iso_c_binding
- type(c_ptr), value::p
- type(c_ptr)::tmpnam
- end function tmpnam
- end interface
- type(c_ptr)::ignored
-
- tmp_name = c_malloc(int(1024, kind=c_size_t))
-
- ignored = tmpnam(tmp_name)
-#endif
-
! Convert the C Ptr to a Fortran object
clength = c_strlen(tmp_name)
+ if(clength == 0) then
+ call write_log("temp name is zero length")
+ stop
+ end if
call c_f_pointer(tmp_name, cfullpath, (/ clength /))
allocate(character(len=clength)::fullpath)
do i = 1, clength
@@ -204,6 +194,18 @@ contains
cfullpath => null()
call c_free(tmp_name)
+#else
+ character(32)::num_text
+ real::rnum
+
+ allocate(character(len=1024) :: fullpath)
+
+ call random_number(rnum)
+ write(num_text, *) abs(rnum)
+ fullpath = "/tmp/lv."//trim(adjustl(num_text))//".tmp"
+
+#endif
+
end function generate_temporary_filename
subroutine delete_file(filename)