Python 实现 Filebrowser

Python 实现 Filebrowser

异步IO实现,HTTP1.0, 200,404,405等信息。实现GET,HEAD, POST方法

一、 代码实现

FileBrowser.py

p# -*- coding: utf-8 -*-
# @File    : FileBrowser.py
# @Author  : zy
import argparse
import asyncio
import urllib.parse
import mimetypes
import os, json, time

html404 = b'<html><head><title>404 Not Found</title></head><body><center><h1>404 Not Found</h1></center></body></html>'
html405 = b'<html><head><title>405 Method Not Found</title></head><body><center><h1>405 Method Not Found</h1></center></body></html>'


async def dispatch(reader, writer):
    try:
        data = await reader.readline()
        if data == b'\r\n':
            return
        message = data.decode().split(' ')
        print(message)  # ['GET', '/', 'HTTP/1.1\r\n']
        # message[0] method
        # message[1] dir
        if message[1] == "./favicon.ico":
            return

        if message[0] == "GET":  # Method GET returns 200 response.
            dir_path = urllib.parse.unquote(message[1])
            if dir_path[0] != '/':
                dir_path = '/' + dir_path[0]
            relative_path = root_dir + dir_path
            print(relative_path)
            if os.path.isfile(relative_path):  # open the file and guess the mimetype.
                mimetype = mimetypes.guess_type(relative_path)[0]
                if mimetype is None:
                    mimetype = 'application/octet-stream'
                httpresponse = [b'HTTP/1.0 200 OK\r\n',
                                bytes('Content-Type:', encoding='UTF-8') +
                                bytes(mimetype + '; charset=utf-8\r\n', encoding='UTF-8'),
                                bytes('Content-Length: ' + str(os.path.getsize(relative_path)) + '\r\n',
                                      encoding="UTF-8"),
                                b'\r\n']
                file = open(relative_path, 'rb')
                httpresponse.append(file.read())
                writer.writelines(httpresponse)
            elif os.path.isdir(relative_path):  # homepage
                httpresponse = [b'HTTP/1.0 200 OK\r\n',
                                b'Content-Type:text/html; charset=utf-8\r\n',
                                b'Connection: close\r\n', b'\r\n',
                                bytes('<html><head><title>Index of ' + relative_path + '</title></head><body>\r\n',
                                      encoding="UTF-8"),
                                bytes('<div style="position:relative;"><img src="https://www.sustech.edu.cn/wp-content/uploads/%E6%A0%A1%E5%8E%86-1.jpg?id=8835261" width="100%"height="30%"></div><div style="position:absolute; left:80px; top:50px; "><img src="https://www.sustech.edu.cn/wp-content/themes/twentyseventeen/images/sustech-logo-cn.png" width="433" height="86"/></div>',encoding='UTF-8'),
                                bytes('<h1>Index of ' + relative_path + '</h1><hr><ul>\r\n', encoding='UTF-8'),
                                bytes('<li><a href="../">..</a></li><br>\r\n', encoding='UTF-8')]
                dirlist = os.listdir(relative_path)
                print(dirlist)
                for i in range(len(dirlist)):
                    if os.path.isfile(dirlist[i]):  # file
                        httpresponse.append(
                            bytes('<li><a href="' + dirlist[i] + '">' + dirlist[i] + "</a></li><br>\r\n",
                                  encoding='UTF-8'))
                    else:  # directory
                        httpresponse.append(
                            bytes('<li><a href="' + dirlist[i] + '/">' + dirlist[i] + '</a></li><br>\r\n',
                                  encoding='UTF-8'))
                httpresponse.append(bytes('</ul><hr></body></html>', encoding='UTF-8'))
                writer.writelines(httpresponse)
            else:  # Not existing file or directory returns 404 response.
                writer.writelines([
                    b'HTTP/1.0 404 Method Not Found\r\n',
                    b'Content-Type:text/html; charset=utf-8\r\n',
                    b'Connection: close\r\n',
                    b'\r\n',
                    html404,
                    b'\r\n'
                ])
            await writer.drain()
            writer.close()

        elif message[0] == "HEAD":  # Method HEAD returns 200 response and the head of http response if such dir exists .
            dir_path = urllib.parse.unquote(message[1])
            if dir_path[0] != '/':
                dir_path = '/' + dir_path[0]
            relative_path = root_dir + dir_path
            print(relative_path)
            if os.path.isfile(relative_path):  # Add mimetype to the http header if the path is a file.
                mimetype = mimetypes.guess_type(relative_path)[0]
                if mimetype is None:
                    mimetype = 'application/octet-stream'
                httpresponse = [b'HTTP/1.0 200 OK\r\n',
                                bytes('Content-Type:', encoding='UTF-8') +
                                bytes(mimetype + '; charset=utf-8\r\n', encoding='UTF-8'),
                                bytes('Content-Length: ' + str(os.path.getsize(relative_path)) + '\r\n',
                                      encoding="UTF-8"),
                                b'\r\n']
                writer.writelines(httpresponse)
            elif os.path.isdir(relative_path):  # Edit the http header of a directory
                httpresponse = [b'HTTP/1.0 200 OK\r\n',
                                b'Content-Type:text/html; charset=utf-8\r\n',
                                b'Connection: close\r\n', b'\r\n',
                                ]
                writer.writelines(httpresponse)
            else:  # Not existing file or directory returns 404 response.
                writer.writelines([
                    b'HTTP/1.0 404 Method Not Found\r\n',
                    b'Content-Type:text/html; charset=utf-8\r\n',
                    b'Connection: close\r\n',
                    b'\r\n',
                    html404,
                    b'\r\n'
                ])
            await writer.drain()
            writer.close()

        elif message[0] == "POST":  # Method POST returns 405 response.
            writer.writelines([
                b'HTTP/1.0 405 Method Not Allowed\r\n',
                b'Content-Type:text/html; charset=utf-8\r\n',
                b'Connection: close\r\n',
                b'\r\n',
                html405,
                b'\r\n'
            ])
            await writer.drain()
            writer.close()

        else:  # Other method returns 405 response.
            writer.writelines([
                b'HTTP/1.0 405 Method Not Allowed\r\n',
                b'Content-Type:text/html; charset=utf-8\r\n',
                b'Connection: close\r\n',
                b'\r\n',
                html405,
                b'\r\n'
            ])
            await writer.drain()
            writer.close()
    except ConnectionError:
        pass


if __name__ == '__main__':
    # python FileBrowser.py --port 8000 --dir ~/
    parser = argparse.ArgumentParser(description='Simple Web File Browser')
    parser.add_argument('--port', type=int, default=8080,
                        help='an integer for the port of the simple web file browser')
    parser.add_argument('--dir', type=str, default="./",
                        help='The Directory that the browser should display for home page')
    args = parser.parse_args()
    loop = asyncio.get_event_loop()
    coro = asyncio.start_server(dispatch, '127.0.0.1', port=args.port, loop=loop)
    server = loop.run_until_complete(coro)
    root_dir = args.dir
    if root_dir[-1] == '/':
        root_dir = root_dir[:-1]
    print("server run at port %d" % args.port)
    print("server run at dir %s" % args.dir)
    print('Serving on {} and Hit Ctrl + C to end the server'.format(server.sockets[0].getsockname()))
    try:
        loop.run_forever()
    except KeyboardInterrupt:
        exit()
    server.close()
    loop.run_until_complete(server.wait_closed())
    loop.close()

  • 在terminal中运行py文件,指定端口和路径:
    python3 FileBrowser.py --port 8080 --dir ~/
  • 实例:
    在这里插入图片描述
  • 打开浏览器看看效果:(自己随便加了个图片)
    在这里插入图片描述
    已知MIME TYPE 打开文件并以HTML文件展示在浏览器,例如打开FileBrowser.py
    在这里插入图片描述
    未知MIME Type 会下载到本地:
    在这里插入图片描述
    进入文件夹后可以通过.. 返回上级目录:
    在这里插入图片描述
    访问不存在的文件,如在地址栏中输入URL:
    在这里插入图片描述
    则会报出404页面:
    在这里插入图片描述
    HEAD 方法测试:
    在这里插入图片描述
    POST 返回405:
    在这里插入图片描述

二、emm

cmd 输入 python -m http.server 就可以实现当前文件夹的file browser。
例如:
在这里插入图片描述
在这里插入图片描述

  • emm,这不啥也有了吗(404 也有。。。)
    在这里插入图片描述

三、总结

  • 需要了解HTTP报文结构:
    结构其实都是:

注意blank line 和 crlf 都不可以少。(\r\n)

在这里插入图片描述

  • 需要自学点HTML(Message body内部)
### 回答1: 使用 Python 实现自动化可以使用 Python 脚本来模拟人类的一些操作,从而实现自动化。 例如,你可以使用 Python 脚本来登录你的电子邮件帐户,然后使用特定的条件来搜索电子邮件,并根据需要自动回复或转发电子邮件。 要实现这一点,你需要了解一些 Python 的基础知识,以及如何使用 Python 的电子邮件库来操作电子邮件。你也可以使用 Python 的第三方库,如 selenium 来模拟人类在浏览器中的操作,从而实现自动化测试或者网络爬虫等。 这里是一个使用 Python 实现自动化的简单示例: ``` import os # 自动打开文件 os.system("open /path/to/file") # 自动发送电子邮件 import smtplib server = smtplib.SMTP('smtp.gmail.com', 587) server.starttls() server.login("your_email@example.com", "your_password") msg = "Hello, this is a test email sent from a Python script." server.sendmail("your_email@example.com", "recipient@example.com", msg) server.quit() # 自动搜索网站 import requests response = requests.get("https://www.example.com/search?q=keyword") print(response.text) # 自动填写表单 import mechanize br = mechanize.Browser() br.open("https://www.example.com/login") br.select_form(nr=0) br["username"] = "your_username" br["password"] = "your_password" response = br.submit() print(response.read()) ``` 希望这能帮到你! ### 回答2: 使用Python实现自动化是通过编写脚本和程序来自动执行重复的任务和流程。Python编程语言具有简单易学、功能强大和丰富的库和模块等特点,因此非常适合用于自动化。 首先,Python可以用于自动化测试。我们可以使用Selenium库来模拟用户在网页上的操作,如点击按钮、输入文本等,从而进行网站功能的自动化测试。此外,Python还可以用于接口自动化测试,通过发送HTTP请求并验证返回结果来实现接口功能的自动化测试。 其次,Python可以用于文件操作的自动化。我们可以使用os和shutil等库来自动处理文件和文件夹,如批量重命名文件、复制和移动文件等。此外,通过使用Python的xlrd和xlwt库,我们还可以实现Excel文件的读取和写入操作,从而实现Excel的自动化处理。 另外,Python可以用于网络爬虫的自动化。通过使用BeautifulSoup、Scrapy和Requests等库,我们可以编写爬虫程序来自动从网页上获取数据,并进行存储和处理。这在获取大量数据或进行数据分析时非常有用。 此外,Python还可以用于自动化的GUI应用程序开发。通过使用PyQt、Tkinter等库,我们可以编写窗口应用程序,实现图形界面的自动化操作。例如,编写一个批量处理图片的程序,实现自动调整尺寸、添加水印等功能。 总而言之,Python的简洁性、灵活性和丰富的库和模块使其成为实现自动化的理想选择。无论是测试自动化、文件处理、网络爬虫还是GUI应用程序开发,Python都能提供强大的支持,帮助我们提高工作效率和降低人为错误。 ### 回答3: 使用Python实现自动化可以帮助简化重复性的任务,提高工作效率。Python拥有丰富的库和模块,可以帮助我们完成各种自动化任务。 首先,Python可以用于文件和文件夹的自动化处理。我们可以使用Python的os模块来批量重命名或移动文件,创建或删除文件夹。这样就能够迅速完成大量文件操作的任务,节省时间和精力。 其次,Python还可以用于Web自动化。我们可以利用Python的selenium库来实现自动化浏览器操作。例如,自动化登录网站,填充表单,爬取网页内容等。这对于需要定期进行网页操作的任务非常有用,可以减轻人工操作带来的繁琐。 此外,Python还可以用于自动化测试。我们可以使用Python的测试框架(如unittest和pytest)来编写自动化测试脚本,以验证代码是否按预期进行。这样可以提高代码质量和稳定性,减少人工测试的工作量。 最后,Python还可以用于项目部署和运维自动化。我们可以使用Python来编写脚本,自动化部署代码、安装依赖包、配置服务器等任务。这将大大简化部署过程,减少错误和时间消耗。 总之,Python的简洁语法和强大的库支持使其成为自动化任务的理想选择。通过使用Python实现自动化,我们能够提高工作效率,减少繁琐的重复操作,从而将更多时间和精力投入到更有意义的工作上。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值