The HTTP protocol has not only evolved to become the dominant protocol used in navigating the web, but it has found operation in other applications such as machine to machine connectivity, IoT and other applications. This article will focus on explaining the basics of HTTP, demonstrating how to incorporate HTTP in a Raspberry Pi project and using the request/response pattern.
At the core of HTTP is request/response approach to support communication between a client and a server. In this pattern, a client makes a request consisting of a method and a resource among other elements and a server responds by returning a status code and content. In the HTTP protocol, a resource maps to a uniform resource locator (URL). A client will use a GET method to make requests to the server. The client uses the PUT method to move content to the server, while the DELETE method is used to remove content from the server. To submit data to a server, a client uses the POST method. To embed meta-information on the requests and responses made headers are used. The headers are human readable key-value pairs that can be used to pass meta-information such as encoding, validity and content type. Other ways in which headers are used are enabling authentication and states via cookies.
Because HTTP works in conjunction with the IP protocol there is no communication difficulty when addressing schemes are different. To enable communication between a client and a server, the transmission control protocol (TCP) is used. An IP address and a port number are some of the elements that define a connection end point. The default port is 80, but there is a flexibility of assigning other ports. To ensure the communication between a client and a server is secure, encryption options such as TLS and SSL can be implemented. After implementing encryption, the HTTP protocol is referred to as HTTPS and communication happens through port 443.
After a brief introduction to HTTP, we are ready to add HTTP support to our Raspberry Pi project we built earlier. When sharing data via HTTP there are three approaches that can be used and they are listed below.
* One approach is to let a sensor act as a client that sends information to a server over the internet which is referred to as publish/subscribe. This approach has the benefit of simplicity in handling events, but it has the shortcoming of lack of simplicity in handling momentary values.
* The second approach is letting any element in the network to become a client or a server. This approach has the benefit of minimizing communication latency but it has the shortcoming of requiring all elements be placed on one side of the firewall
* The third approach is letting a sensor act as a server and any devices that need to know the status of the sensor become clients. This approach has the benefit of simplicity in acquiring momentary values but it has the shortcoming of difficulty in sharing events. Another advantage of this approach is the simplicity in accessing devices protected by a firewall over the internet. This article will focus on demonstrating the use of this approach.
Just like in the previous articles, this article will rely on the Clayster libraries. The type of data that will be processed by the application we will develop include XML, RDF and HTML. To avail these processing capabilities, we need to import relevant namespaces at the beginning of using the code shown below.
using System.Xml; using System.Text; using System.IO; using System.Drawing;
The namespaces that will be used in handling HTTP and more data processing are imported as shown below.
using Clayster.Library.Internet; using Clayster.Library.Internet.HTTP; using Clayster.Library.Internet.HTML; using Clayster.Library.Internet.MIME; using Clayster.Library.Internet.JSON; using Clayster.Library.Internet.Semantic.Turtle; using Clayster.Library.Internet.Semantic.Rdf; using Clayster.Library.IoT; using Clayster.Library.IoT.SensorData; using Clayster.Library.Math;
At the beginning of our application, we need to alert the application there is no need to use proxy servers or lock the proxy settings. Although proxy servers have the benefit of improving security and monitoring the absence of a proxy server results in initialization delay because of unsuccessful search. The code used in application initialization is shown below:
HttpSocketClient.RegisterHttpProxyUse (false, false);
In your application code, before initialization is completed and the main loop is entered the following code needs to be included.
HttpServer HttpServer = new HttpServer (80, 10, true, true, 1); Log.Information ("HTTP Server receiving requests on port " + HttpServer.Port.ToString ());
The resources that are needed on the server are initialized using the code shown below:
HttpServer.Register ("/", HttpGetRoot, false); HttpServer.Register ("/html", HttpGetHtml, false); HttpServer.Register ("/historygraph", HttpGetHistoryGraph, false); HttpServer.Register ("/xml", HttpGetXml, false); HttpServer.Register ("/json", HttpGetJson, false); HttpServer.Register ("/turtle", HttpGetTurtle, false); HttpServer.Register ("/rdf", HttpGetRdf, false);
It is very important to remember to release resources held by the server to ensure correct application termination. This is done by including the code below when terminating the main application.
To encrypt communication between a client and a server, we need to enable HTTPS by loading a certificate in server memory and obtaining a password using the code below
X509Certificate2 Certificate = new X509Certificate2 ("Certificate.pfx", "PASSWORD");
We then create a HTTPS server in a similar way to creating HTTP server. The difference arises because we are using SSL/TLS as opposed to using client certificates. The code shown below is used:
HttpServer HttpsServer = new HttpServer (443, 10, true, true, 1, true, false, Certificate); Log.Information ("HTTPS Server receiving requests on port " + HttpsServer.Port.ToString ());
Registering server resources and disposing them is done using the code shown below.
foreach (IHttpServerResource Resource in HttpServer.GetResources()) HttpsServer.Register (Resource); HttpsServer.Dispose ();
In this article, we discussed the HTTP and HTTPS protocols and discussed communication approaches between a client and a server. We demonstrated how to import required namespaces, initializing an application, disposing and registering server resources.