NetBurner 3.5.6
PDF Version
HTML Server GET Request

HtmlServerGetRequest Example

Overview

This NetBurner example demonstrates how to implement and use web server GET request callbacks to intercept browser requests. The application showcases custom processing capabilities and dynamic web content generation when specific web pages or URLs are requested, providing developers with powerful tools for creating interactive embedded web applications.

Features

  • HTTP GET request interception and custom processing
  • Dynamic content generation based on system state
  • File system integration with fallback mechanisms
  • Real-time request logging with client information
  • Conditional content routing and time-based page selection
  • Seamless integration of static and dynamic content

Project Structure

HtmlServerGetRequest/
├── src/
│ ├── main.cpp # Main application and HTTP server startup
│ ├── web.cpp # GET request callback implementations
│ └── htmlvar.h # HTML variable declarations
├── html/
│ ├── index.html # Main navigation page
│ ├── odd.html # Content for odd seconds
│ ├── even.html # Content for even seconds
│ ├── page2-rename.html # Demo file for testing precedence
│ └── images/
│ └── netburner-logo.gif # NetBurner logo image
└── makefile # Build configuration

Architecture

System Components

┌───────────────────────────────────────────────────────────────────────┐
│ NetBurner HTTP Server │
├───────────────────────────────────────────────────────────────────────┤
│ Request Processing Engine │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────────┐ │
│ │ URL Interceptor │ │ File System │ │ Dynamic Content │ │
│ │ │ │ Handler │ │ Generator │ │
│ │ - page2.html │ │ - Static Files │ │ - Custom Logic │ │
│ │ - OddEven.html │ │ - File Check │ │ - State-based │ │
│ │ - Pattern Match │ │ - Precedence │ │ Routing │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────────┘ │
├───────────────────────────────────────────────────────────────────────┤
│ Application Layer │
│ ┌─────────────────┐ ┌─────────────────────────┐ │
│ │ Main Program │ │ Callback Functions │ │
│ │ │ │ │ │
│ │ - Init System │ <───────────────── │ - callbackGetPage2 │ │
│ │ - Start Server │ │ - callbackGetOddEven │ │
│ │ - Network Setup │ │ - Request Processing │ │
│ └─────────────────┘ └─────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────┘

Request Processing Flow

Browser Request Processing Flow:
┌──────────┐ ┌───────────────┐ ┌──────────────────┐ ┌──────────┐
│ Browser │ │ HTTP Server │ │ URL Pattern │ │ Callback │
│ Request │---->│ (Port 80) │---->│ Matching │---->│ Handler │
└──────────┘ └───────────────┘ └──────────────────┘ └──────────┘
│ │ │
│ V │
│ ┌──────────────────┐ │
│ │ beforeFiles │ │
│ │ Parameter Check │ │
│ └──────────────────┘ │
│ │ │
V V V
┌───────────────┐ ┌──────────────────┐ ┌──────────┐
│ File System │ │ Dynamic Content │ │ Response │
│ Check │ │ Generation │ │ Delivery │
└───────────────┘ └──────────────────┘ └──────────┘

Key Components

Main Application (main.cpp)

The main application handles system initialization and HTTP server setup:

void UserMain(void *pd) {
init(); // Initialize network stack
EnableSystemDiagnostics(); // Enable debug output
StartHttp(); // Start HTTP server on port 80
WaitForActiveNetwork(TICKS_PER_SECOND * 5); // Wait for network connectivity
iprintf("Application: %s\r\nNNDK Revision: %s\r\n", AppName, GetReleaseTag());
// Main application loop - all web processing handled by callbacks
while (1) {
OSTimeDly(TICKS_PER_SECOND);
}
}
#define TICKS_PER_SECOND
System clock ticks per second.
Definition constants.h:49
const char * GetReleaseTag()
Returns the NNDK release tag information.
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...
void EnableSystemDiagnostics()
Turn on the diagnostic reports from the config page.
bool WaitForActiveNetwork(uint32_t ticks_to_wait=120 *TICKS_PER_SECOND, int interface=-1)
Wait for an active network connection on at least one interface.

Key Functions:**

  • System and network initialization
  • HTTP server startup on port 80
  • DHCP network configuration with 5-second timeout
  • Continuous operation loop

Web Server Callbacks (web.cpp)

Callback 1: page2.html Handler

Purpose:** Demonstrates conditional content generation when files don't exist

int callbackGetPage2(int sock, HTTP_Request &pHttpRequest) {
// Custom processing and logging
iprintf("Executing GET request callback function: callbackGetPage2\r\n");
iprintf("Called because page2.html was not found in the file system.\r\n");
// Generate dynamic HTML content
fdprintf(sock, "<html><body>\r\n");
fdprintf(sock, "<h1><font face=\"arial\">");
fdprintf(sock, "Content when a page2.html file does not exist");
fdprintf(sock, "</font></h1>\r\n");
fdprintf(sock, "</body></html>\r\n");
return 1; // Indicate request was handled
}
int fdprintf(int fd, const char *format,...)
Print formatted output to a file descriptor.
void SendHTMLHeader(int sock)
Send a HTML response header.
HTTP Request Structure.
Definition http.h:87

Registration Parameters:**

"page2.html", // URL to intercept
callbackGetPage2, // Callback function pointer
tGet, // HTTP GET request type
0, // No authentication required
false // beforeFiles: only call if file not found
);
Implements the HtmlPageHandler class as a function pointer callback for GET requests.
Definition http.h:326
@ tGet
GET request.
Definition http.h:37

Callback 2: OddEven.html Handler

Purpose:** Demonstrates time-based dynamic content selection

int callbackGetOddEven(int sock, HTTP_Request &pHttpRequest) {
// Request logging with client details
iprintf("Executing GET request callback function: callbackGetOddEven\r\n");
iprintf("Request URL: %s, from: %I\r\n",
pHttpRequest.pURL, pHttpRequest.client_IPaddr);
// Time-based content selection
if ((Secs % 2) == 0) {
SendFileFragment("even.html", sock);
} else {
SendFileFragment("odd.html", sock);
}
return 1; // Indicate request was handled
}
int32_t SendFileFragment(char const *name, int32_t fd, PCSTR url=NULL)
Send a file fragment without a header.
PSTR pURL
Request URL.
Definition http.h:88
IPADDR client_IPaddr
IP address of client.
Definition http.h:100

Registration Parameters:**

CallBackFunctionPageHandler getHandlerOddEven(
"OddEven.html", // URL to intercept (virtual URL)
callbackGetOddEven, // Callback function pointer
tGet, // HTTP GET request type
0, // No authentication required
true // beforeFiles: always call callback
);

Callback Control Mechanisms

beforeFiles Parameter Behavior

beforeFiles Parameter Control Flow:
┌─────────────────────────────────────────────────────────────────────┐
│ beforeFiles = false
├─────────────────────────────────────────────────────────────────────┤
│ Request > File System Check > Found? > Serve Static File │
│ │ │
│ V │
│ Missing? > Execute Callback │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ beforeFiles = true
├─────────────────────────────────────────────────────────────────────┤
│ Request > Execute Callback > Generate Dynamic Content │
└─────────────────────────────────────────────────────────────────────┘

beforeFiles = false (File System Priority)

Behavior:**

  • File system checked first for requested URL
  • If file exists, static file served directly
  • If file missing, callback executes to generate content
  • Callback only runs as fallback mechanism

    Use Cases:**

  • Fallback content when files are missing
  • Development with uploadable content
  • Conditional dynamic generation

beforeFiles = true (Callback Priority)

Behavior:**

  • Callback always executes regardless of file existence
  • No file system check performed
  • Complete control over response generation
  • Always dynamic content

    Use Cases:**

  • Always dynamic content requirements
  • Real-time data streams
  • Custom processing for every request

HTTP_Request Structure

The callback functions receive detailed request information:

HTTP_Request Structure:
┌─────────────────────────────────────────────────────────────┐
│ Field │ Type │ Description │
├─────────────────────────────────────────────────────────────┤
│ pURL │ char* │ Requested URL string
│ client_IPaddr │ IPADDR │ Client IP address │
│ Additional fields... │ Various │ Headers, parameters, etc.│
└─────────────────────────────────────────────────────────────┘
Used to hold and manipulate IPv4 and IPv6 addresses in dual stack mode.
Definition ipv6_addr.h:41

Available Information:**

  • Request URL: Complete URL path requested
  • Client IP: Source IP address of requesting client
  • HTTP headers: Additional request header information
  • Query parameters: URL parameters and values

HTML Content Structure

Static Web Pages

Main Navigation Page (index.html)

<html>
<title>HTML GET Request Example</title>
<body>
<img src="images/netburner-logo.gif">
<font face="arial">
<h1>HTML Server GET Request Response Example</h1>
<a href="page2.html">Run GET Request Example for page2.html</a><br><br>
<a href="OddEven.html">Run GET Request Example for OddEven.html</a><br><br>
</font>
</body>
</html>

Navigation Elements:**

  • NetBurner logo display
  • Links to demonstration pages
  • Clear page structure and formatting

Time-based Content Pages

odd.html - Content for Odd Seconds:**

<html>
<title>HTML GET Request Example</title>
<body>
<img src="images/netburner-logo.gif">
<font face="arial">
<h1>System seconds timer has an odd value: <!--VARIABLE Secs --></h1>
<a href="index.html"><< Back</a>
</font>
</body>
</html>

even.html - Content for Even Seconds:**

<html>
<title>HTML GET Request Example</title>
<body>
<img src="images/netburner-logo.gif">
<font face="arial">
<h1>System seconds timer has an even value: <!--VARIABLE Secs --></h1>
<a href="index.html"><< Back</a>
</font>
</body>
</html>

Demo File for Testing (page2-rename.html)

<html>
<title>HTML GET Request Example</title>
<body>
<img src="images/netburner-logo.gif">
<h1><font face="arial">page2.html from file system</font></h1>
</body>
</html>

Purpose:**

  • Demonstrates file system precedence behavior
  • Shows difference between static and dynamic content
  • Testing tool for beforeFiles parameter functionality

Dynamic Variable Integration

Variable Substitution Process:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ HTML Template │ │ Variable │ │ Final HTML │
│ with Tags │ --> │ Substitution │ --> │ Content │
│ <!--VARIABLE..> │ │ Processing │ │ (Browser Ready) │
└─────────────────┘ └─────────────────┘ └─────────────────┘

The HTML files use NetBurner's variable substitution system:

  • **** - Displays current system seconds timer
  • Automatic substitution - Variables replaced with actual values when page served
  • Real-time updates - Values reflect current system state when page loaded

File System Integration

HTML Content Compilation Process

Build Process Flow:
┌─────────────┐ comphtml ┌─────────────┐ Compile ┌─────────────┐
│ HTML Files │ ─────────────> │ htmldata. │ ────────────> │ Application │
│ in html/ │ │ cpp │ │ Binary │
│ directory │ │ (generated) │ │ (with HTML) │
└─────────────┘ └─────────────┘ └─────────────┘

File System Precedence Testing

File Precedence Testing Workflow:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Initial State │ │ Rename File │ │ Rebuild and │
│ No page2.html │ --> │ page2-rename to │ --> │ Test Behavior │
│ Callback Runs │ │ page2.html │ │ Static File │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
V V V
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Dynamic Content │ │ File Now │ │ Static Content │
│ from Callback │ │ Available │ │ from File │
└─────────────────┘ └─────────────────┘ └─────────────────┘

The example includes demonstration of file system precedence:

  1. Initially: No page2.html file exists, callback executes
  2. Rename test file: Change page2-rename.html to page2.html
  3. Rebuild application: Static file now embedded in application
  4. Result: Static file served instead of callback execution

Usage Instructions

Web Interface Testing

Complete Testing Workflow

Testing Sequence:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Access Main │ │ Test page2.html │ │ Test OddEven │
│ Page │ --> │ Callback │ --> │ Callback │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
V V V
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Verify │ │ Dynamic Content │ │ Time-based │
│ Navigation │ │ Generation │ │ Routing │
└─────────────────┘ └─────────────────┘ └─────────────────┘

Access Main Page

  1. Open browser to http://<device_ip>/
  2. Verify display of main page with navigation links
  3. Check images - NetBurner logo should load correctly

Test page2.html Callback

  1. Click link "Run GET Request Example for page2.html"
  2. Observe result - Dynamic content from callback function
  3. Check console - Callback execution messages displayed
  4. Expected content: "Content when a page2.html file does not exist"

Test OddEven.html Callback

  1. Click link "Run GET Request Example for OddEven.html"
  2. Observe content - Either odd.html or even.html content
  3. Note timer value - System seconds displayed in page
  4. Refresh page - Content may change based on timer parity
  5. Check console - Request logging with client IP address

Test File System Precedence

  1. Rename file - Change page2-rename.html to page2.html
  2. Rebuild application - Recompile with new file included
  3. Redeploy to device
  4. Test page2.html - Now serves static file instead of callback
  5. Expected content: "page2.html from file system"

Expected Console Output

Application Startup

Application: HTML Server GET Request
NNDK Revision: 3.x.x Build xxxx

Callback Execution Logging

Executing GET request callback function: callbackGetPage2
Called because page2.html was not found in the file system.
Executing GET request callback function: callbackGetOddEven
Request URL: OddEven.html, from: 192.168.1.50

Advanced Usage Patterns

Custom Processing Integration

Custom Processing Flow:
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Request │ │ Business Logic │ │ Response │
│ Arrives │ --> │ Processing │ --> │ Generation │
└─────────────────┘ └─────────────────┘ └─────────────────┘
│ │ │
V V V
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│ Log Client │ │ Read Sensors │ │ Dynamic HTML │
│ Information │ │ Update Database │ │ Content │
└─────────────────┘ └─────────────────┘ └─────────────────┘

Callbacks can include any custom processing before generating responses:

int customCallback(int sock, HTTP_Request &pHttpRequest) {
// Custom business logic
readSensorData();
updateDatabase();
logUserActivity(pHttpRequest.client_IPaddr);
// Generate response based on processing results
generateDynamicContent(sock);
return 1;
}

Error Handling Implementation

Implement robust error handling in callbacks:

int errorHandlingCallback(int sock, HTTP_Request &pHttpRequest) {
try {
// Potentially failing operations
if (!performOperation()) {
fdprintf(sock, "<html><body>");
fdprintf(sock, "<h1>Operation Failed</h1>");
fdprintf(sock, "</body></html>");
return 1;
}
// Success path
generateSuccessContent(sock);
return 1;
} catch (...) {
// Error recovery
fdprintf(sock, "<html><body><h1>Internal Error</h1></body></html>");
return 1;
}
}

Multiple Callback Registration

Register multiple callbacks for different URL patterns:

// Different callbacks for various URL patterns
CallBackFunctionPageHandler handler1("api/data.json", jsonDataCallback, tGet, 0, true);
CallBackFunctionPageHandler handler2("status/*", statusCallback, tGet, 0, true);
CallBackFunctionPageHandler handler3("config.html", configCallback, tGet, 1, false);

Performance Considerations

Callback Efficiency Guidelines

Performance Optimization:
┌─────────────────────────────────────────────────────────────────────┐
│ Callback Performance Best Practices │
├─────────────────────────────────────────────────────────────────────┤
│ - Minimize processing time to avoid blocking web server │
│ - Avoid long-running operations in callback functions │
│ - Use efficient string operations and memory management │
│ - Clean up resources properly before returning │
│ - Consider caching for frequently requested dynamic content │
└─────────────────────────────────────────────────────────────────────┘

Efficiency Best Practices

  • Minimize processing time - Keep callback execution fast
  • Avoid blocking operations - Don't block web server threads
  • Memory management - Clean up resources properly
  • Connection handling - Return promptly to free connections

Caching Strategies

  • Static content - Use compiled files for frequently accessed content
  • Dynamic data - Cache computed results when appropriate
  • Resource optimization - Minimize file system access in callbacks

Troubleshooting

Common Issues and Solutions

Troubleshooting Matrix:
┌─────────────────────┬─────────────────────┬─────────────────────┐
│ Symptom │ Possible Cause │ Solution │
├─────────────────────┼─────────────────────┼─────────────────────┤
│ Callback not │ Registration error │ Check parameters │
│ executing │ beforeFiles setting │ Verify URL match │
├─────────────────────┼─────────────────────┼─────────────────────┤
│ Content not │ Missing HTML header │ Call SendHTMLHeader
│ displaying │ Socket parameter │ Check fdprintf
├─────────────────────┼─────────────────────┼─────────────────────┤
│ File system │ File naming │ Check html/ │
│ conflicts │ beforeFiles param │ Rebuild after │
│ │ │ changes │
├─────────────────────┼─────────────────────┼─────────────────────┤
│ Network issues │ IP configuration │ Verify device IP │
│ │ Server startup │ Check console │
└─────────────────────┴─────────────────────┴─────────────────────┘

Callback Not Executing

Symptoms:** Expected callback doesn't run Solutions:**

  • Verify callback registration parameters
  • Check beforeFiles setting matches intended behavior
  • Ensure URL matches exactly (case-sensitive)
  • Confirm no conflicting static files exist

Content Not Displaying

Symptoms:** Blank or incomplete web pages Solutions:**

  • Verify SendHTMLHeader() called before content
  • Check fdprintf() syntax and socket parameter
  • Ensure callback returns 1 to indicate completion
  • Monitor console for error messages

Network Connectivity Issues

Symptoms:** Can't access web interface Solutions:**

  • Verify device IP address from console output
  • Check network connectivity with ping
  • Confirm HTTP server started successfully
  • Test with different browsers or clients

Dependencies

Required NetBurner system libraries:

  • init.h - System initialization
  • nbrtos.h - NetBurner RTOS functions
  • system.h - System utilities and version information
  • http.h - HTTP server support
  • iosys.h - I/O system functions
  • htmlfiles.h - HTML file handling
  • httppost.h - HTTP POST request handling
  • fdprintf.h - File descriptor printf functions
  • string.h - String manipulation functions