I tried to port the HttpClient sample from the NETMF 4.2 SDK to the spider Mainboard but have problems using https.
This is my code. When the button is pressed the page from the GHI Community Dashboard shall be loaded.
using System;
using System.Collections;
using System.Threading;
using System.Security.Cryptography;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation;
using Microsoft.SPOT.Presentation.Controls;
using Microsoft.SPOT.Presentation.Media;
using Microsoft.SPOT.Presentation.Shapes;
using Microsoft.SPOT.Touch;
using Gadgeteer.Networking;
using GT = Gadgeteer;
using GTM = Gadgeteer.Modules; //System.Http, need to also add System.dll to references
using Microsoft.SPOT.Time;
using System.Net;
using Gadgeteer.Modules.GHIElectronics;
using System.Security.Cryptography.X509Certificates;
namespace HttpClient_https_Test
{
public partial class Program
{
byte[] ca = Resources.GetBytes(Resources.BinaryResources.DigiCert);
X509Certificate[] caCerts;
private static IPAddress localIpAddress = null;
private Microsoft.SPOT.Net.NetworkInformation.NetworkInterface settings;
private TimeServiceSettings timeSettings;
private bool timeServiceIsRunnig = false;
private int timeZoneOffset = 0;
void ProgramStarted()
{
Debug.Print("Program Started");
caCerts = new X509Certificate[] { new X509Certificate(ca) };
button.ButtonPressed += button_ButtonPressed;
ethernetJ11D.UseThisNetworkInterface();
ethernetJ11D.NetworkSettings.EnableDhcp();
ethernetJ11D.NetworkSettings.EnableDynamicDns();
ethernetJ11D.NetworkUp += ethernetJ11D_NetworkUp;
ethernetJ11D.NetworkDown += ethernetJ11D_NetworkDown;
timeSettings = new Microsoft.SPOT.Time.TimeServiceSettings()
{
ForceSyncAtWakeUp = true
};
}
void button_ButtonPressed(Button sender, Button.ButtonState state)
{
MyHttpClient.PrintHttpData("https://www.ghielectronics.com/community/dashboard", caCerts);
}
#region initializeNetwork()
void initializeNetwork()
{
try
{
ethernetJ11D.NetworkInterface.Open();
ethernetJ11D.NetworkSettings.EnableDhcp();
ethernetJ11D.NetworkSettings.EnableDynamicDns();
ethernetJ11D.UseStaticIP("192.168.1.222", "255.255.254.0", "192.168.1.1");
ethernetJ11D.UseDHCP();
Thread.Sleep(2000);
while (ethernetJ11D.NetworkSettings.IPAddress == "192.168.1.222")
{
Debug.Print("Waiting for DHCP");
Thread.Sleep(250);
}
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
}
#endregion
#region ListNetworkInterfaces()
void ListNetworkInterfaces()
{
var settings = ethernetJ11D.NetworkSettings;
Debug.Print("------------------------------------------------");
Debug.Print("MAC: " + ByteExtensions.ToHexString(settings.PhysicalAddress));
Debug.Print("IP Address: " + settings.IPAddress);
Debug.Print("DHCP Enabled: " + settings.IsDhcpEnabled);
Debug.Print("Subnet Mask: " + settings.SubnetMask);
Debug.Print("Gateway: " + settings.GatewayAddress);
Debug.Print("------------------------------------------------");
}
#endregion
#region SetTime()
void SetTime()
{
timeSettings = new Microsoft.SPOT.Time.TimeServiceSettings()
{
ForceSyncAtWakeUp = true
};
IPAddress[] address = System.Net.Dns.GetHostEntry("time1.google.com").AddressList;
try
{
timeSettings.PrimaryServer = address[0].GetAddressBytes();
}
catch (Exception ex)
{
Debug.Print(ex.Message);
}
TimeService.Settings = timeSettings;
TimeService.SetTimeZoneOffset(timeZoneOffset);
TimeService.Start();
timeServiceIsRunnig = true;
}
#endregion
#region ethernetJ11D_NetworkUp and ethernetJ11D_NetworkDown Events
void ethernetJ11D_NetworkUp(Gadgeteer.Modules.Module.NetworkModule sender, Gadgeteer.Modules.Module.NetworkModule.NetworkState state)
{
Debug.Print("Network up");
while (ethernetJ11D.NetworkSettings.IPAddress == "0.0.0.0")
{
Thread.Sleep(300);
}
localIpAddress = IPAddress.Parse(ethernetJ11D.NetworkSettings.IPAddress);
Debug.Print("Got IP-Address by DHCP: " + localIpAddress.ToString());
if (!timeServiceIsRunnig)
{
SetTime();
}
settings = ethernetJ11D.NetworkSettings;
ListNetworkInterfaces();
//SetTime();
Thread.Sleep(20);
Debug.Print("Time is: " + DateTime.Now);
}
void ethernetJ11D_NetworkDown(Gadgeteer.Modules.Module.NetworkModule sender, Gadgeteer.Modules.Module.NetworkModule.NetworkState state)
{
Debug.Print("Network down");
}
#endregion
}
}
This is the HttpClient Class
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Net.Security;
using System.Security.Cryptography.X509Certificates;
/// This program demonstrates how to use the .NET Micro Framework HTTP classes
/// to create a simple HTTP client that retrieves pages from several different
/// websites, including secure sites.
namespace HttpClient_https_Test
{
public static class MyHttpClient
{
public static void PrintHttpData(string url, X509Certificate[] caCerts)
{
HttpWebRequest request =
HttpWebRequest.Create(url) as HttpWebRequest;
// Initialize the default webproxy to be used by all
// HttpWebRequests.
// Change the proxy address to fit your environment.
try
{
// Check networking - we need to make sure we can reach our proxy server
//System.Net.Dns.GetHostEntry("itgproxy.dns.microsoft.com"); //this does not work
System.Net.Dns.GetHostEntry("4.2.2.2");
}
catch (Exception ex)
{
Debug.Print("Exception " + ex.Message);
}
HttpWebRequest.DefaultWebProxy = new WebProxy("4.2.2.2", true);
// Assign the certificates. The value must not be null if the connection is HTTPS.
request.HttpsAuthentCerts = caCerts;
// Set request.KeepAlive to use a persistent connection.
request.KeepAlive = true;
// Get a response from the server.
WebResponse resp = null;
try
{
resp = request.GetResponse();
}
catch (Exception e)
{
Debug.Print("Exception in HttpWebRequest.GetResponse(): " +
e.ToString());
}
// Get the network response stream to read the page data.
if (resp != null)
{
Stream respStream = resp.GetResponseStream();
string page = null;
byte[] byteData = new byte[4096];
char[] charData = new char[4096];
int bytesRead = 0;
Decoder UTF8decoder = System.Text.Encoding.UTF8.GetDecoder();
int totalBytes = 0;
// allow 5 seconds for reading the stream
respStream.ReadTimeout = 5000;
// If we know the content length, read exactly that amount of
// data; otherwise, read until there is nothing left to read.
if (resp.ContentLength != -1)
{
for (int dataRem = (int)resp.ContentLength; dataRem > 0; )
{
Thread.Sleep(500);
bytesRead =
respStream.Read(byteData, 0, byteData.Length);
if (bytesRead == 0)
{
Debug.Print("Error: Received " +
(resp.ContentLength - dataRem) + " Out of " +
resp.ContentLength);
break;
}
dataRem -= bytesRead;
// Convert from bytes to chars, and add to the page
int byteUsed, charUsed;
bool completed = false;
totalBytes += bytesRead;
UTF8decoder.Convert(byteData, 0, bytesRead, charData, 0,
bytesRead, true, out byteUsed, out charUsed,
out completed);
page = page + new String(charData, 0, charUsed);
// Display the page download status.
Debug.Print("Bytes Read Now: " + bytesRead +
" Total: " + totalBytes);
}
page = new String(
System.Text.Encoding.UTF8.GetChars(byteData));
}
else
{
// Read until the end of the data is reached.
while (true)
{
// If the Read method times out, it throws an exception,
// which is expected for Keep-Alive streams because the
// connection isn't terminated.
try
{
Thread.Sleep(500);
bytesRead =
respStream.Read(byteData, 0, byteData.Length);
}
catch (Exception)
{
bytesRead = 0;
}
// Zero bytes indicates the connection has been closed
// by the server.
if (bytesRead == 0)
{
break;
}
int byteUsed, charUsed;
bool completed = false;
totalBytes += bytesRead;
UTF8decoder.Convert(byteData, 0, bytesRead, charData, 0,
bytesRead, true, out byteUsed, out charUsed,
out completed);
page = page + new String(charData, 0, charUsed);
// Display page download status.
Debug.Print("Bytes Read Now: " + bytesRead +
" Total: " + totalBytes);
}
Debug.Print("Total bytes downloaded in message body : "
+ totalBytes);
}
// Display the page results.
Debug.Print(page);
// Close the response stream. For Keep-Alive streams, the
// stream will remain open and will be pushed into the unused
// stream list.
resp.Close();
}
}
}
}
The exception is shown in the picture.
The exception is thrown in HttpClient Class in the line: resp = request.GetResponse();
What am I doing wrong?