diff --git a/src/live.jl b/src/live.jl index 72f3337..f947c03 100644 --- a/src/live.jl +++ b/src/live.jl @@ -62,6 +62,6 @@ macro app(def) end end -function serve(h::App, context, host = ip"127.0.0.1", port = 1965; kws...) - @async listen((req) -> h.warez(req), context, host, port; kws...) +function serve(h::App, host = ip"127.0.0.1", port = 1965; kws...) + @async listen((req) -> h.warez(req), host, port; kws...) end diff --git a/src/server.jl b/src/server.jl index 9c00c4d..5ecf58c 100644 --- a/src/server.jl +++ b/src/server.jl @@ -1,5 +1,5 @@ function listen(f, - context::SSLContext, + init_context, host::Union{IPAddr, String} = Sockets.localhost, port::Integer = 1965 ; @@ -9,35 +9,36 @@ function listen(f, server = Sockets.listen(Sockets.InetAddr(host, port)) verbose && @info "Listening on: $host:$port" - - return listenloop(f, server, context, connection_count, readtimeout, verbose) + return listenloop(f, server, init_context, connection_count, readtimeout, verbose) end """" Main server loop. Accepts new tcp connections and spawns async tasks to handle them." """ -function listenloop(f, server, context, connection_count, readtimeout, verbose) +function listenloop(f, server, init_context, connection_count, readtimeout, verbose) count = 1 while isopen(server) try - # @info "Ready to accept new connection" + verbose && @info "Ready to accept new connection" io = accept(server) - if io === nothing + if isnothing(io) verbose && @warn "unable to accept new connection" continue end connection_count[] += 1 + verbose && @info "$(connection_count[]) total connections" @async try - handle_connection(f, server, context, io, verbose) + handle_connection(f, server, init_context, io, verbose) catch e - if e isa Base.IOError && e.code == -54 + if e isa Base.IOError && e.code in (-54, -104) verbose && @warn "connection reset by peer (ECONNRESET)" else - @error exception=(e, stacktrace(catch_backtrace())) + @warn exception=(e, stacktrace(catch_backtrace())) end finally connection_count[] -= 1 + verbose && @info "$(connection_count[]) total connections" # handle_connection is in charge of closing the underlying io end catch e @@ -50,47 +51,43 @@ function listenloop(f, server, context, connection_count, readtimeout, verbose) end end count += 1 + verbose && @info "Responded to $(count) clients in total" end return end -function handle_connection(f, server, context, io, verbose) - client = SSLClient(context, io) - while isopen(server) && isopen(io) - try - while true - if isreadable(io) && length(client.write_buf) == 0 - # verbose && println("do_read") - if OpenSSL.do_sock_read(client) == -1 - break - end - end - if iswritable(io) && length(client.write_buf) > 0 - # verbose && println("do_write") - if OpenSSL.do_sock_write(client) == -1 - break - end - end - # verbose && println("end loop") - if OpenSSL.ssl_init_finished(client) - # verbose && println("init_finished") - # TODO: add a timeout! - while isopen(server) && isopen(io) && - (length(client.context.data) < 2 || - client.context.data[end-1:end] != UInt8['\r', '\n']) - # println("HERE") - OpenSSL.do_sock_read(client) - end - f(GeminiRequest(Connection(server, client), - Request(String(client.context.data)), - Dict())) +function handle_connection(f, server, init_context, io, verbose) + client = SSLClient(init_context(), io) + try + while isopen(server) && isopen(io) + if isreadable(io) && length(client.write_buf) == 0 + if OpenSSL.do_sock_read(client) == -1 break end end - catch e - rethrow(e) - finally - close(client) + if iswritable(io) && length(client.write_buf) > 0 + verbose && println("do_write") + if OpenSSL.do_sock_write(client) == -1 + break + end + end + if OpenSSL.ssl_init_finished(client) + verbose && println("init_finished") + # TODO: add a timeout! + while isopen(server) && isopen(io) && + (length(client.context.data) < 2 || + client.context.data[end-1:end] != UInt8['\r', '\n']) + OpenSSL.do_sock_read(client) + end + f(GeminiRequest(Connection(server, client), + Request(String(client.context.data)), + Dict())) + break + end end + catch e + rethrow(e) + finally + close(client) end end