[英]Docker API returns 200 OK then 400 BAD REQUEST
I am writing an API client for Docker. 我正在为Docker编写API客户端。 I understood from the documentation that the API is Restful/HTTP, yet if you connect to the local daemon you have to do it over the exposed unix socket .
我从文档中了解到该API是Restful / HTTP,但是,如果您连接到本地守护程序,则必须通过公开的unix套接字进行操作 。
It all seems to work, I open a socket, send an HTTP request (which respects the specification ), I receive the expected response, but also a 400 BAD REQUEST
response follows immediately. 一切似乎都正常,我打开一个套接字,发送一个HTTP请求(遵守规范 ),我收到了预期的响应, 但是立即出现了
400 BAD REQUEST
响应。
Here is the request: 这是请求:
GET /info HTTP/1.1
Host: localhost
Accept: application/json
And here is what I get: 这就是我得到的:
HTTP/1.1 200 OK
Api-Version: 1.30
Content-Type: application/json
Docker-Experimental: false
Ostype: linux
Server: Docker/17.06.1-ce (linux)
Date: Thu, 01 Feb 2018 18:53:18 GMT
Transfer-Encoding: chunked
892
{"ID":"6MGE:35TO:BI..." ...}
0
HTTP/1.1 400 Bad Request
Content-Type: text/plain; charset=utf-8
Connection: close
400 Bad Request
First, I figured that there is a bug on my side and I am somehow sending 2 requests, but I enabled debugging and followed the logs with sudo journalctl -fu docker.service
and there is exactly one request received... at least one is logged, the GET /info
. 首先,我发现自己有一个错误,我以某种方式发送了2个请求,但是我启用了调试功能 ,并使用
sudo journalctl -fu docker.service
跟踪了日志,并且恰好收到了一个请求...至少一个是记录的GET /info
。 I've also debugged the code and 1 single request is sent. 我还调试了代码,并发送了1个单个请求。
Any hint is greatly appreciated! 任何提示,不胜感激!
Edit: here is the client's code: 编辑:这是客户的代码:
final StringBuilder hdrs = new StringBuilder();
for(final Map.Entry<String, String> header : headers) {
hdrs.append(header.getKey() + ": " + header.getValue())
.append("\r\n");
}
final String request = String.format(
this.template(), method, home, hdrs, this.readContent(content)
);
final UnixSocketChannel channel = UnixSocketChannel.open(
new UnixSocketAddress(this.path)
);
final PrintWriter writer = new PrintWriter(
Channels.newOutputStream(channel)
);
writer.print(request);
writer.flush();
final InputStreamReader reader = new InputStreamReader(
Channels.newInputStream(channel)
);
CharBuffer result = CharBuffer.allocate(1024);
reader.read(result);
result.flip();
System.out.println("read from server: " + result.toString());
It seems like you have an extra CRLF between headers and body. 似乎您在标头和正文之间有一个额外的CRLF。
private String template() {
final StringBuilder message = new StringBuilder();
message
.append("%s %s HTTP/1.1\r\n")
.append("Host: localhost").append("\r\n")
.append("%s")
.append("\r\n").append("\r\n") //one of these is superfluous, as each header line ends with "\r\n" itself
.append("%s");
return message.toString();
}
Remove one append("\\r\\n")
after headers and see what happens. 删除标题后的一个
append("\\r\\n")
,看看会发生什么。
Fixed. 固定。 Initially, I thought the problem was with the line endings (that they should have been \\n instead of \\r\\n).
最初,我认为问题出在行尾(它们应该是\\ n而不是\\ r \\ n)。 Turns out, the 400 BAD REQUEST occured because the
Connection: close
header was missing, while the Request made was being closed right after receiving the response. 事实证明,发生400错误请求是因为缺少
Connection: close
标头,而在收到响应后立即关闭了发出的请求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.