Ejemplo n.º 1
0
    def getChild(self, chnam, request):
        if chnam == '':
            return error.ErrorPage(http.NOT_FOUND,
                             "Bad URL",
                             "The empty string is not a valid user.")
        import pwd
        td = '.twistd'

        if chnam[-len(td):] == td:
            username = chnam[:-len(td)]
            sub = 1
        else:
            username = chnam
            sub = 0

        try:
            pw_name, pw_passwd, pw_uid, pw_gid, pw_gecos, pw_dir, pw_shell \
                     = pwd.getpwnam(username)
        except KeyError:
            return error.ErrorPage(http.NOT_FOUND,
                                   "No Such User",
                                   "The user %s was not found on this system." %
                                   repr(username))
        if sub:
            twistdsock = os.path.join(pw_dir, self.userSocketName)
            rs = ResourceSubscription('unix',twistdsock)
            self.putChild(chnam, rs)
            return rs
        else:
            return static.File(os.path.join(pw_dir, self.userDirName))
Ejemplo n.º 2
0
    def render(self, resrc):
        try:
            body = resrc.render(self)
        except UnsupportedMethod, e:
            allowedMethods = e.allowedMethods
            if (self.method == "HEAD") and ("GET" in allowedMethods):
                # We must support HEAD (RFC 2616, 5.1.1).  If the
                # resource doesn't, fake it by giving the resource
                # a 'GET' request and then return only the headers,
                # not the body.
                log.msg("Using GET to fake a HEAD request for %s" % (resrc, ))
                self.method = "GET"
                body = resrc.render(self)

                if body is NOT_DONE_YET:
                    log.msg("Tried to fake a HEAD request for %s, but "
                            "it got away from me." % resrc)
                    # Oh well, I guess we won't include the content length.
                else:
                    self.setHeader('content-length', str(len(body)))

                self.write('')
                self.finish()
                return

            if self.method in (supportedMethods):
                # We MUST include an Allow header
                # (RFC 2616, 10.4.6 and 14.7)
                self.setHeader('Allow', allowedMethods)
                s = ('''Your browser approached me (at %(URI)s) with'''
                     ''' the method "%(method)s".  I only allow'''
                     ''' the method%(plural)s %(allowed)s here.''' % {
                         'URI': self.uri,
                         'method': self.method,
                         'plural': ((len(allowedMethods) > 1) and 's') or '',
                         'allowed': string.join(allowedMethods, ', ')
                     })
                epage = error.ErrorPage(http.NOT_ALLOWED, "Method Not Allowed",
                                        s)
                body = epage.render(self)
            else:
                epage = error.ErrorPage(
                    http.NOT_IMPLEMENTED, "Huh?",
                    """I don't know how to treat a"""
                    """ %s request.""" % (self.method))
                body = epage.render(self)
Ejemplo n.º 3
0
 def failed(self, expt):
     self.request.write(
         error.ErrorPage(http.INTERNAL_SERVER_ERROR,
                   "Server Connection Lost",
                   "Connection to distributed server lost:" +
                   html.PRE(expt)).
         render(self.request))
     self.request.finish()
Ejemplo n.º 4
0
 def failed(self, failure):
     #XXX: Argh. FIXME.
     failure = str(failure)
     self.request.write(
         error.ErrorPage(
             http.INTERNAL_SERVER_ERROR, "Server Connection Lost",
             "Connection to distributed server lost:" +
             html.PRE(failure)).render(self.request))
     self.request.finish()
     log.msg(failure)
Ejemplo n.º 5
0
 def connectionLost(self):
     process.Process.connectionLost(self)
     if self.handling_headers:
         self.request.write(
             error.ErrorPage(
                 http.INTERNAL_SERVER_ERROR, "CGI Script Error",
                 "Premature end of script headers; errors follow:<hr>" +
                 html.PRE(self.errortext) + "<hr>" +
                 html.PRE(self.headertext) + "<hr>").render(self.request))
     self.request.finish()
Ejemplo n.º 6
0
def ResourceTemplate(path, registry):
    from quixote import ptl_compile

    glob = {
        '__file__': path,
        'resource': error.ErrorPage(500, "Whoops! Internal Error",
                                    rpyNoResource),
        'registry': registry
    }

    e = ptl_compile.compile_template(open(path), path)
    exec e in glob
    return glob['resource']
Ejemplo n.º 7
0
 def processEnded(self, reason):
     if reason.value.exitCode != 0:
         log.msg("CGI %s exited with exit code %s" %
                 (self.request.uri, reason.value.exitCode))
     if self.errortext:
         log.msg("Errors from CGI %s: %s" % (self.request.uri, self.errortext))
     if self.handling_headers:
         log.msg("Premature end of headers in %s: %s" % (self.request.uri, self.headertext))
         self.request.write(
             error.ErrorPage(http.INTERNAL_SERVER_ERROR,
                             "CGI Script Error",
                             "Premature end of script headers.").render(self.request))
     self.request.unregisterProducer()
     self.request.finish()
Ejemplo n.º 8
0
    def __init__(self, path, registry):
        self.path = path
        self.registry = registry
        self.doCache = 0

    def cache(self):
        c = self.registry.getCachedPath(self.path)
        if c is not None:
            raise AlreadyCached(c)
        self.recache()

    def recache(self):
        self.doCache = 1


noRsrc = error.ErrorPage(500, "Whoops! Internal Error", rpyNoResource)


def ResourceScript(path, registry):
    """
    I am a normal py file which must define a 'resource' global, which should
    be an instance of (a subclass of) web.resource.Resource; it will be
    renderred.
    """
    cs = CacheScanner(path, registry)
    glob = {
        '__file__': path,
        'resource': noRsrc,
        'registry': registry,
        'cache': cs.cache,
        'recache': cs.recache
Ejemplo n.º 9
0
class Request(pb.Copyable, http.Request, components.Componentized):

    site = None
    appRootURL = None
    __pychecker__ = 'unusednames=issuer'

    def __init__(self, *args, **kw):
        http.Request.__init__(self, *args, **kw)
        components.Componentized.__init__(self)
        self.notifications = []

    def getStateToCopyFor(self, issuer):
        x = self.__dict__.copy()
        del x['transport']
        # XXX refactor this attribute out; it's from protocol
        # del x['server']
        del x['channel']
        del x['content']
        del x['site']
        self.content.seek(0, 0)
        x['content_data'] = self.content.read()
        x['remote'] = pb.ViewPoint(issuer, self)

        # Address objects aren't jellyable
        x['host'] = _addressToTuple(x['host'])
        x['client'] = _addressToTuple(x['client'])

        return x

    # HTML generation helpers

    def sibLink(self, name):
        "Return the text that links to a sibling of the requested resource."
        if self.postpath:
            return (len(self.postpath) * "../") + name
        else:
            return name

    def childLink(self, name):
        "Return the text that links to a child of the requested resource."
        lpp = len(self.postpath)
        if lpp > 1:
            return ((lpp - 1) * "../") + name
        elif lpp == 1:
            return name
        else:  # lpp == 0
            if len(self.prepath) and self.prepath[-1]:
                return self.prepath[-1] + '/' + name
            else:
                return name

    def process(self):
        "Process a request."

        # get site from channel
        self.site = self.channel.site

        # set various default headers
        self.setHeader('server', version)
        self.setHeader('date', http.datetimeToString())
        self.setHeader('content-type', "text/html")

        # Resource Identification
        self.prepath = []
        self.postpath = map(unquote, string.split(self.path[1:], '/'))
        try:
            resrc = self.site.getResourceFor(self)
            self.render(resrc)
        except:
            self.processingFailed(failure.Failure())

    def render(self, resrc):
        try:
            body = resrc.render(self)
        except UnsupportedMethod, e:
            allowedMethods = e.allowedMethods
            if (self.method == "HEAD") and ("GET" in allowedMethods):
                # We must support HEAD (RFC 2616, 5.1.1).  If the
                # resource doesn't, fake it by giving the resource
                # a 'GET' request and then return only the headers,
                # not the body.
                log.msg("Using GET to fake a HEAD request for %s" % (resrc, ))
                self.method = "GET"
                body = resrc.render(self)

                if body is NOT_DONE_YET:
                    log.msg("Tried to fake a HEAD request for %s, but "
                            "it got away from me." % resrc)
                    # Oh well, I guess we won't include the content length.
                else:
                    self.setHeader('content-length', str(len(body)))

                self.write('')
                self.finish()
                return

            if self.method in (supportedMethods):
                # We MUST include an Allow header
                # (RFC 2616, 10.4.6 and 14.7)
                self.setHeader('Allow', allowedMethods)
                s = ('''Your browser approached me (at %(URI)s) with'''
                     ''' the method "%(method)s".  I only allow'''
                     ''' the method%(plural)s %(allowed)s here.''' % {
                         'URI': self.uri,
                         'method': self.method,
                         'plural': ((len(allowedMethods) > 1) and 's') or '',
                         'allowed': string.join(allowedMethods, ', ')
                     })
                epage = error.ErrorPage(http.NOT_ALLOWED, "Method Not Allowed",
                                        s)
                body = epage.render(self)
            else:
                epage = error.ErrorPage(
                    http.NOT_IMPLEMENTED, "Huh?",
                    """I don't know how to treat a"""
                    """ %s request.""" % (self.method))
                body = epage.render(self)
        # end except UnsupportedMethod

        if body == NOT_DONE_YET:
            return
        if type(body) is not types.StringType:
            body = error.ErrorPage(
                http.INTERNAL_SERVER_ERROR, "Request did not return a string",
                "Request: " + html.PRE(reflect.safe_repr(self)) + "<br />" +
                "Resource: " + html.PRE(reflect.safe_repr(resrc)) + "<br />" +
                "Value: " + html.PRE(reflect.safe_repr(body))).render(self)

        if self.method == "HEAD":
            if len(body) > 0:
                # This is a Bad Thing (RFC 2616, 9.4)
                log.msg("Warning: HEAD request %s for resource %s is"
                        " returning a message body."
                        "  I think I'll eat it." % (self, resrc))
                self.setHeader('content-length', str(len(body)))
            self.write('')
        else:
            self.setHeader('content-length', str(len(body)))
            self.write(body)
        self.finish()
Ejemplo n.º 10
0
    def process(self):
        "Process a request."
        # Log the request to a file.
        log.msg(self)

        # cache the client information, we'll need this later to be
        # pickled and sent with the request so CGIs will work remotely
        self.client = self.transport.getPeer()

        # set various default headers
        self.setHeader('server', version)
        self.setHeader('date', date_time_string())
        self.setHeader('content-type', "text/html")
        self.setHeader('connection', 'close')
        try:
            # Argument processing
            args = self.args
            if self.method == "POST":
                mfd = 'multipart/form-data'
                key, pdict = cgi.parse_header(self.getHeader('content-type'))
                if key == 'application/x-www-form-urlencoded':
                    args.update(cgi.parse_qs(self.content))

                elif key == mfd:
                    args.update(
                        cgi.parse_multipart(StringIO.StringIO(self.content),
                                            pdict))
                else:
                    pass  #raise 'bad content-type'

            # Resource Identification
            self.server_port = 80
            # XXX ^^^^^^^^^^ Obviously it's not always 80.  figure it
            # out from the URI.
            self.prepath = []
            self.postpath = string.split(self.path[1:], '/')
            resrc = self.site.getResourceFor(self)
            body = resrc.render(self)
            if body == NOT_DONE_YET:
                return
            if type(body) is not types.StringType:
                body = error.ErrorPage(
                    http.INTERNAL_SERVER_ERROR,
                    "Request did not return a string", "Request: " +
                    html.PRE(reflect.safe_repr(self)) + "<BR>" + "Resource: " +
                    html.PRE(reflect.safe_repr(resrc)) + "<BR>" + "Value: " +
                    html.PRE(reflect.safe_repr(body))).render(self)

        except passport.Unauthorized:
            body = "<HTML><BODY>You're not cleared for that.</BODY></HTML>"
            self.setResponseCode(http.UNAUTHORIZED)
            self.setHeader('content-type', "text/html")
        except UnsupportedMethod, e:
            allowedMethods = e.allowedMethods
            if (self.method == "HEAD") and ("GET" in allowedMethods):
                # We must support HEAD (RFC 2616, 5.1.1).  If the resource
                # doesn't, fake it by giving the resource a 'GET' request
                # and then return only the headers -- not the body.

                log.msg("Using GET to fake a HEAD request for %s" % resrc)
                self.method == "GET"
                body = resrc.render(self)

                if body is NOT_DONE_YET:
                    log.msg("Tried to fake a HEAD request for %s, but "
                            "it got away from me." % resrc)
                    # Oh well, I guess we won't include the content
                    # length then.
                else:
                    # XXX: What's this "minus one" for?
                    self.setHeader('content-length', str(len(body) - 1))

                self.write('')
                self.finish()

            if self.method in (supportedMethods):
                # We MUST include an Allow header
                # (RFC 2616, 10.4.6 and 14.7)
                self.setHeader('Allow', allowedMethods)
                s = ('''Your browser approached me (at %(URI)s) with'''
                     ''' the method "%(method)s".  I only allow'''
                     ''' the method%(plural)s %(allowed) here.''' % {
                         'URI': self.uri,
                         'method': self.method,
                         'plural': ((len(allowedMethods) > 1) and 's') or '',
                         'allowed': string.join(allowedMethods, ', ')
                     })
                epage = error.ErrorPage(http.NOT_ALLOWED, "Method Not Allowed",
                                        s)
                body = epage.render(self)
            else:
                epage = error.ErrorPage(
                    http.NOT_IMPLEMENTED, "Huh?",
                    """I don't know how to treat a"""
                    """ %s request.""" % (self.method))
                body = epage.render(self)