I never stop and even now that I'm on vacation I still .... develop!

This time it's up to my uPLibrary I upgraded to version 2.0 (of course also on Nuget with support for three versions of the. NET Micro Framework 4.1 from 4.1 to the current 4.3) with a new component: an HTTP client.

All you're probably asking questions about why the need to rewrite an HTTP client whereas there are already thoroughly tested the HttpWebRequest and HttpWebResponse directly included. Net Micro Framework. The reason is that in some boards with low memory (see Netduino), the assemblies for these two classes are too large and working with streams they are under-performing. For this reason, I decided to create a simple client (any advice for its improvement is welcome) that uses directly the socket without any intermediate layer of abstraction (a concept that many times in embedded systems must be limited to improve performance).

The programming model is quite simple, as it involves the use of the HttpClient class that provides the following three main methods:

  • Send () : to perform a generic HTTP request (GET, POST, PUT, ...);
  • Get () : ad hoc method to perform GET requests;
  • Post () : ad hoc method to perform a POST requests;

The Send () method receives as input an object of type HttpRequest must be specified in which all the data that make up the request (HTTP method, target URI and any headers). It returns an object of type HttpResponse with all the information on the response received from the server. To be able to manage the reception of a body (in the case of GET) or sending (in the case of POST or PUT), you can use the following two events that the class exposes:

  • RecvBody : raised when there is data in the receiving body and can be acquired;
  • SendBody : raised by the client only when there is an event handler registered, which enshrines the will to transfer data to the client through the body;

In the case of reception, the event handler receives as input the HttpResponse object through which to access the Body property on which to invoke the Read() method, which reads the data directly from the socket by returning a buffer specified by us. The event is raised several times until the completion of the body.

When sending, the event handler receives as input the HttpRequest object through which you can always access the Body property on which to invoke the Write() method which can pass a buffer with the data to be written on the underlying socket. This event is raised once from the client, it is necessary to perform inside any more calls on Body.Write() up to the complete transmission of the desired body.

Below is a very simple example to get the page of the Microsoft website.

 

   1: public static void Main()
   2: {
   3:     HttpRequest req = new HttpRequest();
   4:     req.Method = HttpMethod.Get;
   5:     req.Uri = new Uri("http://www.microsoft.com");
   6:     req.Headers.Add("Accept", "text/html");
   7:  
   8:     HttpClient client = new HttpClient();
   9:     client.RecvBody += client_RecvBody;
  10:     client.Send(req);
  11: }
  12:  
  13: static void client_RecvBody(HttpResponse httpResp)
  14: {
  15:     byte buffer = new byte[1024];
  16:     int read = httpResp.Body.Read(buffer, 0, 1024);
  17:     Debug.Print(new String(Encoding.UTF8.GetChars(buffer)));
  18: }

The methods Get() and Post() are trivially two wrapper on Send() method which only serve to simplify the most commonly performed, just GET and POST. Both receive the URI to which to perform the request (without the need to "fill and go" an HttpRequest object, they will do them for us) and the event handler to perform the reception of the body (in case of GET) or the sending (in the case of POST).
Continuing the above example, through the method Get() would have the following code.

   1: public static void Main()
   2: {
   3:     HttpClient client = new HttpClient();
   4:     client.Get("http://www.microsoft.com", client_RecvBody);
   5: }

In the case of connection to a REST service to which having to transmit data, we can think of a use of this type.

   1: public static void Main()
   2: {
   3:     HttpClient client = new HttpClient();
   4:     client.Post("http://myserver/api/", client_SendBody);
   5: }
   6:  
   7: static void client_SendBody(HttpRequest httpReq)
   8: {
   9:     byte buffer = Encoding.UTF8.GetBytes("<body request>");
  10:     httpReq.ContentLength = buffer.Length;
  11:     httpReq.Body.Write(buffer, 0, httpReq.ContentLength);
  12: }