Let’s make a Web Server in LabVIEW from scratch

HTTP Server Example Code

The computing world is getting more and more connected every day.  With this in mind, it is important to understand the technologies used to create these connections.  Although there have been many different technologies that have played a role in the internet revolution, by far the most prevalent one is HTTP.  HTTP is the backbone of the web and is the primary protocol used to transfer information over the internet.  In this article, I’ll walk you through the absolute bare minimum LabVIEW code needed to receive and respond to an HTTP request.

Ok, disclaimer time. This is a blog post, and the code provided here is meant for demonstration and discussion purposes only. This code is by no means compliant with the six HTTP 1.1 specifications (RFC7230 – RFC7235) which total over 200 pages. This code is meant to be educational and to help you to understand how HTTP works, not to be used for real applications. If you use this as a production server, you will have a bad time. Seriously, don’t do it.

Now that that’s out of the way, let’s talk a bit about what a web server actually does.  In general, a web server listens for TCP connections, and when it finds one it reads the message, parses it, sends back the appropriate response, and finally, closes the connection.  That sounds simple enough, but how does the server know what kind of messages it will be receiving?  The client and server must agree on the formatting of the messages in order for them to be speaking the same language.  This is where HTTP comes in.  The HTTP specification describes the semantics of this language in incredible detail.  In this example, however, we will see that with a very small amount of code, you can implement a subset of the specification that is enough for our server to be able to communicate with a web browser.

So, what does an HTTP request look like?  In other words, when Google Chrome requests a web page, what is it actually sending on the TCP connection?  Let’s look at an example:

POST /uri/to/content HTTP/1.1
Content-Type: application/json
Content-Length: 32
  "json key": "json value"

Let’s take this line by line.  The first line consists of three parts, the HTTP verb, the URI, and the HTTP specification.  In this example, the HTTP verb is “POST” which tells the server that this request will be sending information which is found in the body of the request.  The URI, “/uri/to/content” tells the server what the content being sent actually is.  Finally, the HTTP specification “HTTP/1.1” tells the server that this browser is using version 1.1 of the HTTP protocol specification.

The next two lines are called the headers.  Headers contain meta-data about the request that might be useful for the server.  They are always organized in key value pairs.  The headers in this example tell the server to expect a json encoded message with a length of 32 characters.  The server will use the “Content-Length” value to determine when the body of the message is complete.

The next line is blank.  This tells the server that the headers are complete and the body of the message is coming next.  The rest of the request is the body itself.  The server will read this information and act upon it based on the specified URI.

Now that we’ve seen what a typical message looks like, we know what our server has to do.  It has to listen for TCP connections, read and parse the headers until it finds the blank line indicating the headers are complete, read the number of characters in the content length to get the message body, and finally respond back to the client.  Here’s what that looks like in LabVIEW:

First, we listen for localhost connections over port 50000.  Real servers listen on port 80, but since this is just an example, it’s probable better to use a port that’s likely not being used for anything else.  Once a connection is established, we read the message line by line and build the header string on a shift register.  We also look for the Content-Length header and store the length on a shift register.  When the blank line is read, we stop the loop and start reading the body.  To read the body we simply read the number of bytes specified in the Content-Length (one character = one byte).  Finally we respond back to the client with “HTTP/1.1 200 OK”, which tells the server that everything went according to plan, and we close the connection.

To test it out, run the VI and send out an HTTP request over localhost on port 50000.  There are many tools available to make doing this easy.  If you are using Chrome, I like using the Postman extension for this, but other tools (such as curl) would work too.  Here’s what I sent out in Postman and what I received in LabVIEW:

There you have it, a (technically) functional web server in a single VI with 35 nodes.  While this implementation is absurdly simplistic and no where nearly comprehensive enough to be used as an actual production server, hopefully it helped to demystify how the web works a bit.  If you found this information valuable (or not) feel free to leave a comment.  I’m always interested in your feedback!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s