michael@0: Darin Fisher michael@0: darin@netscape.com michael@0: 8/8/2001 michael@0: michael@0: HTTP DESIGN NOTES michael@0: michael@0: michael@0: CLASS BREAKDOWN michael@0: michael@0: nsHttpHandler michael@0: - implements nsIProtocolHandler michael@0: - manages preferences michael@0: - owns the authentication cache michael@0: - holds references to frequently used services michael@0: michael@0: nsHttpChannel michael@0: - implements nsIHttpChannel michael@0: - talks to the cache michael@0: - initiates http transactions michael@0: - processes http response codes michael@0: - intercepts progress notifications michael@0: michael@0: nsHttpConnection michael@0: - implements nsIStreamListener & nsIStreamProvider michael@0: - talks to the socket transport service michael@0: - feeds data to its transaction object michael@0: - routes progress notifications michael@0: michael@0: nsHttpConnectionInfo michael@0: - identifies a connection michael@0: michael@0: nsHttpTransaction michael@0: - implements nsIRequest michael@0: - encapsulates a http request and response michael@0: - parses incoming data michael@0: michael@0: nsHttpChunkedDecoder michael@0: - owned by a transaction michael@0: - removes chunked decoding michael@0: michael@0: nsHttpRequestHead michael@0: - owns a nsHttpHeaderArray michael@0: - knows how to fill a request buffer michael@0: michael@0: nsHttpResponseHead michael@0: - owns a nsHttpHeaderArray michael@0: - knows how to parse response lines michael@0: - performs common header manipulations/calculations michael@0: michael@0: nsHttpHeaderArray michael@0: - stores http "
:" pairs michael@0: michael@0: nsHttpAuthCache michael@0: - stores authentication credentials for http auth domains michael@0: michael@0: nsHttpBasicAuth michael@0: - implements nsIHttpAuthenticator michael@0: - generates BASIC auth credentials from user:pass michael@0: michael@0: michael@0: ATOMS michael@0: michael@0: nsHttp:: (header namespace) michael@0: michael@0: eg. nsHttp::Content_Length michael@0: michael@0: michael@0: TRANSACTION MODEL michael@0: michael@0: InitiateTransaction -> ActivateConnection -> AsyncWrite, AsyncRead michael@0: michael@0: The channel creates transactions, and passes them to the handler via michael@0: InitiateTransaction along with a nsHttpConnectionInfo object michael@0: identifying the requested connection. The handler either dispatches michael@0: the transaction immediately or queues it up to be dispatched later, michael@0: depending on whether or not the limit on the number of connections michael@0: to the requested server has been reached. Once the transaction can michael@0: be run, the handler looks for an idle connection or creates a new michael@0: connection, and then (re)activates the connection, assigning it the michael@0: new transaction. michael@0: michael@0: Once activated the connection ensures that it has a socket transport, michael@0: and then calls AsyncWrite and AsyncRead on the socket transport. This michael@0: begins the process of talking to the server. To minimize buffering, michael@0: socket transport thread-proxying is completely disabled (using the flags michael@0: DONT_PROXY_LISTENER | DONT_PROXY_PROVIDER | DONT_PROXY_OBSERVER with michael@0: both AsyncWrite and AsyncRead). This means that the nsHttpConnection's michael@0: OnStartRequest, OnDataAvailable, OnDataWritable, and OnStopRequest michael@0: methods will execute on the socket transport thread. michael@0: michael@0: The transaction defines (non-virtual) OnDataReadable, OnDataWritable, and michael@0: OnStopTransaction methods, which the connection calls in response to michael@0: its OnDataAvailable, OnDataWritable, and OnStopRequest methods, respectively. michael@0: The transaction owns a nsStreamListenerProxy created by the channel, which michael@0: it uses to transfer data from the socket thread over to the client's thread. michael@0: To mimize buffering, the transaction implements nsIInputStream, and passes michael@0: itself to the stream listener proxy's OnDataAvailable. In this way, we michael@0: have effectively wedged the response parsing between the socket and the michael@0: thread proxy's buffer. When read, the transaction turns around and reads michael@0: from the socket using the buffer passed to it. The transaction scans the michael@0: buffer for headers, removes them as they are detected, and copies the headers michael@0: into its nsHttpResponseHead object. The rest of the data remains in the michael@0: buffer, and is proxied over to the client's thread to be handled first by the michael@0: http channel and eventually by the client. michael@0: michael@0: There are several other major design factors, including: michael@0: michael@0: - transaction cancelation michael@0: - progress notification michael@0: - SSL tunneling michael@0: - chunked decoding michael@0: - thread safety michael@0: - premature EOF detection and transaction restarting michael@0: - pipelining (not yet implemented) michael@0: michael@0: michael@0: CACHING michael@0: michael@0: