How to use the Fluent API of Apache HttpClient to read UTF-8 coded website? - html

String html = Request.Get("https://kokos.pl/")
.execute().returnContent().asString();
System.out.println(html);
What I obtain in the 12th line is:
<title>Szybkie po??yczki got??wkowe, po??yczki spo??eczno??ciowe - Kokos.pl</title>
while it should be:
<title>Szybkie pożyczki gotówkowe, pożyczki społecznościowe - Kokos.pl</title>

[DEBUG] DefaultClientConnection - Sending request: GET / HTTP/1.1
[DEBUG] headers - >> GET / HTTP/1.1
[DEBUG] headers - >> Host: kokos.pl
[DEBUG] headers - >> Connection: Keep-Alive
[DEBUG] headers - >> User-Agent: Apache-HttpClient/4.2.5 (java 1.5)
[DEBUG] DefaultClientConnection - Receiving response: HTTP/1.1 200 OK
[DEBUG] headers - << HTTP/1.1 200 OK
[DEBUG] headers - << Server: nginx
[DEBUG] headers - << Date: Thu, 01 Aug 2013 12:04:12 GMT
[DEBUG] headers - << Content-Type: text/html
[DEBUG] headers - << Connection: keep-alive
...
The response message returned by the server for this URI does not explicitly specify the charset of the content. In such cases HttpClient is forced to use the default charset encoding for HTTP content, which is ISO-8859-1 and not UTF-8.
Unfortunately the only way to override the default content charset used by fluent API is by using a custom response handler
ResponseHandler<String> myHandler = new ResponseHandler<String>() {
#Override
public String handleResponse(
final HttpResponse response) throws IOException {
return EntityUtils.toString(response.getEntity(), Consts.UTF_8);
}
};
String html = Request.Get("https://kokos.pl/").execute().handleResponse(myHandler);
System.out.println(html);

Related

ejabberd ACME unexpected content type when it receives certificate

I am running a processone/ejabberd container that i am trying to get to request a certificate via ACME to a smallstep ca container. The request fails with this error:
#{<<"kid">> =>
<<"https://ca.mydomain.local:8000/acme/acme/account/svUkT7QwXD4pBqyrVdys94VMeVCeeo0D">>,
<<"nonce">> =>
<<"..">>,
<<"url">> =>
<<"https://ca.mydomain.local:8000/acme/acme/certificate/Jks2zJjdJwqDzE7VSsLM0TOaAzzYUB2P">>}}
2022-11-07 08:30:28.355858+00:00 [debug] HTTP request: {post,{"https://ca.mydomain.local:8000/acme/acme/certificate/Jks2zJjdJwqDzE7VSsLM0TOaAzzYUB2P",
[],"application/jose+json",
<<"{\"signature\":\"....\",\"protected\":\"......\",\"payload\":\"\"}">>}}
2022-11-07 08:30:28.608072+00:00 [debug] HTTP response: {{"HTTP/1.1",200,"OK"},
[{"cache-control","no-store"},
{"date","Mon, 07 Nov 2022 08:30:28 GMT"},
{"content-length","2108"},
{"content-type",
"application/pem-certificate-chain; charset=utf-8"},
{"link",
"<https://ca.mydomain.local:8000/acme/acme/directory>;rel=\"index\""},
{"replay-nonce",
".."}],
<<"-----BEGIN CERTIFICATE-----........\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----........\n-----END CERTIFICATE-----\n">>}
2022-11-07 08:30:28.609162+00:00 [error] Failed to request certificate for jabber-gw.mydomain.me: HTTP error: unexpected content type: application/pem-certificate-chain; charset=utf-8
2022-11-07 08:30:28.609456+00:00 [debug] Unregistering ACME challenge #Ref<0.1802325958.1657798659.124306>
2022-11-07 08:35:26.914567+00:00 [debug] Error when retrieving http headers gen_tcp: timeout
Any ideas on why its not happy with the content type and how to resolve?
Prior to the error message, the logs show what looks like a successful ACME challenge:
[<<".well-known">>,<<"acme-challenge">>,
<<"3rNIelLxSuDU0tWZgb3yEw5sL6d6Z61J">>] matches [<<".well-known">>,
<<"acme-challenge">>]
2022-11-04 04:28:12.436337+00:00 [debug] Received ACME challenge request for token: blah
2022-11-04 04:28:12.546710+00:00 [debug] HTTP response: {{"HTTP/1.1",200,"OK"},
The smallstep container was built with this great blog.

Send JSON body using Rest Assured, but server ignores it

I was confronted with difficulties when used RestAssered. My goal send POST request for creation user. How I do it (from documentation https://github.com/rest-assured/rest-assured/wiki/Usage):
Map<String, Object> jsonAsMap = new HashMap<>();
jsonAsMap.put("username", "John");
jsonAsMap.put("email", "testkdd#test.test");
response = restAssured.given()
.contentType(JSON)
.header("Authorization", db.getAuthToken())
.body(jsonAsMap)
.when()
.log().all()
.post(apiCreateManager_POST);
response.then().log().all();
Request:
Request method: POST
Request URI: https://myapplication/api/v1/manager/managers
Proxy: <none>
Request params: <none>
Query params: <none>
Form params: <none>
Path params: <none>
Headers: Authorization=Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXU....
Accept=*/*
Content-Type=application/json; charset=UTF-8
Cookies: <none>
Multiparts: <none>
Body:
{
"email": "testkdd#test.test",
"username": "John"
}
Response:
HTTP/1.1 422 Unprocessable Entity
Server: nginx/1.12.0
Date: Tue, 05 Mar 2019 10:52:54 GMT
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
X-Powered-By: PHP/7.1.20-1+ubuntu16.04.1+deb.sury.org+1
Cache-Control: private, must-revalidate
pragma: no-cache
expires: -1
{
"errors": {
"username": [
"This value should not be null.",
"This value should not be blank."
],
"email": [
"This value should not be blank."
]
}
}
Server did not see my JSON parameters.
I checked server using Postman and everything was OK.
I found solution!
The problem was in Content-Type=application/json; charset=UTF-8
You should avoid adding the charset to content-type header automatically:
RestAssured.config = RestAssured.config().encoderConfig(encoderConfig().appendDefaultContentCharsetToContentTypeIfUndefined(false));
And after that we have:
Content-Type=application/json

Error when accessing rest service from WebExtension using XMLHttpRequest

I am trying to access a rest service that I am hosting on an amazon AWS server from a firefox WebExtension.
I have registered a background script in the manifest.json which then tries to access the service.
"background": {
"scripts": ["OwnerLangBackground.js"]
},
"permissions": [
"*://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/*"
]
However, the XMLHttpRequest just returns an error but I don't see what goes wrong. While researching this issue, I stumbled across the following page:
https://mathiasbynens.be/notes/xhr-responsetype-json
Replacing my own code with a (slightly modifed) copy of the code from the above link I now have:
// OwnerLangBackground.js
console.log("OwnerLangBackground.js loaded");
var getJSON = function(url, successHandler, errorHandler) {
var xhr = new XMLHttpRequest();
xhr.open('get', url, true);
xhr.onreadystatechange = function() {
var status;
var data;
// https://xhr.spec.whatwg.org/#dom-xmlhttprequest-readystate
if (xhr.readyState == 4) { // `DONE`
status = xhr.status;
if (status == 200) {
data = JSON.parse(xhr.responseText);
successHandler && successHandler(data);
} else {
errorHandler && errorHandler(status, xhr.responseText);
}
}
};
xhr.send();
};
/* BLOCK 1: removing the comments for this block works
getJSON('https://mathiasbynens.be/demo/ip', function(data) {
console.log('Your public IP address is: ' + data.ip);
console.log('Your response is: ', data);
}, function(status) {
console.warn('Something went wrong.', status);
});
*/
/* BLOCK 2: removing the comments for this block, does not work
getJSON('http://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/get-languages', function(data) {
console.log('Your response is: ', data);
}, function(status) {
console.warn('Something went wrong.', status);
});
*/
Strangely enough, activating BLOCK 1 works as expected (ip address obscured on purpose).
OwnerLangBackground.js loaded
Your public IP address is: xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xx
Your response is: Object { ip: "xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:…" }
Activating BLOCK 2 results in the error response.
OwnerLangBackground.js loaded
Something went wrong. 0
However, if I call the two URLs using curl directly, they both return valid JSON:
> curl https://mathiasbynens.be/demo/ip
{"ip":"xxxx:xxxx:xxxx::xxx"}
> curl http://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/get-languages
[{"language":"??"},{"language":"de"},{"language":"en"},{"language":"fr"},{"language":"it"}]
I have added debugging output to my rest service on the AWS server and I see that it gets called. I also traced the WebExtension call to the rest service using Wireshark on my local machine on which the WebExtension is running and I can see the JSON string being returned, so I am guessing that the error occurs somewhere within firefox/the webextension, but I am at a total loss.
Things I have considered:
Permissions in the manifest: as far as I can tell the URL pattern for my aws-url is correctly added. However, the call to mathiasbynens.be works even though I have not added the url to the permissions
the call that works uses https while the call that does not work uses http. Could this be the reason?
Can anyone point me in the right direction to get more feedback on what goes wrong? I've tried adding a onerror callback to the xhr request. It is called but as far as I can see doesn't provide more information.
UPDATE:
I've come up with two more ideas. Using curl -v provided me with the headers:
> curl -v http://ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000/get-languages
* Hostname was NOT found in DNS cache
* Trying 35.158.91.62...
* Connected to ec2-35-158-91-62.eu-central-1.compute.amazonaws.com (35.158.91.62) port 9000 (#0)
> GET /get-languages HTTP/1.1
> User-Agent: curl/7.38.0
> Host: ec2-35-158-91-62.eu-central-1.compute.amazonaws.com:9000
> Accept: */*
>
< HTTP/1.1 200
< Content-Type: application/json;charset=UTF-8
< Transfer-Encoding: chunked
< Date: Sun, 23 Apr 2017 06:43:42 GMT
<
* Connection #0 to host ec2-35-158-91-62.eu-central-1.compute.amazonaws.com left intact
[{"language":"??"},{"language":"de"},{"language":"en"},{"language":"fr"},{"language":"it"}]
> curl -v https://mathiasbynens.be/demo/ip
* Hostname was NOT found in DNS cache
* Trying 2a01:1b0:7999:402::144...
* Connected to mathiasbynens.be (2a01:1b0:7999:402::144) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server key exchange (12):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using TLSv1.2 / ECDHE-RSA-AES128-GCM-SHA256
* Server certificate:
* subject: OU=Domain Control Validated; OU=PositiveSSL Wildcard; CN=*.mathiasbynens.be
* start date: 2015-07-28 00:00:00 GMT
* expire date: 2018-08-12 23:59:59 GMT
* subjectAltName: mathiasbynens.be matched
* issuer: C=GB; ST=Greater Manchester; L=Salford; O=COMODO CA Limited; CN=COMODO RSA Domain Validation Secure Server CA
* SSL certificate verify ok.
> GET /demo/ip HTTP/1.1
> User-Agent: curl/7.38.0
> Host: mathiasbynens.be
> Accept: */*
>
< HTTP/1.1 200 OK
< Date: Sun, 23 Apr 2017 06:44:16 GMT
* Server Apache is not blacklisted
< Server: Apache
< Access-Control-Allow-Origin: *
< Strict-Transport-Security: max-age=15768000; includeSubDomains
< Vary: Accept-Encoding
< Cache-Control: max-age=0
< Expires: Sun, 23 Apr 2017 06:44:16 GMT
< X-UA-Compatible: IE=edge
< X-Content-Type-Options: nosniff
< X-Frame-Options: DENY
< X-XSS-Protection: 1; mode=block
< Transfer-Encoding: chunked
< Content-Type: application/json;charset=UTF-8
<
* Connection #0 to host mathiasbynens.be left intact
{"ip":"xxxx:xxxx:xxxx::xxx"}
The one difference that stuck out was that my rest service's response lacks the Transfer-Encoding and Access-Control-Allow-Origin? headers, so I'll look into adding those.
Still, if anyone has a hint on how to get more error information for what goes wrong with XmlHttpRequest I'd be glad to hear it.
Ok, it seems the missing Access-Control-Allow-Origin? header was the root of my problems.
I have now changed all methods in my Spring-RestControllers by adding another method parameter HttpServletResponse response and then calling setHeader() on that parameter.
#RequestMapping("/get-languages")
public #ResponseBody List<Language> getLanguages(HttpServletResponse response) {
response.setHeader("Content-Type", "application/json;charset=UTF-8");
response.setHeader("Access-Control-Allow-Origin", "*");
return languageRepository.findAll();
}
Now my WebExtension can use this rest service sucessfully using XmlHttpRequest.
It would have been helpful if this information (that the CORS header was missing) had been visible somewhere in firefox's debugging or js console, so if anyone can tell me how I could have seen this, I'd still appreciate a hint.

Xively PUT request error HTTP 411, Content-Length Required?

So I've got an arduino uno with a CC3000 shield attached and I want to push data to my Xively account:
https://xively.com/develop/yS4XfViIIEEkB94MJ4zs
However I get this error when I connect:
Connected!
Request DHCP
api.xively.com -> 64.94.18.120
Data Lengthz
PUT /v2/feeds/97346308.json HTTP/1.1
Host: api.xively.com
X-ApiKey:mykey
Content-Length: z
Connection: close
{"version":"1.0.0","datastreams" : [ {"id" : "Longitude","current_value" : ""},{"id" : "Latitude","current_value" : ""}]}
Connected to Xively server.
--------------------------------------
HTTP/1.1 411 Length Required
Date: Fri, 08 Aug 2014 13:19:33 GMT
Content-Type: text/html
Content-Length: 181
Connection: close
<html>
<head><title>411 Length Required</title></head>
<body bgcolor="white">
<center><h1>411 Length Required</h1></center>
<hr><center>nginx/1.1.19</center>
</body>
</html>
I understand that error 411 is a call for content length but I've alread declared this in my header and I still get this error.
Any help would be greatly appreciated :)
The Content-Length value must be a sequence of digits. What you sent is a letter, so the server complained that it didn't get your header in the correct format.
Instead of:
Content-Length: z
Use:
Content-Length: 0
If you are actually including data in the body of your request, the length should be the number of octets in the encoded body.

Cannot receive JSON exception message/content type on remote requests

I have a ASP.NET MVC3 application, which uses JSON to comunicate with a Flash UI.
I´m use an ActionFilterAttribute to handle JSON exceptions (from Handle JSON Exceptions Gracefully in ASP.NET MVC 2: http://www.dotnetcurry.com/ShowArticle.aspx?ID=496):
public class HandleJsonExceptionAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.Exception != null)
{
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult()
{
JsonRequestBehavior = JsonRequestBehavior.AllowGet,
Data = new
{
filterContext.Exception.Message,
}
};
filterContext.ExceptionHandled = true;
}
}
}
It´s works ok when executes on localhost, details from fiddler:
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: application/json; charset=utf-8
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 11 Apr 2011 19:05:21 GMT
Content-Length: 34
{"Message":"No está autenticado"}
But, when executed from remote clients, on the LAN for example, I get the response in "Content-Type: text/html" instead "Content-Type: application/json;" and the content is a standard html error page:
500 - Internal server error.
There is a problem with the resource you are looking for, and it cannot be displayed.
HTTP/1.1 500 Internal Server Error
Cache-Control: private
Content-Type: text/html
Server: Microsoft-IIS/7.5
X-AspNetMvc-Version: 3.0
X-AspNet-Version: 4.0.30319
X-Powered-By: ASP.NET
Date: Mon, 11 Apr 2011 19:07:53 GMT
Content-Length: 1208
What or where I need to configure something to get the JSON response on remote requests?
I need the flash UI receive a http 500 error, but with the json message instead the html.
Looking at the article the javascript only seems to be wire up for local requests.
What you need is to be using jsonp. (json with padding). This will allow you to do proper cross domain request returning a json object.
Further info can be found here and here.
I had a same problem, I solved with this code in web.config
<httpErrors existingResponse="PassTrough"></httpErrors>