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, timehtml404 = 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':returnmessage = data.decode().split(' ')print(message)  # ['GET', '/', 'HTTP/1.1\r\n']# message[0] method# message[1] dirif message[1] == "./favicon.ico":returnif 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_pathprint(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):  # homepagehttpresponse = [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]):  # filehttpresponse.append(bytes('<li><a href="' + dirlist[i] + '">' + dirlist[i] + "</a></li><br>\r\n",encoding='UTF-8'))else:  # directoryhttpresponse.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_pathprint(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 directoryhttpresponse = [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:passif __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.dirif 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内部)

Python 实现 Filebrowser相关推荐

  1. python将txt转json_Python控制乐高EV3,以及VSCODE环境配置

    乐高EV3的可扩展性很强,但如何用pc连接ev3,并用python代码来控制EV3,资料太少了,试着做了一次,记录在这里. 需要的硬/软件 硬件准备 一.乐高EV3 二.PC,win10系统 三.TF ...

  2. Python笔记-centos7使用adb连接真实手机及初始化uiautomatro2项目

    首先看看各个设备对应的IP 系统 ip Android 192.168.1.100 windows 192.168.1.190 centos 192.168.79.134 这里3台机器都是能够相互pi ...

  3. python提取选中文件的文件名_如何从python文件路径中提取文件名?

    项目概述: 用户通过浏览器选择一个文件来导入数据.然后,我解包二进制文件.然后,我将新解包的数据保存为.csv文件,以便以后在excel中查看数据.用户当前通过键入新文件名来创建文件名.然后我继续用m ...

  4. Github配置(git+vscode+python+jupyter)

    ①下载git 打开 git bash 工具的用户名和密码存储 $ git config --global user.name "Your Name" $ git config -- ...

  5. 【实验楼】python简明教程

    ①终端输入python进入 欣赏完自己的杰作后,按 Ctrl + D 输入一个 EOF 字符来退出解释器,你也可以键入 exit() 来退出解释器. ②vim键盘快捷功能分布 ③这里需要注意如果程序中 ...

  6. 【Kaggle Learn】Python 5-8

    五. Booleans and Conditionals Using booleans for branching logic x = True print(x) print(type(x))''' ...

  7. 【Kaggle Learn】Python 1-4

    [Kaggle Learn]Python https://www.kaggle.com/learn/python 一. Hello, Python A quick introduction to Py ...

  8. 使用python愉快地做高数线代题目~

    今天接触到了python,发现真是极易上手啊!对比c语言是什么鬼东西= = 诶,等下,看完教学文章发现TA在下面写了这句话 如果做了前面的内容你可能已被吸引了,觉得c语言真的是废材! 不...不是的. ...

  9. python 位运算与等号_Python 运算符

    和大多数语言一样,Python也有很多运算符,并且运算符跟其他语言的运算符大同小异接下来一一介绍: 算术运算符: 运算符描述实例 +加 - 两个对象相加a+b的输出结果是30 -减 - 得到复数或者一 ...

最新文章

  1. “国产操作系统最大难题在于解决「生产关系」” | 人物志
  2. 吐血整理!这可能是最全的机器学习工具手册
  3. Android Studio 常见插件收藏
  4. 根据pid判断某个进程是否存在
  5. ES6_Set和WeakSet_note
  6. java 值传递 引用传递_Java小白进阶之值传递-引用传递
  7. k8s集群部署项目_JAVA项目(制作镜像)---K8S_Google工作笔记0060
  8. 为什么 a==true 和 a==false 结果都是false ?
  9. JQuery插件之弹窗:lhgDialog
  10. python gridsearch_Python超参数自动搜索模块GridSearchCV上手
  11. SpringBoot之集成MybatisPlus
  12. javascript实现的时钟
  13. 流水账——利用MFC开发的小软件
  14. HTTP 权威指南 详解 (推荐阅读 )
  15. 计算机系毕业论文绪论,本科毕业论文绪论范文
  16. 用Python实现将滑动屏幕保存的录屏视频自动拼接为长截图
  17. 电子计算机eniac的储存能力有限 只能,电子计算机ENIAC的存储能力有限,只能存储简单的控制程序代码。...
  18. roaringbitmap java,BitMap与RoaringBitmap、JavaEWAH
  19. ArcGIS 裁剪地图显示范围
  20. python爬虫数据分析项目 双十一_Python爬取淘宝商品数据,价值千元的爬虫外包项目!...

热门文章

  1. 输入roscore报错:“roscore“ not found
  2. 联通定制无线猫管理员账户密码(大连测试好用)
  3. Redis 下载与安装(Windows版)(*)
  4. 服务器设置邮箱屏蔽,邮箱服务器IP被屏蔽的问题
  5. 那些年,我们一起追过的C++
  6. js 动态设置input 不可编辑
  7. 如何用python画雪人_能力橙少儿编程 - 学员作品 - Python作品-雪人(可变位置和大小)...
  8. 把ChatGPT (野猫),养成家猫(企业专用的ChatGPT)
  9. 关于飞思卡尔S12系列单片机SPI通信MODRR配置
  10. 你真的需要文档管理软件吗?