NTLM auth in multithread via HttpClient - c#

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

Related

Make few requests every 5 minutes to external API from C# Web Service without exhausted all sockets

I need to send few requests to specific URL every 5 minutes from web service methods. I tried using HttpClient, HttpWebRequest and RestClient, but all sockets are exhausted after hour or two.
Can you suggest me what is the right way to send few requests to some URL every 5 minutes without all sockets to be exhausted? Thank you in advance for any help.
Sample of the code
private static HttpClient client = new HttpClient();
public async Task sendReq()
{
client.DefaultRequestHeaders.ConnectionClose = true;
var res = await client.GetStringAsync(url);
}

How to handle multiples accesses to azure service bus

my application is using Azure Service Bus to store messages. I have an Azure function called HttpTriggerEnqueuewhich allow me to enqueue messages. The problem is that this function can be invoked hundreds times in a little interval of time. When I call the HttpTriggerEnqueue once, twice, 10 times, or 50 times everything works correctly. But when I call it 200, 300 times (which is my use case) I get an error and not all messages are enqueued. From the functions portal I get the following error.
threshold exceeded [connections]
I tried both the .NET sdk and the HTTP request. Here is my code
HTTP REQUEST:
try
{
var ENQUEUE = "https://<MyNamespace>.servicebus.windows.net/<MyEntityPath>/messages";
var client = new HttpClient(new HttpClientHandler() { AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip });
var request = new HttpRequestMessage(HttpMethod.Post, ENQUEUE);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
var sasToken = SASTokenGenerator.GetSASToken(
"https://<MyNamespace>.servicebus.windows.net/<MyEntityPath>/",
"<MyKeyName>",
"<MyPrimaryKey>",
TimeSpan.FromDays(1)
);
client.DefaultRequestHeaders.TryAddWithoutValidation("Authorization", sasToken);
request.Content = new StringContent(message, Encoding.UTF8, "application/json");
request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip"));
request.Headers.AcceptEncoding.Add(new StringWithQualityHeaderValue("deflate"));
var res = await client.SendAsync(request);
}
catch (Exception e) { }
And the code using the SDK:
var qClient = QueueClient.CreateFromConnectionString(MyConnectionString, MyQueueName);
var bMessage = new BrokeredMessage(message);
qClient.Send(bMessage);
qClient.Close();
I have the standard tier pricing on Azure.
If I call the function 300 (for example) times in a little interval of time I get the error. How can I solve?
The actual issue here isn't with the Service Bus binding (although you should follow the advice that #Mikhail gave for that), it's a well known issue with HttpClient. You shouldn't be re-creating the HttpClient on every function invocation. Store it in a static field so that it can be reused. Read this blog post for a great breakdown on the actual issue. The main point being that unless you refactor this to use a single instance of HttpClient you're going to continue to run into port exhaustion.
From the MSDN Docs:
HttpClient is intended to be instantiated once and re-used throughout the life of an application. Especially in server applications, creating a new HttpClient instance for every request will exhaust the number of sockets available under heavy loads. This will result in SocketException errors.
You should use Service Bus output binding to send messages to Service Bus from Azure Function. It will handle connection management for you, so you shouldn't be getting such errors.

SignalR Authorize is being called multiple times

I am trying to keep track of connected users to my hub.
The way I tried to do this was by creating a custom Authorize attribute for my hub, and checking for the user that is trying to connect. If the user is already connected then the hub does not authorize the connection
public class SingleHubConnectionPerUserAttribute : Microsoft.AspNet.SignalR.AuthorizeAttribute
{
private static readonly HashSet<UserKey> connections = new HashSet<UserKey>();
public override bool AuthorizeHubConnection(HubDescriptor hubDescriptor, IRequest request)
{
Type hubType = hubDescriptor.HubType;
string userId = request.User.Identity.GetUserId();
UserKey userKey = new UserKey(hubType, userId);
if (connections.Contains(userKey) || !base.AuthorizeHubConnection(hubDescriptor, request))
{
return false;
}
connections.Add(userKey);
return true;
}
}
This would work fine if the method AuthorizeHubConnection was called only once per connection, but that is not what is happening.
When I load the page that tries to connect with the hub, AuthorizeHubConnection oddly runs multiple times, and the number of times it runs is not always the same, sometimes it's 5, some it's 3, I really have no clue of what could possibly be causing it.
Do you know what could cause AuthorizeHubConnection to get called more than once?
Authorization is invoked each time SignalR server receives an HTTP request before it does anything else (See: https://github.com/SignalR/SignalR/blob/dev/src/Microsoft.AspNet.SignalR.Core/PersistentConnection.cs#L161). While SignalR maintains a logically persistent connection it makes multiple HTTP Requests behind the scenes. When using Websockets transport you will typically see only 3 of these when starting the connection (for the negotiate, connect and start requests) and one for each reconnect. longPolling and serverSentEvents transport create an HTTP request each time to send data (send). In addition longPolling creates a polling HTTP request to receive data (poll). Each of these requests has to be authorized so this is the reason why you see multiple calls to the AuthorizeHubConnection method.

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.

Duplicated http request using HttpListener

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?

Categories

Resources