~alinuxninja/nginx-edge/trunk

« back to all changes in this revision

Viewing changes to debian/modules/ngx_pagespeed/psol/include/net/instaweb/rewriter/public/resource_slot.h

  • Committer: Vivian
  • Date: 2015-12-04 18:20:11 UTC
  • Revision ID: git-v1:a36f2bc32e884f7473b3a47040e5411306144d7d
* Do not extract psol.tar.gz

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2011 Google Inc.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 *
8
 
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
// Author: jmarantz@google.com (Joshua Marantz)
18
 
 
19
 
#ifndef NET_INSTAWEB_REWRITER_PUBLIC_RESOURCE_SLOT_H_
20
 
#define NET_INSTAWEB_REWRITER_PUBLIC_RESOURCE_SLOT_H_
21
 
 
22
 
#include <set>
23
 
#include <vector>
24
 
 
25
 
#include "net/instaweb/htmlparse/public/html_element.h"
26
 
#include "net/instaweb/rewriter/public/resource.h"
27
 
#include "net/instaweb/util/public/basictypes.h"
28
 
#include "net/instaweb/util/public/ref_counted_ptr.h"
29
 
#include "net/instaweb/util/public/string.h"
30
 
#include "net/instaweb/util/public/string_util.h"
31
 
#include "net/instaweb/util/public/vector_deque.h"
32
 
#include "pagespeed/kernel/base/ref_counted_ptr.h"
33
 
#include "pagespeed/kernel/http/google_url.h"
34
 
 
35
 
namespace net_instaweb {
36
 
 
37
 
class HtmlResourceSlot;
38
 
class ResourceSlot;
39
 
class RewriteContext;
40
 
class RewriteDriver;
41
 
class RewriteOptions;
42
 
 
43
 
typedef RefCountedPtr<ResourceSlot> ResourceSlotPtr;
44
 
typedef RefCountedPtr<HtmlResourceSlot> HtmlResourceSlotPtr;
45
 
typedef std::vector<ResourceSlotPtr> ResourceSlotVector;
46
 
 
47
 
// A slot is a place in a web-site resource a URL is found, and may be
48
 
// rewritten.  Types of slots include HTML element attributes and CSS
49
 
// background URLs.  In principle they could also include JS ajax
50
 
// requests, although this is NYI.
51
 
//
52
 
// TODO(jmarantz): make this class thread-safe.
53
 
class ResourceSlot : public RefCounted<ResourceSlot> {
54
 
 public:
55
 
  explicit ResourceSlot(const ResourcePtr& resource)
56
 
      : resource_(resource),
57
 
        disable_rendering_(false),
58
 
        should_delete_element_(false),
59
 
        disable_further_processing_(false),
60
 
        was_optimized_(false) {
61
 
  }
62
 
 
63
 
  ResourcePtr resource() const { return resource_; }
64
 
  // Return HTML element associated with slot, or NULL if none (CSS, IPRO)
65
 
  virtual HtmlElement* element() const = 0;
66
 
 
67
 
  // Note that while slots can be mutated by multiple threads; they are
68
 
  // implemented with thread-safety in mind -- only mainline render their
69
 
  // results back into the DOM.
70
 
  //
71
 
  // For example, SetResource may be run from a helper-thread, but we
72
 
  // would not want that threaded mutation to propagate instantly back
73
 
  // into the HTML or CSS DOM.  We buffer the changes in the ResoureSlot
74
 
  // and then render them in the request thread, synchronous to the
75
 
  // HTML filter execution.
76
 
  //
77
 
  // TODO(jmarantz): Add a lock or that we or an overall protocol
78
 
  // preventing unwanted interference between renderer's reads and
79
 
  // worker writes.
80
 
  void SetResource(const ResourcePtr& resource);
81
 
 
82
 
  // If disable_rendering is true, this slot will do nothing on rendering,
83
 
  // neither changing the URL or deleting any elements. This is intended for
84
 
  // use of filters which do the entire work in the Context.
85
 
  void set_disable_rendering(bool x) { disable_rendering_ = x; }
86
 
  bool disable_rendering() const { return disable_rendering_; }
87
 
 
88
 
  // Determines whether rendering the slot deletes the HTML Element.
89
 
  // For example, in the CSS combine filter we want the Render to
90
 
  // rewrite the first <link href>, but delete all the other <link>s.
91
 
  //
92
 
  // Calling RequestDeleteElement() also forces
93
 
  // set_disable_further_processing(true);
94
 
  void RequestDeleteElement() {
95
 
    should_delete_element_ = true;
96
 
    disable_further_processing_ = true;
97
 
  }
98
 
  bool should_delete_element() const { return should_delete_element_; }
99
 
 
100
 
  // Returns true if any of the contexts touching this slot optimized it
101
 
  // successfully. This in particular includes the case where a call to
102
 
  // RewriteContext::Rewrite() on a partition containing this slot returned
103
 
  // kRewriteOk.  Note in particular that was_optimized() does not tell you
104
 
  // whether *your* filter optimized the slot!  For this you should check
105
 
  // output_partition(n)->optimizable().
106
 
  bool was_optimized() const { return was_optimized_; }
107
 
 
108
 
  // Marks the slot as having been optimized.
109
 
  void set_was_optimized(bool x) { was_optimized_ = x; }
110
 
 
111
 
  // If disable_further_processing is true, no further filter taking this slot
112
 
  // as input will run. Note that this affects only HTML rewriting
113
 
  // (or nested rewrites) since fetch-style rewrites do not share slots
114
 
  // even when more than one filter was involved. For this to persist properly
115
 
  // on cache hits it should be set before RewriteDone is called.
116
 
  // (This also means you should not be using this when partitioning failed).
117
 
  // Only later filters are affected, not the currently running one.
118
 
  void set_disable_further_processing(bool x) {
119
 
    disable_further_processing_ = x;
120
 
  }
121
 
 
122
 
  bool disable_further_processing() const {
123
 
    return disable_further_processing_;
124
 
  }
125
 
 
126
 
  // Render is not thread-safe.  This must be called from the thread that
127
 
  // owns the DOM or CSS file. The RewriteContext state machine will only
128
 
  // call ResourceSlot::Render() on slots that were optimized successfully,
129
 
  // and whose partitions are safely url_relocatable(). (Note that this is
130
 
  // different from RewriteContext::Render).
131
 
  virtual void Render() = 0;
132
 
 
133
 
  // Called after all contexts have had a chance to Render.
134
 
  // This is especially useful for cases where Render was never called
135
 
  // but you want something to be done to all slots.
136
 
  virtual void Finished() {}
137
 
 
138
 
  // Update the URL in the slot target without touching the resource. This is
139
 
  // intended for when we're inlining things as data: URLs and also for placing
140
 
  // the rewritten version of the URL in the slot. The method returns true if
141
 
  // it successfully updates the slot target. Resources that are not explicitly
142
 
  // authorized will get rejected at this point. Note that if you
143
 
  // call this you should also call set_disable_rendering(true), or otherwise
144
 
  // the result will be overwritten. Does not alter the URL in any way.  Not
145
 
  // supported on all slot types --- presently only slots representing things
146
 
  // within CSS and HTML have this operation (others will DCHECK-fail).  Must be
147
 
  // called from within a context's Render() method.
148
 
  virtual bool DirectSetUrl(const StringPiece& url);
149
 
 
150
 
  // Returns true if DirectSetUrl is supported by this slot (html and css right
151
 
  // now).
152
 
  virtual bool CanDirectSetUrl() { return false; }
153
 
 
154
 
  // Return the last context to have been added to this slot.  Returns NULL
155
 
  // if no context has been added to the slot so far.
156
 
  RewriteContext* LastContext() const;
157
 
 
158
 
  // Adds a new context to this slot.
159
 
  void AddContext(RewriteContext* context) { contexts_.push_back(context); }
160
 
 
161
 
  // Detaches a context from the slot.  This must be the first or last context
162
 
  // that was added.
163
 
  void DetachContext(RewriteContext* context);
164
 
 
165
 
  // Returns a human-readable description of where this slot occurs, for use
166
 
  // in log messages.
167
 
  virtual GoogleString LocationString() = 0;
168
 
 
169
 
  // Either relativize the URL or pass it through depending on options set.
170
 
  // PRECONDITION: url must parse as a valid GoogleUrl.
171
 
  // TODO(sligocki): Take a GoogleUrl for url?
172
 
  static GoogleString RelativizeOrPassthrough(const RewriteOptions* options,
173
 
                                              StringPiece url,
174
 
                                              UrlRelativity url_relativity,
175
 
                                              const GoogleUrl& base_url);
176
 
 
177
 
 protected:
178
 
  virtual ~ResourceSlot();
179
 
  REFCOUNT_FRIEND_DECLARATION(ResourceSlot);
180
 
 
181
 
 private:
182
 
  ResourcePtr resource_;
183
 
  bool disable_rendering_;
184
 
  bool should_delete_element_;
185
 
  bool disable_further_processing_;
186
 
  bool was_optimized_;
187
 
 
188
 
  // We track the RewriteContexts that are atempting to rewrite this
189
 
  // slot, to help us build a dependency graph between ResourceContexts.
190
 
  VectorDeque<RewriteContext*> contexts_;
191
 
 
192
 
  DISALLOW_COPY_AND_ASSIGN(ResourceSlot);
193
 
};
194
 
 
195
 
// A resource-slot created for a Fetch has an empty Render method -- Render
196
 
// should never be called.
197
 
class FetchResourceSlot : public ResourceSlot {
198
 
 public:
199
 
  explicit FetchResourceSlot(const ResourcePtr& resource)
200
 
      : ResourceSlot(resource) {
201
 
  }
202
 
  virtual HtmlElement* element() const { return NULL; }
203
 
  virtual void Render();
204
 
  virtual GoogleString LocationString();
205
 
 
206
 
 protected:
207
 
  REFCOUNT_FRIEND_DECLARATION(FetchResourceSlot);
208
 
  virtual ~FetchResourceSlot();
209
 
 
210
 
 private:
211
 
  DISALLOW_COPY_AND_ASSIGN(FetchResourceSlot);
212
 
};
213
 
 
214
 
class HtmlResourceSlot : public ResourceSlot {
215
 
 public:
216
 
  HtmlResourceSlot(const ResourcePtr& resource,
217
 
                   HtmlElement* element,
218
 
                   HtmlElement::Attribute* attribute,
219
 
                   RewriteDriver* driver);
220
 
 
221
 
  virtual HtmlElement* element() const { return element_; }
222
 
  HtmlElement::Attribute* attribute() const { return attribute_; }
223
 
 
224
 
  virtual void Render();
225
 
  virtual GoogleString LocationString();
226
 
  virtual bool DirectSetUrl(const StringPiece& url);
227
 
  virtual bool CanDirectSetUrl() { return true; }
228
 
 
229
 
  // How relative the original URL was. If PreserveUrlRelativity is enabled,
230
 
  // Render will try to make the final URL just as relative.
231
 
  UrlRelativity url_relativity() const { return url_relativity_; }
232
 
 
233
 
 protected:
234
 
  REFCOUNT_FRIEND_DECLARATION(HtmlResourceSlot);
235
 
  virtual ~HtmlResourceSlot();
236
 
 
237
 
 private:
238
 
  HtmlElement* element_;
239
 
  HtmlElement::Attribute* attribute_;
240
 
  RewriteDriver* driver_;
241
 
  UrlRelativity url_relativity_;
242
 
 
243
 
  int begin_line_number_;
244
 
  int end_line_number_;
245
 
 
246
 
  DISALLOW_COPY_AND_ASSIGN(HtmlResourceSlot);
247
 
};
248
 
 
249
 
class HtmlResourceSlotComparator {
250
 
 public:
251
 
  bool operator()(const HtmlResourceSlotPtr& p,
252
 
                  const HtmlResourceSlotPtr& q) const;
253
 
};
254
 
 
255
 
typedef std::set<HtmlResourceSlotPtr,
256
 
                 HtmlResourceSlotComparator> HtmlResourceSlotSet;
257
 
 
258
 
}  // namespace net_instaweb
259
 
 
260
 
#endif  // NET_INSTAWEB_REWRITER_PUBLIC_RESOURCE_SLOT_H_