我正在尝试在我的应用中保存指向图片的链接。我在数据库模型中使用URLField
强制执行“url”格式,但我想进一步验证给定链接是否真正针对图像。
为此,我向给定的URL发出HEAD请求,并检查响应的Content-Type
标题中是否包含“image”。
这在我的计算机上运行良好,但是当我将其上传到prod时它不再起作用了。
在prod中我在Docker(python:3.5
Dockerfile)上运行python 3.5,我试图在我的计算机上以相同的方式运行它,但我无法重现该bug。容器在OVH的专用服务器上的VM上运行。我是服务器的管理员之一,但我不控制整个网络基础设施。我在帖子中添加了这些信息。
当运行被控制的行时,应用程序挂起然后崩溃并重新启动,从而导致来自nginx的502用作前端。以下是崩溃时的日志:
[11] [CRITICAL] WORKER TIMEOUT (pid:14)
[14] [INFO] Worker exiting (pid: 14)
[20] [INFO] Booting worker with pid: 20
我尝试在添加到数据库模型中的validators
列表的验证程序函数中执行此检查,并且还尝试创建覆盖clean
方法的自定义表单字段。
两种方法都可以顺利运行,但如果必须运行此行则会失败:
res = urllib.request.urlopen(req)
我也尝试使用requests
模块,与此行的行为相同:
res = requests.head(url)
我还尝试在视图类的requests.head
方法中添加dispatch
调用,但我也有相同的行为。
这是一个带有请求的最小代码示例,因为它更具可读性和简短性:
档案validators.py
def validate_image_url(url):
res = requests.head(url)
if 'image' not in res.headers.get('Content-Type'):
raise ValidationError('Not an image')
档案models.py
class Test:
logo_url = URLField("Logo url", blank=True, validators=[validate_image_url])
我试图在prod容器中运行python shell并运行请求,我没有问题。我也尝试了manage.py shell
,也没有问题。
你们有什么想法吗?我在这里迷路了。目前的假设是:
答案 0 :(得分:0)
看起来您的docker容器不允许发出HTTP请求。这是配置服务器时的常见安全模式。 超时通常表示介于 drop 之间的数据包过滤器。
如何解决此问题取决于谁是网络基础架构的管理员以及提供的内容。