如何在不修改原配置的情况下处理Python requests库的重定向异常?
如何在不修改urllib3模块或原请求URL的前提下处理HDFS重定向主机名解析失败问题?
问题背景
使用Python 3的requests库调用部署在AWS服务器上的HDFS服务时请求失败:
- 初始请求使用私有IP作为URL主机名,但实际请求被重定向到格式类似
ip-10-xxx-xxx-xxx的AWS内部主机名 - 重定向后的URL因主机名无法被本地解析,触发
getaddrinfo错误 - 曾通过修改urllib3的connection模块替换重定向URL的主机名解决问题,但希望找到无需修改底层模块或原请求URL的方案
附调用代码:
modURL = "http://<PRIVATE_IP>/webhdfs/v1/<dummy_path>?user.name=root&op=CREATE&overwrite=true" def writeFileListToHdfs(dirname, fileList): response = requests.put(url = modURL, data=fileList)
可行解决方案
1. 用requests重定向钩子修正目标URL
利用requests的hooks机制,在重定向发起前拦截并修改响应头中的Location字段,将无法解析的主机名替换为原请求的私有IP:
import requests from urllib.parse import urlparse, urlunparse modURL = "http://<PRIVATE_IP>/webhdfs/v1/<dummy_path>?user.name=root&op=CREATE&overwrite=true" def fix_redirect_host(response, **kwargs): # 仅处理重定向响应 if 300 <= response.status_code < 400 and 'Location' in response.headers: parsed_redirect = urlparse(response.headers['Location']) # 判断是否为AWS内部ip-xxx格式主机名 if parsed_redirect.hostname and parsed_redirect.hostname.startswith('ip-'): # 替换重定向主机名为原请求的私有IP original_netloc = urlparse(modURL).netloc new_redirect = parsed_redirect._replace(netloc=original_netloc) response.headers['Location'] = urlunparse(new_redirect) return response def writeFileListToHdfs(dirname, fileList): response = requests.put( url=modURL, data=fileList, hooks={'response': fix_redirect_host} ) # 主动抛出HTTP异常,便于排查请求问题 response.raise_for_status() return response
2. 配置本地DNS映射
如果HDFS返回的ip-10-xxx-xxx-xxx主机名固定,可在本地hosts文件中添加解析映射:
- Linux/macOS:编辑
/etc/hosts - Windows:编辑
C:\Windows\System32\drivers\etc\hosts
添加内容示例:
<Private_IP> ip-10-xxx-xxx-xxx.ec2.internal
系统会直接将该主机名解析为对应私有IP,无需修改代码。
3. 修改HDFS服务端配置(根源解决)
从服务端层面避免返回无法解析的重定向URL:
- 修改HDFS配置文件
hdfs-site.xml,添加或调整以下参数:
该参数禁用WebHDFS的重定向机制,直接返回目标资源地址。<property> <name>dfs.webhdfs.redirect.enabled</name> <value>false</value> </property> - 或者将
dfs.namenode.http-address配置为私有IP而非内部主机名,确保重定向URL使用请求方可解析的IP地址。
内容的提问来源于stack exchange,提问作者protokoul
相关产品推荐
相关产品推荐

