Hot File

Embedding a Webserver in your C++ Application

View: 2836    Dowload: 0   Comment: 0   Post by: hanhga  
Author: none   Category: Embedded Systems   Fields: Computers - Technology

10 point/3 review File has been tested

This article will explain how to integrate an embedded webserver with your Win32/C++ application, using the Lacewing networking library. It could be used for things like: Web administration - Server applications often have a web interface, for remote administration - nothing but a web browser is required to administrate the server Web applications - Web applications written in C++ can be much faster and more scalable than PHP or ASP, with lower resource usage and nothing else to be installed

Introduction

Background

I decided to write my own webserver class as an experiment over the Lacewing::Server class, which is designed for scalability using IO completion ports, epoll or kqueue.

Lacewing::Webserver soon became a powerful HTTP server, featuring things like:

  • HTTP GET/POST with automatic parameter parsing
  • Non-blocking file sending
  • Cookies and sessions
  • Multipart file upload
  • Getting/setting the last modified date, to easily implement caching
  • Full HTTPS support

Installing the Library

Lacewing runs on both Windows and many flavours of *nix (including Linux, BSD, Mac OS X and even Android). This article, however, was originally written for the Windows version - the code for other platforms is identical, but the installation procedure will be different.

For Windows, the first thing is you'll need to download and install the Lacewing Win32 binaries from the liblacewing website. The Lacewing.dll file will need to be distributed alongside your executable file, but you may put it in your Windows\System32 folder (or Windows\SysWOW64 on a 64 bit system) for development convenience if you want.

Put the path to the folder with Lacewing.h and Lacewing.lib in your VC++ directories, in both the header and library sections. This will be under Tools > Options > Projects and Solutions > VC++ directories in Visual C++ 2008. Once the path is added, you should be able to #include <Lacewing.h> in your code, which will automatically link with Lacewing.lib.

Using the Class

For any class in Lacewing to function, you'll first need an instance of Lacewing::EventPump, which is responsible for watching for events and "pumping" them to the interested classes.

You can then create an instance of Lacewing::Webserver, passing the event pump to the constructor.

Lacewing::EventPump EventPump;
Lacewing::Webserver Webserver (EventPump);  

This is already ready to host, and would show a blank page. To make it show something interesting, you'll need to register some handlers. We're only interested in responding to GET for now, but there are more handlers available for things like HEAD, POST, error handling and multipart file upload - see the Lacewing::Webserver class definition in Lacewing.h for the full list.

An example GET handler looks like this:

void onGet (Lacewing::Webserver &Webserver, Lacewing::Webserver::Request &Request)
{
	Request << "Welcome to " << Request.URL ();
} 

This will output the text "Welcome to " followed by the requested URL. To register it with Lacewing so that it will be called when a GET request comes through, simply pass it to the onGet method of your Webserver instance.

When all the initialisation is complete, Host() can be called to start the webserver. If no parameters are passed, it defaults to port 80. You might want to use Host(81) or something similar if port 80 is taken on your system.

Webserver.onGet (onGet);
Webserver.Host (); 

And that's it - providing the Webserver object stays in scope, you should be able to open a web browser and visit http://localhost/home to be greeted with:

Welcome to home

If you ran the webserver on a port other than 80, you'll need to visit something like http://localhost:82/home.

Working with Files

The Request object passed to the GET handler provides two functions to make it simple to send files from the disk:

  • SendFile - Sends a file by filename. The file will not be loaded into memory (TransmitFile is used on Windows, sendfile on *nix)
  • GuessMimeType - Sets an appropriate MIME type for a file extension or filename. For example, a htm file will set the MIME type text/html, while a png file will set the MIME type image/png.

We can easily use these to build a simple webserver, hosting the current directory.

void onGet(Lacewing::Webserver &Webserver, Lacewing::Webserver::Request &Request)
{
	Request.GuessMimeType(Request.URL());
	Request.SendFile(Request.URL());
}  

Note that nothing is actually sent until after the handler is complete, so it wouldn't matter if the GuessMimeType and SendFile functions were called the other way around. All the functions in Lacewing return instantly, and you can do things like set cookies and change HTTP headers right until the handler returns.

With this new GET handler calling the two functions, it's now possible to put an entire website with HTML/CSS/JS in the same folder as the webserver and access it from a web browser. This can be combined with custom behaviour in C++ to do things like C++ based AJAX applications (which is a pretty awesome idea). For now, I just tried it with an image:

Lacewing logo transmitted over HTTP

Setting Up HTTPS

It might surprise you that Lacewing (on Windows) doesn't use OpenSSL or any other library to implement HTTPS. Like the rest of the library, it's built on the APIs provided by the operating system - Windows provides functions for secure sockets, as used by Internet Explorer and IIS. The API isn't very pleasant to use (start here if you're interested), but Lacewing wraps it nicely in Lacewing::Webserver into these functions:

  • HostSecure - Like the Host function, but for HTTPS rather than HTTP. After this has been called, the handlers will be called as normal for HTTPS requests, but Request.Secure() will return true. Either LoadCertificateFile or LoadSystemCertificate must be called before this.
  • LoadCertificateFile - Loads a certificate from a certificate file (CER or PFX). Takes two parameters - the first is the filename of the certificate file, and the second is the common name used when creating the certificate. *nix OR Windows Vista and greater only.
  • LoadSystemCertificate - Loads a certificate that has been imported into the system, (import it by opening the certificate file and following the wizard). Takes three parameters - the first is the store name (the predefined system stores are "MY", "Root", "Trust" and "CA"), the second is the common name used when creating the certificate, and the third (optionally) is which certificate store to look in, the default being "CurrentUser". More information about the system certificate stores can be found here. Windows XP and greater only.

You will need to obtain a certificate from a signing authority, or generate a self-signed certificate for testing. Doing this is beyond the scope of this article, but there's a nice tutorial on generating self-signed certificates with OpenSSL here.

My test certificate with the common name "localhost" has already been imported, so now I can change my initialization code to this:

Webserver.onGet(onGet);
Webserver.Host();

Webserver.LoadSystemCertificate("MY", "localhost");
Webserver.HostSecure();  

And now if I visit https://localhost/lacewing_02.png...

Lacewing logo transmitted over HTTPS

Forms

Lacewing::Webserver has full support for two kinds of request parameters:

  • GET parameters are added as part of the URL. If you were to load http://localhost/home?foo=bar, you could then use Request.GET("foo") in the GET handler, which would return "bar". Multiple parameters can be used in the form http://localhost/home?foo=bar&foo2=bar2. These can be added manually by the user, via links, or via HTML forms with method="GET".
  • POST parameters are the body of the HTTP request, rather than part of the URL. They are added by HTML forms with method="POST", and can be retrieved in the POST handler with Request.POST("name").

GET parameters are limited by the URL length, and GET requests can be subject to browser caching. The general rule for deciding whether to use GET or POST is that GET is for specifying parameters for reading data, and POST is for specifying parameters for writing data.

Both GET and POST parameters can be used from JavaScript. I highly recommend jQuery, which I have used extensively for web applications with Lacewing::Webserver as a backend. The stream << operator in the Request object makes it very easy to generate JSON, which translates directly into Javascript objects.

I won't be covering anything like that in this article, but there is an example available in the library examples folder on GitHub. For a simple HTML form test to try out the POST functionality, you will first need a POST handler in addition to the GET handler:

void onGet(Lacewing::Webserver &Webserver, Lacewing::Webserver::Request &Request)
{
	if(!strcmp(Request.URL(), "form"))
	{
		Request.SendFile("form.html");
		return;
	}
	
	Request << "Page not found";
}

void onPost(Lacewing::Webserver &Webserver, Lacewing::Webserver::Request &Request)
{
	if(!strcmp(Request.URL(), "submit"))
	{
		Request << "Hello, " << Request.POST("name") << "!";
		return;
	}
	
	Request << "Page not found";
}

The POST handler can be registered alongside the GET handler.

Webserver.onGet (onGet);
Webserver.onPost (onPost); 

You'll also need this form.html file:

<form action="submit" method="post">

	Enter your name: <input name="name">
	<input type="submit" value="Go!">
</form>

And that's it! If you run the application, you should be able to visit http://localhost/form:

Lacewing logo transmitted over HTTPS

And submit...

Lacewing logo transmitted over HTTPS

Conclusion

Although I didn't cover every aspect of Lacewing::Webserver, I hope the article was a useful introduction. The rest of the functions are quite straightforward and consistently named, so it should be pretty easy to find your way around.

If you have any questions or suggestions, please do leave a comment or send me an email. The library is also now open source on GitHub with an issue tracker.

Embedding a Webserver in your C++ Application

Embedding a Webserver in your C++ Application Posted on 08-04-2014  This article will explain how to integrate an embedded webserver with your Win32/C++ application, using the Lacewing networking library. It could be used for things like: Web administration - Server applications often have a web interface, for remote administration - nothing but a web browser is required to administrate the server Web applications - Web applications written in C++ can be much faster and more scalable than PHP or ASP, with lower resource usage and nothing else to be installed 3.3333333333333/10 2836

Comment:

To comment you must be logged in members.

Files with category

  • OpenTheme : An open source graphic user interface (GUI) toolkit

    View: 4089    Download: 2   Comment: 0   Author: none  

    OpenTheme : An open source graphic user interface (GUI) toolkit

    Category: Embedded Systems
    Fields: Other

    0.29591836734694/49 review
    OpenTheme is an XML based GUI toolkit with a set of foundation class and WYSIWYG editor. Although it's originally designed for full screen GUI, it is also good for Windowed user interface, with full localization support and arbitary...

  • Design State Machine Engine for embedded system development

    View: 3293    Download: 2   Comment: 0   Author: none  

    Design State Machine Engine for embedded system development

    Category: Embedded Systems
    Fields: none

    0/4 review
    Embedded systems are some special purpose computers that are used inside of devices. Embedded systems generally use micro controllers that contain many functions of a computer on a single device. Embedded systems have to tightly work together with...

  • The StateWizard VC++ Add-in and Engine with Source Code

    View: 3776    Download: 0   Comment: 0   Author: none  

    The StateWizard VC++ Add-in and Engine with Source Code

    Category: Embedded Systems
    Fields: none

    0/7 review
    In an environment where software systems are more and more complex, concurrent, and real-time oriented, the choice of modeling languages and tools becomes the success key for many projects. This article introduces a cross-platform state-oriented...

  • Template merging with NVelocity and ASP.NET

    View: 2821    Download: 0   Comment: 0   Author: none  

    Template merging with NVelocity and ASP.NET

    Category: Embedded Systems
    Fields: Other

    0/5 review
    If you have ever tried to implement a newsletter system or a service for communicating with website users, you have probably faced the requisite to send multiple email messages with a common template and some differences, like a personalized greeting...

  • Use PowerShell to Manage your Intel AMT Data

    View: 1830    Download: 0   Comment: 0   Author: none  

    Use PowerShell to Manage your Intel AMT Data

    Category: Embedded Systems
    Fields: Other

    0.45/10 review
    This article is in the Product Showcase section for our sponsors at CodeProject. These reviews are intended to provide you with information on products and services that we consider useful and of value to developers.

  • A C++ Embedded Web Server

    View: 3004    Download: 1   Comment: 0   Author: none  

    A C++ Embedded Web Server

    Category: Embedded Systems
    Fields: Other

    0.75/6 review
    Do you have a web page or two? Nothing fancy, perhaps, but a neat demonstration of what can be achieved with a handful of HTML tags? Do you have a sophisticated C++ Windows desktop application which now needs to be controlled and monitored remotely?...

  • Java/.NET Integration as Simple as Possible

    View: 1434    Download: 2   Comment: 0   Author: none  

    Java/.NET Integration as Simple as Possible

    Category: Embedded Systems
    Fields: Other

    0/3 review
    For a number of years, I have been developing software for integrating applications written in different platforms. And in my business, I face with interoperability issues: Java and C++, Java and COM, Java and .NET. To solve them, I have developed a...

  • Writing a 16-bit dummy kernel in C/C++

    View: 2594    Download: 3   Comment: 0   Author: none  

    Writing a 16-bit dummy kernel in C/C++

    Category: Embedded Systems
    Fields: Other

    0/11 review
    In my previous articles I was only briefing about on how to write a boot loader. That was fun and challenging. I enjoyed it a lot. But after learning how to write a boot-loader I wanted to write much better stuff like embedding more functionality...

 
Newsletter Email

File suggestion for you

File top downloads

logo codetitle
Codetitle.com - library source code to share, download the file to the community
Copyright © 2015. All rights reserved. codetitle.com Develope by Vinagon .Ltd