def _extents(self, resp, context): # Older daemon considered "/extents" as part of the ticket id, and will # fail to authorize the request. if "extents" not in self.features: raise http.Error(http.FORBIDDEN, "No extents for you!") if context not in self.extents: raise http.Error(http.NOT_FOUND, "No dirty extents for you!") log.debug("EXTENTS context=%s", context) resp.send_json(self.extents[context])
def get(self, req, resp): complete = self.file.seek(0, os.SEEK_END) offset = 0 size = complete # Handle range request. if req.range: offset = req.range.first if offset < 0: offset += complete size = complete - offset elif req.range.last is not None: size = req.range.last - offset + 1 else: size = complete - offset if offset + size > complete: raise http.Error(http.REQUESTED_RANGE_NOT_SATISFIABLE, "Requested {} bytes, available {} bytes".format( size, complete - offset), content_range="bytes */{}".format(complete - offset)) resp.headers["content-length"] = size if req.range: resp.status_code = http.PARTIAL_CONTENT resp.headers["content-range"] = "bytes %d-%d/%d" % ( offset, offset + size - 1, complete) self.file.seek(offset) resp.write(self.file.read(size))
def put(self, req, resp, name): count = req.content_length with open("/dev/null", "wb") as f: while count: with req.clock.run("read"): chunk = req.read(1024 * 1024) if not chunk: raise http.Error(400, "Client disconnected") with req.clock.run("write"): f.write(chunk) count -= len(chunk)
def patch(self, req, resp, path=None): """ Implement PATCH/zero and PATCH/flush. """ self.requests += 1 msg = json.loads(req.read()) if msg["op"] == "zero": self._zero(msg) elif msg["op"] == "flush": self._flush() else: raise http.Error(http.BAD_REQUEST, "Invalid PATCH request")
def put(self, req, resp, ticket): if req.headers.get("expect") == "100-continue": resp.send_info(http.CONTINUE) count = req.content_length resp.headers["content-length"] = count while count: chunk = req.read(1024 * 1024) if not chunk: raise http.Error(http.BAD_REQUEST, "Client disconnected") resp.write(chunk) count -= len(chunk)
def put(self, req, resp, ticket): if req.headers.get("expect") == "100-continue": resp.send_info(http.CONTINUE) count = req.content_length resp.headers["content-length"] = count buf = bytearray(1024**2) with memoryview(buf) as view: while count: n = req.readinto(buf) if not n: raise http.Error(http.BAD_REQUEST, "Client disconnected") resp.write(view[:n]) count -= n
def get(self, req, resp): # Fail after sending the first part of the response. The # connection shold be closed. resp.headers["content-length"] = 1000 resp.write(b"Starting response...") raise http.Error(http.INTERNAL_SERVER_ERROR, "No more data for you!")
def put(self, req, resp): # Fail after reading the entire request payload, so the server # should keep the connection open. req.read() raise http.Error(http.FORBIDDEN, "No data for you!")
def put(self, req, resp, name): # Raising without reading payload wil fail with EPIPE on the # client side. If the client is careful, it will get error 403. raise http.Error(http.FORBIDDEN, "No data for you!")
def get(self, req, resp, name): raise http.Error(http.FORBIDDEN, "No data for you!")
def get(self, req, resp, name): if name not in req.context: raise http.Error(http.NOT_FOUND, "No such name {!r}".format(name)) value = req.context[name] resp.headers["content-length"] = len(value) resp.write(value)
def put(self, req, resp): offset = req.content_range.first if req.content_range else 0 self.file.seek(offset) self.file.write(req.read()) if req.length != 0: raise http.Error(http.BAD_REQUEST, "Unexpected EOF")