How to abort HttpRequest? - java

I'm using ThreadSafeClientConnManager to manage a pool of client connections on HttpClient 4.0.1 environment.
Usually my system works fine when authenticating with NTLM, but sometimes it doesn't work properly.
When authenticating with NTLM, we receive result codes in the same order as below: HTTP/1.1 401 > HTTP/1.1 401 > HTTP/1.1 200.
It is correct process.
But, I don't know why, sometimes MS EWS returns 401 result code 3 times: HTTP/1.1 401 > HTTP/1.1 401 > HTTP/1.1 401.
After that, EWS only returns HTTP/1.1 200 for every request.
to help you understand better..
User A: 401 > 401 > 200 (Good)
User B: 401 > 401 > 200 (Good)
User C: 401 > 401 > 401 (Issue arises)
User D: 200
User E: 200
User F: 200
So, when the issue arises, UserC,D,E,F... can use our system properly.
Here are my questions
Why does EWS only return 200 code after returning 401 three times?
How can I abort the connection when I keep receiving the result code, HTTP/1.1 401?
In more detail,
Why does EWS only return 200 code after returning 401 three times? It doesn't happen often, though. The username and password for authentication is correct.
How can I abort the connection when I receive the third HTTP/1.1 401?
I use request.abort(), but it doesn't work.
My code is as below.
private Response processRequest(AbstractHttpClient httpClient, HttpRequestBase httpRequest, HttpContext httpContext){
Response response = new Response();
try {
// execute request
HttpResponse httpResponse = null;
if(httpContext != null){
httpResponse = httpClient.execute(httpRequest, httpContext);
// retrieve cookie
CookieStore cookieStore = (CookieStore)httpContext.getAttribute(ClientContext.COOKIE_STORE);
List<Cookie> cookieList = cookieStore.getCookies();
for(Cookie cookie : cookieList){
com.XXX.mo.connectivity.info.http.Cookie newCookie = new com.XXX.mo.connectivity.info.http.Cookie(cookie.getName(), cookie.getValue());
newCookie.setVersion(cookie.getVersion());
newCookie.setDomain(cookie.getDomain());
newCookie.setPath(cookie.getPath());
response.addCookie(newCookie);
}
}else{
httpResponse = httpClient.execute(httpRequest);
}
// retrieve header
response.setStatusCode(httpResponse.getStatusLine().getStatusCode());
Header [] headers = httpResponse.getAllHeaders();
for(Header header : headers){
response.addHeader(new com.XXX.mo.connectivity.info.http.Header(header.getName(), header.getValue()));
}
// retrieve body
HttpEntity httpEntity = httpResponse.getEntity();
if(httpEntity != null){
response.setContentCharSet(EntityUtils.getContentCharSet(httpEntity));
response.setBody(EntityUtils.toByteArray(httpEntity));
httpEntity.consumeContent();
}
} catch (Exception e) {
e.printStackTrace();
httpRequest.abort();
}
return response;
}

Related

Send the API Headers in Rest Assured using java

API Headers have two parameter Content-Type=application/json and also accesstoken = "some_token"
I trying to automate the API using Rest assured but not successful.
Below is the code
RestAssured.baseURI = prop.getProperty("serviceurl1");
//2. define the http request:
RequestSpecification httpRequest = RestAssured.given()
.filter(new ResponseLoggingFilter())
.filter(new RequestLoggingFilter());
JSONObject requestParams = new JSONObject();
requestParams.put("longitude", eLongitude);
requestParams.put("latitude", eLaititude);
requestParams.put("country", eCity);
httpRequest.headers("Content-Type", "application/json");
httpRequest.headers("accesstoken", "some_token.");
httpRequest.body(requestParams.toJSONString());
int statusCode = response.getStatusCode();
System.out.println("the status code is: "+ statusCode);
Assert.assertEquals(statusCode, TestUtil.RESPONSE_CODE_200);
System.out.println("the status line is: "+ response.getStatusLine());
//6. get the headers:
Headers headers = response.getHeaders();
System.out.println(headers);
String contentType = response.getHeader("Content-Type");
System.out.println("the value of content-type header is: "+ contentType);
String contentLength = response.getHeader("Content-Length");
System.out.println("the value of Content-Length header is: "+ contentLength);
Getting error message as "Provide Application Token" and 404 error code display.
Your httpRequest.headers("accesstoken", "kggkgkgkgketdfgxgcccvcdftfty."); is wrong. It should be:
httpRequest.headers("Authorization", "Bearer "+token);
can you try this once
Response resp = given().when().contentType(ContentType.JSON).header("accesstoken", "token").body(body).put("url");
You can pass the HashMap as body
These are the issues I can think of
This might be an internal API and it is expecting "Provide Application Token" and not the "accesstoken"
The error code you are getting is 404. So either the service is down or the URL you are using is not correct.
Hope this helps :)

HTTPPOST - Unsuccessful in code but successful via Postman

I am sending a JSON request via http post. Backend requires me to send two headers, namely - Authorization and Content-Type. Then a raw JSON request as body. I send the request via Post method via Postman tool and the message gets through successfully. But when I send the same request with same headers via code, I get a bad request - Error.
I minimized the scope of testing to check.
I have sent only the two headers via Postman and here's the response:
Headers
Authorization: "bearer " + token. The structure is "bearer" keyword + space + Okta token.
Content-Type: application/json
Response:
Headers
Content-Type →application/json; charset=utf-8
Strict-Transport-Security →max-age=31536000
X-Content-Type-Options →nosniff
Request-Context →appId=cid-v1:dc220dda-e515-4dd4-b324-c078a1b8fac4
Date →Sun, 26 May 2019 13:23:01 GMT
Content-Length →29
Body
{
"Message": "No Request Body"
}
But when I send the same thing via code, I get a Bad-Request Error. Please help :(
HttpClient httpclient1;
HttpPost httppost1;
//ArrayList<NameValuePair> postParameters1 = null;
httpclient1 = HttpClientBuilder.create().build
httppost1 = new HttpPost(Constants.URL);
// httppost1.setEntity(new UrlEncodedFormEntity(postParameters1,"UTF-8"));
// httppost1.setEntity(new StringEntity(request,"UTF-8"));
httppost1.setHeader("Authorization", token);
httppost1.setHeader("Content-Type", "application/json");
// httppost1.setHeader("Content-Length", strlength);
// httppost1.setHeader("Accept", "application/json");
// StringEntity entity = new StringEntity(request,ContentType.APPLICATION_JSON);
// httppost1.setEntity(entity);
HttpResponse response1 = httpclient1.execute(httppost1);
InputStream is = response1.getEntity().getContent();
HttpEntity entity1 = httppost1.getEntity();
Header[] headers = httppost1.getAllHeaders();
System.out.println(headers.length);
for(int i=0; i<headers.length;i++)
{
System.out.println(headers[i]);
}
String result = convertInputStreamToStringCommonIO(is);
System.out.println();
System.out.println(result);
int code1 = response1.getStatusLine().getStatusCode();
System.out.println("Code: "+code1+"");
String reason1 = response1.getStatusLine().getReasonPhrase();
System.out.println("Description: "+reason1 +"");
Temporary Request Headers from Postman:
UserAgent: PostmanRuntime/7.13.0
Accept: /
Cache-Contro: no-cache
Postman-Token: *****
Host: *****
accept-encoding: gzip,dflate
content-length:
Connection: keep-alive
Here's the error I am getting:
{"errorCode":"E0000021","errorSummary":"Bad request. Accept and/or Content-Type headers likely do not match supported values.","errorLink":"E0000021","errorId":"oae5BpTGp_5RjaFtGn_Zm_mhw","errorCauses":[]}
Code: 400
Description: Bad Request
Any idea why it's failing via code? Thanks.

Unexpected response code for Spring RestTemplate.getForEntity() after redirect

RestTemplate created as follows:
(HttpClientBuilder comes from org.apache.http.impl.client.*)
CloseableHttpClient chc = HttpClientBuilder.create().disableRedirectHandling().build();
ClientHttpRequestFactory noRedirectFactory = new HttpComponentsClientHttpRequestFactory(chc)
RestTemplate restTemplate = new RestTemplate(noRedirectFactory);
Used as follows:
ResponseEntity<String> response = restTemplate.getForEntity( ${url} , String.class);
int responseCode = response.getStatusCodeValue();
Now 3 cases for ${url}, differences only in query parameters:
http://www.boxofficemojo.com/intl/ukraine/?yr=2017&wk=27
Query params values are all ok, page exists, responseCode == 200 (as expected)
http://www.boxofficemojo.com/intl/ukraine/?yr=99999999&wk=999999
Query params values are wrong, redirect, responseCode == 302 (as expected, thanks to noRedirectFactory)
http://www.boxofficemojo.com/intl/ukraine/?someRandomParam=99999999
Query params are wrong, redirect, responseCode == 200. How is that different from second case?
Thanks in advance.

Convert CookieStore to String: pb with encode/decode value

I have my cookies in a CookieStore Object, but to stream a video I need to convert my CookieStore to a String, but my API in NodeJS (using express, cookie-parser and passport-local) never recognizes the value of the cookie, whenever I try to encode/decode it before. I think it's a stupid problem just I'm not really good in HTTP Headers so I'm doing it wrong.
There is the code:
Method setVideoURIMethod = videovvw.getClass().getMethod("setVideoURI", Uri.class, Map.class);
Map<String, String> params = new HashMap<String, String>(1);
params.put("Cookie", ARequestAPI.getCookieString());
setVideoURIMethod.invoke(videovvw, uri[0], params);
I had the code from here so normally it should work perfectly: Authentication for Videoview in android
I think the problem comes from "ARequest.getCookieString()":
protected static CookieStore _cookies = null;
...
...
...
public static String getCookieString() {
String cookieString = "";
Log.v("Debug", _cookies.toString());
for (Cookie cookie : _cookies.getCookies()) {
try {
Log.v("Debug", "Decode: " + URLDecoder.decode(cookie.getValue(), "UTF-8"));
Log.v("Debug", "Encode: " + URLEncoder.encode(cookie.getValue(), "UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
cookieString += cookie.getName() + "=" + cookie.getValue()+ ";";
}
return cookieString;
}
The display in LogCat:
And the log on my API:
When I do a request using CookieStore:
{ 'connect.sid': 's:NUTf8t9o8cepR1yYItMexMxy.WFv/ZlktryfpVZHweVozabW1US4UBvGlWxQR7G7Aamc' }
When I do the request with my function which convert the CookieStore to a String:
{ 'connect.sid': 's:AZXpZmQGX7eJgej9hVA1qaAk.7vWP756Flwbte/qxBRcLOhl/CXMlVO3HVvmsvsEBpzA' }
I tried all the options, even encode(decode()), ... but it is never a good one on my API.
The weird thing is that I tried to decode 's%3ANUTf...' (so cookie.getValue()) with the javascript function "decodeURIComponent()" and I found exactly 's:NUTf8t9o8cepR1yYItMexMxy.WFv/ZlktryfpVZHweVozabW1US4UBvGlWxQR7G7Aamc', so my cookie is good, but I think I'm doing something wrong on the encode/decode part.
Thanks for your help.
Edit: After many tests, I saw that on the API the value for the cookie is always the same, whenever I use URLDecoder.decode(), URLDecoder.decode() or event directly cookie.getValue(), the only time I get the right value is when I "choose/write" the value myself like "totoauzoo" for example with this wring I get exactly the same value on the API. But it's not working with my old cookie value like "s:DMCBao7zeS9B2jwIfeQoDZtl.3XPIYIm7y2Bz9/o468v4wxvFZmjDrc6hKk4ty89sIX4".
Edit2: I probably found what is wrong, I get that on the API:
request with HttpGet and CookieStore:
headers { host: 'xxx',
connection: 'Keep-Alive',
'user-agent': 'Apache-HttpClient/UNAVAILABLE (java 1.4)',
cookie: 'connect.sid=s%3AGRGciNxOcR4BXHrUG8PikHMX.MyWa6vjW%2BBlcUaaCHHendqc7DEK4aoNFDzm5aabOkDM',
cookie2: '$Version=1' }
cookies { 'connect.sid': 's:GRGciNxOcR4BXHrUG8PikHMX.MyWa6vjW+BlcUaaCHHendqc7DEK4aoNFDzm5aabOkDM' }
request with setVideoURI:
headers { host: 'xxx',
connection: 'keep-alive',
cookie: 'connect.sid=s%3AKWKdcuXqUpzBIMv0sOGpPxqM.xb14kPsGKvn%2Fv%2BVcfUDzxWsye8QdJfuQgonNocsX3k8',
'user-agent': 'stagefright/1.2 (Linux;Android 4.1.2)',
'accept-encoding': 'gzip,deflate' }
cookies { 'connect.sid': 's:KWKdcuXqUpzBIMv0sOGpPxqM.xb14kPsGKvn/v+VcfUDzxWsye8QdJfuQgonNocsX3k8' }
How can I fix that?
I would suggest inspecting the network traffic itself.
Cookies are nothing else than HTTP headers ...
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: name=value
Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14 GMT
or
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: name=value; name2=value2
Accept: */*
I'm not familiar with the classes you are using to set the cookies, but I would inspect two places:
1:
params.put("Cookie", ARequestAPI.getCookieString());
Is this call setting the headers or are you setting POST parameters? This should be visible in the network traffic. What are params? Headers, query string?
2:
ARequestAPI.getCookieString()
Is the output of this function in correct cookie value format, or what is it?
Most probably in one of those places lies the error.

Problem displaying request headers with apache httpclient 4

I've been trying to retrieve the headers sent by a HttpMethod, using HttpClient 4, but without any success...
here is my code :
HttpClient httpClient = new DefaultHttpClient();
HttpParams httpParams = httpClient.getParams();
HttpGet httpGet = new HttpGet("http://www.google.fr");
HttpResponse response = httpClient.execute(httpGet);
log.info("*** Request headers ***");
Header[] requestHeaders = httpGet.getAllHeaders();
for(Header header : requestHeaders) {
log.info(header.toString());
}
log.info("***********************");
log.info("*** reponse ***");
log.info(response.getStatusLine());
Header[] headers = response.getAllHeaders();
for(Header header : headers) {
log.info(header.toString());
}
but the result is :
00:27:57,368 INFO - *** Request headers ***
00:27:57,368 INFO - ***********************
00:27:57,368 INFO - *** reponse ***
00:27:57,368 INFO - HTTP/1.1 200 OK
00:27:57,368 INFO - Date: Sun, 15 Aug 2010 22:28:09 GMT
00:27:57,368 INFO - Expires: -1
00:27:57,368 INFO - Cache-Control: private, max-age=0
00:27:57,368 INFO - Content-Type: text/html; charset=ISO-8859-1
00:27:57,368 INFO - Set-Cookie:
[..]
Aka the response headers are good, but not the request's. ( Same result if I move the log request headers block before the execute statement ).
(and NO, I dont want to simply see them, so setting the log level to debug isnt acceptable )
Anyone can help ?
To get all headers including those which the HTTPclient sets, use
HttpCoreContext. This class allows to read out all the headers.
HttpClient client = HttpClients.createDefault();
HttpCoreContext localContext = new HttpCoreContext();
HttpResponse response = client.execute(request,localContext);
Header[] headers = localContext.getRequest().getAllHeaders();
for (Header header : headers) {
System.out.println(header.toString());
}
Things may have changed since 2010, however this can be done by using a request interceptor (to inspect the request at a lower level) with amazingly similar code.
// So we can get all the headers (not just the ones we explicitly set).
httpClient.addRequestInterceptor(new HttpRequestInterceptor() {
public void process(
final HttpRequest request,
final HttpContext context)
throws HttpException, IOException {
// Start Debug
System.out.println("*** Request headers ***");
Header[] requestHeaders = request.getAllHeaders();
for(Header header : requestHeaders) {
System.out.println(header.toString());
}
System.out.println("***********************");
// End Debug
}
});
In my case, I get the following output (having only explicitly set two of these).
*** Request headers ***
Accept: application/xml
Authorization: Basic bmV3Omd1ZXN0
Content-Length: 772
Content-Type: application/xml; charset=UTF-8
Host: rest3api.sifassociation.org:80
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.2.1 (java 1.5)
***********************
May this help those who travel here.
It will only display the request headers you've set yourself.
If you want to log the request headers which HttpClient has set, then you need to configure HttpClient's builtin logging by Commons Logging. Also see this document.
As an alternative, you can also use an external tool like Fiddler.

Categories