def render_GET(self, ctx): req = IRequest(ctx) # This is where all of the directory-related ?t=* code goes. t = get_arg(req, "t", "").strip() # t=info contains variable ophandles, t=rename-form contains the name # of the child being renamed. Neither is allowed an ETag. FIXED_OUTPUT_TYPES = ["", "json", "uri", "readonly-uri"] if not self.node.is_mutable() and t in FIXED_OUTPUT_TYPES: si = self.node.get_storage_index() if si and req.setETag('DIR:%s-%s' % (base32.b2a(si), t or "")): return "" if not t: # render the directory as HTML, using the docFactory and Nevow's # whole templating thing. return DirectoryAsHTML(self.node, self.client.mutable_file_default) if t == "json": return DirectoryJSONMetadata(ctx, self.node) if t == "info": return MoreInfo(self.node) if t == "uri": return DirectoryURI(ctx, self.node) if t == "readonly-uri": return DirectoryReadonlyURI(ctx, self.node) if t == 'rename-form': return RenameForm(self.node) raise WebError("GET directory: bad t=%s" % t)
def renderHTTP(self, ctx): """Handle HTTP requests.""" srv = IService(ctx) request = IRequest(ctx) current = must_user(ctx) user = srv.validate_challenge( # pylint: disable-msg=E1101 self.challenge, current.session) if user: message(ctx, u'Bienvenue, %s' % (user.email, )) request.redirect("/") request.finish() return '' # Some people simply reuse invitations: don't complain if they # are already connected, just redirect them to the main page. avatar = maybe_user(ctx) if avatar.identified: request.redirect("/") request.finish() return '' # pylint: disable-msg=E1101 self.contentTags = [ T.h1[u"Cette clé n'est pas valable"], T.p[u"Vous pouvez obtenir une nouvelle clé par e-mail.", T.div(_class="editable bl")[T.div(_class="br")[T.div( _class="tl")[T.div(_class="tr")[T.div( _class="edcontent")[login.LoginFragment( original=login.LoginInfo( force_reconnect=True))], ]]]]] ] return BasePage.renderHTTP(self, ctx)
def render_POST(self, ctx): req = IRequest(ctx) log.msg(format="User reports incident through web page: %(details)s", details=get_arg(req, "details", ""), level=log.WEIRD, umid="LkD9Pw") req.setHeader("content-type", "text/plain") return "An incident report has been saved to logs/incidents/ in the node directory."
def error(f): message, code = humanize_failure(f) req = IRequest(ctx) req.setResponseCode(code) return json.dumps({ "error": message, })
def render_POST(self, ctx): req = IRequest(ctx) log.msg(format="User reports incident through web page: %(details)s", details=get_arg(req, "details", ""), level=log.WEIRD, umid="LkD9Pw") req.setHeader("content-type", "text/plain") return "Thank you for your report!"
def renderHTTP_exception(self, ctx, f): try: text, code = humanize_failure(f) except: log.msg("exception in humanize_failure") log.msg("argument was %s" % (f,)) log.err() text, code = str(f), None if code is not None: return self.simple(ctx, text, code) if f.check(server.UnsupportedMethod): # twisted.web.server.Request.render() has support for transforming # this into an appropriate 501 NOT_IMPLEMENTED or 405 NOT_ALLOWED # return code, but nevow does not. req = IRequest(ctx) method = req.method return self.simple(ctx, "I don't know how to treat a %s request." % method, http.NOT_IMPLEMENTED) req = IRequest(ctx) accept = req.getHeader("accept") if not accept: accept = "*/*" if "*/*" in accept or "text/*" in accept or "text/html" in accept: super = appserver.DefaultExceptionHandler return super.renderHTTP_exception(self, ctx, f) # use plain text traceback = f.getTraceback() return self.simple(ctx, traceback, http.INTERNAL_SERVER_ERROR)
def renderHTTP_exception(self, ctx, f): try: text, code = humanize_failure(f) except: log.msg("exception in humanize_failure") log.msg("argument was %s" % (f, )) log.err() text, code = str(f), None if code is not None: return self.simple(ctx, text, code) if f.check(server.UnsupportedMethod): # twisted.web.server.Request.render() has support for transforming # this into an appropriate 501 NOT_IMPLEMENTED or 405 NOT_ALLOWED # return code, but nevow does not. req = IRequest(ctx) method = req.method return self.simple( ctx, "I don't know how to treat a %s request." % method, http.NOT_IMPLEMENTED) req = IRequest(ctx) accept = req.getHeader("accept") if not accept: accept = "*/*" if "*/*" in accept or "text/*" in accept or "text/html" in accept: super = appserver.DefaultExceptionHandler return super.renderHTTP_exception(self, ctx, f) # use plain text traceback = f.getTraceback() return self.simple(ctx, traceback, http.INTERNAL_SERVER_ERROR)
class ManifestStreamer(dirnode.DeepStats): implements(IPushProducer) def __init__(self, ctx, origin): dirnode.DeepStats.__init__(self, origin) self.req = IRequest(ctx) def setMonitor(self, monitor): self.monitor = monitor def pauseProducing(self): pass def resumeProducing(self): pass def stopProducing(self): self.monitor.cancel() def add_node(self, node, path): dirnode.DeepStats.add_node(self, node, path) d = {"path": path, "cap": node.get_uri()} if IDirectoryNode.providedBy(node): d["type"] = "directory" elif IFileNode.providedBy(node): d["type"] = "file" else: d["type"] = "unknown" v = node.get_verify_cap() if v: v = v.to_string() d["verifycap"] = v or "" r = node.get_repair_cap() if r: r = r.to_string() d["repaircap"] = r or "" si = node.get_storage_index() if si: si = base32.b2a(si) d["storage-index"] = si or "" j = simplejson.dumps(d, ensure_ascii=True) assert "\n" not in j self.req.write(j + "\n") def finish(self): stats = dirnode.DeepStats.get_results(self) d = { "type": "stats", "stats": stats, } j = simplejson.dumps(d, ensure_ascii=True) assert "\n" not in j self.req.write(j + "\n") return ""
def render_GET(self, ctx): req = IRequest(ctx) t = get_arg(req, "t", "").strip() # t=info contains variable ophandles, so is not allowed an ETag. FIXED_OUTPUT_TYPES = ["", "json", "uri", "readonly-uri"] if not self.node.is_mutable() and t in FIXED_OUTPUT_TYPES: # if the client already has the ETag then we can # short-circuit the whole process. si = self.node.get_storage_index() if si and req.setETag('%s-%s' % (base32.b2a(si), t or "")): return "" if not t: # just get the contents # the filename arrives as part of the URL or in a form input # element, and will be sent back in a Content-Disposition header. # Different browsers use various character sets for this name, # sometimes depending upon how language environment is # configured. Firefox sends the equivalent of # urllib.quote(name.encode("utf-8")), while IE7 sometimes does # latin-1. Browsers cannot agree on how to interpret the name # they see in the Content-Disposition header either, despite some # 11-year old standards (RFC2231) that explain how to do it # properly. So we assume that at least the browser will agree # with itself, and echo back the same bytes that we were given. filename = get_arg(req, "filename", self.name) or "unknown" d = self.node.get_best_readable_version() d.addCallback(lambda dn: FileDownloader(dn, filename)) return d if t == "json": # We do this to make sure that fields like size and # mutable-type (which depend on the file on the grid and not # just on the cap) are filled in. The latter gets used in # tests, in particular. # # TODO: Make it so that the servermap knows how to update in # a mode specifically designed to fill in these fields, and # then update it in that mode. if self.node.is_mutable(): d = self.node.get_servermap(MODE_READ) else: d = defer.succeed(None) if self.parentnode and self.name: d.addCallback(lambda ignored: self.parentnode.get_metadata_for(self.name)) else: d.addCallback(lambda ignored: None) d.addCallback(lambda md: FileJSONMetadata(ctx, self.node, md)) return d if t == "info": return MoreInfo(self.node) if t == "uri": return FileURI(ctx, self.node) if t == "readonly-uri": return FileReadOnlyURI(ctx, self.node) raise WebError("GET file: bad t=%s" % t)
def render_GET(self, ctx): req = IRequest(ctx) t = get_arg(req, "t", "").strip() # t=info contains variable ophandles, so is not allowed an ETag. FIXED_OUTPUT_TYPES = ["", "json", "uri", "readonly-uri"] if not self.node.is_mutable() and t in FIXED_OUTPUT_TYPES: # if the client already has the ETag then we can # short-circuit the whole process. si = self.node.get_storage_index() if si and req.setETag('%s-%s' % (base32.b2a(si), t or "")): return "" if not t: # just get the contents # the filename arrives as part of the URL or in a form input # element, and will be sent back in a Content-Disposition header. # Different browsers use various character sets for this name, # sometimes depending upon how language environment is # configured. Firefox sends the equivalent of # urllib.quote(name.encode("utf-8")), while IE7 sometimes does # latin-1. Browsers cannot agree on how to interpret the name # they see in the Content-Disposition header either, despite some # 11-year old standards (RFC2231) that explain how to do it # properly. So we assume that at least the browser will agree # with itself, and echo back the same bytes that we were given. filename = get_arg(req, "filename", self.name) or "unknown" d = self.node.get_best_readable_version() d.addCallback(lambda dn: FileDownloader(dn, filename)) return d if t == "json": # We do this to make sure that fields like size and # mutable-type (which depend on the file on the grid and not # just on the cap) are filled in. The latter gets used in # tests, in particular. # # TODO: Make it so that the servermap knows how to update in # a mode specifically designed to fill in these fields, and # then update it in that mode. if self.node.is_mutable(): d = self.node.get_servermap(MODE_READ) else: d = defer.succeed(None) if self.parentnode and self.name: d.addCallback(lambda ignored: self.parentnode.get_metadata_for( self.name)) else: d.addCallback(lambda ignored: None) d.addCallback(lambda md: FileJSONMetadata(ctx, self.node, md)) return d if t == "info": return MoreInfo(self.node) if t == "uri": return FileURI(ctx, self.node) if t == "readonly-uri": return FileReadOnlyURI(ctx, self.node) raise WebError("GET file: bad t=%s" % t)
def renderHTTP(self, ctx): # pylint: disable-msg=C0103 """Handle HTTP requests.""" request = IRequest(ctx) if request.method == 'POST': # pylint: disable-msg=E1101 session.destroy_session(ctx) request.redirect('/') return '' return BasePage.renderHTTP(self, ctx)
class ManifestStreamer(dirnode.DeepStats): implements(IPushProducer) def __init__(self, ctx, origin): dirnode.DeepStats.__init__(self, origin) self.req = IRequest(ctx) def setMonitor(self, monitor): self.monitor = monitor def pauseProducing(self): pass def resumeProducing(self): pass def stopProducing(self): self.monitor.cancel() def add_node(self, node, path): dirnode.DeepStats.add_node(self, node, path) d = {"path": path, "cap": node.get_uri()} if IDirectoryNode.providedBy(node): d["type"] = "directory" elif IFileNode.providedBy(node): d["type"] = "file" else: d["type"] = "unknown" v = node.get_verify_cap() if v: v = v.to_string() d["verifycap"] = v or "" r = node.get_repair_cap() if r: r = r.to_string() d["repaircap"] = r or "" si = node.get_storage_index() if si: si = base32.b2a(si) d["storage-index"] = si or "" j = simplejson.dumps(d, ensure_ascii=True) assert "\n" not in j self.req.write(j+"\n") def finish(self): stats = dirnode.DeepStats.get_results(self) d = {"type": "stats", "stats": stats, } j = simplejson.dumps(d, ensure_ascii=True) assert "\n" not in j self.req.write(j+"\n") return ""
def locateChild(self, context, segments): """ Unwrap the wrapped resource if HTTPS is already being used, otherwise wrap it in a helper which will preserve the wrapping all the way down to the final resource. """ request = IRequest(context) if request.isSecure(): return self.wrappedResource, segments return _SecureWrapper(self.urlGenerator, self.wrappedResource), segments
def renderHTTP(self, context): """ Render the wrapped resource if HTTPS is already being used, otherwise invoke a helper which may generate a redirect. """ request = IRequest(context) if request.isSecure(): renderer = self.wrappedResource else: renderer = _SecureWrapper(self.urlGenerator, self.wrappedResource) return renderer.renderHTTP(context)
def setETag(self, ctx, t): """Set the ETag on the response. If this matches a conditional request, return True to short-circuit the request""" req = IRequest(ctx) if not self.node.is_mutable(): # If the client already has the ETag then we can # short-circuit the whole process. si = self.node.get_storage_index() if si and req.setETag('CHK:%s-%s' % (base32.b2a(si), t or "")): return True return False
def locateChild(self, ctx, segments): try: impl = self.mapping[segments[0]] except KeyError: return rend.NotFound else: req = IRequest(ctx) implgz = impl + '.gz' if self.canCompress(req) and os.path.exists(implgz): impl = implgz req.setHeader('content-encoding', 'gzip') return self.resourceFactory(impl), []
def render_PUT(self, ctx): req = IRequest(ctx) t = get_arg(req, "t", "").strip() replace = parse_replace_arg(get_arg(req, "replace", "true")) assert self.parentnode and self.name if req.getHeader("content-range"): raise WebError("Content-Range in PUT not yet supported", http.NOT_IMPLEMENTED) if not t: return self.replace_me_with_a_child(req, self.client, replace) if t == "uri": return self.replace_me_with_a_childcap(req, self.client, replace) raise WebError("PUT to a file: bad t=%s" % t)
def child_giveup(self, ctx): """Handle reservation cancellation requests.""" srv = IService(ctx) user = must_user(ctx).user if ctx.arg('giveup'): srv.giveupItem(user, self.item) # pylint: disable-msg=E1101 message(ctx, u"Votre modification est enregistrée.") request = IRequest(ctx) referer = request.getHeader('referer') if referer: return url.URL.fromString(referer) return url.URL.fromContext(ctx).up()
def render_login(self, ctx, data): """Render the whole login box.""" # pylint: disable-msg=E1101 if IRequest(ctx).method == 'POST' and data.is_valid(): # Simply send a challenge to this email address message( ctx, u"""Un message de confirmation a été envoyé """ u"""à l'adresse <%s>.""" % data.email) IService(ctx).pretend_email_address( must_user(ctx).user, data.email) IRequest(ctx).redirect(data.referer) IRequest(ctx).finish() else: return ctx.tag
def locateChild(self, context, segments): """ Delegate dispatch to a sharing resource if the request is for a user subdomain, otherwise fall back to the wrapped resource's C{locateChild} implementation. """ request = IRequest(context) hostname = request.getHeader('host') info = self.subdomain(hostname) if info is not None: username, domain = info index = UserIndexPage(IRealm(self.siteStore), self.webViewer) resource = index.locateChild(None, [username])[0] return resource, segments return self.wrapped.locateChild(context, segments)
def childFactory(self, ctx, name): ophandle = name if ophandle not in self.handles: raise WebError("unknown/expired handle '%s'" % escape(ophandle), NOT_FOUND) (monitor, renderer, when_added) = self.handles[ophandle] request = IRequest(ctx) t = get_arg(ctx, "t", "status") if t == "cancel" and request.method == "POST": monitor.cancel() # return the status anyways, but release the handle self._release_ophandle(ophandle) else: retain_for = get_arg(ctx, "retain-for", None) if retain_for is not None: self._set_timer(ophandle, int(retain_for)) if monitor.is_finished(): if boolean_of_arg( get_arg(ctx, "release-after-complete", "false")): self._release_ophandle(ophandle) if retain_for is None: # this GET is collecting the ophandle, so change its timer self._set_timer(ophandle, self.COLLECTED_HANDLE_LIFETIME) status = monitor.get_status() if isinstance(status, Failure): return defer.fail(status) return renderer
def _POST_stream_manifest(self, ctx): walker = ManifestStreamer(ctx, self.node) monitor = self.node.deep_traverse(walker) walker.setMonitor(monitor) # register to hear stopProducing. The walker ignores pauseProducing. IRequest(ctx).registerProducer(walker, True) d = monitor.when_done() def _done(res): IRequest(ctx).unregisterProducer() return res d.addBoth(_done) def _cancelled(f): f.trap(OperationCancelledError) return "Operation Cancelled" d.addErrback(_cancelled) def _error(f): # signal the error as a non-JSON "ERROR:" line, plus exception msg = "ERROR: %s(%s)\n" % (f.value.__class__.__name__, ", ".join( [str(a) for a in f.value.args])) msg += str(f) return msg d.addErrback(_error) return d
def childFactory(self, ctx, name): req = IRequest(ctx) if should_create_intermediate_directories(req): raise WebError("Cannot create directory '%s', because its " "parent is a file, not a directory" % name) raise WebError("Files have no children, certainly not named '%s'" % name)
def renderer(self, context, name): renderMethod = renderer.get(self, name, None) if renderMethod is None: raise MissingRenderMethod(self, name) # XXX Hack to avoid passing context and data to the render method. # Eventually the rendering system should just not pass these to us. return lambda self, ctx, data: renderMethod(IRequest(ctx), ctx.tag)
def _flattenElement(element, ctx): """ Use the new flattener implementation to flatten the given L{IRenderable} in a manner appropriate for the specified context. """ if ctx.precompile: return element synchronous = [] accumulator = [] request = IRequest(ctx, None) # XXX None case is DEPRECATED finished = deferflatten(request, element, ctx.isAttrib, True, accumulator.append) def cbFinished(ignored): if synchronous is not None: synchronous.append(None) return accumulator def ebFinished(err): if synchronous is not None: synchronous.append(err) else: return err finished.addCallbacks(cbFinished, ebFinished) if synchronous: if synchronous[0] is None: return accumulator synchronous[0].raiseException() synchronous = None return finished
def render_POST(self, ctx): req = IRequest(ctx) t = get_arg(req, "t", "").strip() replace = boolean_of_arg(get_arg(req, "replace", "true")) if t == "check": d = self._POST_check(req) elif t == "upload": # like PUT, but get the file data from an HTML form's input field # We could get here from POST /uri/mutablefilecap?t=upload, # or POST /uri/path/file?t=upload, or # POST /uri/path/dir?t=upload&name=foo . All have the same # behavior, we just ignore any name= argument if self.node.is_mutable(): d = self.replace_my_contents_with_a_formpost(req) else: if not replace: raise ExistingChildError() assert self.parentnode and self.name d = self.replace_me_with_a_formpost(req, self.client, replace) else: raise WebError("POST to file: bad t=%s" % t) when_done = get_arg(req, "when_done", None) if when_done: d.addCallback(lambda res: url.URL.fromString(when_done)) return d
def _POST_stream_deep_check(self, ctx): verify = boolean_of_arg(get_arg(ctx, "verify", "false")) repair = boolean_of_arg(get_arg(ctx, "repair", "false")) add_lease = boolean_of_arg(get_arg(ctx, "add-lease", "false")) walker = DeepCheckStreamer(ctx, self.node, verify, repair, add_lease) monitor = self.node.deep_traverse(walker) walker.setMonitor(monitor) # register to hear stopProducing. The walker ignores pauseProducing. IRequest(ctx).registerProducer(walker, True) d = monitor.when_done() def _done(res): IRequest(ctx).unregisterProducer() return res d.addBoth(_done) def _cancelled(f): f.trap(OperationCancelledError) return "Operation Cancelled" d.addErrback(_cancelled) def _error(f): # signal the error as a non-JSON "ERROR:" line, plus exception msg = "ERROR: %s(%s)\n" % (f.value.__class__.__name__, ", ".join([str(a) for a in f.value.args])) msg += str(f) return msg d.addErrback(_error) return d
def renderHTTP(self, nevow_ctx): context = pmap({ NEVOW_REQUEST: IRequest(nevow_ctx), }) d = execute(context, v(nevow()) + self._interceptors) d.addCallback(lambda _: b'') return d
def beforeRender(self, ctx): """ Before rendering this page, identify the correct URL for the login to post to, and the error message to display (if any), and fill the 'login action' and 'error' slots in the template accordingly. """ generator = ixmantissa.ISiteURLGenerator(self.store) url = generator.rootURL(IRequest(ctx)) url = url.child('__login__') for seg in self.segments: url = url.child(seg) for queryKey, queryValues in self.arguments.iteritems(): for queryValue in queryValues: url = url.add(queryKey, queryValue) req = inevow.IRequest(ctx) err = req.args.get('login-failure', ('', ))[0] if 0 < len(err): error = inevow.IQ(self.fragment).onePattern('error').fillSlots( 'error', err) else: error = '' ctx.fillSlots("login-action", url) ctx.fillSlots("error", error)
def locateChild(self, ctx, segments): """ Return a clone of this page that remembers its segments, so that URLs like /login/private/stuff will redirect the user to /private/stuff after login has completed. """ arguments = IRequest(ctx).args return self.__class__(self.store, segments, arguments), ()
def beforeRender(self, ctx): """ Before rendering, retrieve the hostname from the request being responded to and generate an URL which will serve as the root for all JavaScript modules to be loaded. """ request = IRequest(ctx) root = self.webSite.rootURL(request) self._moduleRoot = root.child('__jsmodule__')
def render_HEAD(self, ctx): req = IRequest(ctx) t = get_arg(req, "t", "").strip() if t: raise WebError("HEAD file: bad t=%s" % t) filename = get_arg(req, "filename", self.name) or "unknown" d = self.node.get_best_readable_version() d.addCallback(lambda dn: FileDownloader(dn, filename)) return d
def childFactory(self, ctx, name): req = IRequest(ctx) if isinstance(self.node, ProhibitedNode): raise FileProhibited(self.node.reason) if should_create_intermediate_directories(req): raise WebError("Cannot create directory %s, because its " "parent is a file, not a directory" % quote_output(name, encoding='utf-8')) raise WebError("Files have no children, certainly not named %s" % quote_output(name, encoding='utf-8'))
def renderHTTP(self, context): """ Render C{self.resource} through a L{StylesheetRewritingRequestWrapper}. """ request = IRequest(context) request = StylesheetRewritingRequestWrapper( request, self.installedOfferingNames, self.rootURL) context.remember(request, IRequest) return self.resource.renderHTTP(context)
def renderHTTP(self, ctx): req = IRequest(ctx) if req.method == 'GET': req.setHeader('Content-Type', 'text/plain') return 'PUT data here to create an object.' elif req.method == 'PUT': return self.handlePUT(req) else: req.setResponseCode(http.NOT_ALLOWED) req.setHeader('Content-Type', 'text/plain') return 'Method not allowed'
def __init__(self, ctx, origin): dirnode.DeepStats.__init__(self, origin) self.req = IRequest(ctx)
def renderHTTP(self, ctx): req = IRequest(ctx) gte = static.getTypeAndEncoding ctype, encoding = gte(self.filename, static.File.contentTypes, static.File.contentEncodings, defaultType="text/plain") req.setHeader("content-type", ctype) if encoding: req.setHeader("content-encoding", encoding) if boolean_of_arg(get_arg(req, "save", "False")): # tell the browser to save the file rather display it we don't # try to encode the filename, instead we echo back the exact same # bytes we were given in the URL. See the comment in # FileNodeHandler.render_GET for the sad details. req.setHeader("content-disposition", 'attachment; filename="%s"' % self.filename) filesize = self.filenode.get_size() assert isinstance(filesize, (int,long)), filesize first, size = 0, None contentsize = filesize req.setHeader("accept-ranges", "bytes") # TODO: for mutable files, use the roothash. For LIT, hash the data. # or maybe just use the URI for CHK and LIT. rangeheader = req.getHeader('range') if rangeheader: ranges = self.parse_range_header(rangeheader) # ranges = None means the header didn't parse, so ignore # the header as if it didn't exist. If is more than one # range, then just return the first for now, until we can # generate multipart/byteranges. if ranges is not None: first, last = ranges[0] if first >= filesize: raise WebError('First beyond end of file', http.REQUESTED_RANGE_NOT_SATISFIABLE) else: first = max(0, first) last = min(filesize-1, last) req.setResponseCode(http.PARTIAL_CONTENT) req.setHeader('content-range',"bytes %s-%s/%s" % (str(first), str(last), str(filesize))) contentsize = last - first + 1 size = contentsize req.setHeader("content-length", b"%d" % contentsize) if req.method == "HEAD": return "" finished = [] def _request_finished(ign): finished.append(True) req.notifyFinish().addBoth(_request_finished) d = self.filenode.read(req, first, size) def _finished(ign): if not finished: req.finish() def _error(f): lp = log.msg("error during GET", facility="tahoe.webish", failure=f, level=log.UNUSUAL, umid="xSiF3w") if finished: log.msg("but it's too late to tell them", parent=lp, level=log.UNUSUAL, umid="j1xIbw") return req._tahoe_request_had_error = f # for HTTP-style logging if req.startedWriting: # The content-type is already set, and the response code has # already been sent, so we can't provide a clean error # indication. We can emit text (which a browser might # interpret as something else), and if we sent a Size header, # they might notice that we've truncated the data. Keep the # error message small to improve the chances of having our # error response be shorter than the intended results. # # We don't have a lot of options, unfortunately. req.write("problem during download\n") req.finish() else: # We haven't written anything yet, so we can provide a # sensible error message. eh = MyExceptionHandler() eh.renderHTTP_exception(ctx, f) d.addCallbacks(_finished, _error) return req.deferred
def simple(self, ctx, text, code=http.BAD_REQUEST): req = IRequest(ctx) req.setResponseCode(code) #req.responseHeaders.setRawHeaders("content-encoding", []) #req.responseHeaders.setRawHeaders("content-disposition", []) req.setHeader("content-type", "text/plain;charset=utf-8") if isinstance(text, unicode): text = text.encode("utf-8") req.setHeader("content-length", str(len(text))) req.write(text) # TODO: consider putting the requested URL here req.finishRequest(False)
def text_plain(text, ctx): req = IRequest(ctx) req.setHeader("content-type", "text/plain") req.setHeader("content-length", len(text)) return text
def render_OPTIONS(self, ctx): """ Handle HTTP OPTIONS request by adding appropriate headers. :param ctx: client transaction from which request is extracted :returns: str (empty) """ req = IRequest(ctx) req.setHeader("server", "Tahoe-LAFS gateway") methods = ', '.join([m[7:] for m in dir(self) if m.startswith('render_')]) req.setHeader("allow", methods) req.setHeader("public", methods) req.setHeader("compliance", "rfc=2068, rfc=2616") req.setHeader("content-length", 0) return ""
class DeepCheckStreamer(dirnode.DeepStats): def __init__(self, ctx, origin, verify, repair, add_lease): dirnode.DeepStats.__init__(self, origin) self.req = IRequest(ctx) self.verify = verify self.repair = repair self.add_lease = add_lease def setMonitor(self, monitor): self.monitor = monitor def pauseProducing(self): pass def resumeProducing(self): pass def stopProducing(self): self.monitor.cancel() def add_node(self, node, path): dirnode.DeepStats.add_node(self, node, path) data = {"path": path, "cap": node.get_uri()} if IDirectoryNode.providedBy(node): data["type"] = "directory" elif IFileNode.providedBy(node): data["type"] = "file" else: data["type"] = "unknown" v = node.get_verify_cap() if v: v = v.to_string() data["verifycap"] = v or "" r = node.get_repair_cap() if r: r = r.to_string() data["repaircap"] = r or "" si = node.get_storage_index() if si: si = base32.b2a(si) data["storage-index"] = si or "" if self.repair: d = node.check_and_repair(self.monitor, self.verify, self.add_lease) d.addCallback(self.add_check_and_repair, data) else: d = node.check(self.monitor, self.verify, self.add_lease) d.addCallback(self.add_check, data) d.addCallback(self.write_line) return d def add_check_and_repair(self, crr, data): data["check-and-repair-results"] = json_check_and_repair_results(crr) return data def add_check(self, cr, data): data["check-results"] = json_check_results(cr) return data def write_line(self, data): j = json.dumps(data, ensure_ascii=True) assert "\n" not in j self.req.write(j+"\n") def finish(self): stats = dirnode.DeepStats.get_results(self) d = {"type": "stats", "stats": stats, } j = json.dumps(d, ensure_ascii=True) assert "\n" not in j self.req.write(j+"\n") return ""
def __init__(self, ctx, origin, verify, repair, add_lease): dirnode.DeepStats.__init__(self, origin) self.req = IRequest(ctx) self.verify = verify self.repair = repair self.add_lease = add_lease