def serve_file(sock: socket.socket, path: str) -> None: ''' Given a socket and the relative path to a file (relative to SERVER_SOCK), send that file to the socket if it exists. If the file doesn't exist, send a '404 Not Found' response. ''' if path == '/': path = '/index.html' abspath = os.path.normpath(os.path.join(SERVER_ROOT, path.lstrip('/'))) if not abspath.startswith(SERVER_ROOT): sock.sendall(RESPONSES['404']) return try: with open(abspath, 'rb') as f: stat = os.fstat(f.fileno()) content_type, encoding = mimetypes.guess_type(abspath) if content_type is None: content_type = 'application/octet-stream' if encoding is not None: content_type += f'; charset={encoding}' response_headers = RESPONSES['FILE_RESPONSE_TEMPLATE'].format( content_type=content_type, content_length=stat.st_size, ).encode('utf-8') sock.sendall(response_headers) sock.sendfile(f) except FileNotFoundError: sock.sendall(RESPONSES['404']) return
def serve_file(sock: socket.socket, path: str) -> None: """Given a socket and the relative path to a file (relative to SERVER_SOCK), send that file to the socket if it exists. If the file doesn't exist, send a "404 Not Found" response. """ if path == "/": path = "/index.html" abspath = os.path.normpath(os.path.join(SERVER_ROOT, path.lstrip("/"))) if not abspath.startswith(SERVER_ROOT): sock.sendall(NOT_FOUND_RESPONSE) return try: with open(abspath, "rb") as f: stat = os.fstat(f.fileno()) content_type, encoding = mimetypes.guess_type(abspath) if content_type is None: content_type = "application/octet-stream" if encoding is not None: content_type += f"; charset={encoding}" response_headers = FILE_RESPONSE_TEMPLATE.format( content_type=content_type, content_length=stat.st_size, ).encode("ascii") sock.sendall(response_headers) sock.sendfile(f) except FileNotFoundError: sock.sendall(NOT_FOUND_RESPONSE) return
def serve_file(sock: socket.socket, path: str) -> None: if path == "/": path = "/index.html" abspath = os.path.normcase(os.path.join(SERVER_ROOT, path.lstrip())) print(abspath) # if not abspath.startswith(SERVER_ROOT): # sock.sendall(NOT_FOUND_RESPONSE) # return try: with open("www/index.html", "rb") as f: stat = os.fstat(f.fileno()) content_type, encoding = mimetypes.guess_type(abspath) if content_type is None: content_type = "application/octet-stream" if encoding is not None: content_type += f"; charset={encoding}" response_headers = FILE_RESPONSE_TEMPLATE.format( content_type=content_type, content_length=stat.st_size, ).encode("ascii") sock.sendall(response_headers) sock.sendfile(f) except FileNotFoundError: sock.sendall(NOT_FOUND_RESPONSE) return
def serve_file(sock: socket.socket, path: str) -> None: '''Given a socket and the relative path to a file (relative to SERVER_SOCK), send that file to the socket if it exists. If the file does not exist, sent '404 Not Found' response.''' #construct path to file if path == "/": path = "/index.html" abspath = os.path.normpath(os.path.join(SERVER_ROOT, path.lstrip("/"))) if not abspath.startswith(SERVER_ROOT): sock.sendall(NOT_FOUND_RESPONSE) return try: with open(abspath, "rb") as f:#open file stat = os.fstat(f.fileno()) #get file descriptor and estimate attributes (size) content_type, encoding = mimetypes.guess_type(abspath)#guess file type based on URL if content_type is None:#check for content content_type = "application/octet-stream" if encoding is not None:#check encoding content_type += f"; charset={encoding}" #construct response from template response_headers = FILE_RESPONSE_TEMPLATE.format( content_type=content_type, content_length=stat.st_size, ).encode("ascii") sock.sendall(response_headers)#write file to socket sock.sendfile(f) except FileNotFoundError:#notify if file not found sock.sendall(NOT_FOUND_RESPONSE) return
def send(self, conn: socket): hdrs = self.form_headers() conn.sendall(hdrs) if self.filepath is None or self.method == 'HEAD': return with open(self.filepath, 'rb') as file: conn.sendfile(file)
def send_body(self, conn: socket.socket): """Send body into [conn].""" if self._content_io and (not self.request or self.request.command != "HEAD"): logging.debug('%s <- sending body', conn.getpeername()) with suppress(BrokenPipeError): conn.sendfile(self._content_io) logging.info('%s <- body sent - ok', conn.getpeername())
def handlefile(self, conn: socket.socket, fname: str, mode: Action): if mode == Action.POST: with open(fname, 'rb') as f: conn.sendfile(f) conn.shutdown(socket.SHUT_RD) elif mode == Action.GET: logging.info(f"Receiving data from {conn.getsockname()}") with open(fname, 'wb') as f: while True: data = conn.recv(Packet.BUFFER) f.write(data) if data == b'': break
def send(self, conn: socket): from Responder import HTTP_STATUS_MESSAGES headers = f'{self.__protocol} {self.__status} {HTTP_STATUS_MESSAGES[self.__status]}\r\n' headers += '\r\n'.join( [f'{key}: {value}' for key, value in self.__headers.items()]) + '\r\n\r\n' conn.sendall(headers.encode('utf-8')) if self.__filepath is None or self.__method == 'HEAD': return with open(self.__filepath, 'rb') as file: conn.sendfile(file)
def handle_request(connection: socket.socket, address, logger, root_dir): logger.debug("Connected at %r", address) try: req = models.Request(connection.recv(1024)) except IndexError: connection.send(b'Non HTTP protocol used') connection.close() logger.debug("Connection closed") return is_dir = False path = root_dir + urllib.parse.unquote(urllib.parse.urlparse(req.URL).path) if path[-1] == '/': is_dir = True path += 'index.html' resp_code = 200 if not os.path.exists(path): if is_dir: resp_code = 403 else: resp_code = 404 if path.find('../') != -1: resp_code = 403 resp: models.Response if resp_code == 200 and req.Method in methods: size = os.path.getsize(path) resp = models.Response(req.Protocol, req.Method, resp_code, mimetypes.guess_type(path)[0], size) else: resp = models.Response(req.Protocol, req.Method, resp_code) logger.debug(resp_code) connection.sendall(resp.get_raw_headers()) if req.Method == 'GET' and resp_code == 200: file = open(path, 'rb') connection.sendfile(file, 0) file.close() connection.shutdown(socket.SHUT_RDWR) connection.shutdown(socket.SHUT_RDWR) logger.debug("Connection closed")
def serve_file(conn: socket.socket, path, req: builders.HTTPRequest): try: resp = builders.HTTPResponse() content_size = os.path.getsize(path) content_type = get_content_type(path) resp.set_header('Content-Length', content_size) resp.set_header('Content-Type', content_type) conn.send(resp.to_bytes()) if req.method == methods.HEAD: return with open(path, 'rb') as file: conn.sendfile(file) except Exception as e: serve_not_found(conn)
def send(self, sock: socket.socket) -> None: """Write this response to a socket.""" content_length = self.headers.get_int("content-length") if content_length is None: try: body_stat = os.fstat(self.body.fileno()) content_length = body_stat.st_size except OSError: self.body.seek(0, os.SEEK_END) content_length = self.body.tell() self.body.seek(0, os.SEEK_SET) if content_length > 0: self.headers.add("content-length", str(content_length)) headers = b"HTTP/1.1 " + self.status + b"\r\n" for header_name, header_value in self.headers: headers += f"{header_name}: {header_value}\r\n".encode() sock.sendall(headers + b"\r\n") if content_length > 0: sock.sendfile(self.body) # type: ignore
def send_file_to_sock(sock: socket.socket, path: Path): with path.open("rb") as fptr: sock.sendfile(fptr)
def send(self, conn: socket.socket): logging.info(f"Sending file {self.fname} to client") with open(f'{config.config["dir"]}/{self.fname}', 'rb') as f: conn.sendfile(f) conn.shutdown(socket.SHUT_WR)