From 4e512485c46bbb25cf84e1d60ef3844146173011 Mon Sep 17 00:00:00 2001 From: Spiros Eliopoulos Date: Sat, 12 Jan 2019 12:59:18 +0000 Subject: [PATCH] remove-handle-type-param: approach has been abandoned The handle parameter of a server connection was originally intended to support upgrades within the HTTP state machine. This approach was never actually tested for feasiblity. In the mean time a different approach of building support for upgrading into the runtime has been tested for feasiblity, and will be adopted instead. --- async/httpaf_async.mli | 4 ++-- lib/httpaf.mli | 50 ++++++++++++++++++++-------------------- lib/reqd.ml | 6 ++--- lib/server_connection.ml | 8 +++---- lwt/httpaf_lwt.ml | 3 --- lwt/httpaf_lwt.mli | 26 +++++++++++---------- 6 files changed, 48 insertions(+), 49 deletions(-) diff --git a/async/httpaf_async.mli b/async/httpaf_async.mli index 93691b53..f120624d 100644 --- a/async/httpaf_async.mli +++ b/async/httpaf_async.mli @@ -6,7 +6,7 @@ open Httpaf module Server : sig val create_connection_handler : ?config : Config.t - -> request_handler : ('a -> Fd.t Server_connection.request_handler) + -> request_handler : ('a -> Server_connection.request_handler) -> error_handler : ('a -> Server_connection.error_handler) -> ([< Socket.Address.t] as 'a) -> ([`Active], 'a) Socket.t @@ -15,7 +15,7 @@ end module Client : sig val request - : ?config : Config.t + : ?config : Config.t -> ([`Active], [< Socket.Address.t]) Socket.t -> Request.t -> error_handler : Client_connection.error_handler diff --git a/lib/httpaf.mli b/lib/httpaf.mli index 7468d830..02e93fa3 100644 --- a/lib/httpaf.mli +++ b/lib/httpaf.mli @@ -661,13 +661,13 @@ end (** {2 Request Descriptor} *) module Reqd : sig - type 'handle t + type t - val request : _ t -> Request.t - val request_body : _ t -> [`read] Body.t + val request : t -> Request.t + val request_body : t -> [`read] Body.t - val response : _ t -> Response.t option - val response_exn : _ t -> Response.t + val response : t -> Response.t option + val response_exn : t -> Response.t (** Responding @@ -679,14 +679,14 @@ module Reqd : sig See {{:https://tools.ietf.org/html/rfc7230#section-6.3} RFC7230ยง6.3} for more details. *) - val respond_with_string : _ t -> Response.t -> string -> unit - val respond_with_bigstring : _ t -> Response.t -> Bigstring.t -> unit - val respond_with_streaming : ?flush_headers_immediately:bool -> _ t -> Response.t -> [`write] Body.t + val respond_with_string : t -> Response.t -> string -> unit + val respond_with_bigstring : t -> Response.t -> Bigstring.t -> unit + val respond_with_streaming : ?flush_headers_immediately:bool -> t -> Response.t -> [`write] Body.t (** Exception Handling *) - val report_exn : _ t -> exn -> unit - val try_with : _ t -> (unit -> unit) -> (unit, exn) result + val report_exn : t -> exn -> unit + val try_with : t -> (unit -> unit) -> (unit, exn) result end (** {2 Buffer Size Configuration} *) @@ -706,12 +706,12 @@ end (** {2 Server Connection} *) module Server_connection : sig - type 'handle t + type t type error = [ `Bad_request | `Bad_gateway | `Internal_server_error | `Exn of exn ] - type 'handle request_handler = 'handle Reqd.t -> unit + type request_handler = Reqd.t -> unit type error_handler = ?request:Request.t -> error -> (Headers.t -> [`write] Body.t) -> unit @@ -719,23 +719,23 @@ module Server_connection : sig val create : ?config:Config.t -> ?error_handler:error_handler - -> 'handle request_handler - -> 'handle t + -> request_handler + -> t (** [create ?config ?error_handler ~request_handler] creates a connection handler that will service individual requests with [request_handler]. *) - val next_read_operation : _ t -> [ `Read | `Yield | `Close ] + val next_read_operation : t -> [ `Read | `Yield | `Close ] (** [next_read_operation t] returns a value describing the next operation that the caller should conduct on behalf of the connection. *) - val read : _ t -> Bigstring.t -> off:int -> len:int -> int + val read : t -> Bigstring.t -> off:int -> len:int -> int (** [read t bigstring ~off ~len] reads bytes of input from the provided range of [bigstring] and returns the number of bytes consumed by the connection. {!read} should be called after {!next_read_operation} returns a [`Read] value and additional input is available for the connection to consume. *) - val read_eof : _ t -> Bigstring.t -> off:int -> len:int -> int + val read_eof : t -> Bigstring.t -> off:int -> len:int -> int (** [read t bigstring ~off ~len] reads bytes of input from the provided range of [bigstring] and returns the number of bytes consumed by the connection. {!read} should be called after {!next_read_operation} @@ -743,19 +743,19 @@ module Server_connection : sig channel. The connection will attempt to consume any buffered input and then shutdown the HTTP parser for the connection. *) - val yield_reader : _ t -> (unit -> unit) -> unit + val yield_reader : t -> (unit -> unit) -> unit (** [yield_reader t continue] registers with the connection to call [continue] when reading should resume. {!yield_reader} should be called after {next_read_operation} returns a [`Yield] value. *) - val next_write_operation : _ t -> [ + val next_write_operation : t -> [ | `Write of Bigstring.t IOVec.t list | `Yield | `Close of int ] (** [next_write_operation t] returns a value describing the next operation that the caller should conduct on behalf of the connection. *) - val report_write_result : _ t -> [`Ok of int | `Closed] -> unit + val report_write_result : t -> [`Ok of int | `Closed] -> unit (** [report_write_result t result] reports the result of the latest write attempt to the connection. {report_write_result} should be called after a call to {next_write_operation} that returns a [`Write buffer] value. @@ -767,29 +767,29 @@ module Server_connection : sig {- [`Closed] indicates that the output destination will no longer accept bytes from the write processor. }} *) - val yield_writer : _ t -> (unit -> unit) -> unit + val yield_writer : t -> (unit -> unit) -> unit (** [yield_writer t continue] registers with the connection to call [continue] when writing should resume. {!yield_writer} should be called after {next_write_operation} returns a [`Yield] value. *) - val report_exn : _ t -> exn -> unit + val report_exn : t -> exn -> unit (** [report_exn t exn] reports that an error [exn] has been caught and that it has been attributed to [t]. Calling this function will switch [t] into an error state. Depending on the state [t] is transitioning from, it may call its error handler before terminating the connection. *) - val is_closed : _ t -> bool + val is_closed : t -> bool (** [is_closed t] is [true] if both the read and write processors have been shutdown. When this is the case {!next_read_operation} will return [`Close _] and {!next_write_operation} will do the same will return a [`Write _] until all buffered output has been flushed. *) - val error_code : _ t -> error option + val error_code : t -> error option (** [error_code t] returns the [error_code] that caused the connection to close, if one exists. *) (**/**) - val shutdown : _ t -> unit + val shutdown : t -> unit (**/**) end diff --git a/lib/reqd.ml b/lib/reqd.ml index 42635faf..6696572d 100644 --- a/lib/reqd.ml +++ b/lib/reqd.ml @@ -34,7 +34,7 @@ type error = [ `Bad_request | `Bad_gateway | `Internal_server_error | `Exn of exn ] -type 'handle response_state = +type response_state = | Waiting of (unit -> unit) ref | Complete of Response.t | Streaming of Response.t * [`write] Body.t @@ -67,14 +67,14 @@ module Writer = Serialize.Writer * ]} * * *) -type 'handle t = +type t = { request : Request.t ; request_body : [`read] Body.t ; writer : Writer.t ; response_body_buffer : Bigstring.t ; error_handler : error_handler ; mutable persistent : bool - ; mutable response_state : 'handle response_state + ; mutable response_state : response_state ; mutable error_code : [`Ok | error ] ; mutable wait_for_first_flush : bool } diff --git a/lib/server_connection.ml b/lib/server_connection.ml index 00ed0b99..2ac7beb2 100644 --- a/lib/server_connection.ml +++ b/lib/server_connection.ml @@ -47,7 +47,7 @@ module Reader = Parse.Reader module Writer = Serialize.Writer -type 'fd request_handler = 'fd Reqd.t -> unit +type request_handler = Reqd.t -> unit type error = [ `Bad_gateway | `Bad_request | `Internal_server_error | `Exn of exn] @@ -55,13 +55,13 @@ type error = type error_handler = ?request:Request.t -> error -> (Headers.t -> [`write] Body.t) -> unit -type 'fd t = +type t = { reader : Reader.request ; writer : Writer.t ; response_body_buffer : Bigstring.t - ; request_handler : 'fd request_handler + ; request_handler : request_handler ; error_handler : error_handler - ; request_queue : 'fd Reqd.t Queue.t + ; request_queue : Reqd.t Queue.t (* invariant: If [request_queue] is not empty, then the head of the queue has already had [request_handler] called on it. *) ; wakeup_writer : (unit -> unit) list ref diff --git a/lwt/httpaf_lwt.ml b/lwt/httpaf_lwt.ml index 6a68106f..8764f55b 100644 --- a/lwt/httpaf_lwt.ml +++ b/lwt/httpaf_lwt.ml @@ -75,9 +75,6 @@ let shutdown socket command = module Config = Httpaf.Config module Server = struct - type request_handler = - Lwt_unix.file_descr Httpaf.Server_connection.request_handler - let create_connection_handler ?(config=Config.default) ~request_handler ~error_handler = fun client_addr socket -> let module Server_connection = Httpaf.Server_connection in diff --git a/lwt/httpaf_lwt.mli b/lwt/httpaf_lwt.mli index 27da8742..2967abad 100644 --- a/lwt/httpaf_lwt.mli +++ b/lwt/httpaf_lwt.mli @@ -1,24 +1,26 @@ +open Httpaf + + (* The function that results from [create_connection_handler] should be passed to [Lwt_io.establish_server_with_client_socket]. For an example, see [examples/lwt_echo_server.ml]. *) module Server : sig - type request_handler = - Lwt_unix.file_descr Httpaf.Server_connection.request_handler - val create_connection_handler - : ?config : Httpaf.Config.t - -> request_handler : (Unix.sockaddr -> request_handler) - -> error_handler : (Unix.sockaddr -> Httpaf.Server_connection.error_handler) - -> (Unix.sockaddr -> Lwt_unix.file_descr -> unit Lwt.t) + : ?config : Config.t + -> request_handler : (Unix.sockaddr -> Server_connection.request_handler) + -> error_handler : (Unix.sockaddr -> Server_connection.error_handler) + -> Unix.sockaddr + -> Lwt_unix.file_descr + -> unit Lwt.t end (* For an example, see [examples/lwt_get.ml]. *) module Client : sig val request - : ?config : Httpaf.Config.t + : ?config : Httpaf.Config.t -> Lwt_unix.file_descr - -> Httpaf.Request.t - -> error_handler : Httpaf.Client_connection.error_handler - -> response_handler : Httpaf.Client_connection.response_handler - -> [`write] Httpaf.Body.t + -> Request.t + -> error_handler : Client_connection.error_handler + -> response_handler : Client_connection.response_handler + -> [`write] Httpaf.Body.t end