从放弃迅雷到自己开发下载工具
前言
在这个网络带宽飞速增长的年代,下载文件要充分利用好网速就得用到下载工具,比如迅雷、IDM。然而贫穷限制了下载速度,这两个下载软件不花钱毫无体验可言。本人两年迅雷年费会员在离线下载越来越形如虚设的情况下,选择投入了IDM的怀抱,然而IDM丑陋的界面和破解版的无限弹框让我产生了开发一款属于自己下载器的想法。
成果
没图说个xx,下图是在20M带宽的情况下载网盘文件的过程,可以看到网速基本跑满。
下载(https://pan.baidu.com/s/1eRDVYPc)试用,需要JAVA8+运行环境。 启动:
java -jar proxyee-down-1.0-SNAPSHOT.jar
访问http://127.0.0.1:9999,点击ProxyeeRoot ca.crt下载证书并安装到受信任的根证书颁发机构中
设置浏览器http代理为127.0.0.1:9999即可
更新个exe版本的,把JRE打包进去了,体积会稍微大点。下载(https://pan.baidu.com/s/1eROfzDw)。
介绍
本下载器开源,代码托管在proxyee-down(https://github.com/monkeyWie/proxyee-down),是一款基于http代理服务器嗅探http下载请求的下载工具,支持插件化开发,目前内置百度云大文件下载限制插件和百度云合并下载限制插件。
技术简介
本项目使用java+netty+spring boot+vue.js+element ui编写,这里只谈一谈核心的技术点,细节请参考源码。
1.http代理
基于http代理服务器来实现下载请求的嗅探,实现了https的报文解密,在代理服务器嗅探到下载请求头时,进行拦截处理。
//例如Content-Disposition请求头拦截
Content-Disposition,attachment;filename=FileName.txt
之后修改响应体跳转到前端下载页面
HTTP/1.1 200 OK
Conten-type:text/html
Conten-length:129
<script>window.top.location.href='http://localhost:9000"</script>
2.http断点下载
拦截到下载请求之后,自动试探下载请求是否支持http断点下载。
//发送range请求头,下载一个字节
range:bytes=0-0
若支持断点下载则可开启分段下载
//返回206响应码
HTTP/1.1 206 Partial Content
根据前端填写的下载段数计算出每个请求的下载范围
//例如文件总大小为10byte分成2段下载
//第一段请求头
range:bytes=0-4
//第二段请求头
range:bytes=5-9
下载完之后所有段落按顺序合并,看看这里是不是很像IDM,其实原理是一样的。
后记
在写此下载器的过程中对http和https协议又有了新的认识,特别是https若不能实现https的报文解密就做不到https下载请求的嗅探,在熟悉https协议后采用MITM(中间人攻击)动态生成ssl证书的方式,来对https的报文进行解密。http代理服务器核心已经独立出来了,托管在proxyee,可以轻易的对http(s)协议进行拦截和处理。
觉得本文对你有帮助?请分享给更多人
- 一个快速方便的图形化 Python 调试器 —— birdseye | Github 项目推荐
- 关于分区表的在线重定义(r5笔记第98天)
- 10个实用的但偏执的Java编程技术
- 看似诡异的tablespace online问题(r5笔记第95天)
- python2.7进行爬虫POI代码(划分小网格算法)
- 从 Encoder 到 Decoder 实现 Seq2Seq 模型
- python2.7进行爬虫百度POI代码(划分小网格算法)
- 如何通过TTL调试光猫
- 基于树莓派和Tensowflow的物体识别-brain
- SNA中:中心度及中心势诠释(不完整代码)
- 教程 | 基于计算机视觉使用Python和OpenCV计算道路交通
- 干货 | MVP模式在携程酒店的应用和扩展
- memlock过低导致的数据库性能问题(r6笔记第10天)
- OpenCV和SVM分类器在自动驾驶中的车辆检测
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 数据库压力测试方法概述
- Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) B. Bash's Big Day (Hash+简单数论)
- 随机点名系统——html初学实战
- Centos 7 使用 rpm 安装 JDK 1.8
- PAT (Advanced Level) Practice 1145 Hashing - Average Search Time (25分)
- Centos 7使用 rpm 安装 MySQL 5.7
- Leetcode 300. 最长上升子序列(n方dp,nlogn贪心+二分查找)
- select 进阶查询
- Codeforces Round #627 (Div. 3) E. Sleeping Schedule (DP)
- PAT (Advanced Level) Practice 1144 The Missing Number (20分)
- JDBC 基础操作
- Codeforces Round #625 (Div. 2, based on Technocup 2020 Final Round) C. Remove Adjacent
- MySQL 存储过程
- MySQL 约束
- MySQL 中的流程控制语句