JDK12 HttpClient - how to remove content-length header - java

Is there any way to remove content-length request header?
Here's the code I use to initialize HttpRequest:
HttpRequest get = HttpRequest.newBuilder()
.GET()
.uri(URI.create("https://www.google.com/"))
.build();
Unfortunately the request headers contains "Content-Length: 0" (checked using fiddler)

Related

java http request cannot post

I have a nodejs web server running and I want to a body to the request in my java program.
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.header( "Content-Type", "text/plain;charset=UTF-8")
.uri(URI.create("http://localhost:3000"))
.POST(HttpRequest.BodyPublishers.ofString("Hello"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("status:" + response.statusCode());
System.out.println("response:" + response.body());
If I delete this line: .POST(HttpRequest.BodyPublishers.ofString("Hello")) everything works fine, I get the response from the server, but there is no body to the request.
With this line I get status code 404 and the body of the response to the client is:
How can I add body to the request?
First of all try understand differences between GET and POST HTTP methods
https://www.w3schools.com/tags/ref_httpmethods.asp
There is also a good example in docs: https://docs.oracle.com/en/java/javase/11/docs/api/java.net.http/java/net/http/HttpRequest.BodyPublishers.html
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://example.com/"))
.header("Content-Type", "text/plain; charset=UTF-8")
.POST(BodyPublishers.ofString("some body text"))
.build();
You can also look here as well
https://www.baeldung.com/java-9-http-client

Howto send PUT request without content and Content-Length header with Apache http client?

I'd like to test (via automated test) how server (and all proxies in-the-middle) responds to a PUT request without body and Content-Length header.
Similar to what curl does
curl -XPUT http://example.com
with Apache HTTP client (4.5.13)
But it looks like it always adds Content-Length header if I specify no body.
Is there any way to do that with Apache HTTP client?
Already tried (no luck)
final HttpPut request = new HttpPut(url);
request.removeHeaders("Content-Length");
Use a request interceptor to modify requests generated by the standard protocol processor
CloseableHttpClient httpClient = HttpClients.custom()
.addInterceptorLast((HttpRequestInterceptor) (request, context) ->
request.removeHeaders(HttpHeaders.CONTENT_LENGTH))
.build();
HttpPut httpPut = new HttpPut("http://httpbin.org/put");
httpClient.execute(httpPut, response -> {
EntityUtils.consume(response.getEntity());
return null;
});

HTTP Authentication - Java Http Client is missing header that is present via curl

I'm trying to send a simple GET to an HTTP endpoint with java.net.http.HttpClient. The endpoint requires basic authentication. Simple enough, I'm doing what everyone's doing:
HttpClient httpClient = HttpClient.newBuilder()
.version(HttpClient.Version.HTTP_1_1)
.authenticator(new Authenticator(){
#Override
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication("guest","guest".toCharArray());
}
})
.build();
HttpRequest request = HttpRequest.newBuilder()
.GET()
.uri(URI.create("localhost:15672/api/overview")
.build();
HttpResponse<Void> httpResponse = httpClient.send(request, HttpResponse.BodyHandlers.discarding());
However, this throws an IOException "WWW-Authenticate header missing for response code 401". It is not completely unreasonable to me that the server initially responds with 401 and the client then re-tries the request with the help of the Authenticator. The header is mandatory and if it is absent, that warrants an exception.
So far, so good. However, when I do the same request via curl, the header is present:
> curl -i http://localhost:15672/api/overview
HTTP/1.1 401 Unauthorized
content-length: 0
content-security-policy: script-src 'self' 'unsafe-eval' 'unsafe-inline'; object-src 'self'
date: Thu, 08 Jul 2021 11:06:45 GMT
server: Cowboy
vary: origin
www-authenticate: Basic realm="RabbitMQ Management"
What am I doing wrong here?
In the mean time I found out what the problem was: The server I'm contacting is buggy. The first GET returned exactly what is shown as the curl result. The Java HttpClient reacted correctly and sent a second GET with credentials. The credentials were wrong (for testing purposes) but the response was not a 403 as one would expect, but another 401 and this second 401 response is the one missing the header.
For basic authorization, you can do
String plainCreds = "myuser:mypassword";
byte[] base64Bytes = Base64.encodeBase64(plainCreds.getBytes());
HttpRequest request = HttpRequest.newBuilder()
.get()
.uri(URI.create("localhost:15672/api/overview"))
.header("Authorization", "Basic " + new String(base64Bytes))
.build();

Accessing User Profile on Graph Microsoft using OKHttp returns special characters

I am trying to retrieve my user profile from graph.microsoft as show here. I am using a Java library OKHttp to achieve this however the server is returning special characters in the response. I checked my headers and I did include "Accept-Encoding: gzip". However the issue is not resolved. See code under;
Java Code
Request userProfileRequest = new Request.Builder()
.url("https://graph.microsoft.com/v1.0/me")
.get()
.addHeader("Authorization", "Bearer "+accessTkn)
.addHeader("Accept", "*/*")
.addHeader("Cache-Control", "no-cache")
.addHeader("Content-Type", "application/json;odata.metadata=minimal;odata.streaming=true;IEEE754Compatible=false;charset=utf-8")
.addHeader("Accept-Encoding", "gzip")
.addHeader("Connection", "keep-alive")
.addHeader("cache-control", "no-cache")
.build();
Response userProfileResponse = client2.newCall(userProfileRequest).execute();
System.out.println("Authorization is " +userProfileRequest.header("Authorization"));
System.out.println(userProfileResponse.body().string());
Console output
OkHttp does transparent compression for you. However by explicitly specifying "Accept-Encoding: gzip" you are indicating that you want gzip compression and will handle it yourself.
Removing everything except Authorization as you have done in your answer is the correct solution.
The solution that worked for me was to remove all the headers except for "Authorization"
Java Code
Request userProfileRequest = new Request.Builder()
.url("https://graph.microsoft.com/v1.0/me")
.get()
.addHeader("Authorization", "Bearer "+accessTkn)
.build();

How do I add Content-Length header to HttpPost within Apache HttpComponents?

I have a server which expects Content-Length as a part of POST header. For POSTing, I am using Apache HttpComponents library.
This is a stripped down version of the expected request (with all the required headers ofcourse):
POST /ParlayREST/1.0/sample/ HTTP/1.1
Content-Type: application/json
Accept: application/json
Host: server.url.com:8080
Content-Length: 287
{
"listenerURL":"http://application.example.com/notifyURL"},
"sessionId":"12345"
}
I have used the setEntity method of HttpPost to set a StringEntity (converted json -> String -> StringEntity) as content of the POST. But when I execute the request, I end up with a POST request which doesn't specify Content-length within it's header.
Is there anyway to add this missing header?
(I tried setHeader() to set the Content-Length which threw an error saying that the content length is already present)
This is the code that I am using to create the POST request:
//Convert the registration request object to json
StringEntity registrationRequest_json_entity = new StringEntity(gsonHandle.toJson(registrationRequest));
registrationRequest_json_entity.setContentType("application/json");
//Creating the HttpPost object which contains the endpoint URI
HttpPost httpPost = new HttpPost(Constants.CLIENT_REGISTRATION_URL);
httpPost.setHeader(HTTP.CONTENT_TYPE,"application/json");
httpPost.setHeader("Accept","application/json");
httpPost.setHeader(HTTP.TARGET_HOST,Constants.REGISTRATION_HOST + ":" + Constants.REGISTRATION_PORT);
//Set the content as enitity within the HttpPost object
httpPost.setEntity(registrationRequest_json_entity);
HttpResponse response = httpClient.execute(httpPost, new BasicHttpContext());
HttpEntity entity = response.getEntity();
if (entity != null) {
//work on the response
}
EntityUtils.consume(entity);
HttpClient automatically generates Content-Length and Transfer-Encoding header values based on properties of the enclosed message entity and the actual protocol settings.
Do not set those headers manually.
Try:
httppost.setHeader(HTTP.CONTENT_LEN,"0");
This will set the content length to 0.

Categories

Resources