Using HttpWebRequest to perform HTTPS post fails with strange error message

Posted on August 13th, 2008 in .NET, Vista, Windows Server 2008 by Tom

Recently, after upgrading a server to Server 2008, some developers (ok, about 15 developers and BAs) began complaining that a post to a 3rd party vendor was no longer functioning. One of the devs whipped up a winform app to test from the server and locally from his workstation. From his Windows XP workstation, it was fine. From the Server 2008 box (and from my Vista laptop) it failed to connect with:

The underlying connection was closed: An unexpected error occurred on a send.

Descriptive.

A full stack trace revealed:

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.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
— End of inner exception stack trace —
at System.Net.Sockets.NetworkStream.Read(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.FixedSizeReader.ReadPacket(Byte[] buffer, Int32 offset, Int32 count)
at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
at System.Threading.ExecutionContext.runTryCode(Object userData)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode code, CleanupCode backoutCode, Object userData)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Net.TlsStream.ProcessAuthentication(LazyAsyncResult result)
at System.Net.TlsStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.PooledStream.Write(Byte[] buffer, Int32 offset, Int32 size)
at System.Net.ConnectStream.WriteHeaders(Boolean async)
The underlying connection was closed: An unexpected error occurred on a send.
at System.Net.HttpWebRequest.GetRequestStream()

Keep in mind that this worked fine on XP and 2003. Vista and 2008 always threw that exception…without exception. The code was just doing a basic XML post to an HTTPS service with authentication enabled.


ASCIIEncoding ascii = new ASCIIEncoding();
string requestToSend = body;
byte[] data = ascii.GetBytes(requestToSend);
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(destination);

webRequest.Credentials = new NetworkCredential("User", "Pass");
webRequest.Method = "POST";
webRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.2";
webRequest.ContentType = "text/xml";
webRequest.ContentLength = data.Length;
webRequest.KeepAlive = false;                                              

//Throws an exception HERE
Stream outStream = webRequest.GetRequestStream();
outStream.Write(data, 0, data.Length);
outStream.Close();

From that stack trace, I could see that the remote server was closing the connection…but, I had no idea why. Something in how it made the request was different than XP or 2003.

ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;

As it turns out, the defult behavior in Vista and Server 2008 is to use TLS first for secure connections. If the server doesn’t support TLS, it’s supposed to negotiate with the client to use SSL3. In this case, the remote server wasn’t negotiating at all…It was just dropping the connection.

http://blogs.msdn.com/wndp/archive/2006/04/12/tls_enabled_by_default.aspx

Long story short:

If you upgrade to Server 2008 or Vista, and your HTTPS XML POSTs are failing due to some strange error, try to force SSL3.

www.chaoscollectibles.com and PowerShell system.net.webclient Script

Posted on January 12th, 2008 in PowerShell, Vista by Tom

I finally did it. I got the e-commerce bug and started my own shop. I’m working with Dave K on it, and we’re progressing quite well with a lot of mentoring from Bill and all of his XekoShop experience.

So, PhishThis will contain a lot of posts related to how I’m making like easier for myself as far as batch watermarking, getting images, etc.

Here’s one:

I need to scan all of my cards for Chaotic. But they have them all online and could save me some trouble. However, I don’t feel like right-click-saving 250 times. Enter, you guessed it, PowerShell.

I need to create a web client to connect to the site.
$wc = new-object system.net.webclient
Now, the site requires a login. You might say “CRAP!” However, the webclient supports passing credentials, as long as they’re typed as system.net.networkcredential

So, I can login to the site, from PowerShell with:
$wc.credentials = new-object system.net.networkcredential("username", "password")

Now, there were around 250 images, so I construct a simple for loop that uses $wc.downloadfile(”source”, “location”) and we end up with:

$wc = new-object system.net.webclient
$wc.credentials = new-object system.net.networkcredential("username", "password")
for ($i = 0; $i -lt 250;$i++)
{
  $wc.downloadfile("www.foobar.com/getimages.aspx?ImageID=$($i)", "C:\images\$($i).jpg")
}

This script saved me HOURS of scanning and stuff…and now, even if the card is out of stock, I still have the image. That makes sense in my head.  

After, I set my view for that folder to EXTRA LARGE icons. This shows a readable preview of the jpeg. I renamed the first one, and instead of hitting enter after each one, I hit tab, and it went to the next file to rename it. I didn’t know you could do that, and tried on a whim. Saved me many keystrokes.

Next, I’m going to need to add them all to Zen Cart. Since I’m lazy a script kiddy, I’m going to write a script that will look at all of the product images in a folder, and write my SQL queries based on them. Hopefully I’ll even get it to do all of my formatting, too. We’ll see. Look for that this weekend sometime.

Windows Media Player 11 Won’t Minimize to Taskbar

Posted on November 28th, 2007 in Vista by Tom

This has nothing to do with PowerShell :p

That said, I was sitting here working on ye olde blog when I thought “I want to listen to some Foo Fighters”…then I minimized WMP and it just…minimized. I wanted mini mode, where I get all of the controls on the taskbar…it works on my laptop, why not my desktop?

I don’t know why this took me so long to find. Wait, yes I do. I was looking all over WMP 11 for the setting. Turns out it isn’t there. To get WMP 11 to minimize to the taskbar (aka, mini-mode), right click your taskbar, go to toolbars, and make sure Windows Media Player is checked. Maybe I turned that off on my own a while ago and forgot it was there. I can’t remember the default behavior.

What makes this all more amusing is that I have a Logitech G15 keyboard, which has all of the controls right on top…