1# Life of a URLRequest 2 3This document gives an overview of the browser's lower-layers for networking. 4 5Networking in the browser ranges from high level Javascript APIs like 6`fetch()`, all the way down to writing encrypted bytes on a socket. 7 8This document assumes that requests for URLs are mediated through the browser's 9[Network Service](../../services/network/README.md), and focuses on all the 10layers below the Network Service, including key points of integration. 11 12It's particularly targeted at people new to the Chrome network stack, but 13should also be useful for team members who may be experts at some parts of the 14stack, but are largely unfamiliar with other components. It starts by walking 15through how a basic request issued by another process works its way through the 16network stack, and then moves on to discuss how various components plug in. 17 18If you notice any inaccuracies in this document, or feel that things could be 19better explained, please do not hesitate to submit patches. 20 21 22# Anatomy of the Network Stack 23 24The network stack is located in //net/ in the Chrome repo, and uses the 25namespace "net". Whenever a class name in this doc has no namespace, it can 26generally be assumed it's in //net/ and is in the net namespace. 27 28The top-level network stack object is the URLRequestContext. The context has 29non-owning pointers to everything needed to create and issue a URLRequest. The 30context must outlive all requests that use it. Creating a context is a rather 31complicated process usually managed by URLRequestContextBuilder. 32 33The primary use of the URLRequestContext is to create URLRequest objects using 34URLRequestContext::CreateRequest(). The URLRequest is the main interface used 35by direct consumers of the network stack. It manages loading URLs with the 36http, https, ws, and wss schemes. URLs for other schemes, such as file, 37filesystem, blob, chrome, and data, are managed completely outside of //net. 38Each URLRequest tracks a single request across all redirects until an error 39occurs, it's canceled, or a final response is received, with a (possibly empty) 40body. 41 42The HttpNetworkSession is another major network stack object. It owns the 43HttpStreamFactory, the socket pools, and the HTTP/2 and QUIC session pools. It 44also has non-owning pointers to the network stack objects that more directly 45deal with sockets. 46 47This document does not mention either of these objects much, but at layers 48above the HttpStreamFactory, objects often grab their dependencies from the 49URLRequestContext, while the HttpStreamFactory and layers below it generally 50get their dependencies from the HttpNetworkSession. 51 52 53# How many "Delegates"? 54 55A URLRequest informs the consumer of important events for a request using two 56main interfaces: the URLRequest::Delegate interface and the NetworkDelegate 57interface. 58 59The URLRequest::Delegate interface consists of a small set of callbacks needed 60to let the embedder drive a request forward. The NetworkDelegate is an object 61pointed to by the URLRequestContext and shared by all requests, and includes 62callbacks corresponding to most of the URLRequest::Delegate's callbacks, as 63well as an assortment of other methods. 64 65# The Network Service and Mojo 66 67The network service, which lives in //services/network/, wraps //net/ objects, 68and provides cross-process network APIs and their implementations for the rest 69of Chrome. The network service uses the namespace "network" for all its classes. 70The Mojo interfaces it provides are in the network::mojom namespace. Mojo is 71Chrome's IPC layer. Generally there's a `mojo::Remote<network::mojom::Foo>` 72proxy object in the consumer's process which also implements 73the network::mojom::Foo interface. When the proxy object's methods are invoked, 74it passes the call and all its arguments over a Mojo IPC channel, using a 75`mojo::Receiver<network::mojom::Foo>`, to an implementation of the 76network::mojom::Foo interface in the network service (the implementation is 77typically a class named network::Foo), which may be running in another process, 78another thread in the consumer's process, or even the same thread in the 79consumer's process. 80 81The network::NetworkService object is singleton that is used by Chrome to create 82all other network service objects. The primary objects it is used to create are 83the network::NetworkContexts, each of which owns its own mostly independent 84URLRequestContext. Chrome has a number of different NetworkContexts, as there 85is often a need to keep cookies, caches, and socket pools separate for different 86types of requests, depending on what's making the request. Here are the main 87NetworkContexts used by Chrome: 88 89* The system NetworkContext, created and owned by Chrome's 90SystemNetworkContextManager, is used for requests that aren't associated with 91particular user or Profile. It has no on-disk storage, so loses all state, like 92cookies, after each browser restart. It has no in-memory http cache, either. 93SystemNetworkContextManager also sets up global network service preferences. 94* Each Chrome Profile, including incognito Profiles, has its own NetworkContext. 95Except for incognito and guest profiles, these contexts store information in 96their own on-disk store, which includes cookies and an HTTP cache, among other 97things. Each of these NetworkContexts is owned by a StoragePartition object in 98the browser process, and created by a Profile's ProfileNetworkContextService. 99* On platforms that support apps, each Profile has a NetworkContext for each app 100installed on that Profile. As with the main NetworkContext, these may have 101on-disk data, depending on the Profile and the App. 102 103 104# Life of a Simple URLRequest 105 106A request for data is dispatched from some process, which results in creating 107a network::URLLoader in the network service (which, on desktop platform, is 108typically in its own process). The URLLoader then creates a URLRequest to 109drive the network request. That job first checks the HTTP cache, and then 110creates a network transaction object, if necessary, to actually fetch the data. 111That transaction tries to reuse a connection if available. If none is available, 112it creates a new one. Once it has established a connection, the HTTP request is 113dispatched, the response read and parsed, and the result returned back up the 114stack and sent over to the caller. 115 116Of course, it's not quite that simple :-}. 117 118Consider a simple request issued by some process other than the network 119service's process. Suppose it's an HTTP request, the response is uncompressed, 120no matching entry in the cache, and there are no idle sockets connected to the 121server in the socket pool. 122 123Continuing with a "simple" URLRequest, here's a bit more detail on how things 124work. 125 126### Request starts in some (non-network) process 127 128Summary: 129 130* In the browser process, the network::mojom::NetworkContext interface is used 131to create a network::mojom::URLLoaderFactory. 132* A consumer (e.g. the content::ResourceDispatcher for Blink, the 133content::NavigationURLLoaderImpl for frame navigations, or a 134network::SimpleURLLoader) passes a network::ResourceRequest object and 135network::mojom::URLLoaderClient Mojo channel to the 136network::mojom::URLLoaderFactory, and tells it to create and start a 137network::mojom::URLLoader. 138* Mojo sends the network::ResourceRequest over an IPC pipe to a 139network::URLLoaderFactory in the network process. 140 141Chrome has a single browser process which handles starting and configuring other 142processes, tab management, and navigation, among other things, and multiple 143child processes, which are generally sandboxed and have no network access 144themselves, apart from the network service (Which either runs in its own 145process, or potentially in the browser process to conserve RAM). There are 146multiple types of child processes (renderer, GPU, plugin, network, etc). The 147renderer processes are the ones that layout webpages and run HTML. 148 149The browser process creates the top level network::mojom::NetworkContext 150objects. The NetworkContext interface is privileged and can only be accessed 151from the browser process. The browser process uses it to create 152network::mojom::URLLoaderFactories, which can then be passed to less 153privileged processes to allow them to load resources using the NetworkContext. 154To create a URLLoaderFactory, a network::mojom::URLLoaderFactoryParams object 155is passed to the NetworkContext to configure fields that other processes are 156not trusted to set, for security and privacy reasons. 157 158One such field is the net::IsolationInfo field, which includes: 159* A net::NetworkIsolationKey, which is used to enforce the 160[privacy sandbox](https://www.chromium.org/Home/chromium-privacy/privacy-sandbox) 161in the network stack, separating network resources used by different sites in 162order to protect against tracking a user across sites. 163* A net::SiteForCookies, which is used to determine which site to send SameSite 164cookies for. SameSite cookies prevent cross-site attacks by only being 165accessible when that site is the top-level site. 166* How to update these values across redirects. 167 168A consumer, either in the browser process or a child process, that wants to 169make a network request gets a URLLoaderFactory from the browser process through 170some manner, assembles a bunch of parameters in the large 171network::ResourceRequest object, creates a network::mojom::URLLoaderClient Mojo 172channel for the network::mojom::URLLoader to use to talk back to it, and then 173passes them all to the URLLoaderFactory, which returns a URLLoader object that 174it can use to manage the network request. 175 176### network::URLLoaderFactory sets up the request in the network service 177 178Summary: 179 180* network::URLLoaderFactory creates a network::URLLoader. 181* network::URLLoader uses the network::NetworkContext's URLRequestContext to 182create and start a URLRequest. 183 184The network::URLLoaderFactory, along with all NetworkContexts and most of the 185network stack, lives on a single thread in the network service. It gets a 186reconstituted ResourceRequest object from the network::mojom::URLLoaderFactory 187Mojo pipe, does some checks to make sure it can service the request, and if so, 188creates a URLLoader, passing the request and the NetworkContext associated with 189the URLLoaderFactory. 190 191The URLLoader then calls into the NetworkContext's net::URLRequestContext to 192create the URLRequest. The URLRequestContext has pointers to all the network 193stack objects needed to issue the request over the network, such as the cache, 194cookie store, and host resolver. The URLLoader then calls into the 195network::ResourceScheduler, which may delay starting the request, based on 196priority and other activity. Eventually, the ResourceScheduler starts the 197request. 198 199### Check the cache, request an HttpStream 200 201Summary: 202 203* The URLRequest asks the URLRequestJobFactory to create a URLRequestJob, 204and gets a URLRequestHttpJob. 205* The URLRequestHttpJob asks the HttpCache to create an HttpTransaction, and 206gets an HttpCache::Transaction, assuming caching is enabled. 207* The HttpCache::Transaction sees there's no cache entry for the request, 208and creates an HttpNetworkTransaction. 209* The HttpNetworkTransaction calls into the HttpStreamFactory to request an 210HttpStream. 211 212The URLRequest then calls into the URLRequestJobFactory to create a 213URLRequestHttpJob, a subclass of URLRequestJob, and then starts it 214(historically, non-network URL schemes were also disptched through the 215network stack, so there were a variety of job types.) The 216URLRequestHttpJob attaches cookies to the request, if needed. Whether or 217not SameSite cookies are attached depends on the IsolationInfo's 218SiteForCookies, the URL, and the URLRequest's request_initiator field. 219 220The URLRequestHttpJob calls into the HttpCache to create an 221HttpCache::Transaction. The cache checks for an entry with the same URL 222and NetworkIsolationKey. If there's no matching entry, the 223HttpCache::Transaction will call into the HttpNetworkLayer to create an 224HttpNetworkTransaction, and transparently wrap it. The HttpNetworkTransaction 225then calls into the HttpStreamFactory to request an HttpStream to the server. 226 227### Create an HttpStream 228 229Summary: 230 231* HttpStreamFactory creates an HttpStreamFactory::Job. 232* HttpStreamFactory::Job calls into the TransportClientSocketPool to 233populate an ClientSocketHandle. 234* TransportClientSocketPool has no idle sockets, so it creates a 235TransportConnectJob and starts it. 236* TransportConnectJob creates a StreamSocket and establishes a connection. 237* TransportClientSocketPool puts the StreamSocket in the ClientSocketHandle, 238and calls into HttpStreamFactory::Job. 239* HttpStreamFactory::Job creates an HttpBasicStream, which takes 240ownership of the ClientSocketHandle. 241* It returns the HttpBasicStream to the HttpNetworkTransaction. 242 243The HttpStreamFactory::Job creates a ClientSocketHandle to hold a socket, 244once connected, and passes it into the ClientSocketPoolManager. The 245ClientSocketPoolManager assembles the TransportSocketParams needed to 246establish the connection and creates a group name ("host:port") used to 247identify sockets that can be used interchangeably. 248 249The ClientSocketPoolManager directs the request to the 250TransportClientSocketPool, since there's no proxy and it's an HTTP request. The 251request is forwarded to the pool's ClientSocketPoolBase<TransportSocketParams>'s 252ClientSocketPoolBaseHelper. If there isn't already an idle connection, and there 253are available socket slots, the ClientSocketPoolBaseHelper will create a new 254TransportConnectJob using the aforementioned params object. This Job will do the 255actual DNS lookup by calling into the HostResolverImpl, if needed, and then 256finally establishes a connection. 257 258Once the socket is connected, ownership of the socket is passed to the 259ClientSocketHandle. The HttpStreamFactory::Job is then informed the 260connection attempt succeeded, and it then creates an HttpBasicStream, which 261takes ownership of the ClientSocketHandle. It then passes ownership of the 262HttpBasicStream back to the HttpNetworkTransaction. 263 264### Send request and read the response headers 265 266Summary: 267 268* HttpNetworkTransaction gives the request headers to the HttpBasicStream, 269and tells it to start the request. 270* HttpBasicStream sends the request, and waits for the response. 271* The HttpBasicStream sends the response headers back to the 272HttpNetworkTransaction. 273* The response headers are sent up through the URLRequest, to the 274network::URLLoader. 275* They're then sent to the network::mojom::URLLoaderClient via Mojo. 276 277The HttpNetworkTransaction passes the request headers to the HttpBasicStream, 278which uses an HttpStreamParser to (finally) format the request headers and body 279(if present) and send them to the server. 280 281The HttpStreamParser waits to receive the response and then parses the HTTP/1.x 282response headers, and then passes them up through both the 283HttpNetworkTransaction and HttpCache::Transaction to the URLRequestHttpJob. The 284URLRequestHttpJob saves any cookies, if needed, and then passes the headers up 285to the URLRequest and on to the network::URLLoader, which sends the data over 286a Mojo pipe to the network::mojom::URLLoaderClient, passed in to the URLLoader 287when it was created. 288 289### Response body is read 290 291Summary: 292 293* network::URLLoader creates a raw Mojo data pipe, and passes one end to the 294network::mojom::URLLoaderClient. 295* The URLLoader requests shared memory buffer from the Mojo data pipe. 296* The URLLoader tells the URLRequest to write to the memory buffer, and tells 297the pipe when data has been written to the buffer. 298* The last two steps repeat until the request is complete. 299 300Without waiting to hear back from the network::mojom::URLLoaderClient, the 301network::URLLoader allocates a raw mojo data pipe, and passes the client the 302read end of the pipe. The URLLoader then grabs an IPC buffer from the pipe, 303and passes a 64KB body read request down through the URLRequest all the way 304down to the HttpStreamParser. Once some data is read, possibly less than 64KB, 305the number of bytes read makes its way back to the URLLoader, which then tells 306the Mojo pipe the read was complete, and then requests another buffer from the 307pipe, to continue writing data to. The pipe may apply back pressure, to limit 308the amount of unconsumed data that can be in shared memory buffers at once. 309This process repeats until the response body is completely read. 310 311### URLRequest is destroyed 312 313Summary: 314 315* When complete, the network::URLLoaderFactory deletes the network::URLLoader, 316which deletes the URLRequest. 317* During destruction, the HttpNetworkTransaction determines if the socket is 318reusable, and if so, tells the HttpBasicStream to return it to the socket pool. 319 320When the URLRequest informs the network::URLLoader the request is complete, the 321URLLoader passes the message along to the network::mojom::URLLoaderClient, over 322its Mojo pipe, before telling the URLLoaderFactory to destroy the URLLoader, 323which results in destroying the URLRequest and closing all Mojo pipes related to 324the request. 325 326When the HttpNetworkTransaction is being torn down, it figures out if the 327socket is reusable. If not, it tells the HttpBasicStream to close the socket. 328Either way, the ClientSocketHandle returns the socket is then returned to the 329socket pool, either for reuse or so the socket pool knows it has another free 330socket slot. 331 332### Object Relationships and Ownership 333 334A sample of the object relationships involved in the above process is 335diagramed here: 336 337 338 339There are a couple of points in the above diagram that do not come 340clear visually: 341 342* The method that generates the filter chain that is hung off the 343 URLRequestJob is declared on URLRequestJob, but the only current 344 implementation of it is on URLRequestHttpJob, so the generation is 345 shown as happening from that class. 346* HttpTransactions of different types are layered; i.e. a 347 HttpCache::Transaction contains a pointer to an HttpTransaction, but 348 that pointed-to HttpTransaction generally is an 349 HttpNetworkTransaction. 350 351# Additional Topics 352 353## HTTP Cache 354 355The HttpCache::Transaction sits between the URLRequestHttpJob and the 356HttpNetworkTransaction, and implements the HttpTransaction interface, just like 357the HttpNetworkTransaction. The HttpCache::Transaction checks if a request can 358be served out of the cache. If a request needs to be revalidated, it handles 359sending a conditional revalidation request over the network. It may also break a 360range request into multiple cached and non-cached contiguous chunks, and may 361issue multiple network requests for a single range URLRequest. 362 363The HttpCache::Transaction uses one of three disk_cache::Backends to actually 364store the cache's index and files: The in memory backend, the blockfile cache 365backend, and the simple cache backend. The first is used in incognito. The 366latter two are both stored on disk, and are used on different platforms. 367 368One important detail is that it has a read/write lock for each URL. The lock 369technically allows multiple reads at once, but since an HttpCache::Transaction 370always grabs the lock for writing and reading before downgrading it to a read 371only lock, all requests for the same URL are effectively done serially. The 372renderer process merges requests for the same URL in many cases, which mitigates 373this problem to some extent. 374 375It's also worth noting that each renderer process also has its own in-memory 376cache, which has no relation to the cache implemented in net/, which lives in 377the network service. 378 379## Cancellation 380 381A consumer can cancel a request at any time by deleting the 382network::mojom::URLLoader pipe used by the request. This will cause the 383network::URLLoader to destroy itself and its URLRequest. 384 385When an HttpNetworkTransaction for a cancelled request is being torn down, it 386figures out if the socket the HttpStream owns can potentially be reused, based 387on the protocol (HTTP / HTTP/2 / QUIC) and any received headers. If the socket 388potentially can be reused, an HttpResponseBodyDrainer is created to try and 389read any remaining body bytes of the HttpStream, if any, before returning the 390socket to the SocketPool. If this takes too long, or there's an error, the 391socket is closed instead. Since this all happens at the layer below the cache, 392any drained bytes are not written to the cache, and as far as the cache layer is 393concerned, it only has a partial response. 394 395## Redirects 396 397The URLRequestHttpJob checks if headers indicate a redirect when it receives 398them from the next layer down (typically the HttpCache::Transaction). If they 399indicate a redirect, it tells the cache the response is complete, ignoring the 400body, so the cache only has the headers. The cache then treats it as a complete 401entry, even if the headers indicated there will be a body. 402 403The URLRequestHttpJob then checks with the URLRequest if the redirect should be 404followed. The URLRequest then informs the network::URLLoader about the redirect, 405which passes information about the redirect to network::mojom::URLLoaderClient, 406in the consumer process. Whatever issued the original request then checks 407if the redirect should be followed. 408 409If the redirect should be followed, the URLLoaderClient calls back into the 410URLLoader over the network::mojom::URLLoader Mojo interface, which tells the 411URLRequest to follow the redirect. The URLRequest then creates a new 412URLRequestJob to send the new request. If the URLLoaderClient chooses to 413cancel the request instead, it can delete the network::mojom::URLLoader 414pipe, just like the cancellation case discussed above. In either case, the 415old HttpTransaction is destroyed, and the HttpNetworkTransaction attempts to 416drain the socket for reuse, as discussed in the previous section. 417 418In some cases, the consumer may choose to handle a redirect itself, like 419passing off the redirect to a ServiceWorker. In this case, the consumer cancels 420the request and then calls into some other network::mojom::URLLoaderFactory 421with the new URL to continue the request. 422 423## Filters (gzip, deflate, brotli, etc) 424 425When the URLRequestHttpJob receives headers, it sends a list of all 426Content-Encoding values to Filter::Factory, which creates a (possibly empty) 427chain of filters. As body bytes are received, they're passed through the 428filters at the URLRequestJob layer and the decoded bytes are passed back to the 429URLRequest::Delegate. 430 431Since this is done above the cache layer, the cache stores the responses prior 432to decompression. As a result, if files aren't compressed over the wire, they 433aren't compressed in the cache, either. 434 435## Socket Pools 436 437The ClientSocketPoolManager is responsible for assembling the parameters needed 438to connect a socket, and then sending the request to the right socket pool. 439Each socket request sent to a socket pool comes with a socket params object, a 440ClientSocketHandle, and a "group name". The params object contains all the 441information a ConnectJob needs to create a connection of a given type, and 442different types of socket pools take different params types. The 443ClientSocketHandle will take temporary ownership of a connected socket and 444return it to the socket pool when done. All connections with the same group name 445in the same pool can be used to service the same connection requests, so it 446consists of host, port, protocol, and whether "privacy mode" is enabled for 447sockets in the goup. 448 449All socket pool classes derive from the ClientSocketPoolBase<SocketParamType>. 450The ClientSocketPoolBase handles managing sockets - which requests to create 451sockets for, which requests get connected sockets first, which sockets belong 452to which groups, connection limits per group, keeping track of and closing idle 453sockets, etc. Each ClientSocketPoolBase subclass has its own ConnectJob type, 454which establishes a connection using the socket params, before the pool hands 455out the connected socket. 456 457### Socket Pool Layering 458 459Some socket pools are layered on top other socket pools. This is done when a 460"socket" in a higher layer needs to establish a connection in a lower level 461pool and then take ownership of it as part of its connection process. For 462example, each socket in the SSLClientSocketPool is layered on top of a socket 463in the TransportClientSocketPool. There are a couple additional complexities 464here. 465 466From the perspective of the lower layer pool, all of its sockets that a higher 467layer pools owns are actively in use, even when the higher layer pool considers 468them idle. As a result, when a lower layer pool is at its connection limit and 469needs to make a new connection, it will ask any higher layer pools to close an 470idle connection if they have one, so it can make a new connection. 471 472Since sockets in the higher layer pool are also in a group in the lower layer 473pool, they must have their own distinct group name. This is needed so that, for 474instance, SSL and HTTP connections won't be grouped together in the 475TcpClientSocketPool, which the SSLClientSocketPool sits on top of. 476 477### Socket Pool Class Relationships 478 479The relationships between the important classes in the socket pools is 480shown diagrammatically for the lowest layer socket pool 481(TransportSocketPool) below. 482 483 484 485The ClientSocketPoolBase is a template class templatized on the class 486containing the parameters for the appropriate type of socket (in this 487case TransportSocketParams). It contains a pointer to the 488ClientSocketPoolBaseHelper, which contains all the type-independent 489machinery of the socket pool. 490 491When socket pools are initialized, they in turn initialize their 492templatized ClientSocketPoolBase member with an object with which it 493should create connect jobs. That object must derive from 494ClientSocketPoolBase::ConnectJobFactory templatized by the same type 495as the ClientSocketPoolBase. (In the case of the diagram above, that 496object is a TransportConnectJobFactory, which derives from 497ClientSocketPoolBase::ConnectJobFactory<TransportSocketParams>.) 498Internally, that object is wrapped in a type-unsafe wrapper 499(ClientSocketPoolBase::ConnectJobFactoryAdaptor) so that it can be 500passed to the initialization of the ClientSocketPoolBaseHelper. This 501allows the helper to create connect jobs while preserving a type-safe 502API to the initialization of the socket pool. 503 504### SSL 505 506When an SSL connection is needed, the ClientSocketPoolManager assembles the 507parameters needed both to connect the TCP socket and establish an SSL 508connection. It then passes them to the SSLClientSocketPool, which creates 509an SSLConnectJob using them. The SSLConnectJob's first step is to call into the 510TransportSocketPool to establish a TCP connection. 511 512Once a connection is established by the lower layered pool, the SSLConnectJob 513then starts SSL negotiation. Once that's done, the SSL socket is passed back to 514the HttpStreamFactory::Job that initiated the request, and things proceed 515just as with HTTP. When complete, the socket is returned to the 516SSLClientSocketPool. 517 518## Proxies 519 520Each proxy has its own completely independent set of socket pools. They have 521their own exclusive TransportSocketPool, their own protocol-specific pool above 522it, and their own SSLSocketPool above that. HTTPS proxies also have a second 523SSLSocketPool between the the HttpProxyClientSocketPool and the 524TransportSocketPool, since they can talk SSL to both the proxy and the 525destination server, layered on top of each other. 526 527The first step the HttpStreamFactory::Job performs, just before calling 528into the ClientSocketPoolManager to create a socket, is to pass the URL to the 529Proxy service to get an ordered list of proxies (if any) that should be tried 530for that URL. Then when the ClientSocketPoolManager tries to get a socket for 531the Job, it uses that list of proxies to direct the request to the right socket 532pool. 533 534## Alternate Protocols 535 536### HTTP/2 (Formerly SPDY) 537 538HTTP/2 negotation is performed as part of the SSL handshake, so when 539HttpStreamFactory::Job gets a socket, it may have HTTP/2 negotiated over it 540as well. When it gets a socket with HTTP/2 negotiated as well, the Job creates a 541SpdySession using the socket and a SpdyHttpStream on top of the SpdySession. 542The SpdyHttpStream will be passed to the HttpNetworkTransaction, which drives 543the stream as usual. 544 545The SpdySession will be shared with other Jobs connecting to the same server, 546and future Jobs will find the SpdySession before they try to create a 547connection. HttpServerProperties also tracks which servers supported HTTP/2 when 548we last talked to them. We only try to establish a single connection to servers 549we think speak HTTP/2 when multiple HttpStreamFactory::Jobs are trying to 550connect to them, to avoid wasting resources. 551 552### QUIC 553 554QUIC works quite a bit differently from HTTP/2. Servers advertise QUIC support 555with an "Alternate-Protocol" HTTP header in their responses. 556HttpServerProperties then tracks servers that have advertised QUIC support. 557 558When a new request comes in to HttpStreamFactory for a connection to a 559server that has advertised QUIC support in the past, it will create a second 560HttpStreamFactory::Job for QUIC, which returns an QuicHttpStream on success. 561The two Jobs (one for QUIC, one for all versions of HTTP) will be raced against 562each other, and whichever successfully creates an HttpStream first will be used. 563 564As with HTTP/2, once a QUIC connection is established, it will be shared with 565other Jobs connecting to the same server, and future Jobs will just reuse the 566existing QUIC session. 567 568## Prioritization 569 570URLRequests are assigned a priority on creation. It only comes into play in 571a couple places: 572 573* The ResourceScheduler lives outside net/, and in some cases, delays starting 574low priority requests on a per-tab basis. 575* DNS lookups are initiated based on the highest priority request for a lookup. 576* Socket pools hand out and create sockets based on prioritization. However, 577when a socket becomes idle, it will be assigned to the highest priority request 578for the server it's connected to, even if there's a higher priority request to 579another server that's waiting on a free socket slot. 580* HTTP/2 and QUIC both support sending priorities over-the-wire. 581 582At the socket pool layer, sockets are only assigned to socket requests once the 583socket is connected and SSL is negotiated, if needed. This is done so that if 584a higher priority request for a group reaches the socket pool before a 585connection is established, the first usable connection goes to the highest 586priority socket request. 587 588## Non-HTTP Schemes 589 590WebSockets requests (wss:// and ws://) start as HTTP requests with an HTTP 591upgrade header. Once the handshake completes successfully, the connection 592is used as a full-duplex communication channel to the server for WebSocket 593frames, rather than to receive an HTTP response body. WebSockets have their 594own Mojo interfaces and //net classes, but internally they reuse the full 595URLRequest machinery up to the point headers are received from the server. 596Then the connection is handed off to the WebSocket code to manage. 597 598Other schemes typically have their own network::mojom::URLLoaderFactory that 599is not part of the network service. Standard schemes like file:// and blob:// 600are handled by the content layer and its dependencies 601(content::FileURLLoaderFactory and storage::BlobURLLoaderFactory, respectively, 602for those two schemes). Chrome-specific schemes, like externalfile:// and 603chrome-extension:// are often handled by a URLLoaderFactory in the chrome layer, 604though chrome:// itself is actually handled in //content. 605 606data:// URLs are handled a bit differently from other schemes. If a renderer 607process requests a data:// subresource, the renderer typically decodes it 608internally, as sending it to an out-of-process URLLoader would be inefficient. 609Navigations are a bit different. To navigate to a URL, the browser process 610creates a URLLoader and passes it over to a renderer process. So in the 611case of a navigation to a data:// URL, a URLLoader is created using a 612content::DataURLLoaderFactory that lives in the browser process, and then a 613mojo::Remote for the browser-hosted URLLoader is passed to a renderer 614proceess. 615 616about:blank is similarly often handled in the renderer, though there is a 617factory for that used in the case of navigations as well. Other about: URLs 618are mapped to the corresponding Chrome URLs by the navigation code, rather 619than having that logic live in a URLLoaderFactory. 620