Reputation: 11227
I'm using ReCAPTCHA in MVC4 application hosted in Azure cloud for a simple website with one registration form. We have about 100-120 successful registrations per hour currently. The problem is that I have hundreds of System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
errors in the logs, and then number keeps growing fast:
System.Net.Http.HttpRequestException: An error occurred while sending the request. --->
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. --->
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at System.Net.Connection.ReadCallback(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
at System.Net.HttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.Net.Http.HttpClientHandler.GetResponseCallback(IAsyncResult ar)
--- End of inner exception stack trace ---
--- End of inner exception stack trace ---
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at My.Web.Infrastructure.Filters.ValidateReCaptchaAttribute.OnActionExecuting(ActionExecutingContext filterContext) in My.Web\Infrastructure\Filters\ValidateReCaptchaAttribute.cs:line 49 --->
(Inner Exception #0) System.Net.Http.HttpRequestException: An error occurred while sending the request. --->
System.Net.WebException: The underlying connection was closed: An unexpected error occurred on a receive. --->
System.IO.IOException: Unable to read data from the transport connection: An existing connection was forcibly closed by the remote host. --->
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
--- End of inner exception stack trace ---
I use attribute to validate captcha as follows (i deleted some non-important details):
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = false, Inherited = true)]
public class ValidateReCaptchaAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var formValues = new[]
{
new KeyValuePair<string, string>("privatekey", ConfigurationProvider.ReCaptchaPrivateKey),
new KeyValuePair<string, string>("remoteip", remoteIp.ToString()),
new KeyValuePair<string, string>("challenge", challengeField),
new KeyValuePair<string, string>("response", responseField)
};
try
{
using (var client = HttpClientFactory.Create())
using (var data = new FormUrlEncodedContent(formValues))
using (var response = client.PostAsync("http://www.google.com/recaptcha/api/verify", data).Result)
{
var responseString = response.Content.ReadAsStringAsync().Result;
if (responseString.StartsWith("true") == false)
{
modelState.AddModelError(string.Empty, DisplayName.Validation_CaptchaMissing);
}
}
}
catch (Exception ex)
{
log4net.LogManager.GetLogger("WebLogger").Error(string.Format("ValidateReCaptcha failed on {0}/{1}. {2}", controller, action, formValuesRaw), ex);
modelState.AddModelError(string.Empty, DisplayName.Validation_CaptchaMissing);
}
}
}
it fails on var response = client.PostAsync()
line. Not always. I was not able to reproduce it locally. But it fails pretty much for every user of the website - sometimes once, sometimes twice, sometimes more. Eventually they are able to register - as I said, I'm seeing more than 100 registrations per hour - but that results in 300-400 errors in the log table for that hour. I tried to register myself - and though I was 100% sure that I entered captcha correctly, I got validation error.
Any ideas? Does my validation attribute look okay? what can be other reasons?
Upvotes: 4
Views: 7064
Reputation: 11227
Ah!.. fixed it by removing
using (var client = HttpClientFactory.Create())
line and creating HttpClient
as singleton:
public class ValidateReCaptchaAttribute : ActionFilterAttribute
{
private static readonly HttpClient HttpClient = new HttpClient();
// rest of the code goes here...
as suggested by this SO answer
Upvotes: 3