Linux端Git客户端不显示HTTP错误消息show_http_message未执行
问题背景
在GitLab服务端的gitlab-workhorse/git/info-refs.go代码中添加自定义HTTP错误返回逻辑,代码如下:
http.Error(responseWriter, "Check user ip failed", 500) return
现象对比
- Windows系统下使用Git客户端执行仓库克隆命令
git clone https://mygitlabserver/server/admin.git时,可正常看到服务端返回的自定义错误提示Check user ip failed,完整输出如下:
C:\Users\mairongcong>git clone https://mygitlabserver/server/admin.git Cloning into 'admin'... remote: Check user ip failed fatal: unable to access 'https://mygitlabserver/server/admin.git/': The requested URL returned error: 500
- Linux系统(Git版本2.37.0)下执行相同克隆操作
git clone http://mygitlabserver/server/admin.git/,输入账号密码完成认证后,仅返回500错误提示,未展示服务端返回的Check user ip failed自定义错误内容,完整输出如下:
[root@localhost git-2.37.0]# git clone http://mygitlabserver/server/admin.git/ Cloning into 'admin'... Username for 'http://mygitlabserver': mairongcong Password for 'http://mairongcong@mygitlabserver': fatal: unable to access 'http://mygitlabserver/server/admin.git/': The requested URL returned error: 500
排查进展
查阅Git客户端源码发现,负责输出HTTP响应消息的remote-curl.c文件中show_http_message()函数似乎未被触发执行。
原因说明
Linux端Git 2.37.0无法展示自定义错误是两个逻辑共同导致的:
show_http_message()存在前置校验规则:仅当错误响应的Content-Type头以text/开头、响应体长度大于0时,才会读取并打印响应内容。Go标准库http.Error虽然默认返回text/plain; charset=utf-8类型,但如果前置逻辑、反向代理修改过响应头,就会触发校验失败直接跳过响应体解析。- Git 2.37.0版本处理
info/refs接口请求时,会优先按Git Smart HTTP协议格式解析响应,只要响应中没有携带协议要求的001e# service=git-upload-pack起始标识,就会直接丢弃已读取的响应体,仅返回状态码错误。该逻辑在2.38及之后版本才补充了兼容逻辑:协议解析失败时如果响应是普通文本类型,仍会打印响应内容。
Windows端Git for Windows默认携带兼容补丁,错误状态码下无论响应格式是否符合Git协议要求,都会读取响应体以remote:前缀打印,因此两端表现不一致。
排查解决步骤
- 第一步:执行带调试参数的克隆命令确认响应实际内容,命令如下:
检查返回的500响应头中GIT_CURL_VERBOSE=1 GIT_TRACE=1 git clone http://mygitlabserver/server/admin.git/Content-Type的实际值,确认响应体是否正常返回、有没有被Nginx等反向代理替换成默认错误页。 - 第二步:替换原有错误返回逻辑,手动设置明确的响应头,不依赖
http.Error的默认行为,代码参考:
不需要手动给错误内容加responseWriter.Header().Set("Content-Type", "text/plain") responseWriter.WriteHeader(500) _, _ = responseWriter.Write([]byte("Check user ip failed\n")) returnremote:前缀,Git客户端会自动补充该前缀。 - 第三步:如果调整响应头后仍不生效,升级Linux端Git到2.39及以上稳定版本,新版本已经修复了非协议格式错误响应体被丢弃的问题。
- 第四步:如果服务端前部署了反向代理,检查代理的错误页配置,关闭5xx状态码的自定义错误页替换规则,保证原始响应体透传到客户端。
内容的提问来源于stack exchange,提问作者rongcong mai
相关产品推荐
相关产品推荐

