The following handlers are used during connection establishment.
graph LR
A[DataSourceHandler] --> B[TransportHandler]
B --> C[PreLoginHandler]
C --> D[LoginHandler]
The handlers will be assembled by the ConnectionExecutor
As we develop the chain of responsibilities, the implementors may need some more information from the previous handler, and may need to enhance the ConnectionRequest object with more information. The implementations can take the call and enhance the ConnectionRequest as the need arises.
The request
object being passed around in these handlers is ConnectionRequest
After each handler executes, it enriches the ConnectionRequest
with more information.
The ConnectionRequest
will be initialized with the connection string.
DataSourceHandler::Handle()
-> Parses the Data source and enriches the request object with DataSource
TransportHandler::Handle()
-> Uses the DataSource information to establish the transport connection with the server. If TCP is the protocol, then it will levarage the ConnectionString
to fetch the other parameters which govern TCP connectivity.
It will enrich the ConnectionRequest with the Stream
instance, and add more information like the Socket in case of TCP Connectivity.
A low level information like the socket, may be used later on to check for the socket being alive, or to dispose the socket.
PreloginHandler::Handle()
-> Uses the stream and the information in the connection string to negotiate FedAuth, MARS, SSL etc.
It will also decide whether to perform TLS handshake before or after Prelogin negotiation, based on the Encrypt parameter.
Prelogin handler, will enhance the request object to set parameters like Mars Enabled, SSLStream, and TDS stream.
It will also setup the layering of the TDS stream appropriately based on encryption.
LoginHandler::Handle()
-> Uses the TDS stream to send the login packet and then receive the Login acknowledgement from the server. It will leverage a bunch of other parameters in the connection string to negotiate information with the server.
The Login Handler will also make sure that we negotiate the features in the feature extension.
The LoginHandler can dynamically enhance the chain of responsibilities to add another TransportHandler, PreloginHandler and LoginHandler if the Routing information is received from the server and the last login handler can keep doing this, till the server stops routing.
Since the routing based handling is based on the response from the server, we cannot determine the chain before executing the TDS request.
sequenceDiagram
participant ConnectionExecutor
participant DataSourceHandler
participant TransportHandler
participant PreloginHandler
participant LoginHandler
ConnectionExecutor->>ConnectionRequest: Initialize with connection string
ConnectionExecutor->>DataSourceHandler: Handle()
DataSourceHandler->>ConnectionRequest: Enrich with DataSource
DataSourceHandler->>TransportHandler: Handle()
TransportHandler->>ConnectionRequest: Enrich with Stream and Socket
TransportHandler->>PreloginHandler: Handle()
PreloginHandler->>ConnectionRequest: Enrich with Mars Enabled, SSLStream, and TDS stream
PreloginHandler->>LoginHandler: Handle()
LoginHandler->>ConnectionRequest: Enrich with Login acknowledgement and feature negotiation
LoginHandler->>LoginHandler: Handle() (if Routing information is received)