📄 http.py
字号:
self.request_uri = uri self.request_version = version uri_query = uri.split('?') if len(uri_query) == 1: self.request_path = uri else: self.request_path = uri_query[0] self.request_query = uri_query[1] self.request_args = parseQueryArgs(self.request_query) self.args = self.request_args def parseRequestHeaders(self): header_bytes = "" header_count = 0 while True: if header_count >= self.max_headers: self.requestError(BAD_REQUEST, "Bad request (too many headers)") line = self.rin.readline() header_bytes += line header_count += 1 if line == '\r\n' or line == '\n' or line == '': break header_input = StringIO(header_bytes) self.request_headers = Message(header_input) def parseRequestCookies(self): cookie_hdr = self.getHeader("cookie") if not cookie_hdr: return for cookie in cookie_hdr.split(';'): try: cookie = cookie.lstrip() (k, v) = cookie.split('=', 1) self.request_cookies[k] = v except ValueError: pass def parseRequestArgs(self): if ((self.content is None) or (self.request_method != "POST")): return content_type = self.getHeader('content-type') if not content_type: return (encoding, params) = cgi.parse_header(content_type) if encoding == URLENCODED: xargs = cgi.parse_qs(self.content.getvalue(), keep_blank_values=True) elif encoding == MULTIPART_FORM_DATA: xargs = cgi.parse_multipart(self.content, params) else: xargs = {} self.request_args.update(xargs) def getCookie(self, k): return self.request_cookies[k] def readContent(self): try: self.content_length = int(self.getHeader("Content-Length")) except: return if self.content_length > self.max_content_length: self.requestError(REQUEST_ENTITY_TOO_LARGE) self.content = self.rin.read(self.content_length) self.content = StringIO(self.content) self.content.seek(0,0) def parseRequest(self): self.request_line = self.rin.readline() self.parseRequestLine() self.parseRequestHeaders() self.parseRequestCookies() connection_mode = self.getHeader('Connection') self.setCloseConnection(connection_mode) self.readContent() self.parseRequestArgs() def setCloseConnection(self, mode): if not mode: return mode = mode.lower() if mode == 'close': self.close_connection = True elif (mode == 'keep-alive') and (self.http_version >= (1, 1)): self.close_connection = False def getCloseConnection(self): return self.close_connection def getHeader(self, k, v=None): return self.request_headers.get(k, v) def getRequestMethod(self): return self.request_method def getRequestPath(self): return self.request_path def setResponseCode(self, code, status=None, msg=None): self.response_code = code if not status: status = getStatus(code) self.response_status = status def setResponseHeader(self, k, v): k = k.lower() self.response_headers[k] = v if k == 'connection': self.setCloseConnection(v) setHeader = setResponseHeader def setLastModified(self, when): # time.time() may be a float, but the HTTP-date strings are # only good for whole seconds. when = long(math.ceil(when)) if (not self.last_modified) or (self.last_modified < when): self.lastModified = when modified_since = self.getHeader('if-modified-since') if modified_since: modified_since = stringToDatetime(modified_since) if modified_since >= when: self.setResponseCode(NOT_MODIFIED) self.cached = True def setContentType(self, ty): self.setResponseHeader("Content-Type", ty) def setEtag(self, etag): if etag: self.etag = etag tags = self.getHeader("if-none-match") if tags: tags = tags.split() if (etag in tags) or ('*' in tags): if self.request_method in ("HEAD", "GET"): code = NOT_MODIFIED else: code = PRECONDITION_FAILED self.setResponseCode(code) self.cached = True def addCookie(self, k, v, expires=None, domain=None, path=None, max_age=None, comment=None, secure=None): cookie = v if expires != None: cookie += "; Expires=%s" % expires if domain != None: cookie += "; Domain=%s" % domain if path != None: cookie += "; Path=%s" % path if max_age != None: cookie += "; Max-Age=%s" % max_age if comment != None: cookie += "; Comment=%s" % comment if secure: cookie += "; Secure" self.response_cookies[k] = cookie def sendResponseHeaders(self): if self.etag: self.setResponseHeader("ETag", self.etag) for (k, v) in self.response_headers.items(): self.send("%s: %s\r\n" % (k.capitalize(), v)) for (k, v) in self.response_cookies.items(): self.send("Set-Cookie: %s=%s\r\n" % (k, v)) self.send("\r\n") def sendResponse(self): if self.response_sent: return self.response_sent = True send_body = self.hasBody() if not self.close_connection: self.setResponseHeader("Connection", "keep-alive") self.setResponseHeader("Pragma", "no-cache") self.setResponseHeader("Cache-Control", "no-cache") self.setResponseHeader("Expires", "-1") if send_body: self.output.seek(0, 0) body = self.output.getvalue() body_length = len(body) self.setResponseHeader("Content-Length", body_length) if self.http_version > (0, 9): self.send("%s %d %s\r\n" % (self.http_version_string, self.response_code, self.response_status)) self.sendResponseHeaders() if send_body: self.send(body) self.flush() def write(self, data): self.output.write(data) def send(self, data): #print 'send>', data self.out.write(data) def flush(self): self.out.flush() def hasNoBody(self): return ((self.request_method == "HEAD") or (self.response_code in NO_BODY_CODES) or self.cached) def hasBody(self): return not self.hasNoBody() def process(self): pass return self.close_connection def getRequestHostname(self): """Get the hostname that the user passed in to the request. Uses the 'Host:' header if it is available, and the host we are listening on otherwise. """ return (self.getHeader('host') or socket.gethostbyaddr(self.getHostAddr())[0] ).split(':')[0] def getHost(self): return self.host def getHostAddr(self): return self.host[0] def getPort(self): return self.host[1] def setHost(self, host, port, ssl=0): """Change the host and port the request thinks it's using. This method is useful for working with reverse HTTP proxies (e.g. both Squid and Apache's mod_proxy can do this), when the address the HTTP client is using is different than the one we're listening on. For example, Apache may be listening on https://www.example.com, and then forwarding requests to http://localhost:8080, but we don't want HTML produced to say 'http://localhost:8080', they should say 'https://www.example.com', so we do:: request.setHost('www.example.com', 443, ssl=1) """ self.forceSSL = ssl self.received_headers["host"] = host self.host = (host, port)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -