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(len_trim(request) .ge. 4) then if(request(1:4) == '/api') then !call handle_api_request(request) else call external_request_gemini(request) end if else call external_request_gemini(request) end if end subroutine handle_request end module gemini