From 738833d70c8d6cca3bbf9efe0c8dd24ed0395dde Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Wed, 12 May 2021 09:19:59 -0400 Subject: Added post handling to the captain. Improved the query utilities for extracting values from a query string. Added a redirect template for html. --- captain/levitating-captain.prj | 65 +++++++++++++++++++++++------------------ captain/postutils.f90 | 45 ++++++++++++++++++++++++++++ captain/queryutils.f90 | 34 +++++++++++++++++++++ captain/templates/redirect.html | 10 +++++++ captain/web.f90 | 45 ++++++++++++++++++++++++++++ 5 files changed, 171 insertions(+), 28 deletions(-) create mode 100644 captain/postutils.f90 create mode 100644 captain/templates/redirect.html (limited to 'captain') 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 @@ + + + + + + Command Received + + + + 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 -- cgit v1.2.3