Duplicated http request using HttpListener - c#

I have a scenario where an HttpListener listens for http requests. I created a thread where is called Request method of HttpListenerContext:
while (true)
{
var ctx = listener.GetContext();
HttpListenerRequest req = ctx.Request;
...
ctx.Response.StatusCode = 200;
ctx.Response.StatusDescription = "OK";
ctx.Response.Close();
}
The problem here is that even if i send only one request (for example by telnet) sometimes i see a lot of requests. The listener prefix is http://localhost:9999. The strange thing is that printing remote endpoint of the request i see two or more different end points for each request. Any ideas?

Related

NTLM auth in multithread via HttpClient

I'm trying to create an application which will continously send many http requests to one web endpoint which uses NTLM authentification (via login and password). To optimize the app, it was decided to use multithread execution, so I can send many http requests simultaneously. I'm using following code:
private string DoGetRequestWithCredentials(Uri callUri, NetworkCredential credentials)
{
using (var handler = new HttpClientHandler {Credentials = credentials})
{
using (var client = new HttpClient(handler))
{
MediaTypeWithQualityHeaderValue mtqhv;
MediaTypeWithQualityHeaderValue.TryParse(
"application/json;odata=verbose", out mtqhv);//success
client.DefaultRequestHeaders.Accept.Add(mtqhv);
client.Timeout = RequestTimeout.Value;
var result = client.GetAsync(callUri).Result;
result.EnsureSuccessStatusCode();
return result.Content.ReadAsStringAsync().Result;
}
}
}
Code works fine in a single thread, but when I enable multithread, I'm starting to receive 401 UNAUTHORIZED exceptions.
My suggestion why this happens is because some of requests in multithread are trying to be executed between consiquential NTLM calls.
Is my assumption correct?
How can I avoid this situations without locking the method? Because I really want requests to be sent simultaneously

HttpClient aborting simple get request

I am doing a simple Get request with HttpClient. But I am have issues with it aborting before the request is complete. Fiddler shows that it the request should return a 200, but it shows that the request was aborted. It is diffenitally not hitting the default 100s timeout. Is there any hidden setting I am missing?
var new_client = new HttpClient();
var req = await new_client.GetAsync("http://a20.skout.com/support/captchaMobile/?sid=e91af660-0b3d-4c2f-bbdd-249506b9c440");
req.EnsureSuccessStatusCode();
Image of fiddler request. Showing a sucessful 200 status code but aborted by the client.
Update1: use sid to try "36598189-0f2f-45b9-a794-385a5d5e11c8"
Update2: I am also having problem with this url "http://api.recaptcha.net/challenge?k=6Lc2qN8SAAAAAEe8_R2ALF4hu1V_x34nUV1mzW-W"
Update3: So I manage to get a response with new_client.GetAsync("http://a20.skout.com/support/captchaMobile/?sid=e91af660-0b3d-4c2f-bbdd-249506b9c440").Result. I am unsure why that works but not await. I guess it has to be done syncronously. I will leave the question up just incase someone has a more vaild answer.

Empty http response body

I am trying to make HTTP request/response using sockets in C#. GET request appears below.
StringBuilder sb = new StringBuilder();
sb.AppendFormat("GET http://{0}/ HTTP/1.1\r\n", hostname);
sb.AppendFormat("Host: {0}\r\n", hostname);
sb.Append("Connection: keep-alive\r\n");
sb.Append(#"Accept:text/html,*/*");
sb.Append("\r\n\r\n");
where hostname is something like 'mit.edu' or 'facebook.com' or 'google.com' or anything else. For some strange reason I have just a status-line (with 200 status code) and headers as http response. But there is no message body in the response: attached srceenshot of my console app
Here is a method that perform all manipulations with socket and make http request:
public static void DoHttpGetRequest(String hostname, Int16 port = 80) {
IPHostEntry ipHostEntry = Dns.GetHostEntry(hostname);
IPAddress ipAdress = ipHostEntry.AddressList[0];
IPEndPoint ipEndPoint = new IPEndPoint(ipAdress, port);
Socket socket = new Socket(ipAdress.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
socket.Connect(ipEndPoint);
String request = CreateRequest(hostname);
Byte[] byteRequest = Encoding.UTF8.GetBytes(request);
Byte[] byteResponse = new Byte[1000];
int bytesSent = socket.Send(byteRequest);
int bytesReceive = socket.Receive(byteResponse);
Console.WriteLine(request);
Console.WriteLine();
Console.WriteLine(Encoding.UTF8.GetString(byteResponse, 0, bytesReceive));
socket.Shutdown(SocketShutdown.Both);
socket.Close();
}
My first thought was that the socket hadn't received the whole response from the server. In this case I do still not know how to solve the problem.
So what is going on? Where is the mistake?
Don't expect to get the full response inside a single receive. What you do is to receive data until you have the full response header (this could take several receive calls too), then parse the header to find out how long the response is and then read the necessary data of the response which also can need multiple receive calls. And since you are doing a HTTP/1.1 request you also have to deal with chunked responses.
I recommend to better use a HTTP library to handle all the problems. If you insist on doing it all by your own read the specification of HTTP and implemented accordingly.
It also helps to look around at stackoverflow for similar requests because this problem you have is very typical for someone trying to implement HTTP first time, without understanding enough on how sockets, TCP and HTTP work.
I think you should keep the socket open for a longer time. Insert a
Thread.Wait(5000);
may help. Then you can do a second socket.Receive as Steffen proposed. Maybe you can try the following (wait until the server closed the connection):
while (socket.Connected) do
{
int bytesReceive = socket.Receive(byteResponse);
}
But I didn't test this. It's easier to use the System.Net.Http.HttpClient
Everything I need to do is to receive data with multiple receive calls until all response information received.
do
{
bytesReceive = socket.Receive(byteResponse, byteResponse.Length, 0);
response += Encoding.UTF8.GetString(byteResponse, 0, bytesReceive);
}
while (bytesReceive > 0);
Thanx everybody for your help!

HttpModule - Asynchronous not working

I have written an asynchronous HttpModule which logs all the request coming to a website.
When the request arrives at the website, the custom http module calls the WebAPI to log the information to the database. .Net 4.5/Visual studio with IIS Express.
////////////Custom HTTP module////////////////////
public class MyHttpLogger : IHttpModule
{
public void Init(HttpApplication httpApplication)
{
EventHandlerTaskAsyncHelper taskAsyncHelper = new EventHandlerTaskAsyncHelper(LogMessage);
httpApplication.AddOnBeginRequestAsync(taskAsyncHelper.BeginEventHandler, taskAsyncHelper.EndEventHandler);
}
private async Task LogMessage(object sender, EventArgs e)
{
var app = (HttpApplication)sender;
var ctx = app.Context;
//use default credentials aka Windows Credentials
HttpClientHandler handler = new HttpClientHandler()
{
UseDefaultCredentials = true
};
using (var client = new HttpClient(handler))
{
client.BaseAddress = new Uri("http://localhost:58836/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var actvity = new Activities() { AppId = "TEST123", ActivityId = 10, CreatedBy = 1 };
await client.PostAsJsonAsync("api/activity", actvity);
}
}
Simplified WebAPI code for “api/activity”.
public async Task<HttpResponseMessage>Post(Activities activity)
{
await Task.Delay(30000);
// Database logging code goes here….
return new HttpResponseMessage(HttpStatusCode.Created);
}
The question is: when the PostAsJsonAsync is getting executed the code stops there. This is correct as the code has to wait. But the calling routine is not getting continued asynchronously as expected and the website response is slower by 30 seconds.
What is wrong with this code? Hooking an async HttpModule should not interfere in the flow of the Http application? Currently when I visit the website the code is getting blocked.
Now, you have to understand the difference between HTTP request and local application. HTTP is totally stateless. Basically you send out a request, the server process it and send back the response. The server does NOT keep any state info about the client, it doesn't have any idea who the client is at all. So in your case, browser sends out a request -> server got it, waited for 30 sec to process it and then sends back result -> browser got the response and this is the point where the browser shows the result. I am assuming what you are trying to do is, browser sends a request, and then you expect the browser to display something and then after 30 sec the server finishes processing and you want to display something else. This is NOT possible to do with await because of the reason mentioned above. What you should do is to write some javascript codes to send out the request with some identifier, and then ask the server every x seconds to see if task{ID} has finished, if so whats the result.

HttpListenerResponse - behavior when throwing HttpListenerException

people,
I created a small webserver for a custom application. The webserver works fine, yet from time to time it throws some exceptions, when I try to send a response to the client using HttpListenerResponse. Assume I have
HttpListenerResponse res = ctx.Response; // My HttpListenerContext
... //initialize the response
res.StatusCode = 200;
try
{
res.OutputStream.Write(terminate, 0, terminate.Length);
res.Close();
}
catch(HttpListenerException hex){ ... }
Now, it happens that the connection breaks down (I get Windows System Error-Codes 22, 64, 1229)
MSDN-reference. My client is the WPF-Webbrowser-control.
What does the client receive? Does the client receive the HTTP 200? Or can I alter the status-code inside the exception and somehow push it to the client?
Thank you for your help.

Categories

Resources