diff options
Diffstat (limited to 'captain/gemini.f90')
-rw-r--r-- | captain/gemini.f90 | 131 |
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 |