00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00022
00023 #ifndef NET_INSTAWEB_AUTOMATIC_PUBLIC_PROXY_FETCH_H_
00024 #define NET_INSTAWEB_AUTOMATIC_PUBLIC_PROXY_FETCH_H_
00025
00026 #include <map>
00027 #include <set>
00028 #include <vector>
00029
00030 #include "base/scoped_ptr.h"
00031 #include "net/instaweb/automatic/public/html_detector.h"
00032 #include "net/instaweb/http/public/async_fetch.h"
00033 #include "net/instaweb/util/public/queued_worker_pool.h"
00034 #include "net/instaweb/util/public/basictypes.h"
00035 #include "net/instaweb/util/public/property_cache.h"
00036 #include "net/instaweb/util/public/string.h"
00037 #include "net/instaweb/util/public/string_util.h"
00038
00039 namespace net_instaweb {
00040
00041 class AbstractClientState;
00042 class AbstractMutex;
00043 class CacheUrlAsyncFetcher;
00044 class Function;
00045 class MessageHandler;
00046 class ProxyFetch;
00047 class ProxyFetchPropertyCallbackCollector;
00048 class QueuedAlarm;
00049 class ResourceManager;
00050 class ResponseHeaders;
00051 class RewriteDriver;
00052 class RewriteOptions;
00053 class Timer;
00054
00057 class ProxyFetchFactory {
00058 public:
00059 explicit ProxyFetchFactory(ResourceManager* manager);
00060 ~ProxyFetchFactory();
00061
00062 void StartNewProxyFetch(
00063 const GoogleString& url,
00064 AsyncFetch* async_fetch,
00065 RewriteDriver* driver,
00066 ProxyFetchPropertyCallbackCollector* property_callback,
00067 AsyncFetch* original_content_fetch);
00068
00069 void set_server_version(const StringPiece& server_version) {
00070 server_version.CopyToString(&server_version_);
00071 }
00072 const GoogleString& server_version() const { return server_version_; }
00073
00074 MessageHandler* message_handler() const { return handler_; }
00075
00076 private:
00077 friend class ProxyFetch;
00078
00083 void Start(ProxyFetch* proxy_fetch);
00084 void Finish(ProxyFetch* proxy_fetch);
00085
00086 ResourceManager* manager_;
00087 Timer* timer_;
00088 MessageHandler* handler_;
00089 GoogleString server_version_;
00090
00091 scoped_ptr<AbstractMutex> outstanding_proxy_fetches_mutex_;
00092 std::set<ProxyFetch*> outstanding_proxy_fetches_;
00093
00094 DISALLOW_COPY_AND_ASSIGN(ProxyFetchFactory);
00095 };
00096
00105 class ProxyFetchPropertyCallback : public PropertyPage {
00106 public:
00108 enum CacheType {
00109 kPagePropertyCache,
00110 kClientPropertyCache
00111 };
00112
00113 explicit ProxyFetchPropertyCallback(
00114 CacheType cache_type,
00115 const StringPiece& key,
00116 ProxyFetchPropertyCallbackCollector* collector,
00117 AbstractMutex* mutex);
00118
00119 CacheType cache_type() const { return cache_type_; }
00120
00121 virtual void Done(bool success);
00122
00123 private:
00124 CacheType cache_type_;
00125 ProxyFetchPropertyCallbackCollector* collector_;
00126 DISALLOW_COPY_AND_ASSIGN(ProxyFetchPropertyCallback);
00127 };
00128
00130 class ProxyFetchPropertyCallbackCollector {
00131 public:
00132 explicit ProxyFetchPropertyCallbackCollector(ResourceManager* manager);
00133 virtual ~ProxyFetchPropertyCallbackCollector();
00134
00137 void AddCallback(ProxyFetchPropertyCallback* callback);
00138
00145 void ConnectProxyFetch(ProxyFetch* proxy_fetch);
00146
00151 void Detach();
00152
00155 PropertyPage* GetPropertyPage(
00156 ProxyFetchPropertyCallback::CacheType cache_type);
00157
00160 PropertyPage* GetPropertyPageWithoutOwnership(
00161 ProxyFetchPropertyCallback::CacheType cache_type);
00162
00172 void AddPostLookupTask(Function* func);
00173
00175 virtual void Done(ProxyFetchPropertyCallback* callback, bool success);
00176
00177 private:
00178 std::set<ProxyFetchPropertyCallback*> pending_callbacks_;
00179 std::map<ProxyFetchPropertyCallback::CacheType, PropertyPage*>
00180 property_pages_;
00181 scoped_ptr<AbstractMutex> mutex_;
00182 ResourceManager* resource_manager_;
00183 bool detached_;
00184 bool done_;
00185 bool success_;
00186 ProxyFetch* proxy_fetch_;
00187
00188 scoped_ptr<std::vector<Function*> > post_lookup_task_vector_;
00189
00190 DISALLOW_COPY_AND_ASSIGN(ProxyFetchPropertyCallbackCollector);
00191 };
00192
00213 class ProxyFetch : public SharedAsyncFetch {
00214 public:
00217 static const char kCollectorDone[];
00218 static const char kCollectorPrefix[];
00219 static const char kCollectorReady[];
00220
00223 static const char kHeadersSetupRaceAlarmQueued[];
00224 static const char kHeadersSetupRaceDone[];
00225 static const char kHeadersSetupRaceFlush[];
00226 static const char kHeadersSetupRacePrefix[];
00227 static const char kHeadersSetupRaceWait[];
00228
00235 static const int kTestSignalTimeoutMs = 200;
00236
00237 protected:
00239 virtual void HandleHeadersComplete();
00240 virtual bool HandleWrite(const StringPiece& content, MessageHandler* handler);
00241 virtual bool HandleFlush(MessageHandler* handler);
00242 virtual void HandleDone(bool success);
00243 virtual bool IsCachedResultValid(const ResponseHeaders& headers);
00244
00245 private:
00246 friend class ProxyFetchFactory;
00247 friend class ProxyFetchPropertyCallbackCollector;
00248 friend class MockProxyFetch;
00249
00252 virtual void PropertyCacheComplete(
00253 ProxyFetchPropertyCallbackCollector* collector, bool success);
00254
00259 AbstractClientState* GetClientState(
00260 ProxyFetchPropertyCallbackCollector* collector);
00261
00264 ProxyFetch(const GoogleString& url,
00265 bool cross_domain,
00266 ProxyFetchPropertyCallbackCollector* property_cache_callback,
00267 AsyncFetch* async_fetch,
00268 AsyncFetch* original_content_fetch,
00269 RewriteDriver* driver,
00270 ResourceManager* manager,
00271 Timer* timer,
00272 ProxyFetchFactory* factory);
00273 virtual ~ProxyFetch();
00274
00275 const RewriteOptions* Options();
00276
00278 void SetupForHtml();
00279
00281 void AddPagespeedHeader();
00282
00285 bool StartParse();
00286
00288 void StartFetch();
00289
00291 void DoFetch();
00292
00295 void ExecuteQueued();
00296
00299 void ScheduleQueueExecutionIfNeeded();
00300
00305 void Finish(bool success);
00306
00308 void CompleteFinishParse(bool success);
00309
00312 void FlushDone();
00313
00316
00318 void CancelIdleAlarm();
00319
00321 void QueueIdleAlarm();
00322
00324 void HandleIdleAlarm();
00325
00326 GoogleString url_;
00327 ResourceManager* resource_manager_;
00328 Timer* timer_;
00329
00330 scoped_ptr<CacheUrlAsyncFetcher> cache_fetcher_;
00331
00334 bool cross_domain_;
00335
00337 bool claims_html_;
00338
00341 bool started_parse_;
00342
00344 bool done_called_;
00345
00346 HtmlDetector html_detector_;
00347
00349 int64 start_time_us_;
00350
00355 ProxyFetchPropertyCallbackCollector* property_cache_callback_;
00356
00360 AsyncFetch* original_content_fetch_;
00361
00364 RewriteDriver* driver_;
00365
00368 bool queue_run_job_created_;
00369
00381 scoped_ptr<AbstractMutex> mutex_;
00382 StringStarVector text_queue_;
00383 bool network_flush_outstanding_;
00384 QueuedWorkerPool::Sequence* sequence_;
00385
00388 bool done_outstanding_;
00389
00392 bool finishing_;
00393
00396 bool done_result_;
00397
00401 bool waiting_for_flush_to_finish_;
00402
00405 QueuedAlarm* idle_alarm_;
00406
00407 ProxyFetchFactory* factory_;
00408
00410 bool prepare_success_;
00411
00412 DISALLOW_COPY_AND_ASSIGN(ProxyFetch);
00413 };
00414
00415 }
00416
00417 #endif ///< NET_INSTAWEB_AUTOMATIC_PUBLIC_PROXY_FETCH_H_