parent
ebfbc1144c
commit
f64935eb1d
19 changed files with 5050 additions and 0 deletions
13
examples/http_server/Makefile
Normal file
13
examples/http_server/Makefile
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
PROGRAM=http_server
|
||||||
|
|
||||||
|
#ESPBAUD=921600
|
||||||
|
|
||||||
|
EXTRA_CFLAGS=-DLWIP_HTTPD_CGI=1 -DLWIP_HTTPD_SSI=1 -I./fsdata
|
||||||
|
|
||||||
|
EXTRA_COMPONENTS=extras/httpd
|
||||||
|
|
||||||
|
include ../../common.mk
|
||||||
|
|
||||||
|
html:
|
||||||
|
@echo "Generating fsdata.."
|
||||||
|
cd fsdata && ./makefsdata
|
25
examples/http_server/fsdata/fs/404.html
Normal file
25
examples/http_server/fsdata/fs/404.html
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/siimple.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||||
|
<link rel="shortcut icon" href="img/favicon.png">
|
||||||
|
|
||||||
|
<title>HTTP Server</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul class="navbar">
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
<li><a href="about">About</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="grid main">
|
||||||
|
<h1>404 - Page not found</h1>
|
||||||
|
<div class="alert alert-error">Sorry, the page you are requesting was not found on this server.</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
26
examples/http_server/fsdata/fs/about.html
Normal file
26
examples/http_server/fsdata/fs/about.html
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/siimple.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||||
|
<link rel="shortcut icon" href="img/favicon.png">
|
||||||
|
|
||||||
|
<title>HTTP Server</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul class="navbar">
|
||||||
|
<li><a href="/">Home</a></li>
|
||||||
|
<li><a class="active" href="about">About</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="grid main">
|
||||||
|
<h1>About</h1>
|
||||||
|
<p>This server is built on httpd from LwIP.</p>
|
||||||
|
<p>For more info see <a href="http://www.nongnu.org/lwip/2_0_0/group__httpd.html">HTTP Server documentation</a>.</p>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
8
examples/http_server/fsdata/fs/css/siimple.min.css
vendored
Normal file
8
examples/http_server/fsdata/fs/css/siimple.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
73
examples/http_server/fsdata/fs/css/style.css
Normal file
73
examples/http_server/fsdata/fs/css/style.css
Normal file
|
@ -0,0 +1,73 @@
|
||||||
|
ul.navbar {
|
||||||
|
list-style-type: none;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
padding: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
ul.navbar li {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
ul.navbar li a {
|
||||||
|
display: block;
|
||||||
|
color: white;
|
||||||
|
text-align: center;
|
||||||
|
padding: 14px 16px;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
ul.navbar li a:hover:not(.active) {
|
||||||
|
background-color: #111;
|
||||||
|
}
|
||||||
|
ul.navbar li a.active {
|
||||||
|
background-color: #09a0f6;
|
||||||
|
}
|
||||||
|
@media screen and (max-width: 600px){
|
||||||
|
ul.navbar li.right,
|
||||||
|
ul.navbar li {float: none;}
|
||||||
|
}
|
||||||
|
.onoffswitch {
|
||||||
|
position: relative; width: 90px;
|
||||||
|
-webkit-user-select:none; -moz-user-select:none; -ms-user-select: none;
|
||||||
|
}
|
||||||
|
.onoffswitch-checkbox {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.onoffswitch-label {
|
||||||
|
display: block; overflow: hidden; cursor: pointer;
|
||||||
|
border: 2px solid #03A9F4; border-radius: 20px;
|
||||||
|
}
|
||||||
|
.onoffswitch-inner {
|
||||||
|
display: block; width: 200%; margin-left: -100%;
|
||||||
|
transition: margin 0.3s ease-in 0s;
|
||||||
|
}
|
||||||
|
.onoffswitch-inner:before, .onoffswitch-inner:after {
|
||||||
|
display: block; float: left; width: 50%; height: 30px; padding: 0; line-height: 30px;
|
||||||
|
font-size: 14px; color: white; font-family: Trebuchet, Arial, sans-serif; font-weight: bold;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.onoffswitch-inner:before {
|
||||||
|
content: "ON";
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 14px;
|
||||||
|
background-color: #E1F5FE; color: #03A9F4;
|
||||||
|
}
|
||||||
|
.onoffswitch-inner:after {
|
||||||
|
content: "OFF";
|
||||||
|
padding-right: 14px;
|
||||||
|
background-color: #FFFFFF; color: #999999;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
.onoffswitch-switch {
|
||||||
|
display: block; width: 18px; margin: 6px;
|
||||||
|
background: #FFFFFF;
|
||||||
|
position: absolute; top: 0; bottom: 0;
|
||||||
|
right: 56px;
|
||||||
|
border: 2px solid #03A9F4; border-radius: 20px;
|
||||||
|
transition: all 0.3s ease-in 0s;
|
||||||
|
}
|
||||||
|
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-inner {
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
.onoffswitch-checkbox:checked + .onoffswitch-label .onoffswitch-switch {
|
||||||
|
right: 0px;
|
||||||
|
}
|
BIN
examples/http_server/fsdata/fs/img/favicon.png
Normal file
BIN
examples/http_server/fsdata/fs/img/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 760 B |
76
examples/http_server/fsdata/fs/index.ssi
Normal file
76
examples/http_server/fsdata/fs/index.ssi
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width, user-scalable=no">
|
||||||
|
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/siimple.min.css">
|
||||||
|
<link rel="stylesheet" type="text/css" href="css/style.css">
|
||||||
|
<link rel="shortcut icon" href="img/favicon.png">
|
||||||
|
|
||||||
|
<title>HTTP Server</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<ul class="navbar">
|
||||||
|
<li><a class="active" href="/">Home</a></li>
|
||||||
|
<li><a href="about">About</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="grid main">
|
||||||
|
<h1>ESP8266 HTTP Server</h1>
|
||||||
|
|
||||||
|
<div class="alert alert-done">HTTP Server is up and running.</div>
|
||||||
|
|
||||||
|
<p>This is an example HTTP server with CGI and SSI support. The switch below will allow you to test CGI handler and turn
|
||||||
|
the blue LED on or off.</p>
|
||||||
|
|
||||||
|
<div class="cover" align="center">
|
||||||
|
<div class="onoffswitch">
|
||||||
|
<input type="checkbox" name="onoffswitch" class="onoffswitch-checkbox" id="led-switch" onclick="gpio();">
|
||||||
|
<label class="onoffswitch-label" for="led-switch">
|
||||||
|
<span class="onoffswitch-inner"></span>
|
||||||
|
<span class="onoffswitch-switch"></span>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1>Server Status</h1>
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tr>
|
||||||
|
<td><b>Uptime:</b></td>
|
||||||
|
<td><!--#uptime--> seconds</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b>Free heap:</b></td>
|
||||||
|
<td><!--#heap--> bytes</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><b>LED state:</b></td>
|
||||||
|
<td id="ledState"><!--#led--></td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<h1>How it works</h1>
|
||||||
|
<p> Each time the server detects a tag of the form <code><!--#name--></code> in a .shtml, .ssi or .shtm file
|
||||||
|
where <code>name</code> appears as one of the tags supplied to <code>http_set_ssi_handler</code> in the <code>pcConfigSSITags</code> array,
|
||||||
|
an insert string is appended after the tag string in file and sent back to the client.</p>
|
||||||
|
<p>A CGI handler function is called each time the server is asked for a file
|
||||||
|
whose name was previously registered as a CGI function using a call to <code>http_set_cgi_handler</code>.
|
||||||
|
This function allows you to access the parameters provided along with the URI.</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.onload = function () {
|
||||||
|
var ls = document.getElementById('ledState').innerHTML;
|
||||||
|
ls = ls.split(/-->/).pop().trim();
|
||||||
|
document.getElementById('led-switch').checked = (ls == 'On');
|
||||||
|
};
|
||||||
|
function gpio() {
|
||||||
|
if (document.getElementById('led-switch').checked)
|
||||||
|
window.location.href = 'gpio?off=2';
|
||||||
|
else
|
||||||
|
window.location.href = 'gpio?on=2';
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1361
examples/http_server/fsdata/fsdata.c
Normal file
1361
examples/http_server/fsdata/fsdata.c
Normal file
File diff suppressed because it is too large
Load diff
114
examples/http_server/fsdata/makefsdata
Executable file
114
examples/http_server/fsdata/makefsdata
Executable file
|
@ -0,0 +1,114 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
$incHttpHeader = 1;
|
||||||
|
|
||||||
|
open(OUTPUT, "> fsdata.c");
|
||||||
|
print(OUTPUT "#include \"httpd/fsdata.h\"\n\n");
|
||||||
|
|
||||||
|
chdir("fs");
|
||||||
|
open(FILES, "find . -type f |");
|
||||||
|
|
||||||
|
while($file = <FILES>) {
|
||||||
|
|
||||||
|
# Do not include files in CVS directories nor backup files.
|
||||||
|
if($file =~ /(CVS|~)/) {
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
chop($file);
|
||||||
|
|
||||||
|
if($incHttpHeader == 1) {
|
||||||
|
open(HEADER, "> /tmp/header") || die $!;
|
||||||
|
if($file =~ /404/) {
|
||||||
|
print(HEADER "HTTP/1.0 404 File not found\r\n");
|
||||||
|
} else {
|
||||||
|
print(HEADER "HTTP/1.0 200 OK\r\n");
|
||||||
|
}
|
||||||
|
print(HEADER "lwIP/1.4.1 (http://savannah.nongnu.org/projects/lwip)\r\n");
|
||||||
|
if($file =~ /\.html$/ || $file =~ /\.htm$/ || $file =~ /\.shtml$/ || $file =~ /\.shtm$/ || $file =~ /\.ssi$/) {
|
||||||
|
print(HEADER "Content-type: text/html\r\n");
|
||||||
|
} elsif($file =~ /\.js$/) {
|
||||||
|
print(HEADER "Content-type: application/x-javascript\r\n\r\n");
|
||||||
|
} elsif($file =~ /\.css$/) {
|
||||||
|
print(HEADER "Content-type: text/css\r\n\r\n");
|
||||||
|
} elsif($file =~ /\.ico$/) {
|
||||||
|
print(HEADER "Content-type: image/x-icon\r\n\r\n");
|
||||||
|
} elsif($file =~ /\.gif$/) {
|
||||||
|
print(HEADER "Content-type: image/gif\r\n");
|
||||||
|
} elsif($file =~ /\.png$/) {
|
||||||
|
print(HEADER "Content-type: image/png\r\n");
|
||||||
|
} elsif($file =~ /\.jpg$/) {
|
||||||
|
print(HEADER "Content-type: image/jpeg\r\n");
|
||||||
|
} elsif($file =~ /\.bmp$/) {
|
||||||
|
print(HEADER "Content-type: image/bmp\r\n\r\n");
|
||||||
|
} elsif($file =~ /\.class$/) {
|
||||||
|
print(HEADER "Content-type: application/octet-stream\r\n");
|
||||||
|
} elsif($file =~ /\.ram$/) {
|
||||||
|
print(HEADER "Content-type: audio/x-pn-realaudio\r\n");
|
||||||
|
} else {
|
||||||
|
print(HEADER "Content-type: text/plain\r\n");
|
||||||
|
}
|
||||||
|
print(HEADER "\r\n");
|
||||||
|
close(HEADER);
|
||||||
|
|
||||||
|
unless($file =~ /\.plain$/ || $file =~ /cgi/) {
|
||||||
|
system("cat /tmp/header $file > /tmp/file");
|
||||||
|
} else {
|
||||||
|
system("cp $file /tmp/file");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
system("cp $file /tmp/file");
|
||||||
|
}
|
||||||
|
|
||||||
|
open(FILE, "/tmp/file");
|
||||||
|
unlink("/tmp/file");
|
||||||
|
unlink("/tmp/header");
|
||||||
|
|
||||||
|
$file =~ s/\.//;
|
||||||
|
$fvar = $file;
|
||||||
|
$fvar =~ s-/-_-g;
|
||||||
|
$fvar =~ s-\.-_-g;
|
||||||
|
|
||||||
|
print(OUTPUT "static const unsigned char data".$fvar."[] = {\n");
|
||||||
|
print(OUTPUT "\t/* $file */\n\t");
|
||||||
|
for($j = 0; $j < length($file); $j++) {
|
||||||
|
printf(OUTPUT "0x%02X, ", unpack("C", substr($file, $j, 1)));
|
||||||
|
}
|
||||||
|
printf(OUTPUT "0,\n");
|
||||||
|
|
||||||
|
|
||||||
|
$i = 0;
|
||||||
|
while(read(FILE, $data, 1)) {
|
||||||
|
if($i == 0) {
|
||||||
|
print(OUTPUT "\t");
|
||||||
|
}
|
||||||
|
printf(OUTPUT "0x%02X, ", unpack("C", $data));
|
||||||
|
$i++;
|
||||||
|
if($i == 10) {
|
||||||
|
print(OUTPUT "\n");
|
||||||
|
$i = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
print(OUTPUT "};\n\n");
|
||||||
|
close(FILE);
|
||||||
|
push(@fvars, $fvar);
|
||||||
|
push(@files, $file);
|
||||||
|
}
|
||||||
|
|
||||||
|
for($i = 0; $i < @fvars; $i++) {
|
||||||
|
$file = $files[$i];
|
||||||
|
$fvar = $fvars[$i];
|
||||||
|
|
||||||
|
if($i == 0) {
|
||||||
|
$prevfile = "NULL";
|
||||||
|
} else {
|
||||||
|
$prevfile = "file" . $fvars[$i - 1];
|
||||||
|
}
|
||||||
|
print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{\n$prevfile,\ndata$fvar, ");
|
||||||
|
print(OUTPUT "data$fvar + ". (length($file) + 1) .",\n");
|
||||||
|
print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) .",\n");
|
||||||
|
print(OUTPUT $incHttpHeader."\n}};\n\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n");
|
||||||
|
print(OUTPUT "#define FS_NUMFILES $i\n");
|
2
examples/http_server/fsdata/readme.txt
Normal file
2
examples/http_server/fsdata/readme.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
This directory contains a script ('makefsdata') to create C code suitable for
|
||||||
|
httpd for given html pages (or other files) in a directory.
|
114
examples/http_server/http_server.c
Normal file
114
examples/http_server/http_server.c
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* HTTP server example.
|
||||||
|
*
|
||||||
|
* This sample code is in the public domain.
|
||||||
|
*/
|
||||||
|
#include <espressif/esp_common.h>
|
||||||
|
#include <esp8266.h>
|
||||||
|
#include <esp/uart.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <FreeRTOS.h>
|
||||||
|
#include <task.h>
|
||||||
|
#include <ssid_config.h>
|
||||||
|
#include <httpd/httpd.h>
|
||||||
|
|
||||||
|
#define LED_PIN 2
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SSI_UPTIME,
|
||||||
|
SSI_FREE_HEAP,
|
||||||
|
SSI_LED_STATE
|
||||||
|
};
|
||||||
|
|
||||||
|
char *gpio_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||||
|
{
|
||||||
|
for (int i = 0; i < iNumParams; i++) {
|
||||||
|
if (strcmp(pcParam[i], "on") == 0) {
|
||||||
|
uint8_t gpio_num = atoi(pcValue[i]);
|
||||||
|
gpio_enable(gpio_num, GPIO_OUTPUT);
|
||||||
|
gpio_write(gpio_num, true);
|
||||||
|
} else if (strcmp(pcParam[i], "off") == 0) {
|
||||||
|
uint8_t gpio_num = atoi(pcValue[i]);
|
||||||
|
gpio_enable(gpio_num, GPIO_OUTPUT);
|
||||||
|
gpio_write(gpio_num, false);
|
||||||
|
} else if (strcmp(pcParam[i], "toggle") == 0) {
|
||||||
|
uint8_t gpio_num = atoi(pcValue[i]);
|
||||||
|
gpio_enable(gpio_num, GPIO_OUTPUT);
|
||||||
|
gpio_toggle(gpio_num);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "/index.ssi";
|
||||||
|
}
|
||||||
|
|
||||||
|
char *about_cgi_handler(int iIndex, int iNumParams, char *pcParam[], char *pcValue[])
|
||||||
|
{
|
||||||
|
return "/about.html";
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t ssi_handler(int32_t iIndex, char *pcInsert, int32_t iInsertLen)
|
||||||
|
{
|
||||||
|
switch (iIndex) {
|
||||||
|
case SSI_UPTIME:
|
||||||
|
snprintf(pcInsert, iInsertLen, "%d",
|
||||||
|
xTaskGetTickCount() * portTICK_PERIOD_MS / 1000);
|
||||||
|
break;
|
||||||
|
case SSI_FREE_HEAP:
|
||||||
|
snprintf(pcInsert, iInsertLen, "%d", (int) xPortGetFreeHeapSize());
|
||||||
|
break;
|
||||||
|
case SSI_LED_STATE:
|
||||||
|
snprintf(pcInsert, iInsertLen, (GPIO.OUT & BIT(LED_PIN)) ? "Off" : "On");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
snprintf(pcInsert, iInsertLen, "N/A");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tell the server how many characters to insert */
|
||||||
|
return (strlen(pcInsert));
|
||||||
|
}
|
||||||
|
|
||||||
|
void httpd_task(void *pvParameters)
|
||||||
|
{
|
||||||
|
tCGI pCGIs[] = {
|
||||||
|
{"/gpio", (tCGIHandler) gpio_cgi_handler},
|
||||||
|
{"/about", (tCGIHandler) about_cgi_handler},
|
||||||
|
};
|
||||||
|
|
||||||
|
const char *pcConfigSSITags[] = {
|
||||||
|
"uptime", // SSI_UPTIME
|
||||||
|
"heap", // SSI_FREE_HEAP
|
||||||
|
"led" // SSI_LED_STATE
|
||||||
|
};
|
||||||
|
|
||||||
|
/* register handlers and start the server */
|
||||||
|
http_set_cgi_handlers(pCGIs, sizeof (pCGIs) / sizeof (pCGIs[0]));
|
||||||
|
http_set_ssi_handler((tSSIHandler) ssi_handler, pcConfigSSITags,
|
||||||
|
sizeof (pcConfigSSITags) / sizeof (pcConfigSSITags[0]));
|
||||||
|
httpd_init();
|
||||||
|
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
void user_init(void)
|
||||||
|
{
|
||||||
|
uart_set_baud(0, 115200);
|
||||||
|
printf("SDK version:%s\n", sdk_system_get_sdk_version());
|
||||||
|
|
||||||
|
struct sdk_station_config config = {
|
||||||
|
.ssid = WIFI_SSID,
|
||||||
|
.password = WIFI_PASS,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* required to call wifi_set_opmode before station_set_config */
|
||||||
|
sdk_wifi_set_opmode(STATION_MODE);
|
||||||
|
sdk_wifi_station_set_config(&config);
|
||||||
|
sdk_wifi_station_connect();
|
||||||
|
|
||||||
|
/* turn off LED */
|
||||||
|
gpio_enable(LED_PIN, GPIO_OUTPUT);
|
||||||
|
gpio_write(LED_PIN, true);
|
||||||
|
|
||||||
|
/* initialize tasks */
|
||||||
|
xTaskCreate(&httpd_task, "HTTP Daemon", 1024, NULL, 2, NULL);
|
||||||
|
}
|
9
extras/httpd/component.mk
Normal file
9
extras/httpd/component.mk
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
# Component makefile for extras/httpd
|
||||||
|
|
||||||
|
# expected anyone using httpd includes it as 'httpd/httpd.h'
|
||||||
|
INC_DIRS += $(httpd_ROOT)..
|
||||||
|
|
||||||
|
# args for passing into compile rule generation
|
||||||
|
httpd_SRC_DIR = $(httpd_ROOT)
|
||||||
|
|
||||||
|
$(eval $(call component_compile_rules,httpd))
|
180
extras/httpd/fs.c
Normal file
180
extras/httpd/fs.c
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/def.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "fsdata.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the
|
||||||
|
* file system (to prevent changing the file included in CVS) */
|
||||||
|
#ifndef HTTPD_USE_CUSTOM_FSDATA
|
||||||
|
#define HTTPD_USE_CUSTOM_FSDATA 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if HTTPD_USE_CUSTOM_FSDATA
|
||||||
|
#include "fsdata_custom.c"
|
||||||
|
#else /* HTTPD_USE_CUSTOM_FSDATA */
|
||||||
|
#include "fsdata.c"
|
||||||
|
#endif /* HTTPD_USE_CUSTOM_FSDATA */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
int fs_open_custom(struct fs_file *file, const char *name);
|
||||||
|
void fs_close_custom(struct fs_file *file);
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
u8_t fs_canread_custom(struct fs_file *file);
|
||||||
|
u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
err_t
|
||||||
|
fs_open(struct fs_file *file, const char *name)
|
||||||
|
{
|
||||||
|
const struct fsdata_file *f;
|
||||||
|
|
||||||
|
if ((file == NULL) || (name == NULL)) {
|
||||||
|
return ERR_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (fs_open_custom(file, name)) {
|
||||||
|
file->is_custom_file = 1;
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
file->is_custom_file = 0;
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
|
for (f = FS_ROOT; f != NULL; f = f->next) {
|
||||||
|
if (!strcmp(name, (char *)f->name)) {
|
||||||
|
file->data = (const char *)f->data;
|
||||||
|
file->len = f->len;
|
||||||
|
file->index = f->len;
|
||||||
|
file->pextension = NULL;
|
||||||
|
file->http_header_included = f->http_header_included;
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
file->chksum_count = f->chksum_count;
|
||||||
|
file->chksum = f->chksum;
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
file->state = fs_state_init(file, name);
|
||||||
|
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||||
|
return ERR_OK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* file not found */
|
||||||
|
return ERR_VAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
fs_close(struct fs_file *file)
|
||||||
|
{
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (file->is_custom_file) {
|
||||||
|
fs_close_custom(file);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
fs_state_free(file, file->state);
|
||||||
|
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||||
|
LWIP_UNUSED_ARG(file);
|
||||||
|
}
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#if LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int
|
||||||
|
fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg)
|
||||||
|
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int
|
||||||
|
fs_read(struct fs_file *file, char *buffer, int count)
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
{
|
||||||
|
int read;
|
||||||
|
|
||||||
|
if(file->index == file->len) {
|
||||||
|
return FS_READ_EOF;
|
||||||
|
}
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (!fs_canread_custom(file)) {
|
||||||
|
if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
|
||||||
|
return FS_READ_DELAYED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
LWIP_UNUSED_ARG(callback_fn);
|
||||||
|
LWIP_UNUSED_ARG(callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
|
||||||
|
read = file->len - file->index;
|
||||||
|
if(read > count) {
|
||||||
|
read = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
MEMCPY(buffer, (file->data + file->index), read);
|
||||||
|
file->index += read;
|
||||||
|
|
||||||
|
return(read);
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int
|
||||||
|
fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg)
|
||||||
|
{
|
||||||
|
if (file != NULL) {
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (!fs_canread_custom(file)) {
|
||||||
|
if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
LWIP_UNUSED_ARG(callback_fn);
|
||||||
|
LWIP_UNUSED_ARG(callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
fs_bytes_left(struct fs_file *file)
|
||||||
|
{
|
||||||
|
return file->len - file->index;
|
||||||
|
}
|
132
extras/httpd/fs.h
Normal file
132
extras/httpd/fs.h
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __FS_H__
|
||||||
|
#define __FS_H__
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
|
||||||
|
/** Set this to 1 and provide the functions:
|
||||||
|
* - "int fs_open_custom(struct fs_file *file, const char *name)"
|
||||||
|
* Called first for every opened file to allow opening files
|
||||||
|
* that are not included in fsdata(_custom).c
|
||||||
|
* - "void fs_close_custom(struct fs_file *file)"
|
||||||
|
* Called to free resources allocated by fs_open_custom().
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
#define LWIP_HTTPD_CUSTOM_FILES 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support fs_read() to dynamically read file data.
|
||||||
|
* Without this (default=off), only one-block files are supported,
|
||||||
|
* and the contents must be ready after fs_open().
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||||
|
#define LWIP_HTTPD_DYNAMIC_FILE_READ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to include an application state argument per file
|
||||||
|
* that is opened. This allows to keep a state per connection/file.
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HTTPD_FILE_STATE
|
||||||
|
#define LWIP_HTTPD_FILE_STATE 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for
|
||||||
|
* predefined (MSS-sized) chunks of the files to prevent having to calculate
|
||||||
|
* the checksums at runtime. */
|
||||||
|
#ifndef HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
#define HTTPD_PRECALCULATED_CHECKSUM 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations
|
||||||
|
* (fs_read_async returns FS_READ_DELAYED and calls a callback when finished).
|
||||||
|
*/
|
||||||
|
#ifndef LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
#define LWIP_HTTPD_FS_ASYNC_READ 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define FS_READ_EOF -1
|
||||||
|
#define FS_READ_DELAYED -2
|
||||||
|
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
struct fsdata_chksum {
|
||||||
|
u32_t offset;
|
||||||
|
u16_t chksum;
|
||||||
|
u16_t len;
|
||||||
|
};
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
|
||||||
|
struct fs_file {
|
||||||
|
const char *data;
|
||||||
|
int len;
|
||||||
|
int index;
|
||||||
|
void *pextension;
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
const struct fsdata_chksum *chksum;
|
||||||
|
u16_t chksum_count;
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
u8_t http_header_included;
|
||||||
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
u8_t is_custom_file;
|
||||||
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
void *state;
|
||||||
|
#endif /* LWIP_HTTPD_FILE_STATE */
|
||||||
|
};
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
typedef void (*fs_wait_cb)(void *arg);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
|
||||||
|
err_t fs_open(struct fs_file *file, const char *name);
|
||||||
|
void fs_close(struct fs_file *file);
|
||||||
|
#if LWIP_HTTPD_DYNAMIC_FILE_READ
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
#else /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int fs_read(struct fs_file *file, char *buffer, int count);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ
|
||||||
|
int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg);
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
int fs_bytes_left(struct fs_file *file);
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
/** This user-defined function is called when a file is opened. */
|
||||||
|
void *fs_state_init(struct fs_file *file, const char *name);
|
||||||
|
/** This user-defined function is called when a file is closed. */
|
||||||
|
void fs_state_free(struct fs_file *file, void *state);
|
||||||
|
#endif /* #if LWIP_HTTPD_FILE_STATE */
|
||||||
|
|
||||||
|
#endif /* __FS_H__ */
|
50
extras/httpd/fsdata.h
Normal file
50
extras/httpd/fsdata.h
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
#ifndef __FSDATA_H__
|
||||||
|
#define __FSDATA_H__
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "fs.h"
|
||||||
|
|
||||||
|
struct fsdata_file {
|
||||||
|
const struct fsdata_file *next;
|
||||||
|
const unsigned char *name;
|
||||||
|
const unsigned char *data;
|
||||||
|
int len;
|
||||||
|
u8_t http_header_included;
|
||||||
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
|
u16_t chksum_count;
|
||||||
|
const struct fsdata_chksum *chksum;
|
||||||
|
#endif /* HTTPD_PRECALCULATED_CHECKSUM */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* __FSDATA_H__ */
|
2504
extras/httpd/httpd.c
Normal file
2504
extras/httpd/httpd.c
Normal file
File diff suppressed because it is too large
Load diff
236
extras/httpd/httpd.h
Normal file
236
extras/httpd/httpd.h
Normal file
|
@ -0,0 +1,236 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
|
* this list of conditions and the following disclaimer in the documentation
|
||||||
|
* and/or other materials provided with the distribution.
|
||||||
|
* 3. The name of the author may not be used to endorse or promote products
|
||||||
|
* derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
||||||
|
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
|
||||||
|
* SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
||||||
|
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
|
||||||
|
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the lwIP TCP/IP stack.
|
||||||
|
*
|
||||||
|
* Author: Adam Dunkels <adam@sics.se>
|
||||||
|
*
|
||||||
|
* This version of the file has been modified by Texas Instruments to offer
|
||||||
|
* simple server-side-include (SSI) and Common Gateway Interface (CGI)
|
||||||
|
* capability.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __HTTPD_H__
|
||||||
|
#define __HTTPD_H__
|
||||||
|
|
||||||
|
#include "lwip/opt.h"
|
||||||
|
#include "lwip/err.h"
|
||||||
|
#include "lwip/pbuf.h"
|
||||||
|
|
||||||
|
|
||||||
|
/** Set this to 1 to support CGI */
|
||||||
|
#ifndef LWIP_HTTPD_CGI
|
||||||
|
#define LWIP_HTTPD_CGI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support SSI (Server-Side-Includes) */
|
||||||
|
#ifndef LWIP_HTTPD_SSI
|
||||||
|
#define LWIP_HTTPD_SSI 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 to support HTTP POST */
|
||||||
|
#ifndef LWIP_HTTPD_SUPPORT_POST
|
||||||
|
#define LWIP_HTTPD_SUPPORT_POST 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_CGI
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function pointer for a CGI script handler.
|
||||||
|
*
|
||||||
|
* This function is called each time the HTTPD server is asked for a file
|
||||||
|
* whose name was previously registered as a CGI function using a call to
|
||||||
|
* http_set_cgi_handler. The iIndex parameter provides the index of the
|
||||||
|
* CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters
|
||||||
|
* pcParam and pcValue provide access to the parameters provided along with
|
||||||
|
* the URI. iNumParams provides a count of the entries in the pcParam and
|
||||||
|
* pcValue arrays. Each entry in the pcParam array contains the name of a
|
||||||
|
* parameter with the corresponding entry in the pcValue array containing the
|
||||||
|
* value for that parameter. Note that pcParam may contain multiple elements
|
||||||
|
* with the same name if, for example, a multi-selection list control is used
|
||||||
|
* in the form generating the data.
|
||||||
|
*
|
||||||
|
* The function should return a pointer to a character string which is the
|
||||||
|
* path and filename of the response that is to be sent to the connected
|
||||||
|
* browser, for example "/thanks.htm" or "/response/error.ssi".
|
||||||
|
*
|
||||||
|
* The maximum number of parameters that will be passed to this function via
|
||||||
|
* iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming
|
||||||
|
* HTTP request above this number will be discarded.
|
||||||
|
*
|
||||||
|
* Requests intended for use by this CGI mechanism must be sent using the GET
|
||||||
|
* method (which encodes all parameters within the URI rather than in a block
|
||||||
|
* later in the request). Attempts to use the POST method will result in the
|
||||||
|
* request being ignored.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[],
|
||||||
|
char *pcValue[]);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure defining the base filename (URL) of a CGI and the associated
|
||||||
|
* function which is to be called when that URL is requested.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *pcCGIName;
|
||||||
|
tCGIHandler pfnCGIHandler;
|
||||||
|
} tCGI;
|
||||||
|
|
||||||
|
void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers);
|
||||||
|
|
||||||
|
|
||||||
|
/* The maximum number of parameters that the CGI handler can be sent. */
|
||||||
|
#ifndef LWIP_HTTPD_MAX_CGI_PARAMETERS
|
||||||
|
#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_CGI */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SSI
|
||||||
|
|
||||||
|
/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more
|
||||||
|
* arguments indicating a counter for insert string that are too long to be
|
||||||
|
* inserted at once: the SSI handler function must then set 'next_tag_part'
|
||||||
|
* which will be passed back to it in the next call. */
|
||||||
|
#ifndef LWIP_HTTPD_SSI_MULTIPART
|
||||||
|
#define LWIP_HTTPD_SSI_MULTIPART 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Function pointer for the SSI tag handler callback.
|
||||||
|
*
|
||||||
|
* This function will be called each time the HTTPD server detects a tag of the
|
||||||
|
* form <!--#name--> in a .shtml, .ssi or .shtm file where "name" appears as
|
||||||
|
* one of the tags supplied to http_set_ssi_handler in the ppcTags array. The
|
||||||
|
* returned insert string, which will be appended after the the string
|
||||||
|
* "<!--#name-->" in file sent back to the client,should be written to pointer
|
||||||
|
* pcInsert. iInsertLen contains the size of the buffer pointed to by
|
||||||
|
* pcInsert. The iIndex parameter provides the zero-based index of the tag as
|
||||||
|
* found in the ppcTags array and identifies the tag that is to be processed.
|
||||||
|
*
|
||||||
|
* The handler returns the number of characters written to pcInsert excluding
|
||||||
|
* any terminating NULL or a negative number to indicate a failure (tag not
|
||||||
|
* recognized, for example).
|
||||||
|
*
|
||||||
|
* Note that the behavior of this SSI mechanism is somewhat different from the
|
||||||
|
* "normal" SSI processing as found in, for example, the Apache web server. In
|
||||||
|
* this case, the inserted text is appended following the SSI tag rather than
|
||||||
|
* replacing the tag entirely. This allows for an implementation that does not
|
||||||
|
* require significant additional buffering of output data yet which will still
|
||||||
|
* offer usable SSI functionality. One downside to this approach is when
|
||||||
|
* attempting to use SSI within JavaScript. The SSI tag is structured to
|
||||||
|
* resemble an HTML comment but this syntax does not constitute a comment
|
||||||
|
* within JavaScript and, hence, leaving the tag in place will result in
|
||||||
|
* problems in these cases. To work around this, any SSI tag which needs to
|
||||||
|
* output JavaScript code must do so in an encapsulated way, sending the whole
|
||||||
|
* HTML <script>...</script> section as a single include.
|
||||||
|
*/
|
||||||
|
typedef u16_t (*tSSIHandler)(int iIndex, char *pcInsert, int iInsertLen
|
||||||
|
#if LWIP_HTTPD_SSI_MULTIPART
|
||||||
|
, u16_t current_tag_part, u16_t *next_tag_part
|
||||||
|
#endif /* LWIP_HTTPD_SSI_MULTIPART */
|
||||||
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
, void *connection_state
|
||||||
|
#endif /* LWIP_HTTPD_FILE_STATE */
|
||||||
|
);
|
||||||
|
|
||||||
|
void http_set_ssi_handler(tSSIHandler pfnSSIHandler,
|
||||||
|
const char **ppcTags, int iNumTags);
|
||||||
|
|
||||||
|
/* The maximum length of the string comprising the tag name */
|
||||||
|
#ifndef LWIP_HTTPD_MAX_TAG_NAME_LEN
|
||||||
|
#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* The maximum length of string that can be returned to replace any given tag */
|
||||||
|
#ifndef LWIP_HTTPD_MAX_TAG_INSERT_LEN
|
||||||
|
#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_SSI */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SUPPORT_POST
|
||||||
|
|
||||||
|
/* These functions must be implemented by the application */
|
||||||
|
|
||||||
|
/** Called when a POST request has been received. The application can decide
|
||||||
|
* whether to accept it or not.
|
||||||
|
*
|
||||||
|
* @param connection Unique connection identifier, valid until httpd_post_end
|
||||||
|
* is called.
|
||||||
|
* @param uri The HTTP header URI receiving the POST request.
|
||||||
|
* @param http_request The raw HTTP request (the first packet, normally).
|
||||||
|
* @param http_request_len Size of 'http_request'.
|
||||||
|
* @param content_len Content-Length from HTTP header.
|
||||||
|
* @param response_uri Filename of response file, to be filled when denying the
|
||||||
|
* request
|
||||||
|
* @param response_uri_len Size of the 'response_uri' buffer.
|
||||||
|
* @param post_auto_wnd Set this to 0 to let the callback code handle window
|
||||||
|
* updates by calling 'httpd_post_data_recved' (to throttle rx speed)
|
||||||
|
* default is 1 (httpd handles window updates automatically)
|
||||||
|
* @return ERR_OK: Accept the POST request, data may be passed in
|
||||||
|
* another err_t: Deny the POST request, send back 'bad request'.
|
||||||
|
*/
|
||||||
|
err_t httpd_post_begin(void *connection, const char *uri, const char *http_request,
|
||||||
|
u16_t http_request_len, int content_len, char *response_uri,
|
||||||
|
u16_t response_uri_len, u8_t *post_auto_wnd);
|
||||||
|
|
||||||
|
/** Called for each pbuf of data that has been received for a POST.
|
||||||
|
* ATTENTION: The application is responsible for freeing the pbufs passed in!
|
||||||
|
*
|
||||||
|
* @param connection Unique connection identifier.
|
||||||
|
* @param p Received data.
|
||||||
|
* @return ERR_OK: Data accepted.
|
||||||
|
* another err_t: Data denied, http_post_get_response_uri will be called.
|
||||||
|
*/
|
||||||
|
err_t httpd_post_receive_data(void *connection, struct pbuf *p);
|
||||||
|
|
||||||
|
/** Called when all data is received or when the connection is closed.
|
||||||
|
* The application must return the filename/URI of a file to send in response
|
||||||
|
* to this POST request. If the response_uri buffer is untouched, a 404
|
||||||
|
* response is returned.
|
||||||
|
*
|
||||||
|
* @param connection Unique connection identifier.
|
||||||
|
* @param response_uri Filename of response file, to be filled when denying the request
|
||||||
|
* @param response_uri_len Size of the 'response_uri' buffer.
|
||||||
|
*/
|
||||||
|
void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len);
|
||||||
|
|
||||||
|
#ifndef LWIP_HTTPD_POST_MANUAL_WND
|
||||||
|
#define LWIP_HTTPD_POST_MANUAL_WND 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_POST_MANUAL_WND
|
||||||
|
void httpd_post_data_recved(void *connection, u16_t recved_len);
|
||||||
|
#endif /* LWIP_HTTPD_POST_MANUAL_WND */
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_SUPPORT_POST */
|
||||||
|
|
||||||
|
void httpd_init(void);
|
||||||
|
|
||||||
|
#endif /* __HTTPD_H__ */
|
125
extras/httpd/httpd_structs.h
Normal file
125
extras/httpd/httpd_structs.h
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
#ifndef __HTTPD_STRUCTS_H__
|
||||||
|
#define __HTTPD_STRUCTS_H__
|
||||||
|
|
||||||
|
#include "httpd.h"
|
||||||
|
|
||||||
|
/** This string is passed in the HTTP header as "Server: " */
|
||||||
|
#ifndef HTTPD_SERVER_AGENT
|
||||||
|
#define HTTPD_SERVER_AGENT "lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip)"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/** Set this to 1 if you want to include code that creates HTTP headers
|
||||||
|
* at runtime. Default is off: HTTP headers are then created statically
|
||||||
|
* by the makefsdata tool. Static headers mean smaller code size, but
|
||||||
|
* the (readonly) fsdata will grow a bit as every file includes the HTTP
|
||||||
|
* header. */
|
||||||
|
#ifndef LWIP_HTTPD_DYNAMIC_HEADERS
|
||||||
|
#define LWIP_HTTPD_DYNAMIC_HEADERS 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_DYNAMIC_HEADERS
|
||||||
|
/** This struct is used for a list of HTTP header strings for various
|
||||||
|
* filename extensions. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *extension;
|
||||||
|
int headerIndex;
|
||||||
|
} tHTTPHeader;
|
||||||
|
|
||||||
|
/** A list of strings used in HTTP headers */
|
||||||
|
static const char * const g_psHTTPHeaderStrings[] =
|
||||||
|
{
|
||||||
|
"Content-type: text/html\r\n\r\n",
|
||||||
|
"Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n",
|
||||||
|
"Content-type: image/gif\r\n\r\n",
|
||||||
|
"Content-type: image/png\r\n\r\n",
|
||||||
|
"Content-type: image/jpeg\r\n\r\n",
|
||||||
|
"Content-type: image/bmp\r\n\r\n",
|
||||||
|
"Content-type: image/x-icon\r\n\r\n",
|
||||||
|
"Content-type: application/octet-stream\r\n\r\n",
|
||||||
|
"Content-type: application/x-javascript\r\n\r\n",
|
||||||
|
"Content-type: application/x-javascript\r\n\r\n",
|
||||||
|
"Content-type: text/css\r\n\r\n",
|
||||||
|
"Content-type: application/x-shockwave-flash\r\n\r\n",
|
||||||
|
"Content-type: text/xml\r\n\r\n",
|
||||||
|
"Content-type: text/plain\r\n\r\n",
|
||||||
|
"HTTP/1.0 200 OK\r\n",
|
||||||
|
"HTTP/1.0 404 File not found\r\n",
|
||||||
|
"HTTP/1.0 400 Bad Request\r\n",
|
||||||
|
"HTTP/1.0 501 Not Implemented\r\n",
|
||||||
|
"HTTP/1.1 200 OK\r\n",
|
||||||
|
"HTTP/1.1 404 File not found\r\n",
|
||||||
|
"HTTP/1.1 400 Bad Request\r\n",
|
||||||
|
"HTTP/1.1 501 Not Implemented\r\n",
|
||||||
|
"Content-Length: ",
|
||||||
|
"Connection: Close\r\n",
|
||||||
|
"Connection: keep-alive\r\n",
|
||||||
|
"Server: "HTTPD_SERVER_AGENT"\r\n",
|
||||||
|
"\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Indexes into the g_psHTTPHeaderStrings array */
|
||||||
|
#define HTTP_HDR_HTML 0 /* text/html */
|
||||||
|
#define HTTP_HDR_SSI 1 /* text/html Expires... */
|
||||||
|
#define HTTP_HDR_GIF 2 /* image/gif */
|
||||||
|
#define HTTP_HDR_PNG 3 /* image/png */
|
||||||
|
#define HTTP_HDR_JPG 4 /* image/jpeg */
|
||||||
|
#define HTTP_HDR_BMP 5 /* image/bmp */
|
||||||
|
#define HTTP_HDR_ICO 6 /* image/x-icon */
|
||||||
|
#define HTTP_HDR_APP 7 /* application/octet-stream */
|
||||||
|
#define HTTP_HDR_JS 8 /* application/x-javascript */
|
||||||
|
#define HTTP_HDR_RA 9 /* application/x-javascript */
|
||||||
|
#define HTTP_HDR_CSS 10 /* text/css */
|
||||||
|
#define HTTP_HDR_SWF 11 /* application/x-shockwave-flash */
|
||||||
|
#define HTTP_HDR_XML 12 /* text/xml */
|
||||||
|
#define HTTP_HDR_DEFAULT_TYPE 13 /* text/plain */
|
||||||
|
#define HTTP_HDR_OK 14 /* 200 OK */
|
||||||
|
#define HTTP_HDR_NOT_FOUND 15 /* 404 File not found */
|
||||||
|
#define HTTP_HDR_BAD_REQUEST 16 /* 400 Bad request */
|
||||||
|
#define HTTP_HDR_NOT_IMPL 17 /* 501 Not Implemented */
|
||||||
|
#define HTTP_HDR_OK_11 18 /* 200 OK */
|
||||||
|
#define HTTP_HDR_NOT_FOUND_11 19 /* 404 File not found */
|
||||||
|
#define HTTP_HDR_BAD_REQUEST_11 20 /* 400 Bad request */
|
||||||
|
#define HTTP_HDR_NOT_IMPL_11 21 /* 501 Not Implemented */
|
||||||
|
#define HTTP_HDR_CONTENT_LENGTH 22 /* Content-Length: (HTTP 1.1)*/
|
||||||
|
#define HTTP_HDR_CONN_CLOSE 23 /* Connection: Close (HTTP 1.1) */
|
||||||
|
#define HTTP_HDR_CONN_KEEPALIVE 24 /* Connection: keep-alive (HTTP 1.1) */
|
||||||
|
#define HTTP_HDR_SERVER 25 /* Server: HTTPD_SERVER_AGENT */
|
||||||
|
#define DEFAULT_404_HTML 26 /* default 404 body */
|
||||||
|
|
||||||
|
/** A list of extension-to-HTTP header strings */
|
||||||
|
const static tHTTPHeader g_psHTTPHeaders[] =
|
||||||
|
{
|
||||||
|
{ "html", HTTP_HDR_HTML},
|
||||||
|
{ "htm", HTTP_HDR_HTML},
|
||||||
|
{ "shtml",HTTP_HDR_SSI},
|
||||||
|
{ "shtm", HTTP_HDR_SSI},
|
||||||
|
{ "ssi", HTTP_HDR_SSI},
|
||||||
|
{ "gif", HTTP_HDR_GIF},
|
||||||
|
{ "png", HTTP_HDR_PNG},
|
||||||
|
{ "jpg", HTTP_HDR_JPG},
|
||||||
|
{ "bmp", HTTP_HDR_BMP},
|
||||||
|
{ "ico", HTTP_HDR_ICO},
|
||||||
|
{ "class",HTTP_HDR_APP},
|
||||||
|
{ "cls", HTTP_HDR_APP},
|
||||||
|
{ "js", HTTP_HDR_JS},
|
||||||
|
{ "ram", HTTP_HDR_RA},
|
||||||
|
{ "css", HTTP_HDR_CSS},
|
||||||
|
{ "swf", HTTP_HDR_SWF},
|
||||||
|
{ "xml", HTTP_HDR_XML},
|
||||||
|
{ "xsl", HTTP_HDR_XML}
|
||||||
|
};
|
||||||
|
|
||||||
|
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
|
||||||
|
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
|
||||||
|
|
||||||
|
#if LWIP_HTTPD_SSI
|
||||||
|
static const char * const g_pcSSIExtensions[] = {
|
||||||
|
".shtml", ".shtm", ".ssi", ".xml"
|
||||||
|
};
|
||||||
|
#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *))
|
||||||
|
#endif /* LWIP_HTTPD_SSI */
|
||||||
|
|
||||||
|
#endif /* __HTTPD_STRUCTS_H__ */
|
2
extras/httpd/readme.txt
Normal file
2
extras/httpd/readme.txt
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
Note: this module expects your project to provide "fsdata.c" created with "makefsdata" utility.
|
||||||
|
See examples/http_server.
|
Loading…
Reference in a new issue