发送 zero-length HTTPS PUT?
Sending a zero-length HTTPS PUT?
我正在使用一个系统,为了进行特定的服务调用,需要以下内容:
- 发出 HTTP PUT 命令
- 将 URL 设置为
some_url_here
- 设置最终用户证书。
- 确保实体 body 为空并将 Content-Length headers 设置为 0。
这是我写的建立安全连接的方法。我已经测试了 GET;他们工作正常。我知道问题不在证书中。
public HttpsURLConnection getSecureConnection(final URL url, final String method, final int connectTimeout,
final int readTimeout) throws IOException {
Validate.notNull(sslContext);
Validate.notNull(url);
Validate.notNull(method);
Validate.isTrue(connectTimeout > 0);
Validate.isTrue(readTimeout > 0);
HttpsURLConnection connection;
try {
connection = (HttpsURLConnection) url.openConnection();
} catch (final IOException ioe) {
LOGGER.error("[CertificateLoader] Unable to open URL connection!", ioe);
throw new IOException("Unable to open URL connection!", ioe);
}
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.setRequestMethod(method);
connection.setConnectTimeout(connectTimeout);
connection.setReadTimeout(readTimeout);
connection.setHostnameVerifier(NoopHostnameVerifier.INSTANCE);
if (method.equals("PUT")) {
connection.setRequestProperty("Content-Length", "0");
}
if (connection.getContentLength() > 0) {
Object foo = connection.getContent();
LOGGER.error("This is what's in here: " + foo.toString());
}
return connection;
}
现在,底部那个时髦的 if
的原因是当我去进行 PUT 调用时,即使我没有直接在调用中放置 body,我的日志坚持我得到的是 non-zero 内容长度。所以,我添加了那个小块,试图弄清楚里面有什么,你瞧,它报告了以下内容:
This is what's in here: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@70972170
现在,默认情况下那个笨蛋就在那里。我没有把它放在那里。我没有创建 object 放在那里。我刚刚从 URL 创建了 object,它是我从别处的字符串创建的。我需要的是一种方法来 删除 那个 HttpInputStream object,或者将它设置为 null,或者告诉代码应该有 no body 添加到此 PUT 请求,这样我的服务器就不会拒绝我的消息 ill-formatted。建议?
Now, the reason for that funky if at the bottom is that when I go to make the PUT call, even though I'm not putting a body on the call directly, my logs insist I'm getting a non-zero content length.
Content-length设置为零的方法如下:
connection.setDoOutput(true); // if it's PUT or POST
connection.setRequestMethod(method);
connection.getOutputStream().close(); // send a zero length request body
永远不需要调用 connection.setRequestProperty("Content-Length", "0")
。 Java 为您设置。或者它可能被省略,在这种情况下你可以通过
来确保它
connection.setFixedLengthStreamingMode(0);
So, I added that little block to try to figure out what's in there, and lo and behold it reports the following:
This is what's in here: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@70972170
Now, that sucker's in there by default. I didn't put it in there.
Java放在那里。
I didn't create that object to put in there.
Java放在那里。
I just created the object as is from the URL, which I created from a String elsewhere. What I need is a way to remove that HttpInputStream object, or set it to null, or otherwise tell the code that there should be no body to this PUT request, so that my server won't reject my message as being ill-formatted.
不,不是。它是一个输入流,而不是一段内容。它是 响应 内容的输入流,而不是 请求的内容。 在任何情况下,服务器都完全有权 return 您满足于响应您的请求。
你的任务是:
- 获取响应代码并记录。
- 如果 >=200 且 <= 299,获取连接的输入流。
- 否则获取连接的错误流。
- 无论你得到哪个流,阅读它直到流结束,然后记录它。
这会告诉你真正发生了什么。
我要补充一点,没有主体的 PUT 是一件非常奇怪的事情。你确定你已经理解了这个要求吗? 411表示长度需要.
我正在使用一个系统,为了进行特定的服务调用,需要以下内容:
- 发出 HTTP PUT 命令
- 将 URL 设置为
some_url_here
- 设置最终用户证书。
- 确保实体 body 为空并将 Content-Length headers 设置为 0。
这是我写的建立安全连接的方法。我已经测试了 GET;他们工作正常。我知道问题不在证书中。
public HttpsURLConnection getSecureConnection(final URL url, final String method, final int connectTimeout,
final int readTimeout) throws IOException {
Validate.notNull(sslContext);
Validate.notNull(url);
Validate.notNull(method);
Validate.isTrue(connectTimeout > 0);
Validate.isTrue(readTimeout > 0);
HttpsURLConnection connection;
try {
connection = (HttpsURLConnection) url.openConnection();
} catch (final IOException ioe) {
LOGGER.error("[CertificateLoader] Unable to open URL connection!", ioe);
throw new IOException("Unable to open URL connection!", ioe);
}
connection.setSSLSocketFactory(sslContext.getSocketFactory());
connection.setRequestMethod(method);
connection.setConnectTimeout(connectTimeout);
connection.setReadTimeout(readTimeout);
connection.setHostnameVerifier(NoopHostnameVerifier.INSTANCE);
if (method.equals("PUT")) {
connection.setRequestProperty("Content-Length", "0");
}
if (connection.getContentLength() > 0) {
Object foo = connection.getContent();
LOGGER.error("This is what's in here: " + foo.toString());
}
return connection;
}
现在,底部那个时髦的 if
的原因是当我去进行 PUT 调用时,即使我没有直接在调用中放置 body,我的日志坚持我得到的是 non-zero 内容长度。所以,我添加了那个小块,试图弄清楚里面有什么,你瞧,它报告了以下内容:
This is what's in here: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@70972170
现在,默认情况下那个笨蛋就在那里。我没有把它放在那里。我没有创建 object 放在那里。我刚刚从 URL 创建了 object,它是我从别处的字符串创建的。我需要的是一种方法来 删除 那个 HttpInputStream object,或者将它设置为 null,或者告诉代码应该有 no body 添加到此 PUT 请求,这样我的服务器就不会拒绝我的消息 ill-formatted。建议?
Now, the reason for that funky if at the bottom is that when I go to make the PUT call, even though I'm not putting a body on the call directly, my logs insist I'm getting a non-zero content length.
Content-length设置为零的方法如下:
connection.setDoOutput(true); // if it's PUT or POST
connection.setRequestMethod(method);
connection.getOutputStream().close(); // send a zero length request body
永远不需要调用 connection.setRequestProperty("Content-Length", "0")
。 Java 为您设置。或者它可能被省略,在这种情况下你可以通过
connection.setFixedLengthStreamingMode(0);
So, I added that little block to try to figure out what's in there, and lo and behold it reports the following:
This is what's in here: sun.net.www.protocol.http.HttpURLConnection$HttpInputStream@70972170
Now, that sucker's in there by default. I didn't put it in there.
Java放在那里。
I didn't create that object to put in there.
Java放在那里。
I just created the object as is from the URL, which I created from a String elsewhere. What I need is a way to remove that HttpInputStream object, or set it to null, or otherwise tell the code that there should be no body to this PUT request, so that my server won't reject my message as being ill-formatted.
不,不是。它是一个输入流,而不是一段内容。它是 响应 内容的输入流,而不是 请求的内容。 在任何情况下,服务器都完全有权 return 您满足于响应您的请求。
你的任务是:
- 获取响应代码并记录。
- 如果 >=200 且 <= 299,获取连接的输入流。
- 否则获取连接的错误流。
- 无论你得到哪个流,阅读它直到流结束,然后记录它。
这会告诉你真正发生了什么。
我要补充一点,没有主体的 PUT 是一件非常奇怪的事情。你确定你已经理解了这个要求吗? 411表示长度需要.