Home | History | Annotate | Download | only in base
      1 // Copyright 2014 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // TODO(rdsmith): This class needs to be moved out to the net/ embedder and
      6 // hooked into whatever mechanisms the embedder uses for authentication.
      7 // Specifically, this class needs methods overriding
      8 // URLRequest::Delegate::{OnAuthRequired,OnCertificateRequested} and can't
      9 // implement them at the net/ layer.
     10 
     11 #ifndef NET_BASE_SDCH_DICTIONARY_FETCHER_H_
     12 #define NET_BASE_SDCH_DICTIONARY_FETCHER_H_
     13 
     14 #include <queue>
     15 #include <set>
     16 #include <string>
     17 
     18 #include "base/memory/scoped_ptr.h"
     19 #include "base/memory/weak_ptr.h"
     20 #include "base/threading/non_thread_safe.h"
     21 #include "net/base/sdch_manager.h"
     22 #include "net/url_request/url_fetcher_delegate.h"
     23 #include "net/url_request/url_request.h"
     24 
     25 namespace net {
     26 
     27 class URLRequest;
     28 class URLRequestThrottlerEntryInterface;
     29 
     30 // This class implements the SdchFetcher interface. It queues requests
     31 // for dictionaries and dispatches them serially, implementing
     32 // the URLRequest::Delegate interface to handle callbacks (but see above
     33 // TODO). It tracks all requests, only attempting to fetch each dictionary
     34 // once.
     35 class NET_EXPORT SdchDictionaryFetcher
     36     : public SdchFetcher,
     37       public URLRequest::Delegate,
     38       public base::NonThreadSafe {
     39  public:
     40   // The consumer must guarantee that |*consumer| and |*context| outlive
     41   // this object.
     42   SdchDictionaryFetcher(SdchFetcher::Delegate* consumer,
     43                         URLRequestContext* context);
     44   virtual ~SdchDictionaryFetcher();
     45 
     46   // Implementation of SdchFetcher methods.
     47   virtual void Schedule(const GURL& dictionary_url) OVERRIDE;
     48   virtual void Cancel() OVERRIDE;
     49 
     50   // Implementation of URLRequest::Delegate methods.
     51   virtual void OnResponseStarted(URLRequest* request) OVERRIDE;
     52   virtual void OnReadCompleted(URLRequest* request, int bytes_read) OVERRIDE;
     53 
     54  private:
     55   enum State {
     56     STATE_NONE,
     57     STATE_IDLE,
     58     STATE_REQUEST_STARTED,
     59     STATE_REQUEST_READING,
     60     STATE_REQUEST_COMPLETE,
     61   };
     62 
     63   // State machine implementation.
     64   int DoLoop(int rv);
     65   int DoDispatchRequest(int rv);
     66   int DoRequestStarted(int rv);
     67   int DoRead(int rv);
     68   int DoCompleteRequest(int rv);
     69 
     70   State next_state_;
     71   bool in_loop_;
     72 
     73   SdchFetcher::Delegate* const consumer_;
     74 
     75   // A queue of URLs that are being used to download dictionaries.
     76   std::queue<GURL> fetch_queue_;
     77 
     78   // The request and buffer used for getting the current dictionary
     79   // Both are null when a fetch is not in progress.
     80   scoped_ptr<URLRequest> current_request_;
     81   scoped_refptr<IOBuffer> buffer_;
     82 
     83   // The currently accumulating dictionary.
     84   std::string dictionary_;
     85 
     86   // Althought the SDCH spec does not preclude a server from using a single URL
     87   // to load several distinct dictionaries (by telling a client to load a
     88   // dictionary from an URL several times), current implementations seem to have
     89   // that 1-1 relationship (i.e., each URL points at a single dictionary, and
     90   // the dictionary content does not change over time, and hence is not worth
     91   // trying to load more than once). In addition, some dictionaries prove
     92   // unloadable only after downloading them (because they are too large?  ...or
     93   // malformed?). As a protective element, Chromium will *only* load a
     94   // dictionary at most once from a given URL (so that it doesn't waste
     95   // bandwidth trying repeatedly).
     96   // The following set lists all the dictionary URLs that we've tried to load,
     97   // so that we won't try to load from an URL more than once.
     98   // TODO(jar): Try to augment the SDCH proposal to include this restiction.
     99   std::set<GURL> attempted_load_;
    100 
    101   // Store the URLRequestContext associated with the owning SdchManager for
    102   // use while fetching.
    103   URLRequestContext* context_;
    104 
    105   base::WeakPtrFactory<SdchDictionaryFetcher> weak_factory_;
    106 
    107   DISALLOW_COPY_AND_ASSIGN(SdchDictionaryFetcher);
    108 };
    109 
    110 }  // namespace net
    111 
    112 #endif  // NET_BASE_SDCH_DICTIONARY_FETCHER_H_
    113