NetBurner Web Server Guide
Overview
The NetBurner web server provides a powerful embedded HTTP server with support for both static and dynamic content. The web server architecture integrates seamlessly with your application, allowing real-time data display and interactive control through web pages.
NetBurner Web Server Architecture
─────────────────────────────────
Web Browser NetBurner Device Application
─────────── ──────────────── ───────────
┌──────────┐ ┌──────────────┐ ┌─────────┐
│ │ │ │ │ │
│ HTTP │ Request │ Web Server │ │ User │
│ Client │───────────────>│ │ │ Code │
│ │ │ - Routes │ │ │
│ │ │ - Static │<────────────│ - Data │
│ │ Response │ - Dynamic │ Calls │ - Logic │
│ │<───────────────│ │ │ │
│ │ └──────────────┘ └─────────┘
└──────────┘ |
v
┌──────────────┐
│ html/ │
│ ├─ *.html │
│ ├─ *.css │
│ ├─ *.js │
│ └─ images/ │
└──────────────┘
Key Features
- Static Content Serving - HTML, CSS, JavaScript, images
- Dynamic Content Generation - Real-time data display
- C++ Integration - Direct callback functions
- Variable Display - Automatic type handling
- URL Parsing - Request parameter processing
- File System - Organized resource management
Basic Web Server Setup
Project Structure
When you create a NetBurner web application, the following structure is automatically generated:
Project Directory Structure
───────────────────────────
YourProject/
│
├── src/
│ ├── main.cpp <── Application entry point
│ └── htmldata.cpp <── Auto-generated from html/
│
├── html/ <── Web content directory
│ ├── index.html <── Default home page
│ ├── styles.css <── (Optional) Stylesheets
│ ├── script.js <── (Optional) JavaScript
│ └── images/ <── (Optional) Image assets
│ ├── logo.png
│ └── icon.jpg
│
└── makefile <── Build configuration
Initial index.html
The Application Wizard creates a basic index.html file:
<html>
<body>
The main page for the AppWizard project.
</body>
</html>
Static Content
All files in the html/ directory are compiled into your application binary. The web server serves these files when requested by a browser.
Static Content Flow
───────────────────
Build Time: Run Time:
─────────── ─────────
┌──────────┐ ┌──────────┐
│ html/ │ │ Browser │
│ Files │ │ Request │
└────┬─────┘ └────┬─────┘
| |
v v
┌──────────┐ Embedded ┌──────────┐
│ comphtml │ in Binary │ Web │
│ Tool │ ─────────> │ Server │
└────┬─────┘ └────┬─────┘
| |
v v
┌──────────┐ ┌──────────┐
│htmldata │ Linked to │ Static │
│ .cpp │ ─────────> │ Content │
└──────────┘ └──────────┘
Adding Resources
Adding Images
Create an images/ folder in your html/ directory:
html/
├── index.html
└── images/
└── logo.jpg
Reference images in your HTML:
<html>
<body>
<h1>The main page for the AppWizard project</h1>
<img src="images/logo.jpg" alt="Company Logo">
</body>
</html>
Adding CSS and JavaScript
html/
├── index.html
├── styles.css
├── script.js
└── images/
styles.css:**
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
}
index.html with resources:**
<html>
<head>
<link rel="stylesheet" href="styles.css">
<script src="script.js"></script>
</head>
<body>
<h1>My NetBurner Application</h1>
<img src="images/logo.jpg" alt="Logo">
</body>
</html>
Editing HTML Files in NBEclipse
Right-click on an HTML file and select "Open With" > "Text Editor" to edit the raw HTML content.
Dynamic Web Content
NetBurner provides three HTML tags for dynamic content generation:
Dynamic Content Tags
────────────────────
Tag Type Purpose When to Use
──────── ─────── ───────────
CPPCALL Execute C++ function Complex logic, control
VARIABLE Display variable/expr Data display, sensors
INCLUDE Link external code Variable declarations
CPPCALL Tag - C++ Callback Functions
The CPPCALL tag executes a C++ function when the web page is served.
Syntax
<!--CPPCALL YourFunctionName -->
Function Signature
void YourFunctionName(int sock, PCSTR url)
{
}
Parameters Explained
CPPCALL Function Parameters
───────────────────────────
Parameter: sock (int)
┌─────────────────────────────────┐
│ TCP Socket File Descriptor │
│ - Use for writing output │
└─────────────────────────────────┘
Parameter: url (PCSTR)
┌─────────────────────────────────┐
│ Complete URL String │
│ "http:
│ - Parse query parameters │
│ - Extract values after '?' │
└─────────────────────────────────┘
int fdprintf(int fd, const char *format,...)
Print formatted output to a file descriptor.
int writestring(int fd, const char *str)
Write a null terminated ascii string to the stream associated with a file descriptor (fd)....
Basic Example
main.cpp:**
#include <nbrtos.h>
#include <init.h>
#include <http.h>
void webHelloWorld(int sock, PCSTR url)
{
}
void UserMain(void *pd)
{
while (1) {
}
}
#define TICKS_PER_SECOND
System clock ticks per second.
Definition constants.h:49
void StartHttp(uint16_t port, bool RunConfigMirror)
Start the HTTP web server. Further documentation in the Initialization section Initialization - Syste...
void init()
System initialization. Ideally called at the beginning of all applications, since the easiest Recover...
index.html:**
<html>
<body>
<h1>The main page for the AppWizard project</h1>
<p>Message from device: <!--CPPCALL webHelloWorld --></p>
</body>
</html>
Request Flow
CPPCALL Execution Flow
──────────────────────
Browser Web Server Application
─────── ────────── ───────────
| | |
| GET /index.html | |
|────────────────────────────>| |
| | |
| | Stream static content |
|<────────────────────────────| |
| "<html><body><h1>..." | |
| | |
| | <!--CPPCALL detected --> |
| | |
| | Call webHelloWorld(sock) |
| |───────────────────────────>|
| | |
| | Execute function |
|<────────────────────────────|<───────────────────────────|
| "Hello World" | |
| | |
| | Continue static content |
|<────────────────────────────| |
| "</body></html>" | |
Advanced CPPCALL Example - URL Parsing
void webDeviceControl(int sock, PCSTR url)
{
if (strstr(url, "action=toggle")) {
char *pinParam = strstr(url, "pin=");
if (pinParam) {
int pinNum = atoi(pinParam + 4);
Pins[pinNum].set(!Pins[pinNum].
read());
pinNum,
Pins[pinNum].
read() ?
"HIGH" :
"LOW");
}
} else if (strstr(url, "action=status")) {
fdprintf(sock,
"Device uptime: %lu seconds", Secs);
} else {
}
}
int read(int fd, char *buf, int nbytes)
Read data from a file descriptor (fd).
index.html:**
<html>
<body>
<h1>Device Control</h1>
<p>
<a href="?action=toggle&pin=23">Toggle Pin 23</a><br>
<a href="?action=status">Check Status</a>
</p>
<div>Response: <!--CPPCALL webDeviceControl --></div>
</body>
</html>
VARIABLE Tag - Displaying Variables
The VARIABLE tag displays application variables or expressions on web pages.
Syntax
<!--VARIABLE expression -->
Basic Usage
<!-- Display a simple variable -->
<!--VARIABLE TimeTick -->
<!-- Display an expression -->
<!--VARIABLE TimeTick/TICKS_PER_SECOND -->
<!-- Display with calculation -->
<!--VARIABLE (Temperature * 9/5) + 32 -->
Compilation Process
VARIABLE Tag Processing
───────────────────────
HTML Source: Generated Code:
──────────── ───────────────
<!--VARIABLE TimeTick --> WriteHtmlVariable(fd, TimeTick);
<!--VARIABLE TimeTick/ WriteHtmlVariable(fd,
<!--VARIABLE IPCAST( WriteHtmlVariable(fd,
IpAddress) --> IPCAST(IpAddress));
Supported Data Types
The following types are automatically handled by WriteHtmlVariable():
void WriteHtmlVariable(int fd, char c);
void WriteHtmlVariable(int fd, int i);
void WriteHtmlVariable(int fd, short i);
void WriteHtmlVariable(int fd, long i);
void WriteHtmlVariable(int fd, BYTE b);
void WriteHtmlVariable(int fd, WORD w);
void WriteHtmlVariable(int fd, unsigned long dw);
void WriteHtmlVariable(int fd, const char *);
void WriteHtmlVariable(
int fd,
MACADR ip);
Used to store and manipulate MAC addresses.
Definition nettypes.h:69
Type Handling Overview
Type Conversion Flow
────────────────────
Variable Type Overloaded Function Output
───────────── ─────────────────── ──────
char ──> WriteHtmlVariable(fd, c) ──> 'A'
int ──> WriteHtmlVariable(fd, i) ──> 123
const char* ──> WriteHtmlVariable(fd, s) ──> "Hello"
unsigned long ──> WriteHtmlVariable(fd, ul) ──> 4294967295
MACADR ──> WriteHtmlVariable(fd, mac) ──> 00:03:F4:...
IP Address Display
Use the IPCAST() helper to convert 32-bit integers to IP address format:
<!-- Without IPCAST - displays as integer -->
IP Address: <!--VARIABLE IpAddress -->
<!-- Output: 3232235777 -->
<!-- With IPCAST - displays in dotted notation -->
IP Address: <!--VARIABLE IPCAST(IpAddress) -->
<!-- Output: 192.168.1.1 -->
Complete Example
main.cpp:**
#include <init.h>
#include <nbrtos.h>
int Temperature = 25;
unsigned long Counter = 0;
const char *DeviceStatus = "Running";
void UserMain(void *pd)
{
while (1) {
Counter++;
Temperature = 20 + (Counter % 15);
}
}
index.html:**
<html>
<head>
<title>Device Status</title>
</head>
<body>
<h1>Device Status Monitor</h1>
<table border="1">
<tr>
<td>Uptime (seconds):</td>
<td><!--VARIABLE Secs --></td>
</tr>
<tr>
<td>System Ticks:</td>
<td><!--VARIABLE TimeTick --></td>
</tr>
<tr>
<td>Temperature (C):</td>
<td><!--VARIABLE Temperature --></td>
</tr>
<tr>
<td>Counter:</td>
<td><!--VARIABLE Counter --></td>
</tr>
<tr>
<td>Status:</td>
<td><!--VARIABLE DeviceStatus --></td>
</tr>
<tr>
<td>IP Address:</td>
<td><!--VARIABLE IPCAST(IpAddress) --></td>
</tr>
</table>
</body>
</html>
INCLUDE Tag - Linking Variables
To use variables with the VARIABLE tag, your application must link to them. Two methods are available:
Variable Linking Methods
────────────────────────
Method 1: htmlvar.h Header Method 2: INCLUDE Tag
───────────────────────── ─────────────────────
Project/ HTML File:
├── src/ ┌──────────────────────────────────┐
│ ├── main.cpp │ <!--INCLUDE mycustomheader.h --> │
│ └── htmlvar.h <───Link─── │ │
└── html/ └──────────────────────────────────┘
└── index.html |
v
Both methods allow Project/
htmldata.cpp to └── src/
link to your variables └── mycustomheader.h
Method 1: htmlvar.h Header File
Create htmlvar.h in your project's src/ directory:
htmlvar.h:**
#ifndef HTMLVARS_H_
#define HTMLVARS_H_
#include <init.h>
extern int Temperature;
extern unsigned long Counter;
extern const char *DeviceStatus;
const char *webMyVarFunction(int fd, int value);
#endif
Project structure:**
Project/
├── src/
│ ├── main.cpp
│ ├── htmlvar.h <── Add this file
│ └── htmldata.cpp <── Auto-generated (includes htmlvar.h)
└── html/
└── index.html
Method 2: INCLUDE Tag in HTML
index.html:**
<html>
<!--INCLUDE customheader.h -->
<body>
<h1>Temperature: <!--VARIABLE Temperature --> C</h1>
</body>
</html>
src/customheader.h:**
#ifndef CUSTOMHEADER_H_
#define CUSTOMHEADER_H_
extern int Temperature;
#endif
Linking Flow
Variable Linking at Compile Time
─────────────────────────────────
Step 1: HTML Processing
┌────────────────────────┐
│ <!--VARIABLE Temp --> │
└───────────┬────────────┘
|
v
Step 2: Code Generation
┌─────────────────────────────────┐
│ WriteHtmlVariable(fd, Temp); │
└───────────┬─────────────────────┘
|
v
Step 3: Include Headers
┌─────────────────────────────────┐
│ #include "htmlvar.h" │
│
│ #include "customheader.h" │
└───────────┬─────────────────────┘
|
v
Step 4: Link Variable
┌─────────────────────────────────┐
│ extern int Temp; │
│ (declared in header) │
└───────────┬─────────────────────┘
|
v
Step 5: Compilation Success
┌─────────────────────────────────┐
│ htmldata.cpp links to Temp │
│ in main.cpp │
└─────────────────────────────────┘
Advanced Techniques
Function Callbacks with Parameters
The VARIABLE tag can be used for function callbacks that accept parameters, providing more flexibility than CPPCALL.
Comparison: CPPCALL vs VARIABLE Functions
CPPCALL vs VARIABLE Function Callbacks
───────────────────────────────────────
CPPCALL: VARIABLE Function:
──────── ──────────────────
Fixed Signature: Flexible Signature:
void func(int sock, PCSTR url) const char* func(int fd, int val)
const char* func(int fd, float val)
etc.
Limited Parameters Custom Parameters
Can't pass app data Can pass any type
Use for: Use for:
- URL parsing - Parameterized display
- Control actions - Formatted output
- General callbacks - Data transformation
Function Callback Workflow
VARIABLE Function Callback Flow
───────────────────────────────
HTML:
┌────────────────────────────────────┐
│ <!--VARIABLE myFunc(fd, myVar) --> │
└────────────────┬───────────────────┘
|
v
Generated Code:
┌────────────────────────────────────────────┐
│ WriteHtmlVariable(fd, myFunc(fd, myVar)); │
└────────────────┬───────────────────────────┘
|
v
Your Implementation:
┌─────────────────────────────────────────────┐
│ const char* myFunc(int fd, int myVar) { │
│ return "";
│ } │
└─────────────────────────────────────────────┘
Example: Temperature Formatter
htmlvar.h:**
#ifndef HTMLVARS_H_
#define HTMLVARS_H_
#include <init.h>
extern int Temperature;
const char *FormatTemperature(int fd, int tempC);
#endif
main.cpp:**
#include <nbrtos.h>
#include <init.h>
#include "htmlvar.h"
int Temperature = 25;
const char *FormatTemperature(int fd, int tempC)
{
if (tempC < 20) {
} else if (tempC < 30) {
fdprintf(fd,
"green'>Normal: %dC", tempC);
} else {
}
return "";
}
void UserMain(void *pd)
{
while (1) {
Temperature = 15 + (Secs % 25);
}
}
index.html:**
<html>
<body>
<h1>Temperature Monitor</h1>
<!-- Pass fd and Temperature to function -->
<p>Current: <!--VARIABLE FormatTemperature(fd, Temperature) --></p>
<!-- Direct variable display for comparison -->
<p>Raw value: <!--VARIABLE Temperature --> C</p>
</body>
</html>
Multi-Parameter Function Example
htmlvar.h:**
extern int SensorValue;
extern int SensorID;
const char *DisplaySensor(int fd, int id, int value);
main.cpp:**
const char *DisplaySensor(int fd, int id, int value)
{
fdprintf(fd,
"Sensor #%d: %d units",
id, value);
return "";
}
index.html:**
<p><!--VARIABLE DisplaySensor(fd, SensorID, SensorValue) --></p>
Return Value Handling
Function Return Value Options
─────────────────────────────
Option 1: Write to Socket, Return Empty
┌───────────────────────────────────────┐
│ const char *func(int fd, int val) { │
│ return "";
│ } │
└───────────────────────────────────────┘
|
v
Output: "Data: 123"
Option 2: Return String for Printing
┌───────────────────────────────────────┐
│ const char *func(int fd, int val) { │
│ static char buf[80]; │
│ sprintf(buf, "Value: %d", val); │
│ return buf;
│ } │
└───────────────────────────────────────┘
|
v
Output: "Value: 123"
Option 3: Both (Write + Return)
┌───────────────────────────────────────┐
│ const char *func(int fd, int val) { │
│ return "End";
│ } │
└───────────────────────────────────────┘
|
v
Output: "Start: End"
Custom Data Types
Extend the VARIABLE tag to support user-defined structures and classes.
Custom Type Flow
Custom Type Support Architecture
─────────────────────────────────
Step 1: Define Your Type
┌────────────────────────────┐
│ struct MY_STRUCT { │
│ int value; │
│ char name[40]; │
│ }; │
│ │
│ MY_STRUCT myData; │
└────────────┬───────────────┘
|
v
Step 2: Declare in htmlvar.h
┌────────────────────────────────────────┐
│ extern MY_STRUCT myData; │
│ │
│ void WriteHtmlVariable(int fd, │
│ MY_STRUCT s); │
└────────────┬───────────────────────────┘
|
v
Step 3: Implement Function
┌────────────────────────────────────────┐
│ void WriteHtmlVariable(int fd, │
│ MY_STRUCT s) { │
│ s.name, s.value); │
│ } │
└────────────┬───────────────────────────┘
|
v
Step 4: Use in HTML
┌────────────────────────────────────────┐
│ <!--VARIABLE myData --> │
└────────────────────────────────────────┘
Complete Custom Type Example
main.cpp:**
#include <nbrtos.h>
#include <init.h>
struct SensorData {
int temperature;
char location[80];
uint32_t timestamp;
};
SensorData hallwaySensor;
SensorData laboratorySensor;
void WriteHtmlVariable(int fd, SensorData sensor)
{
fdprintf(fd,
" <strong>Location:</strong> %s<br>", sensor.location);
fdprintf(fd,
" <strong>Temperature:</strong> %dC<br>", sensor.temperature);
fdprintf(fd,
" <strong>Reading Time:</strong> %lu seconds<br>", sensor.timestamp);
}
void UserMain(void *pd)
{
strcpy(hallwaySensor.location, "Main Hallway");
strcpy(laboratorySensor.location, "Laboratory");
while (1) {
hallwaySensor.temperature = 20 + (Secs % 10);
hallwaySensor.timestamp = Secs;
laboratorySensor.temperature = 18 + (Secs % 8);
laboratorySensor.timestamp = Secs;
}
}
htmlvar.h:**
#ifndef HTMLVARS_H_
#define HTMLVARS_H_
#include <init.h>
struct SensorData {
int temperature;
char location[80];
uint32_t timestamp;
};
extern SensorData hallwaySensor;
extern SensorData laboratorySensor;
void WriteHtmlVariable(int fd, SensorData sensor);
#endif
index.html:**
<html>
<head>
<style>
.sensor {
border: 1px solid #ccc;
padding: 10px;
margin: 10px 0;
background-color: #f9f9f9;
}
</style>
</head>
<body>
<h1>Multi-Sensor Dashboard</h1>
<h2>Sensor 1</h2>
<!--VARIABLE hallwaySensor -->
<h2>Sensor 2</h2>
<!--VARIABLE laboratorySensor -->
<hr>
<p><small>System Time: <!--VARIABLE Secs --> seconds</small></p>
</body>
</html>
Class-Based Custom Type
class DeviceStatus {
public:
bool online;
int errorCount;
const char *version;
DeviceStatus() : online(true), errorCount(0), version("1.0.0") {}
};
DeviceStatus systemStatus;
void WriteHtmlVariable(int fd, DeviceStatus status)
{
fdprintf(fd,
"<tr><td>Status:</td><td>%s</td></tr>",
status.online ? "Online" : "Offline");
fdprintf(fd,
"<tr><td>Errors:</td><td>%d</td></tr>",
status.errorCount);
fdprintf(fd,
"<tr><td>Version:</td><td>%s</td></tr>",
status.version);
}
HTML usage:**
<div>
<h3>System Status</h3>
<!--VARIABLE systemStatus -->
</div>
Best Practices
Project Organization
Recommended Project Structure
─────────────────────────────
YourProject/
│
├── src/
│ ├── main.cpp <── Core application logic
│ ├── htmlvar.h <── Web variable declarations
│ ├── web_callbacks.cpp <── CPPCALL implementations
│ ├── web_callbacks.h <── CPPCALL declarations
│ └── htmldata.cpp <── Auto-generated (don't edit)
│
├── html/
│ ├── index.html <── Main page
│ ├── control.html <── Control interface
│ ├── status.html <── Status display
│ ├── styles/
│ │ └── main.css <── Stylesheets
│ ├── scripts/
│ │ └── main.js <── JavaScript
│ └── images/
│ ├── logo.png
│ └── icons/
│
└── makefile
Code Organization
Separate Web Logic
web_callbacks.h:**
#ifndef WEB_CALLBACKS_H_
#define WEB_CALLBACKS_H_
void webDeviceControl(int sock, PCSTR url);
void webSystemStatus(int sock, PCSTR url);
void webSensorData(int sock, PCSTR url);
const char *FormatTimestamp(int fd, unsigned long timestamp);
const char *FormatIPAddress(int fd, uint32_t ip);
#endif
web_callbacks.cpp:**
#include "web_callbacks.h"
#include <nbrtos.h>
void webDeviceControl(int sock, PCSTR url)
{
}
void webSystemStatus(int sock, PCSTR url)
{
}
Performance Optimization
Web Server Performance Tips
───────────────────────────
1. Minimize CPPCALL Processing
┌──────────────────────────────┐
│ void fastCallback(int sock, │
│ PCSTR url) │
│ { │
│
│
│ } │
└──────────────────────────────┘
│
v
Don't block web server thread!
2. Use VARIABLE for Simple Data
┌──────────────────────────────┐
│ <!--VARIABLE Temperature --> │
└──────────────────────────────┘
│
v
Faster than CPPCALL for display
3. Cache Formatted Strings
┌──────────────────────────────┐
│ static char statusBuf[256]; │
│ // Update periodically │
│ // in background task │
└──────────────────────────────┘
│
v
Reduce real-time formatting
4. Limit Dynamic Content
┌──────────────────────────────┐
│ Use static content where │
│ possible (HTML, CSS, JS) │
└──────────────────────────────┘
Security Considerations
Web Security Best Practices
───────────────────────────
Input Validation URL Parameter Sanitization
──────────────── ───────────────────────────
┌─────────────────────┐ ┌──────────────────────────┐
│ void callback( │ │ void handler(int sock, │
│ int sock, │ │ PCSTR url) │
│ PCSTR url) { │ │ { │
│ │ │
│
│ if (!isValid(url))│ │ │
│ { │ │
│ sock, │ │ parseParam(url); │
│ "Invalid"); │ │ if (isSafe(param)) { │
│ return; │ │
│ } │ │ } │
│ } │ │ } │
└─────────────────────┘ └──────────────────────────┘
Buffer Overflow Prevention Authentication
────────────────────────── ──────────────
┌─────────────────────┐ ┌──────────────────────────┐
│ char buf[256]; │ │ bool authenticated = │
│ │ │ CheckCredentials(url); │
│
│ sprintf(buf, ...); │ │ if (!authenticated) { │
│
│ sprintf(buf, │ │ return; │
│ sizeof(buf),...); │ │ } │
└─────────────────────┘ └──────────────────────────┘
Error Handling
void robustCallback(int sock, PCSTR url)
{
if (sock < 0) {
return;
}
if (!url || strlen(url) == 0) {
return;
}
char *param = strstr(url, "value=");
if (!param) {
return;
}
int value = atoi(param + 6);
if (value < 0 || value > 100) {
fdprintf(sock,
"Error: Value %d out of range", value);
return;
}
fdprintf(sock,
"Success: Value set to %d", value);
}
HTML Best Practices
<!-- Good: Clean, organized structure -->
<html>
<head>
<title>Device Control</title>
<link rel="stylesheet" href="styles/main.css">
</head>
<body>
<header>
<h1>NetBurner Device</h1>
<p>System Time: <!--VARIABLE Secs --> seconds</p>
</header>
<main>
<section id="status">
<h2>Status</h2>
<!--CPPCALL webSystemStatus -->
</section>
<section id="control">
<h2>Control</h2>
<!--CPPCALL webDeviceControl -->
</section>
</main>
<footer>
<p>Version: <!--VARIABLE FirmwareVersion --></p>
</footer>
<script src="scripts/main.js"></script>
</body>
</html>
Testing Strategy
Web Application Testing Flow
────────────────────────────
1. Unit Test Callbacks
┌──────────────────────┐
│ Test each CPPCALL │
│ function in │
│ isolation │
└──────────┬───────────┘
|
v
2. Validate Output
┌──────────────────────┐
│ Verify VARIABLE tags │
│ display correctly │
└──────────┬───────────┘
|
v
3. Test URL Parsing
┌──────────────────────┐
│ Various query params │
│ Edge cases │
└──────────┬───────────┘
|
v
4. Load Testing
┌──────────────────────┐
│ Multiple concurrent │
│ connections │
└──────────┬───────────┘
|
v
5. Security Testing
┌──────────────────────┐
│ Invalid inputs │
│ Buffer limits │
└──────────────────────┘
Debugging Tips
void debugCallback(int sock, PCSTR url)
{
printf("Callback called: %s\r\n", url);
char *param = strstr(url, "cmd=");
if (param) {
printf("Command parameter: %s\r\n", param);
}
printf("Response complete\r\n");
}
Common Pitfalls to Avoid
Common Mistakes and Solutions
─────────────────────────────
MISTAKE SOLUTION
─────── ────────
┌──────────────────────┐ ┌──────────────────────┐
│ void bad(int sock) { │ │ void good(int sock) {│
│ } │ │ "Hi"); │
└──────────────────────┘ │ } │
Output goes nowhere! └──────────────────────┘
Output to browser
Forgetting extern Declare in htmlvar.h
┌──────────────────────┐ ┌──────────────────────┐
│
│ int Temperature; │ │ extern int │
│ │ │ Temperature; │
│
└──────────────────────┘ htmldata.cpp can link
Blocking in callback Quick exit pattern
┌──────────────────────┐ ┌──────────────────────┐
│ void bad(int sock) { │ │ void good(int sock) {│
│
│ } │ │
└──────────────────────┘ │ } │
└──────────────────────┘
Not validating input Always validate
┌──────────────────────┐ ┌──────────────────────┐
│ int val = │ │ char *p = strstr(url,│
│ atoi(url+5); │ │ "val="); │
│
└──────────────────────┘ │ int val=atoi(p+4); │
│ } │
└──────────────────────┘
Quick Reference
Tag Summary
NetBurner Web Tags Quick Reference
──────────────────────────────────
Tag Purpose Syntax
─── ─────── ──────
CPPCALL Execute C++ <!--CPPCALL FuncName -->
function void FuncName(int sock,
PCSTR url)
VARIABLE Display variable <!--VARIABLE VarName -->
or expression <!--VARIABLE expr -->
INCLUDE Link header file <!--INCLUDE header.h -->
for variable access
VARIABLE Function Parameterized <!--VARIABLE Func(fd, var) -->
callback const char* Func(int fd,
int var)
Function Signatures
void CallbackFunction(int sock, PCSTR url);
const char *VariableFunction(int fd, <param_type> param);
void WriteHtmlVariable(int fd, CustomType data);
Common Patterns
void webStatus(int sock, PCSTR url) {
fdprintf(sock,
"Uptime: %lu seconds", Secs);
}
void webControl(int sock, PCSTR url) {
if (strstr(url, "action=reset")) {
}
}
const char *FormatData(int fd, int value) {
return "";
}
void WriteHtmlVariable(int fd, MyStruct s) {
fdprintf(fd,
"%s: %d", s.name, s.value);
}
Summary
The NetBurner web server provides a powerful platform for embedded web applications:
Web Server Capabilities Overview
────────────────────────────────
Static Content Dynamic Content Integration
────────────── ─────────────── ───────────
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ HTML Files │ │ CPPCALL │ │ Real-time │
│ CSS Styles │ │ - Callbacks │ │ Data │
│ JavaScript │ │ - Control │ │ Display │
│ Images │ │ │ │ │
│ Resources │ │ VARIABLE │ │ Device │
│ │ │ - Variables │ │ Control │
│ All embedded│ │ - Functions │ │ │
│ in binary │ │ - Custom │ │ Interactive │
└─────────────┘ └─────────────┘ └─────────────┘
| | |
└───────────────────────────┴─────────────────────────────┘
|
v
┌──────────────────┐
│ Unified Web │
│ Application │
└──────────────────┘
Key Takeaways
- Static content is compiled into the application binary
- CPPCALL provides flexible callback functions for dynamic control
- VARIABLE tags display real-time data with automatic type handling
- Custom types can be added by overloading WriteHtmlVariable()
- Security and input validation are critical for robust applications
- Performance is maintained by keeping callbacks fast and efficient