Skip to content

Commit

Permalink
Add support for detaching server socket (#11)
Browse files Browse the repository at this point in the history
  • Loading branch information
andersjohnsen authored Dec 16, 2021
1 parent 5c6b658 commit a696851
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 24 deletions.
16 changes: 16 additions & 0 deletions src/connection.toit
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import reader
import writer
import net
import net.tcp

import .request
Expand Down Expand Up @@ -171,3 +172,18 @@ class ContentLengthWriter implements BodyWriter:
close:
if remaining_length_ != 0:
connection_.socket_.close_write

class DetachedSocket_ implements tcp.Socket:
socket_/tcp.Socket
reader_/reader.Reader?

constructor .socket_ .reader_:

read -> ByteArray?: return reader_.read
write data from=0 to=data.size: return socket_.write data from to
close_write: return socket_.close_write
close: return socket_.close
local_address -> net.SocketAddress: return socket_.local_address
peer_address -> net.SocketAddress: return socket_.peer_address
set_no_delay enabled/bool: socket_.set_no_delay enabled
mtu -> int: return socket_.mtu
18 changes: 1 addition & 17 deletions src/response.toit
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
// Use of this source code is governed by an MIT-style license that can be
// found in the LICENSE file.
import net
import net.tcp
import reader
import writer
Expand All @@ -24,19 +23,4 @@ class Response:

// Return a reader & writer object, used to send raw data on the connection.
detach -> tcp.Socket:
return DetachedSocket connection_.socket_ body

class DetachedSocket implements tcp.Socket:
socket_/tcp.Socket
reader_/reader.Reader?

constructor .socket_ .reader_:

read -> ByteArray?: return reader_.read
write data from=0 to=data.size: return socket_.write data from to
close_write: return socket_.close_write
close: return socket_.close
local_address -> net.SocketAddress: return socket_.local_address
peer_address -> net.SocketAddress: return socket_.peer_address
set_no_delay enabled/bool: socket_.set_no_delay enabled
mtu -> int: return socket_.mtu
return DetachedSocket_ connection_.socket_ body
26 changes: 19 additions & 7 deletions src/server.toit
Original file line number Diff line number Diff line change
Expand Up @@ -57,41 +57,48 @@ class Server:
--root_certificates=root_certificates_

connection := Connection socket
detached := false
try:
address := socket.peer_address
logger := logger_.with_tag "peer" address
logger.debug "client connected"
e := catch:
run_connection_ connection handler logger
detached = run_connection_ connection handler logger
close_logger := e ? logger.with_tag "reason" e : logger
close_logger.debug "client disconnected"
if detached:
close_logger.debug "client socket detached"
else:
close_logger.debug "client disconnected"
finally:
socket.close
if not detached: socket.close

run_connection_ connection/Connection handler/Lambda logger/log.Logger:
run_connection_ connection/Connection handler/Lambda logger/log.Logger -> bool:
while true:
request := null
with_timeout read_timeout:
request = connection.read_request
if not request: return
if not request: return false
request_logger := logger.with_tag "path" request.path
request_logger.debug "incoming request"
writer ::= ResponseWriter_ connection request_logger
writer ::= ResponseWriter_ connection request request_logger
catch --trace=(: it != DEADLINE_EXCEEDED_ERROR):
handler.call request writer
// Drain unread content to get allow the connection to be reused.
if writer.detached_: return true
request.drain
writer.close

class ResponseWriter_ implements ResponseWriter:
static VERSION ::= "HTTP/1.1"

connection_/Connection
request_/Request
logger_/log.Logger
headers_/Headers
body_writer_/BodyWriter? := null
detached_/bool := false

constructor .connection_ .logger_:
constructor .connection_ .request_ .logger_:
headers_ = Headers

headers -> Headers:
Expand All @@ -116,7 +123,12 @@ class ResponseWriter_ implements ResponseWriter:
write_headers_ STATUS_OK
body_writer_.close

detach -> tcp.Socket:
detached_ = true
return DetachedSocket_ connection_.socket_ request_.body

interface ResponseWriter:
headers -> Headers
write_headers status_code/int
write data
detach -> tcp.Socket
2 changes: 2 additions & 0 deletions src/status_codes.toit
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@
// Use of this source code is governed by an MIT-style license that can be
// found in the LICENSE file.
STATUS_SWITCHING_PROTOCOLS ::= 101
STATUS_OK ::= 200

status_messages_/Map ::= {
STATUS_OK: "OK",
STATUS_SWITCHING_PROTOCOLS: "Switching Protocols",
}

status_message status_code/int -> string:
Expand Down

0 comments on commit a696851

Please sign in to comment.