Saturday, February 28, 2009

Unable to connect to the remote server

I was programming a payment gateway for NAB. I construct the xml in vb.net and then send the web request of xml contenttype to the NAB payment gateway URL using the WebRequest class:

Imports System.Reflection

Imports System.Web

Imports System.Net

Imports System.IO

Imports System.Text


Public Class clsNABTransact


Private mstrErrorMessage As String = ""


Public Property strErrorMessage() As String


Get


strErrorMessage = mstrErrorMessage


End Get


Set(ByVal Value As String)


mstrErrorMessage = Value


End Set


End Property


Public Function ReadHtmlPagePost(ByVal sURL As String, ByVal sPostData As String) As String


Dim objResponse As WebResponse


Dim objRequest As WebRequest


Dim result As String


Dim myWriter As StreamWriter


Try


objRequest = WebRequest.Create(sURL)


objRequest.Method = "POST"


objRequest.ContentLength = sPostData.Length()


objRequest.ContentType = "text/xml"


Try


myWriter = New StreamWriter(objRequest.GetRequestStream())


myWriter.Write(sPostData)


myWriter.Close()


objResponse = objRequest.GetResponse()


Dim sr As New StreamReader(objResponse.GetResponseStream())


result += sr.ReadToEnd()


'clean up StreamReader


sr.Close()


Return result


Catch Ex As Exception


strErrorMessage = Ex.ToString


Return ""


End Try


Catch E As Exception


strErrorMessage = E.ToString


Return ""


End Try


End Function


End Class


When I tested on my local, I can get the response XML from NAB with no problems. But when the client test it on their end, they get the following error:

Credit card payment unsuccessful Problem in Payment Gateway Error:System.Net.WebException: Unable to connect to the remote server ---> System.Net.Sockets.SocketException: No connection could be made because the target machine actively refused it XXX.XX.XXX.XXX:XXX at System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress) at System.Net.Sockets.Socket.InternalConnect(EndPoint remoteEP) at System.Net.ServicePoint.ConnectSocketInternal(Boolean connectFailure, Socket s4, Socket s6, Socket& socket, IPAddress& address, ConnectSocketState state, IAsyncResult asyncResult, Int32 timeout, Exception& exception) — End of inner exception stack trace — at System.Net.HttpWebRequest.GetRequestStream() at clsNABTransact.ReadHtmlPagePost(String sURL, String sPostData)()

Reason:

  • Cannot connet to the Remote Server (NAB), because the proxy server is blocking the your access to the NAB server.
  • The ISA server (proxy server) on the client side is set such that you need to be a member of a windows security group to browse the internet.

What I tried:

1. Firstly, I add the following in the web.config:

<system.net>


<defaultProxy useDefaultCredentials="true" >


<proxy usesystemdefault="True" proxyaddress="http://proxy.test.com.au:8080" bypassonlocal="True"/>


</defaultProxy>


</system.net>


2. Then I got a different error says:

Credit card payment unsuccessful Problem in Payment Gateway Error:System.Net.WebException: The remote server returned an error: (407) Proxy Authentication Required. at System.Net.HttpWebRequest.GetRequestStream() at CMDotNet.Common.clsNABTransact.ReadHtmlPagePost(String sURL, String sPostData)()

3. Then what I did was: on the proxy server, there’s some site that all users are able to access regardless of whether you are a member of a windows security group or not, I added the Nab URl to this allow access list.

4. Then everything is working.

5. But I think what the real reason is that:

  • Firstly, it says it cannot connect to the NAB server is because
    • The Network Service account is a special built in account that is local and unique to each machine. That means the Network Service account on Server A is different from the Network Service on Server B. If it is the Network Service account that running your application pool identity in IIS, it is a low access account which does not have access to the machine proxy configuration settings which are stored in the registry under HKLM keys. So you can’t get the proxy settings.
  • When I added the proxy info in the web.config, the web.config tells the application where to find the proxy, then it will try to connect to the NAB URL throught the proxy server, but since Network Service is a local account, it may not have the access to the NAB URL, so you got the Proxy Authentication Required.
  • Then I added the URL to the access list which means everyone can access the URL. Here are the better solutions which does not require you to change the web.config:
    • You can try to change the application pool identity to a domain account whose password never expires.
    • Alternatively, when you are using WebRequest, you can set WebRequest.UseDefaultCredentials or WebRequest.Credentials in the code or web.config.

Terms:

  • bypassonlocal : if you do not want the proxy server computer to be used when you connect to a computer on the local network (this may speed up performance).
  • usesystemdefault : if true, then it will pick up the default proxy you set in the IE. If false, then it will pick up the proxy in the control panel. My company is using a transparent proxy setting which means that you do not get to see what proxy you are using in the IE, the proxy is set in a way that it is both the default proxy and a transparent proxy.



If you are expericing slow connection, but finally you can connect to the internet, then you can disables automatic Proxy detection. According to Rick, the reasons it happened is because
  • In .NET 1.1 no proxy is set, it would try to connect directly.
  • .NET 2.0 uses the machine’s default proxy configuration by default. The default proxy configuration is the configuration you see in the IE proxy configuration settings.
  • NETWORK SERVICE is a low access account which does not have access to the machine proxy configuration settings which are stored in the registry under HKLM keys. So you can’t get the proxy settings.

There are two ways you can solve this:

  • Set usesystemdefault="false" in the web.config
  • In the code to explicitly set the Proxy property of the Http object (WebRequest, XmlDom, Web Service Client etc.) to null

proxy server

  • A server that sits between a client application, such as a Web browser, and a real server. It intercepts all requests to the real server to see if it can fulfill the requests itself. If not, it forwards the request to the real server.
  • Proxy servers have two main purposes:
    • Improve Performance
    • Filter Requests

References:

Sending HttpWebRequest via firewall & over SSL

Unable to connect to the remote server

Slow Http client calls from ASP.NET 2.0? Make sure you check your Proxy Settings!

proxy server

Is it possible to specify proxy credentials in your web.config?
(407) proxy authentication required : Use HttpWebRequest with Proxy

blog comments powered by Disqus