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) {
iprintf(
"Application: %s\r\nNNDK Revision: %s\r\n", AppName,
GetReleaseTag());
while (1) {
}
}
#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) {
iprintf("Executing GET request callback function: callbackGetPage2\r\n");
iprintf("Called because page2.html was not found in the file system.\r\n");
fdprintf(sock,
"<h1><font face=\"arial\">");
fdprintf(sock,
"Content when a page2.html file does not exist");
return 1;
}
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",
callbackGetPage2,
0,
false
);
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) {
iprintf("Executing GET request callback function: callbackGetOddEven\r\n");
iprintf("Request URL: %s, from: %I\r\n",
if ((Secs % 2) == 0) {
} else {
}
return 1;
}
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:**
"OddEven.html",
callbackGetOddEven,
0,
true
);
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:**
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:
┌─────────────────────────────────────────────────────────────┐
│ 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:
- Initially: No
page2.html file exists, callback executes
- Rename test file: Change
page2-rename.html to page2.html
- Rebuild application: Static file now embedded in application
- 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
- Open browser to
http://<device_ip>/
- Verify display of main page with navigation links
- Check images - NetBurner logo should load correctly
Test page2.html Callback
- Click link "Run GET Request Example for page2.html"
- Observe result - Dynamic content from callback function
- Check console - Callback execution messages displayed
- Expected content: "Content when a page2.html file does not exist"
Test OddEven.html Callback
- Click link "Run GET Request Example for OddEven.html"
- Observe content - Either odd.html or even.html content
- Note timer value - System seconds displayed in page
- Refresh page - Content may change based on timer parity
- Check console - Request logging with client IP address
Test File System Precedence
- Rename file - Change
page2-rename.html to page2.html
- Rebuild application - Recompile with new file included
- Redeploy to device
- Test page2.html - Now serves static file instead of callback
- 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:
readSensorData();
updateDatabase();
generateDynamicContent(sock);
return 1;
}
Error Handling Implementation
Implement robust error handling in callbacks:
int errorHandlingCallback(
int sock,
HTTP_Request &pHttpRequest) {
try {
if (!performOperation()) {
fdprintf(sock,
"<h1>Operation Failed</h1>");
return 1;
}
generateSuccessContent(sock);
return 1;
} catch (...) {
fdprintf(sock,
"<html><body><h1>Internal Error</h1></body></html>");
return 1;
}
}
Multiple Callback Registration
Register multiple callbacks for different URL patterns:
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 │
├─────────────────────┼─────────────────────┼─────────────────────┤
│ 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