Windows Service using BackgroundService fails when calling HttpClient.Send

Viewed 29

I have created a Windows service using the Worker template and everything works fine, until I try to send a request with HttpClient.Send(). Once I mark this out, everything works again.

It works when I start this in Visual Studio and debug it there, but if I publish it and register it as a Windows service, it fails with this exception:


Category: CorewsWorkerService.WindowsBackgroundService EventId: 0

A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (SECRET:443)

Exception: System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (SECRET:443) ---> System.Net.Sockets.SocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at ......


I don't know why it works when run manually and the connected party doesn't "properly respond after a period of time" when run in Windows services.

I have removed secrets and attached the code that is called from the WindowsBackgroundService class.

public class TotalArchiveService
{
    public string CallService()
    {
        //SendRequest().GetAwaiter().GetResult();
        SendRequest();
        return "OK - " + DateTime.Now.ToString();
    }

    //static async Task SendRequest()
    private void SendRequest()
    {

        try
        {
            using (var client = new HttpClient {})
            {
                var endpointUrlCustomer = "https://SECRET";

                // Create HTTP request.
                var customerBuilder = new UriBuilder(new Uri($"{endpointUrlCustomer}"));
                var customerRequest = new HttpRequestMessage(HttpMethod.Post, customerBuilder.Uri);
                // set SOAP action
                customerRequest.Headers.Add("SOAPAction", "");
                // set SOAP body content 
                string xmlSOAP = GetXmlSOAP();
                customerRequest.Content = new StringContent(xmlSOAP, Encoding.UTF8, "text/xml");
                // Add signature headers to request object
                SignHttpRequestMessage(customerRequest);

                // Perform request
                var customerResponse = client.Send(customerRequest);
            }
        }
        catch (HttpRequestException e)
        {
            throw e;
        }
    }

    //static async Task SignHttpRequestMessage(HttpRequestMessage request)
    private void SignHttpRequestMessage(HttpRequestMessage request)
    {
        // externalize configuration of these
        string certPath = "";
        string keyStorePassword = "";
        string keyId = "";

        certPath = Path.GetFullPath(@"c:\cert2\cert.pfx"); // path to keystorefile
        keyStorePassword = "SECRET";
        keyId = "SECRET";

        X509Certificate2Collection certs = new X509Certificate2Collection();
        X509Certificate2 cert = new X509Certificate2(certPath, keyStorePassword, X509KeyStorageFlags.DefaultKeySet | X509KeyStorageFlags.Exportable);
        var services = new ServiceCollection()
            .AddHttpMessageSigning()
            .UseKeyId(keyId)
            .UseSignatureAlgorithm(SignatureAlgorithm.CreateForSigning(cert, HashAlgorithmName.SHA256))
            .UseDigestAlgorithm(HashAlgorithmName.SHA256)
            .UseUseDeprecatedAlgorithmParameter()
            .UseNonce(false)
            .UseHeaders()
            .Services;
        using (var serviceProvider = services.BuildServiceProvider())
        {
            using (var signerFactory = serviceProvider.GetRequiredService<IRequestSignerFactory>())
            {
                var requestSigner = signerFactory.CreateFor(keyId);
                //await requestSigner.Sign(request);
                requestSigner.Sign(request);
            }
        }
        request.Headers.Add("Signature", request.Headers.Authorization.ToString());
        request.Headers.Authorization = null;
    }

    static string GetXmlSOAP()
    {
        string xmlSOAP = "";

        xmlSOAP = @"<?xml version=""1.0"" encoding=""utf-8""?>
        <soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" 
                          xmlns:wsc=""http://edb.com/ws/WSCommon_v22"" 
                          xmlns:urn=""urn:srv.cus.corews.enterprise.fs.evry.com:ws:customer:v20_1"" 
                          xmlns:urn1=""urn:srv.cus.corews.enterprise.fs.evry.com:domain:customer:v20_1"" 
                          xmlns:urn2=""urn:corews.enterprise.fs.evry.com:domain:common:v8"">
        <soapenv:Header>
      <wsc:AutHeader>
         <wsc:SourceApplication>SECRET</wsc:SourceApplication>
         <wsc:DestinationApplication>SECRET</wsc:DestinationApplication>
         <wsc:Function>SECRET</wsc:Function>
         <wsc:Version>20_1</wsc:Version>
         <wsc:ClientContext>
            <wsc:userid>SECRET</wsc:userid>
            <wsc:credentials/>
            <wsc:channel>BRA</wsc:channel>
            <wsc:orgid>9057</wsc:orgid>
            <!--Optional:-->
            <wsc:orgunit>36000</wsc:orgunit>
            <!--Optional:-->
            <wsc:customerid>SECRET</wsc:customerid>
            <!--Optional:-->
            <wsc:locale>no_NO</wsc:locale>
            <wsc:ip>127.0.0.1</wsc:ip>
         </wsc:ClientContext>
      </wsc:AutHeader>
   </soapenv:Header>
    <soapenv:Body>
        <urn:customerReadRequest>
            <urn:readQualification>
                <urn1:internationalCustomerKey>
                    <urn2:internationalCustomerNumber>SECRET</urn2:internationalCustomerNumber>
                </urn1:internationalCustomerKey>
            </urn:readQualification>
        </urn:customerReadRequest>
    </soapenv:Body>
</soapenv:Envelope>";


        return xmlSOAP;
    }
}

I have also tried async method, that's why there's marked out lines with async methods, "endRequest().GetAwaiter().GetResult();", "await requestSigner.Sign(request)" etc.

Why can't I call the web service after I register the app as a Windows service, when I active this line?

var customerResponse = client.Send(customerRequest);

When I start it in Visual Studio (result being a cmd prompt with the execution details), the request and response are captured by Fiddler as you would expect. When registering it as a service and starting that, even the request isn't captured in Fiddler. After a while, the above exception is present in the Event Viewer.

0 Answers
Related