This file is indexed.

/usr/share/pyshared/twisted/web2/resource.py is in python-twisted-web2 8.1.0-3build1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
# -*- test-case-name: twisted.web2.test.test_server,twisted.web2.test.test_resource -*-
# Copyright (c) 2001-2007 Twisted Matrix Laboratories.
# See LICENSE for details.

"""
I hold the lowest-level L{Resource} class and related mix-in classes.
"""

# System Imports
from zope.interface import implements

from twisted.web2 import iweb, http, server, responsecode

class RenderMixin(object):
    """
    Mix-in class for L{iweb.IResource} which provides a dispatch mechanism for
    handling HTTP methods.
    """
    def allowedMethods(self):
        """
        @return: A tuple of HTTP methods that are allowed to be invoked on this resource.
        """
        if not hasattr(self, "_allowed_methods"):
            self._allowed_methods = tuple([name[5:] for name in dir(self) if name.startswith('http_')])
        return self._allowed_methods

    def checkPreconditions(self, request):
        """
        Checks all preconditions imposed by this resource upon a request made
        against it.
        @param request: the request to process.
        @raise http.HTTPError: if any precondition fails.
        @return: C{None} or a deferred whose callback value is C{request}.
        """
        #
        # http.checkPreconditions() gets called by the server after every
        # GET or HEAD request.
        #
        # For other methods, we need to know to bail out before request
        # processing, especially for methods that modify server state (eg. PUT).
        # We also would like to do so even for methods that don't, if those
        # methods might be expensive to process.  We're assuming that GET and
        # HEAD are not expensive.
        #
        if request.method not in ("GET", "HEAD"):
            http.checkPreconditions(request)

        # Check per-method preconditions
        method = getattr(self, "preconditions_" + request.method, None)
        if method:
            return method(request)

    def renderHTTP(self, request):
        """
        See L{iweb.IResource.renderHTTP}.

        This implementation will dispatch the given C{request} to another method
        of C{self} named C{http_}METHOD, where METHOD is the HTTP method used by
        C{request} (eg. C{http_GET}, C{http_POST}, etc.).

        Generally, a subclass should implement those methods instead of
        overriding this one.

        C{http_*} methods are expected provide the same interface and return the
        same results as L{iweb.IResource}C{.renderHTTP} (and therefore this method).

        C{etag} and C{last-modified} are added to the response returned by the
        C{http_*} header, if known.

        If an appropriate C{http_*} method is not found, a
        L{responsecode.NOT_ALLOWED}-status response is returned, with an
        appropriate C{allow} header.

        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        method = getattr(self, "http_" + request.method, None)
        if not method:
            response = http.Response(responsecode.NOT_ALLOWED)
            response.headers.setHeader("allow", self.allowedMethods())
            return response

        d = self.checkPreconditions(request)
        if d is None:
            return method(request)
        else:
            return d.addCallback(lambda _: method(request))

    def http_OPTIONS(self, request):
        """
        Respond to a OPTIONS request.
        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        response = http.Response(responsecode.OK)
        response.headers.setHeader("allow", self.allowedMethods())
        return response

    def http_TRACE(self, request):
        """
        Respond to a TRACE request.
        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        return server.doTrace(request)

    def http_HEAD(self, request):
        """
        Respond to a HEAD request.
        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        return self.http_GET(request)

    def http_GET(self, request):
        """
        Respond to a GET request.

        This implementation validates that the request body is empty and then
        dispatches the given C{request} to L{render} and returns its result.

        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        if request.stream.length != 0:
            return responsecode.REQUEST_ENTITY_TOO_LARGE

        return self.render(request)

    def render(self, request):
        """
        Subclasses should implement this method to do page rendering.
        See L{http_GET}.
        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        raise NotImplementedError("Subclass must implement render method.")

class Resource(RenderMixin):
    """
    An L{iweb.IResource} implementation with some convenient mechanisms for
    locating children.
    """
    implements(iweb.IResource)

    addSlash = False

    def locateChild(self, request, segments):
        """
        Locates a child resource of this resource.
        @param request: the request to process.
        @param segments: a sequence of URL path segments.
        @return: a tuple of C{(child, segments)} containing the child
        of this resource which matches one or more of the given C{segments} in
        sequence, and a list of remaining segments.
        """
        w = getattr(self, 'child_%s' % (segments[0], ), None)

        if w:
            r = iweb.IResource(w, None)
            if r:
                return r, segments[1:]
            return w(request), segments[1:]

        factory = getattr(self, 'childFactory', None)
        if factory is not None:
            r = factory(request, segments[0])
            if r:
                return r, segments[1:]

        return None, []

    def child_(self, request):
        """
        This method locates a child with a trailing C{"/"} in the URL.
        @param request: the request to process.
        """
        if self.addSlash and len(request.postpath) == 1:
            return self
        return None

    def putChild(self, path, child):
        """
        Register a static child.

        This implementation registers children by assigning them to attributes
        with a C{child_} prefix.  C{resource.putChild("foo", child)} is
        therefore same as C{o.child_foo = child}.

        @param path: the name of the child to register.  You almost certainly
            don't want C{"/"} in C{path}. If you want to add a "directory"
            resource (e.g. C{/foo/}) specify C{path} as C{""}.
        @param child: an object adaptable to L{iweb.IResource}.
        """
        setattr(self, 'child_%s' % (path, ), child)

    def http_GET(self, request):
        if self.addSlash and request.prepath[-1] != '':
            # If this is a directory-ish resource...
            return http.RedirectResponse(request.unparseURL(path=request.path+'/'))

        return super(Resource, self).http_GET(request)


class PostableResource(Resource):
    """
    A L{Resource} capable of handling the POST request method.

    @cvar maxMem: maximum memory used during the parsing of the data.
    @type maxMem: C{int}
    @cvar maxFields: maximum number of form fields allowed.
    @type maxFields: C{int}
    @cvar maxSize: maximum size of the whole post allowed.
    @type maxSize: C{int}
    """
    maxMem = 100 * 1024
    maxFields = 1024
    maxSize = 10 * 1024 * 1024

    def http_POST(self, request):
        """
        Respond to a POST request.
        Reads and parses the incoming body data then calls L{render}.

        @param request: the request to process.
        @return: an object adaptable to L{iweb.IResponse}.
        """
        return server.parsePOSTData(request,
            self.maxMem, self.maxFields, self.maxSize
            ).addCallback(lambda res: self.render(request))


class LeafResource(RenderMixin):
    """
    A L{Resource} with no children.
    """
    implements(iweb.IResource)

    def locateChild(self, request, segments):
        return self, server.StopTraversal

class RedirectResource(LeafResource):
    """
    A L{LeafResource} which always performs a redirect.
    """
    implements(iweb.IResource)

    def __init__(self, *args, **kwargs):
        """
        Parameters are URL components and are the same as those for
        L{urlparse.urlunparse}.  URL components which are not specified will
        default to the corresponding component of the URL of the request being
        redirected.
        """
        self._args   = args
        self._kwargs = kwargs

    def renderHTTP(self, request):
        return http.RedirectResponse(request.unparseURL(*self._args, **self._kwargs))

class WrapperResource(object):
    """
    An L{iweb.IResource} implementation which wraps a L{RenderMixin} instance
    and provides a hook in which a subclass can implement logic that is called
    before request processing on the contained L{Resource}.
    """
    implements(iweb.IResource)

    def __init__(self, resource):
        self.resource=resource

    def hook(self, request):
        """
        Override this method in order to do something before passing control on
        to the wrapped resource's C{renderHTTP} and C{locateChild} methods.
        @return: None or a L{Deferred}.  If a deferred object is
            returned, it's value is ignored, but C{renderHTTP} and
            C{locateChild} are chained onto the deferred as callbacks.
        """
        raise NotImplementedError()

    def locateChild(self, request, segments):
        x = self.hook(request)
        if x is not None:
            return x.addCallback(lambda data: (self.resource, segments))
        return self.resource, segments

    def renderHTTP(self, request):
        x = self.hook(request)
        if x is not None:
            return x.addCallback(lambda data: self.resource)
        return self.resource


__all__ = ['RenderMixin', 'Resource', 'PostableResource', 'LeafResource', 'WrapperResource']