def error(f): message, code = humanize_failure(f) req = IRequest(ctx) req.setResponseCode(code) return json.dumps({ "error": message, })
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 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", b"%d" % len(text)) req.write(text) # TODO: consider putting the requested URL here req.finishRequest(False)
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 renderHTTP_exception(self, ctx, failure): """Render the error page.""" request = IRequest(ctx) request.setResponseCode(http.INTERNAL_SERVER_ERROR) res = self.renderHTTP(ctx) request.finishRequest(False) log.err(failure) service = IService(ctx) service.build_and_send(service.ADMIN, '[crash report] mes-souhaits.net', str(failure)) return res
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") if not self.filenode.is_mutable(): # TODO: look more closely at Request.setETag and how it interacts # with a conditional "if-etag-equals" request, I think this may # need to occur after the setResponseCode below si = self.filenode.get_storage_index() if si: req.setETag(base32.b2a(si)) # 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", str(contentsize)) if req.method == "HEAD": return "" # Twisted >=9.0 throws an error if we call req.finish() on a closed # HTTP connection. It also has req.notifyFinish() to help avoid it. finished = [] def _request_finished(ign): finished.append(True) if hasattr(req, "notifyFinish"): 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 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