Question

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?

Was it helpful?

Solution

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top