求教转发本地应用网络请求的方法

2022-03-31 19:37:34 +08:00
 lon91ong

程序目标

用本地服务代替网络服务, 使得需要依赖网络运行的一款第三方应用能够脱机运行。

已实现的阶段目标

使用 RESTful 架构的 falcon 包实现了基本的网络请求响应,在依赖的资源文件完整的情况下,程序可以脱机运行。 但是遇到资源文件缺失,需要通过网络下载补足的情况就会报错。

问题描述

本地文件请求:GET http://127.0.0.1:8686/Download/example.zip

文件远程真实地址:GET http://down.domain.com/Download/example.zip

用什么方法能在 python 程序接收到本地文件请求时,由 python重定向连接到文件远程真实地址,并将响应数据原样发回给本地第三方应用。类似于本地应用通过代理的方式取得了文件。

用关键词redirect在 Github 搜索了一些 python 项目,没找到特别适用的。

希望大侠不吝赐教,万分感谢。

3269 次点击
所在节点    Python
26 条回复
lizenghui
2022-03-31 19:50:15 +08:00
nginx 可以啊。
lon91ong
2022-03-31 19:53:23 +08:00
@lizenghui 有没有相近的应用实例呢? nginx 似乎时个网站后台框架吧? 只玩过 RESTful 类的简单的
seakingii
2022-03-31 19:57:01 +08:00
@lon91ong 搜索 nginx 反向代理
cheng6563
2022-03-31 20:02:56 +08:00
你收到请求后直接改下地址然后 urllib.request 发请求出去就行了啊,把收到的数据直接返回或者临时存盘再返回都行。HTTP 文件下载有几个特殊 Header 表示文件名什么的,你响应的时候填上就行。
cheng6563
2022-03-31 20:04:49 +08:00
你先试试写一个提供文件下载接口,随便返回点数据就行。
再写一个用 urllib.request 下载远程文件的用例。
最后把两个方法整合下就行了。
Puteulanus
2022-03-31 20:17:38 +08:00
听起来像个 cache proxy ,squid transparent proxy 是不是就能做
xuxuxu123
2022-03-31 20:26:54 +08:00
如果远程文件的真实地址是确定的,那么 nginx 反向代理就可以了
ClericPy
2022-03-31 20:43:07 +08:00
这说的是 gost 么... https://github.com/ginuerzh/gost

或者用 Python 随手写个端口转发? https://github.com/ClericPy/ichrome/issues/84

如果我理解错了, 就当没看到我
lon91ong
2022-03-31 21:00:04 +08:00
@seakingii 有点牛刀杀鸡的赶脚
lon91ong
2022-03-31 21:02:51 +08:00
@cheng6563 这就是我想要的思路, 还需要找例程实验一番,多谢指点迷津
lon91ong
2022-03-31 21:33:31 +08:00
@cheng6563 遇到资源文件比较大的情况,四五十 M 的大小, 没法等下载完了再响应, 这种情况怎么处理呢?
lon91ong
2022-03-31 21:52:31 +08:00
@Puteulanus 感谢提供关键词 squid, 找到个相关的项目, https://github.com/GlobalRadio/squid-redirect
简单看了看 readme, 似乎用得上, 明天再看看
mingl0280
2022-03-31 23:43:08 +08:00
……你就不会检查一下 file exist 然后不存在的文件自动下载了返回么?
Tink
2022-03-31 23:51:39 +08:00
很多办法,上面说的 nginx 反代可以,也可以在你的程序里判断本地文件是否存在,不存在就去下载
biubiuF
2022-04-01 00:40:54 +08:00
iptables redirect
ec0
2022-04-01 03:10:59 +08:00
试试这段代码

```
class ProxyResource:
____def file_generator(self, url):
________with requests.get(url, stream=True) as r:
____________for chunk in r.iter_content(chunk_size=8192):
________________yield chunk


____def on_get(self, req, resp):
________resp.downloadable_as = 'example.zip'
________resp.stream = self.file_generator('http://down.domain.com/Download/example.zip')
```
lon91ong
2022-04-01 09:11:55 +08:00
@ec0 太感谢了! 感激涕零了要!!!
另外遇到一点小麻烦, 不知道时这个方法的问题, 还是我用的 WSGI 标准的 waitress 包的问题,
在转发时没有转发 headers 信息, 文件长度、编码等信息全都丢失了
需要用什么方法补救呢?
enrolls
2022-04-01 11:26:17 +08:00
这个需求就跟在腾讯云买了同主机和 cos 一个道理,主机跟 cos 免流量通信,cos 直接下载需要流量。主机返回 cos 的 body 出去。headers 可以一并 yield ,之后自己组装
lon91ong
2022-04-01 11:52:41 +08:00
@enrolls headers 一并 yield 要如何操作? yield 只能返回一个对象吧???
ec0
2022-04-01 12:01:27 +08:00
这样呢?

```
def on_get(self, req, resp):
____resp.downloadable_as = 'example.zip'
____r = requests.head('http://down.domain.com/Download/example.zip')
____resp.content_length = r.headers['content-length']
____resp.content_type = r.headers['content-type']
____resp.stream = self.file_generator('http://down.domain.com/Download/example.zip')
```

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/844170

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX