Apache HttpClient 4.5: Why does the second package wait for the ack of the first package? - apache-httpclient-4.x

I am using apache http client in version 4.5.13 within my java application to send a post request. I used following line of code to set up the http client.
SocketConfig socketConfig = SocketConfig.custom()
.setSoKeepAlive(true)
.setTcpNoDelay(true)
.build();
ConnectionConfig connectionConfig = ConnectionConfig.custom()
.setMalformedInputAction(CodingErrorAction.IGNORE)
.setUnmappableInputAction(CodingErrorAction.IGNORE)
.setCharset(Consts.UTF_8)
.setMessageConstraints(messageConstraints)
.build();
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setCookieSpec(CookieSpecs.DEFAULT)
.setExpectContinueEnabled(true)
.setTargetPreferredAuthSchemes(Arrays.asList(AuthSchemes.NTLM, AuthSchemes.DIGEST))
.setContentCompressionEnabled(true)
.build();
BasicHttpClientConnectionManager connectionManager = new BasicHttpClientConnectionManager();
connectionManager.setSocketConfig(socketConfig);
connectionManager.setConnectionConfig(connectionConfig);
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(defaultRequestConfig)
.build();
And I am sending the data via
CloseableHttpResponse response = httpClient.execute(postRequest);
The issue I am experiencing is that when I look how the messages are send (using tshark) I can see that the application data is split in two messages. The first one leaves my system around 0.5ms after the httpClient.execute(postRequest), but the second part is send around 10ms-20ms after the first one. It looks like the second part is waiting to receive the ack for the first part of the message. I tried to change a a lot of configurations (buffer sizes, TcpNoDelay, different TLS ...) but cannot figure out what is causing this behavior.
I also tried http.net client to send post requests. With this client the message was also split in two messages but they where both send right after each other (with around 0.3ms delay).
I am pretty new to network so I would appreciate a helpful answer and apologize upfront if I did not explain it very well (I do not know all the specific wordings).
Thanks

Try disabling expect-continue handshake.

Related

Web API call not returning

I have a RESTful Web API that is running properly as I can test it with Fiddler. I see calls going through, I see responses coming back.
I am developing a tablet application that needs to use the Web API in order to fetch data or make updates in the repository.
My calls do not return and there is not a single trace in the Fiddler to show that my calls even reach the server.
The first call I need to make is to login. The URI would be this:
http://localhost:53060/api/user
This call would normally return some information about the user (such as group membership, level of authorization and so on). The Web API uses Windows Authentication, so the repository is able to resolve all these fields based on the credentials passed in. As I said, in Fiddler I see the three calls made to the URI as the authentication is negotiated between the caller and the server. The third call returns with a JSON object that contains all information generated from the repository as expected.
Now, moving to my client I have the following:
var webApiClient = new HttpClient(new HttpClientHandler()
{
UseDefaultCredentials = true
})
{
BaseAddress = new Uri("http://localhost:53060/")
};
webApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = await webApiClient.GetAsync("api/user");
var userLoginInfo = await response.Content.ReadAsAsync<UserLoginInformation>();
My call to "GetAsync" never returns and, like I said, I see no trace of it in Fiddler.
Any idea of what I'm doing wrong?
Changing the URL where the Web API was exposed seemed to have fixed the problem. Thanks to #Nkosi for the suggestion.
For anyone stumbling onto this question and asking themselves how to change the URL of the Web API, there are two ways. If the simulator is running on the same machine with the Web API, the change has to be made in the "applicationhost.config" file for IIS Express. You can locate this file by right-clicking on the IIS Express icon in the Notification Area (the bottom right corner) and selecting show all websites. Highlight the desired Web API and it will show where the application host configuration file is located. In there, one needs to locate the following section:
<bindings>
<binding protocol="http" bindingInformation="*:53060:localhost" />
</bindings>
and replace the "localhost" name with the IP address of the machine where the Web API is running.
However, this approach will not work once you start testing your tablet app with a real device. IIS Express must be coerced into exposing the Web API to the outside world. I found an excellent node.js package that can help with that. It is called IISExpress-proxy.

GameMaker runner crashes when making HTTP requests

I recently got back into using GameMaker:Studio, and hoo boy have there been some massive updates since I last used it! In fact the last time I used it they only had Windows and HTML5 as export options...
Anyway, eager to try out some of the new stuff, I decided to take a shot at the native HTTP functions, since they looked very promising.
I did a test using http_post_string() to great effect, sending a JSON string to my server and getting a JSON string back. The returned string actually represented an object with a single property, "echo", which contained the HTTP request that had been made, just to see what GM:S was sending.
I didn't like that it sent Content-Type: application/x-www-form-urlencoded when it was quite clearly JSON, and I wanted the ability to set my own User Agent string so that the server could know which game was talking to it without having to pass an extra parameter.
So I re-created the same request using the lower-level http_request() function. Everything looked fine, so I tested it.
It crashed. Like, no error messages or anything, just a total crash and Windows had to force-close it.
So here I am with code that by all rights should work fine, but crashes when run...
///send_request(file,ds_map_data,callback_event_id)
var request = ds_map_create();
request[? "instance"] = id;
request[? "event"] = argument2;
if( !instance_exists(obj_ajax_callback)) {
instance_create(0,0,obj_ajax_callback);
}
var payload = json_encode(argument1);
var headers = ds_map_create();
headers[? "Content-Length"] = string_length(payload);
headers[? "Content-Type"] = "application/json";
headers[? "User-Agent"] = obj_ajax_callback.uastring;
var xhr = http_request("https://example.com/"+argument0,"POST",headers,payload);
with(obj_ajax_callback) {
active_callbacks[? xhr] = request;
}
ds_map_destroy(headers);
obj_ajax_callback is an object that maintains a ds_map of active requests, and in its HTTP event it listens for those requests' callbacks and reacts along the lines of with(request[? "instance"]) event_user(request[? "event"]) so that the calling object can handle the response. This hasn't changed from the fully working http_post_string() attempt.
Any idea what could be causing this crash?
The reason why this crashes is because you are sending the Content-Length header as a real instead of a string. If you change your line to
headers[? "Content-Length"] = string(string_length(payload));
It should work.

Extjs application with Json-server not working fine

I have a small app and I am using Rest Proxy. I set up json-server https://github.com/typicode/json-server locally.
I have not changed anything in server settings. I am able to successfully GET data from server but when I try to create data like this
var people = App.model.myModel;
var ed = new people({"id": 2,"title": "test","body": "test"});
ed.save();
Error appears in browser console is
PUT http://localhost:3000/posts/11?_dc=1427464731634 404 (Not Found)
Can some one point out why it is trying to PUT data and not POST data ?
PUT is used to update an item, Not Create.
As you have specified an id value ExtJs will presume that you need to update the record rather than create it, therefore making the PUT request.
Most RESTful API's will provide GET, PUT, POST and sometimes DELETE, LINK Endpoints for each entity.
I found the problem my self. I was sending the "id" as well and it was looking for a post with Id 2, and obviously that doesn't exist.
var people = App.model.myModel;
var ed = new people({"title": "test","body": "test"});
ed.save();
Works perfectly

Actionscript services stop functioning

I have built a complex AIR application which has been successfully running for quite some time of many PCs. Unfortunately, I have a plaguing problem with internet connectivity and I was wondering if anyone had encountered this issue before.
Every once in a while, the program will completely stop talking to the internet (all services start faulting). I wrote special code in my program to monitor the situation in which I use two different services to contact the same server.
The first service:
var req:URLRequest = new URLRequest("myURL.com");
this.urlMonitor = new URLMonitor(req, [200, 304]); // Acceptable status codes
this.urlMonitor.pollInterval = 60 * 1000; // Every minute
this.urlMonitor.addEventListener(StatusEvent.STATUS, onStatusChange);
this.urlMonitor.start();
private function onStatusChange(e:StatusEvent):void
{
if (this.urlMonitor.available)
{
pollStatusOnline = true;
Online = true;
}
else
{
pollStatusOnline = false;
Online = false;
}
}
The secondary method is a normal HTTP Service call:
checkInService = new HTTPService();
checkInService.method = "POST";
checkInService.addEventListener(ResultEvent.RESULT,sendResult);
checkInService.addEventListener(FaultEvent.FAULT, faultResult);
checkInService.addEventListener(InvokeEvent.INVOKE, invokeAttempt);
checkInService.url = "myURL.com";
checkInService.concurrency = Concurrency.LAST;
checkInService.send(params);
These two services point to the same location and work 98% of the time. Sometimes, after a few hours, I have noticed that both services no longer can connect to the website. The HTTP Service returns a StatusCode 0. I am able to open command prompt and ping the server directly with no problem from the PC which is failing. The services will not function again until the program is restarted.
I have been working on this issue for many months now without resolution. If anyone is able to even point me in a somewhat possible, maybe this might be the problem, possibly, direction, I would really appreciate it.
Thank you in advance.
Check the code value of the StatusEvent you receive from the URLMonitor - this might give more info than the HTTPService (you might also want to try passing a null value to URLMonitor constructor, to widen the acceptable status codes).
If you have access to the server(s?) in question, check their logs. Could the server config have changed such that it might now consider such frequent requests as flooding?
You should also be able to use an HTTP debugger like Fiddler or Charles on the client machine to see more information about the requests going out of your application.

Error sending data to a HTTPS server with as3httpclientlib

I'm trying to send some data from flash to a server. I was doing it with a test server and everything was ok. But when I change to test it into a real server it send me an error: " got Alert! Type=22" So I searched about it and I discover that its because the real server runs on HTTPS and the test runs on HTTP. So, reading the documentation of the as3httpclienlib library that I am using, I found that there is a bug with some HTTPS servers and cause some errors and don't leave flash send more than 40kb of data, so that throws the error Type 22 -> Record overflow
This only happens with TLS Sockets so I think that the solution is change the TLSSocket to a SSLSocket.
This is the code that I use to send the data to the server:
var client:HttpClient = new HttpClient();
var uri:URI = new URI("http://www.snee.com/xml/crud/posttest.cgi");
var variables:Array = [{name:"fname", value:"FirstName1"}, {name:"lname", value: "LastName1"}];
client.listener.onData = function(event:HttpDataEvent):void {
// Notified with response content in event.bytes as it streams in
};
client.listener.onComplete = function(event:HttpResponseEvent):void {
// Notified when complete (after status and data)
};
client.postFormData(uri, variables);
How can I change this sockets?
Does anyone have an example?
Is this the solution of the problem?