def render(self, request): title = "Directory listing for %s" % urllib.unquote(request.path) s = """<html><head><title>%s</title><style> th, .even td, .odd td { padding-right: 0.5em; font-family: monospace} .even-dir { background-color: #efe0ef } .even { background-color: #eee } .odd-dir {background-color: #f0d0ef } .odd { background-color: #dedede } .icon { text-align: center } .listing { margin-left: auto; margin-right: auto; width: 50%%; padding: 0.1em; } body { border: 0; padding: 0; margin: 0; background-color: #efefef;} h1 {padding: 0.1em; background-color: #777; color: white; border-bottom: thin white dashed;} </style></head><body><div class="directory-listing"><h1>%s</h1>""" % (title, title) s += "<table>" s += "<tr><th>Filename</th><th>Size</th><th>Last Modified</th><th>File Type</th></tr>" even = False for row in self.data_listing(request, None): s += '<tr class="%s">' % (even and 'even' or 'odd', ) s += '<td><a href="%(link)s">%(linktext)s</a></td><td align="right">%(size)s</td><td>%(lastmod)s</td><td>%(type)s</td></tr>' % row even = not even s += "</table></div></body></html>" response = http.Response(200, {}, s) response.headers.setHeader("content-type", http_headers.MimeType('text', 'html')) return response
def makeUnsatisfiable(request, oldresponse): if request.headers.hasHeader('if-range'): return oldresponse # Return resource instead of error response = http.Response(responsecode.REQUESTED_RANGE_NOT_SATISFIABLE) response.headers.setHeader( "content-range", ('bytes', None, None, oldresponse.stream.length)) return response
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(method)
def render(self, request): for filterscript in self.filters: if os.path.exists(filterscript): return runCGI(request, self.filename, filterscript) else: log.err(self.__class__.__name__ + ' could not find any of: ' + ', '.join(self.filters)) return http.Response(responsecode.INTERNAL_SERVER_ERROR)
def __init__(self, request): from OPSI.web2 import http components.Componentized.__init__(self) self.request = request self.response = http.Response(stream=stream.ProducerStream()) # This deferred will be fired by the first call to write on OldRequestAdapter # and will cause the headers to be output. self.deferredResponse = defer.Deferred()
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 _setResponse(self, result): logger.debug(u"Client requests DAV operation: {0}", self.request) if not self.resource._authRequired and self.request.method not in ( 'GET', 'PROPFIND', 'OPTIONS', 'USERINFO', 'HEAD'): logger.critical(u"Method '{0}' not allowed (read only)", self.request.method) return http.Response(code=responsecode.FORBIDDEN, stream="Readonly!") return self.resource.renderHTTP_super(self.request, self)
def _generateResponse(self, result): if not isinstance(result, http.Response): result = http.Response() result.code = responsecode.OK result.headers.setHeader( 'content-type', http_headers.MimeType("text", "html", {"charset": "utf-8"})) result.stream = stream.IByteStream("") return result
def render(self, request): # For GET/HEAD: Return an error message s = ( "<html><head><title>XML-RPC responder</title></head>" "<body><h1>XML-RPC responder</h1>POST your XML-RPC here.</body></html>" ) return http.Response( responsecode.OK, {'content-type': http_headers.MimeType('text', 'html')}, s)
def testIfMatch(self): request = http.Request(None, "GET", "/", "HTTP/1.1", 0, http_headers.Headers()) out_headers = http_headers.Headers() response = http.Response(responsecode.OK, out_headers, None) # Behavior with no ETag set, should be same as with an ETag request.headers.setRawHeaders("If-Match", ('*', )) self.checkPreconditions(request, response, True, responsecode.OK) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED, entityExists=False) # Ask for tag, but no etag set. request.headers.setRawHeaders("If-Match", ('"frob"', )) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) ## Actually set the ETag header out_headers.setHeader("ETag", http_headers.ETag('foo')) out_headers.setHeader("Last-Modified", 946771200) # Sun, 02 Jan 2000 00:00:00 GMT # behavior of entityExists request.headers.setRawHeaders("If-Match", ('*', )) self.checkPreconditions(request, response, True, responsecode.OK) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED, entityExists=False) # tag matches request.headers.setRawHeaders("If-Match", ('"frob", "foo"', )) self.checkPreconditions(request, response, True, responsecode.OK) # none match request.headers.setRawHeaders("If-Match", ('"baz", "bob"', )) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) # But if we have an error code already, ignore this header response.code = responsecode.INTERNAL_SERVER_ERROR self.checkPreconditions(request, response, True, responsecode.INTERNAL_SERVER_ERROR) response.code = responsecode.OK # Must only compare strong tags out_headers.setHeader("ETag", http_headers.ETag('foo', weak=True)) request.headers.setRawHeaders("If-Match", ('W/"foo"', )) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED)
def _cbRender(self, result, request): if not isinstance(result, Fault): result = (result, ) try: s = xmlrpclib.dumps(result, methodresponse=1) except: f = Fault(self.FAILURE, "can't serialize output") s = xmlrpclib.dumps(f, methodresponse=1) return http.Response( responsecode.OK, {'content-type': http_headers.MimeType('text', 'xml')}, s)
def render(self, req): if req.avatar.username == 'anonymous': if not self.sendOwnHeaders: raise http.HTTPError(responsecode.UNAUTHORIZED) else: return http.Response( responsecode.UNAUTHORIZED, {'www-authenticate': [('basic', { 'realm': 'foo' })]}) else: return super(NonAnonymousResource, self).render(req)
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.response = http.Response(responsecode.INTERNAL_SERVER_ERROR) self._sendResponse() self.stream.finish()
def _renderError(self, failure): result = http.Response() result.headers.setHeader( 'content-type', http_headers.MimeType("text", "html", {"charset": "utf-8"})) error = u'Unknown error' try: failure.raiseException() except Exception as error: error = forceUnicode(error) result.stream = stream.IByteStream( stream.IByteStream(error.encode('utf-8'))) return result
def _renderError(self, failure): result = http.Response() result.headers.setHeader( 'content-type', http_headers.MimeType("text", "html", {"charset": "utf-8"})) error = u'Unknown error' try: failure.raiseException() except Exception as err: error = {'class': err.__class__.__name__, 'message': unicode(err)} error = toJson({"id": None, "result": None, "error": error}) result.stream = stream.IByteStream(error.encode('utf-8')) return result
def renderHTTP(self, request): try: if self._readOnly and request.method not in ('GET', 'PROPFIND', 'OPTIONS', 'USERINFO', 'HEAD'): logger.warning(u"Command %s not allowed (readonly)" % request.method) return http.Response(code=responsecode.FORBIDDEN, stream="Readonly!") worker = self.WorkerClass(self._service, request, self) return worker.process() except Exception as exc: logger.logException(exc)
def _setCookie(self, result): logger.debug(u"%s._setCookie" % self) if not self.session: return result # Add cookie to headers cookie = http_headers.Cookie( self.session.name.encode('ascii', 'replace'), self.session.uid.encode('ascii', 'replace'), path='/') if not isinstance(result, http.Response): result = http.Response() result.headers.setHeader('set-cookie', [cookie]) return result
def startWSGIResponse(self, status, response_headers, exc_info=None): # Called in application thread if exc_info is not None: try: if self.headersSent: raise exc_info[0], exc_info[1], exc_info[2] finally: exc_info = None elif self.response is not None: raise AlreadyStartedResponse, 'startWSGIResponse(%r)' % status status = int(status.split(' ')[0]) self.response = http.Response(status) for key, value in response_headers: self.response.headers.addRawHeader(key, value) return self.write
def testIfModifiedSince(self): if time.time() < 946771200: raise "Your computer's clock is way wrong, this test will be invalid." request = http.Request(None, "GET", "/", "HTTP/1.1", 0, http_headers.Headers()) out_headers = http_headers.Headers() response = http.Response(responsecode.OK, out_headers, None) # No Last-Modified => always succeed request.headers.setRawHeaders("If-Modified-Since", ('Mon, 03 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, True, responsecode.OK) # Set output headers out_headers.setHeader("ETag", http_headers.ETag('foo')) out_headers.setHeader("Last-Modified", 946771200) # Sun, 02 Jan 2000 00:00:00 GMT request.headers.setRawHeaders("If-Modified-Since", ('Mon, 03 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED) # With a non-GET method request.method = "PUT" self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) request.method = "GET" request.headers.setRawHeaders("If-Modified-Since", ('Sat, 01 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, True, responsecode.OK) # But if we have an error code already, ignore this header response.code = responsecode.INTERNAL_SERVER_ERROR self.checkPreconditions(request, response, True, responsecode.INTERNAL_SERVER_ERROR) response.code = responsecode.OK # invalid date => header ignored request.headers.setRawHeaders("If-Modified-Since", ('alalalalalalalalalala', )) self.checkPreconditions(request, response, True, responsecode.OK) # date in the future => assume modified request.headers.setHeader("If-Modified-Since", time.time() + 500) self.checkPreconditions(request, response, True, responsecode.OK)
def testWithoutHeaders(self): request = http.Request(None, "GET", "/", "HTTP/1.1", 0, http_headers.Headers()) out_headers = http_headers.Headers() response = http.Response(responsecode.OK, out_headers, None) self.checkPreconditions(request, response, True, responsecode.OK) out_headers.setHeader("ETag", http_headers.ETag('foo')) self.checkPreconditions(request, response, True, responsecode.OK) out_headers.removeHeader("ETag") out_headers.setHeader("Last-Modified", 946771200) # Sun, 02 Jan 2000 00:00:00 GMT self.checkPreconditions(request, response, True, responsecode.OK) out_headers.setHeader("ETag", http_headers.ETag('foo')) self.checkPreconditions(request, response, True, responsecode.OK)
def runCGI(request, filename, filterscript=None): # Make sure that we don't have an unknown content-length if request.stream.length is None: return http.Response(responsecode.LENGTH_REQUIRED) env = createCGIEnvironment(request) env['SCRIPT_FILENAME'] = filename if '=' in request.querystring: qargs = [] else: qargs = [urllib.unquote(x) for x in request.querystring.split('+')] if filterscript is None: filterscript = filename qargs = [filename] + qargs else: qargs = [filterscript, filename] + qargs d = defer.Deferred() proc = CGIProcessProtocol(request, d) reactor.spawnProcess(proc, filterscript, qargs, env, os.path.dirname(filename)) return d
def testIfUnmodifiedSince(self): request = http.Request(None, "GET", "/", "HTTP/1.1", 0, http_headers.Headers()) out_headers = http_headers.Headers() response = http.Response(responsecode.OK, out_headers, None) # No Last-Modified => always fail. request.headers.setRawHeaders("If-Unmodified-Since", ('Mon, 03 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) # Set output headers out_headers.setHeader("ETag", http_headers.ETag('foo')) out_headers.setHeader("Last-Modified", 946771200) # Sun, 02 Jan 2000 00:00:00 GMT request.headers.setRawHeaders("If-Unmodified-Since", ('Mon, 03 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, True, responsecode.OK) request.headers.setRawHeaders("If-Unmodified-Since", ('Sat, 01 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) # But if we have an error code already, ignore this header response.code = responsecode.INTERNAL_SERVER_ERROR self.checkPreconditions(request, response, True, responsecode.INTERNAL_SERVER_ERROR) response.code = responsecode.OK # invalid date => header ignored request.headers.setRawHeaders("If-Unmodified-Since", ('alalalalalalalalalala', )) self.checkPreconditions(request, response, True, responsecode.OK)
class File(StaticRenderMixin): """ File is a resource that represents a plain non-interpreted file (although it can look for an extension like .rpy or .cgi and hand the file to a processor for interpretation if you wish). Its constructor takes a file path. Alternatively, you can give a directory path to the constructor. In this case the resource will represent that directory, and its children will be files underneath that directory. This provides access to an entire filesystem tree with a single Resource. If you map the URL 'http://server/FILE' to a resource created as File('/tmp'), then http://server/FILE/ will return an HTML-formatted listing of the /tmp/ directory, and http://server/FILE/foo/bar.html will return the contents of /tmp/foo/bar.html . """ implements(iweb.IResource) def _getContentTypes(self): if not hasattr(File, "_sharedContentTypes"): File._sharedContentTypes = loadMimeTypes() return File._sharedContentTypes contentTypes = property(_getContentTypes) contentEncodings = {".gz": "gzip", ".bz2": "bzip2"} processors = {} indexNames = ["index", "index.html", "index.htm", "index.trp", "index.rpy"] type = None def __init__(self, path, defaultType="text/plain", ignoredExts=(), processors=None, indexNames=None): """Create a file with the given path. """ super(File, self).__init__() self.putChildren = {} self.fp = filepath.FilePath(path) # Remove the dots from the path to split self.defaultType = defaultType self.ignoredExts = list(ignoredExts) if processors is not None: self.processors = dict([(key.lower(), value) for key, value in processors.items()]) if indexNames is not None: self.indexNames = indexNames def exists(self): return self.fp.exists() def etag(self): if not self.fp.exists(): return None st = self.fp.statinfo # # Mark ETag as weak if it was modified more recently than we can # measure and report, as it could be modified again in that span # and we then wouldn't know to provide a new ETag. # weak = (time.time() - st.st_mtime <= 1) return http_headers.ETag("%X-%X-%X" % (st.st_ino, st.st_size, st.st_mtime), weak=weak) def lastModified(self): if self.fp.exists(): return self.fp.getmtime() else: return None def creationDate(self): if self.fp.exists(): return self.fp.getmtime() else: return None def contentLength(self): if self.fp.exists(): if self.fp.isfile(): return self.fp.getsize() else: # Computing this would require rendering the resource; let's # punt instead. return None else: return None def _initTypeAndEncoding(self): self._type, self._encoding = getTypeAndEncoding( self.fp.basename(), self.contentTypes, self.contentEncodings, self.defaultType) # Handle cases not covered by getTypeAndEncoding() if self.fp.isdir(): self._type = "httpd/unix-directory" def contentType(self): if not hasattr(self, "_type"): self._initTypeAndEncoding() return http_headers.MimeType.fromString(self._type) def contentEncoding(self): if not hasattr(self, "_encoding"): self._initTypeAndEncoding() return self._encoding def displayName(self): if self.fp.exists(): return self.fp.basename() else: return None def ignoreExt(self, ext): """Ignore the given extension. Serve file.ext if file is requested """ self.ignoredExts.append(ext) def directoryListing(self): return dirlist.DirectoryLister(self.fp.path, self.listChildren(), self.contentTypes, self.contentEncodings, self.defaultType) def putChild(self, name, child): """ Register a child with the given name with this resource. @param name: the name of the child (a URI path segment) @param child: the child to register """ self.putChildren[name] = child def getChild(self, name): """ Look up a child resource. @return: the child of this resource with the given name. """ if name == "": return self child = self.putChildren.get(name, None) if child: return child child_fp = self.fp.child(name) if child_fp.exists(): return self.createSimilarFile(child_fp.path) else: return None def listChildren(self): """ @return: a sequence of the names of all known children of this resource. """ children = self.putChildren.keys() if self.fp.isdir(): children += [c for c in self.fp.listdir() if c not in children] return children def locateChild(self, req, segments): """ See L{IResource}C{.locateChild}. """ # If getChild() finds a child resource, return it child = self.getChild(segments[0]) if child is not None: return (child, segments[1:]) # If we're not backed by a directory, we have no children. # But check for existance first; we might be a collection resource # that the request wants created. self.fp.restat(False) if self.fp.exists() and not self.fp.isdir(): return (None, ()) # OK, we need to return a child corresponding to the first segment path = segments[0] if path: fpath = self.fp.child(path) else: # Request is for a directory (collection) resource return (self, server.StopTraversal) # Don't run processors on directories - if someone wants their own # customized directory rendering, subclass File instead. if fpath.isfile(): processor = self.processors.get(fpath.splitext()[1].lower()) if processor: return (processor(fpath.path), segments[1:]) elif not fpath.exists(): sibling_fpath = fpath.siblingExtensionSearch(*self.ignoredExts) if sibling_fpath is not None: fpath = sibling_fpath return self.createSimilarFile(fpath.path), segments[1:] def renderHTTP(self, req): self.fp.restat(False) return super(File, self).renderHTTP(req) def render(self, req): """You know what you doing.""" if not self.fp.exists(): return responsecode.NOT_FOUND if self.fp.isdir(): if req.uri[-1] != "/": # Redirect to include trailing '/' in URI return http.RedirectResponse( req.unparseURL(path=req.path + '/')) else: ifp = self.fp.childSearchPreauth(*self.indexNames) if ifp: # Render from the index file standin = self.createSimilarFile(ifp.path) else: # Render from a DirectoryLister #standin = self.directoryListing() standin = dirlist.DirectoryLister(self.fp.path, self.listChildren(), self.contentTypes, self.contentEncodings, self.defaultType) return standin.render(req) try: f = self.fp.open() except IOError, e: import errno if e[0] == errno.EACCES: return responsecode.FORBIDDEN elif e[0] == errno.ENOENT: return responsecode.NOT_FOUND else: raise response = http.Response() response.stream = stream.FileStream(f, 0, self.fp.getsize()) for (header, value) in ( ("content-type", self.contentType()), ("content-encoding", self.contentEncoding()), ): if value is not None: response.headers.setHeader(header, value) return response
def createRequest(self): self.stream = stream_mod.ProducerStream(self.length) self.response = http.Response(self.code, self.inHeaders, self.stream) self.stream.registerProducer(self, True) del self.inHeaders
def renderHTTP(self, req): return http.Response(responsecode.NOT_FOUND)
def render(self, req): return http.Response(200)
def render(self, req): return http.Response(stream="Host:%s, Path:%s" % (req.host, req.path))
def render(self, req): return http.Response(stream="prepath:%s postpath:%s" % (req.prepath, req.postpath))
def render(self, req): return http.Response(self.responseCode, headers=self.responseHeaders, stream=self.responseStream())
def testIfNoneMatch(self): request = http.Request(None, "GET", "/", "HTTP/1.1", 0, http_headers.Headers()) out_headers = http_headers.Headers() response = http.Response(responsecode.OK, out_headers, None) request.headers.setRawHeaders("If-None-Match", ('"foo"', )) self.checkPreconditions(request, response, True, responsecode.OK) out_headers.setHeader("ETag", http_headers.ETag('foo')) out_headers.setHeader("Last-Modified", 946771200) # Sun, 02 Jan 2000 00:00:00 GMT # behavior of entityExists request.headers.setRawHeaders("If-None-Match", ('*', )) request.method = "PUT" self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) request.method = "GET" self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED) self.checkPreconditions(request, response, True, responsecode.OK, entityExists=False) # tag matches request.headers.setRawHeaders("If-None-Match", ('"frob", "foo"', )) request.method = "PUT" self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) request.method = "GET" self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED) # now with IMS, also: request.headers.setRawHeaders("If-Modified-Since", ('Mon, 03 Jan 2000 00:00:00 GMT', )) request.method = "PUT" self.checkPreconditions(request, response, False, responsecode.PRECONDITION_FAILED) request.method = "GET" self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED) request.headers.setRawHeaders("If-Modified-Since", ('Sat, 01 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, True, responsecode.OK) request.headers.removeHeader("If-Modified-Since") # none match request.headers.setRawHeaders("If-None-Match", ('"baz", "bob"', )) self.checkPreconditions(request, response, True, responsecode.OK) # now with IMS, also: request.headers.setRawHeaders("If-Modified-Since", ('Mon, 03 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, True, responsecode.OK) request.headers.setRawHeaders("If-Modified-Since", ('Sat, 01 Jan 2000 00:00:00 GMT', )) self.checkPreconditions(request, response, True, responsecode.OK) request.headers.removeHeader("If-Modified-Since") # But if we have an error code already, ignore this header response.code = responsecode.INTERNAL_SERVER_ERROR self.checkPreconditions(request, response, True, responsecode.INTERNAL_SERVER_ERROR) response.code = responsecode.OK # Weak tags okay for GET out_headers.setHeader("ETag", http_headers.ETag('foo', weak=True)) request.headers.setRawHeaders("If-None-Match", ('W/"foo"', )) self.checkPreconditions(request, response, False, responsecode.NOT_MODIFIED) # Weak tags not okay for other methods request.method = "PUT" out_headers.setHeader("ETag", http_headers.ETag('foo', weak=True)) request.headers.setRawHeaders("If-None-Match", ('W/"foo"', )) self.checkPreconditions(request, response, True, responsecode.OK)