The network stack is a mostly single-threaded cross-platform library primarily for resource fetching. Its main interfaces are URLRequest and URLRequestContext.

Net Code Layout

HTTP Network Diagram

URLRequest

class URLRequest {
 public:
  // Construct a URLRequest for |url|, notifying events to |delegate|.
  URLRequest(const GURL& url, Delegate* delegate);
  
  // Specify the shared state
  void set_context(URLRequestContext* context);

  // Start the request.  Notifications will be sent to |delegate|.
  void Start();

  // Read data from the request.
  bool Read(IOBuffer* buf, int max_bytes, int* bytes_read);
};

class URLRequest::Delegate {
 public:
  // Called after the response has started coming in or an error occurred.
  virtual void OnResponseStarted(...) = 0;

  // Called when Read() calls complete.
  virtual void OnReadCompleted(...) = 0;
};

URLRequestHttpJob

URLRequestHttpJob is used for dealing with http request, resource may be cached or to download from remote web service.

  1. URLRequestHttpJob will first identify the cookies to set for the HTTP request, which requires querying the CookieMonster in the request context. This can be asynchronous since the CookieMonster may be backed by an sqlite database.
  2. After doing so, it will ask the request context’s HttpTransactionFactory to create a HttpTransaction. Typically, the HttpCache will be specified as the HttpTransactionFactory. The HttpCache will create a HttpCache::Transaction to handle the HTTP request.
  3. The HttpCache::Transaction will first check the HttpCache (which checks the disk cache) to see if the cache entry already exists. If so, that means that the response was already cached, or a network transaction already exists for this cache entry, so just read from that entry.
  4. If the cache entry does not exist, then we create it and ask the HttpCache’s HttpNetworkLayer to create a HttpNetworkTransaction to service the request.
  5. The HttpNetworkTransaction is given a HttpNetworkSession which contains the contextual state for performing HTTP requests. Some of this state comes from the URLRequestContext.

Example

The example shows to use net::URLFetcher to fetch data from a url.

class SyncUrlFetcher : public net::URLFetcherDelegate {
public:
  SyncUrlFetcher(const GURL& url,
    net::URLRequestContextGetter* getter,
    std::string* response)
    : url_(url), getter_(getter), response_(response), event_(false, false) {}

  virtual ~SyncUrlFetcher() {}

  bool Fetch() {
    getter_->GetNetworkTaskRunner()->PostTask(
      FROM_HERE,
      base::Bind(&SyncUrlFetcher::FetchOnIOThread, base::Unretained(this)));
    
    // sync fetch, wait for complete  
    event_.Wait();
    return success_;
  }

  void FetchOnIOThread() {
    fetcher_.reset(net::URLFetcher::Create(url_, net::URLFetcher::GET, this));
    fetcher_->SetRequestContext(getter_);
    fetcher_->Start();
  }

  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE {
    success_ = (source->GetResponseCode() == 200);
    if (success_)
      success_ = source->GetResponseAsString(response_);
    fetcher_.reset();  // Destroy the fetcher on IO thread.
    
    // complete and signal
    event_.Signal();
  }

private:
  GURL url_;
  net::URLRequestContextGetter* getter_;
  std::string* response_;
  base::WaitableEvent event_;
  scoped_ptr<net::URLFetcher> fetcher_;
  bool success_;
};

// Fetch data from url sync, MUST NOT call on chrome IO thread
// can be used on custom worker thread
inline bool FetchUrl(const std::string& url,
  net::URLRequestContextGetter* getter,
  std::string* response) {
    return SyncUrlFetcher(GURL(url), getter, response).Fetch();
}

reference

http://www.chromium.org/developers/design-documents/network-stack https://insouciant.org/tech/connection-management-in-chromium/