aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2021-05-12 09:19:59 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2021-05-12 09:19:59 -0400
commit738833d70c8d6cca3bbf9efe0c8dd24ed0395dde (patch)
tree2b7a565b3a9753f9aa78defcbe2ba57805d51ee7
parenta213818a689e41df697d1b2baf6864fc62859fdb (diff)
downloadlevitating-738833d70c8d6cca3bbf9efe0c8dd24ed0395dde.tar.gz
levitating-738833d70c8d6cca3bbf9efe0c8dd24ed0395dde.zip
Added post handling to the captain. Improved the query utilities for extracting values from a query string. Added a redirect template for html.
-rw-r--r--captain/levitating-captain.prj65
-rw-r--r--captain/postutils.f9045
-rw-r--r--captain/queryutils.f9034
-rw-r--r--captain/templates/redirect.html10
-rw-r--r--captain/web.f9045
5 files changed, 171 insertions, 28 deletions
diff --git a/captain/levitating-captain.prj b/captain/levitating-captain.prj
index 261c717..0f996ef 100644
--- a/captain/levitating-captain.prj
+++ b/captain/levitating-captain.prj
@@ -10,107 +10,116 @@
"Folders":[],
"Name":"+bin",
"Files":[{
- "filename":"bin/local.conf",
+ "filename":".\\bin\\local.conf",
"enabled":"1"
},{
- "filename":"bin/startlight.sh",
+ "filename":".\\bin\\startlight.sh",
"enabled":"1"
}]
},{
"Folders":[],
"Name":"+common",
"Files":[{
- "filename":"../common/jessl.f90",
+ "filename":"..\\common\\jessl.f90",
"enabled":"1"
},{
- "filename":"../common/network.F90",
+ "filename":"..\\common\\network.F90",
"enabled":"1"
},{
- "filename":"../common/protocol.f90",
+ "filename":"..\\common\\protocol.f90",
"enabled":"1"
},{
- "filename":"../common/request.f90",
+ "filename":"..\\common\\request.f90",
"enabled":"1"
},{
- "filename":"../common/utilities.F90",
+ "filename":"..\\common\\utilities.F90",
"enabled":"1"
},{
- "filename":"../common/wsa.f90",
+ "filename":"..\\common\\wsa.f90",
"enabled":"0"
}]
},{
"Folders":[],
"Name":"+example",
"Files":[{
- "filename":"example/levitating.conf",
+ "filename":".\\example\\levitating.conf",
"enabled":"1"
}]
},{
"Folders":[],
"Name":"+sql",
"Files":[{
- "filename":"sql/create.sql",
+ "filename":".\\sql\\create.sql",
"enabled":"1"
},{
- "filename":"sql/scan_instructions.sh",
+ "filename":".\\sql\\scan_instructions.sh",
"enabled":"1"
}]
},{
"Folders":[],
"Name":"+templates",
"Files":[{
- "filename":"templates/index.gmi",
+ "filename":".\\templates\\index.gmi",
"enabled":"1"
},{
- "filename":"templates/index.html",
+ "filename":".\\templates\\index.html",
+ "enabled":"1"
+ },{
+ "filename":".\\templates\\redirect.html",
"enabled":"1"
}]
}],
"Name":"+levitating-captain (levitating-captain)",
"Files":[{
- "filename":"api.f90",
+ "filename":".\\api.f90",
+ "enabled":"1"
+ },{
+ "filename":".\\captain.f90",
+ "enabled":"1"
+ },{
+ "filename":".\\config.f90",
"enabled":"1"
},{
- "filename":"captain.f90",
+ "filename":".\\db.f90",
"enabled":"1"
},{
- "filename":"config.f90",
+ "filename":".\\external.f90",
"enabled":"1"
},{
- "filename":"db.f90",
+ "filename":".\\gemini.f90",
"enabled":"1"
},{
- "filename":"external.f90",
+ "filename":".\\http.f90",
"enabled":"1"
},{
- "filename":"gemini.f90",
+ "filename":".\\launch.f90",
"enabled":"1"
},{
- "filename":"http.f90",
+ "filename":".\\log.f90",
"enabled":"1"
},{
- "filename":"launch.f90",
+ "filename":".\\postutils.f90",
"enabled":"1"
},{
- "filename":"log.f90",
+ "filename":".\\queryutils.f90",
"enabled":"1"
},{
- "filename":"requtils.f90",
+ "filename":".\\requtils.f90",
"enabled":"1"
},{
- "filename":"response.f90",
+ "filename":".\\response.f90",
"enabled":"1"
},{
- "filename":"special.f90",
+ "filename":".\\special.f90",
"enabled":"1"
},{
- "filename":"sqlite.f90",
+ "filename":".\\sqlite.f90",
"enabled":"1"
},{
- "filename":"template.f90",
+ "filename":".\\template.f90",
"enabled":"1"
},{
- "filename":"web.f90",
+ "filename":".\\web.f90",
"enabled":"1"
}]
},
diff --git a/captain/postutils.f90 b/captain/postutils.f90
new file mode 100644
index 0000000..c5af8bd
--- /dev/null
+++ b/captain/postutils.f90
@@ -0,0 +1,45 @@
+module http_post_utilities
+implicit none
+
+ character(*), parameter::content_type_required = "application/x-www-form-urlencoded"
+
+contains
+
+ function read_post_contents() result(res)
+ use query_utilities, only: query
+ implicit none
+
+ type(query)::res
+
+ character(len=:), allocatable::transfered
+ character(256)::header_info
+ integer::content_length, istat, i
+
+ call get_environment_variable("CONTENT_LENGTH", header_info, status=istat)
+ if(istat == 0) then
+ read(header_info, '(I8)') content_length
+ else
+ content_length = 0
+ end if
+
+ call get_environment_variable("CONTENT_TYPE", header_info, status=istat)
+ if(content_length > 0 .and. &
+ istat == 0 .and. &
+ trim(header_info) /= content_type_required) &
+ then
+
+ allocate(character(len=content_length) :: transfered)
+
+ do i = 1, content_length
+ read(*, '(A1)', advance='no') transfered(i:i)
+ end do
+
+ call res%init(transfered)
+
+ deallocate(transfered)
+
+ end if
+
+ end function read_post_contents
+
+end module http_post_utilities \ No newline at end of file
diff --git a/captain/queryutils.f90 b/captain/queryutils.f90
index c6b5d83..5e97023 100644
--- a/captain/queryutils.f90
+++ b/captain/queryutils.f90
@@ -24,6 +24,10 @@ implicit none
procedure :: init => query_init
procedure :: destroy => query_destroy
procedure :: component_count => query_component_count
+ procedure :: get_value_by_index => get_query_value_from_index
+ procedure :: get_value_by_key => get_query_value_from_key
+
+ generic, public :: get_value => get_value_by_index, get_value_by_key
end type query
@@ -173,4 +177,34 @@ contains
end subroutine query_destroy
+ function get_query_value_from_index(self, i) result(res)
+ implicit none
+
+ class(query), intent(in)::self
+ integer, intent(in)::i
+ character(len=:), pointer::res
+
+ if(i <= self%component_count()) then
+ res => self%components(i)%value
+ end if
+
+ end function get_query_value_from_index
+
+ function get_query_value_from_key(self, k) result(res)
+ implicit none
+
+ class(query), intent(in)::self
+ character(len=*), intent(in)::k
+ character(len=:), pointer::res
+
+ integer::i
+
+ do i = 1, self%component_count()
+ if(associated(self%components(i)%key) .and. self%components(i)%key == trim(k)) then
+ res => get_query_value_from_index(self, i)
+ end if
+ end do
+
+ end function get_query_value_from_key
+
end module query_utilities
diff --git a/captain/templates/redirect.html b/captain/templates/redirect.html
new file mode 100644
index 0000000..dec695f
--- /dev/null
+++ b/captain/templates/redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <meta charset="utf-8"/>
+ <meta http-equiv="Refresh" content="0; url='{{ base_url }}/{{ destination }}'" />
+ <title>Command Received</title>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/captain/web.f90 b/captain/web.f90
index 0f741d8..57f57f9 100644
--- a/captain/web.f90
+++ b/captain/web.f90
@@ -650,12 +650,57 @@ contains
use server_response, only:request, response
use http, only: HTTP_CODE_SUCCESS, HTTP_CODE_NOTFOUND
use request_utils, only: get_job_page_title, handle_instruction_command
+ use http_post_utilities
+ use query_utilities, only: query
implicit none
type(request), intent(in)::req
type(response)::resp
+ type(query)::posted
+
+ character(1024)::template_file
+ type(template)::page
+
+ character(64)::category, second
+
+ posted = read_post_contents()
+ if(posted%component_count() > 0) then
+
+ ! We will immediately redirect after the command is handled
+ call template_filepath("redirect.html", template_file)
+ call page%init(trim(template_file))
+
+ ! Handle based on category
+ call req%path_component(1, category)
+ if(trim(category) == "players") then
+ call req%path_component(2, second)
+
+ ! Add a player
+ if(trim(second) == "add.html") then
+
+ call add_player_db(posted%get_value("name"))
+ call page%assign('destination', 'players.html')
+
+ end if
+
+ end if
+
+ ! Handle the template
+ call page%assign('base_url', req%server)
+ call page%render()
+ call write_log("Finalizing response", LOG_INFO)
+ resp%temporary_file = .true.
+ resp%body_filename => page%output_filename
+ resp%body_mimetype = "text/html"
+
+ call posted%destroy()
+
+ else
+ resp%code = 500
+
+ end if
end function handle_post