mirror of
https://github.com/ep00ch/lwip-contrib-mac.git
synced 2024-08-27 11:29:21 +00:00
httpd + makefsdata:
- added delayed open/read functionality (so that SSI code can delay sending of a file until internal data is available); - clean up fs-handling: additional read is not required with our current fs implementation; - kill oldest connection when running out of http_state memory; - splitted SSI state into its own struct so that non-SSI pages don't consume too much memory (SSI buffer can get quit big); - added support for HTTP/1.1 persistent connections (use the '-11' switch of makefsdata; not available for SSI files since we cannot calculate the file length in advance); - splitted the unreadably-long function http_send_data into multiple smaller functions;
This commit is contained in:
parent
227475a45e
commit
d1bf1ee0da
@ -65,6 +65,10 @@ struct fs_table fs_memory[LWIP_MAX_OPEN_FILES];
|
|||||||
#if LWIP_HTTPD_CUSTOM_FILES
|
#if LWIP_HTTPD_CUSTOM_FILES
|
||||||
int fs_open_custom(struct fs_file *file, const char *name);
|
int fs_open_custom(struct fs_file *file, const char *name);
|
||||||
void fs_close_custom(struct fs_file *file);
|
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 */
|
#endif /* LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
@ -151,14 +155,27 @@ fs_close(struct fs_file *file)
|
|||||||
fs_free(file);
|
fs_free(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
|
int
|
||||||
fs_read(struct fs_file *file, char *buffer, int count)
|
fs_read(struct fs_file *file, char *buffer, int count)
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
{
|
{
|
||||||
int read;
|
int read;
|
||||||
|
|
||||||
if(file->index == file->len) {
|
if(file->index == file->len) {
|
||||||
return -1;
|
return FS_READ_EOF;
|
||||||
}
|
}
|
||||||
|
#if LWIP_HTTPD_FS_ASYNC_READ && LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (!fs_canread_custom(file)) {
|
||||||
|
if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
|
||||||
|
return FS_READ_DELAYED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ && LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
|
||||||
read = file->len - file->index;
|
read = file->len - file->index;
|
||||||
if(read > count) {
|
if(read > count) {
|
||||||
@ -170,8 +187,27 @@ fs_read(struct fs_file *file, char *buffer, int count)
|
|||||||
|
|
||||||
return(read);
|
return(read);
|
||||||
}
|
}
|
||||||
|
#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */
|
||||||
/*-----------------------------------------------------------------------------------*/
|
/*-----------------------------------------------------------------------------------*/
|
||||||
int fs_bytes_left(struct fs_file *file)
|
#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 && LWIP_HTTPD_CUSTOM_FILES
|
||||||
|
if (!fs_canread_custom(file)) {
|
||||||
|
if (fs_wait_read_custom(file, callback_fn, callback_arg)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ && LWIP_HTTPD_CUSTOM_FILES */
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||||
|
/*-----------------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
fs_bytes_left(struct fs_file *file)
|
||||||
{
|
{
|
||||||
return file->len - file->index;
|
return file->len - file->index;
|
||||||
}
|
}
|
||||||
|
@ -45,6 +45,14 @@
|
|||||||
#define LWIP_HTTPD_CUSTOM_FILES 0
|
#define LWIP_HTTPD_CUSTOM_FILES 0
|
||||||
#endif
|
#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
|
/** Set this to 1 to include an application state argument per file
|
||||||
* that is opened. This allows to keep a state per connection/file.
|
* that is opened. This allows to keep a state per connection/file.
|
||||||
*/
|
*/
|
||||||
@ -59,6 +67,16 @@
|
|||||||
#define HTTPD_PRECALCULATED_CHECKSUM 0
|
#define HTTPD_PRECALCULATED_CHECKSUM 0
|
||||||
#endif
|
#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
|
#if HTTPD_PRECALCULATED_CHECKSUM
|
||||||
struct fsdata_chksum {
|
struct fsdata_chksum {
|
||||||
u32_t offset;
|
u32_t offset;
|
||||||
@ -85,9 +103,22 @@ struct fs_file {
|
|||||||
#endif /* LWIP_HTTPD_FILE_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 */
|
||||||
|
|
||||||
struct fs_file *fs_open(const char *name);
|
struct fs_file *fs_open(const char *name);
|
||||||
void fs_close(struct fs_file *file);
|
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);
|
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);
|
int fs_bytes_left(struct fs_file *file);
|
||||||
|
|
||||||
#if LWIP_HTTPD_FILE_STATE
|
#if LWIP_HTTPD_FILE_STATE
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -54,6 +54,7 @@ static const char * const g_psHTTPHeaderStrings[] =
|
|||||||
"HTTP/1.1 501 Not Implemented\r\n",
|
"HTTP/1.1 501 Not Implemented\r\n",
|
||||||
"Content-Length: ",
|
"Content-Length: ",
|
||||||
"Connection: Close\r\n",
|
"Connection: Close\r\n",
|
||||||
|
"Connection: keep-alive\r\n",
|
||||||
"Server: "HTTPD_SERVER_AGENT"\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"
|
"\r\n<html><body><h2>404: The requested file cannot be found.</h2></body></html>\r\n"
|
||||||
};
|
};
|
||||||
@ -83,8 +84,9 @@ static const char * const g_psHTTPHeaderStrings[] =
|
|||||||
#define HTTP_HDR_NOT_IMPL_11 21 /* 501 Not Implemented */
|
#define HTTP_HDR_NOT_IMPL_11 21 /* 501 Not Implemented */
|
||||||
#define HTTP_HDR_CONTENT_LENGTH 22 /* Content-Length: (HTTP 1.1)*/
|
#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_CLOSE 23 /* Connection: Close (HTTP 1.1) */
|
||||||
#define HTTP_HDR_SERVER 24 /* Server: HTTPD_SERVER_AGENT */
|
#define HTTP_HDR_CONN_KEEPALIVE 24 /* Connection: keep-alive (HTTP 1.1) */
|
||||||
#define DEFAULT_404_HTML 25 /* default 404 body */
|
#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 */
|
/** A list of extension-to-HTTP header strings */
|
||||||
const static tHTTPHeader g_psHTTPHeaders[] =
|
const static tHTTPHeader g_psHTTPHeaders[] =
|
||||||
@ -105,11 +107,19 @@ const static tHTTPHeader g_psHTTPHeaders[] =
|
|||||||
{ "ram", HTTP_HDR_RA},
|
{ "ram", HTTP_HDR_RA},
|
||||||
{ "css", HTTP_HDR_CSS},
|
{ "css", HTTP_HDR_CSS},
|
||||||
{ "swf", HTTP_HDR_SWF},
|
{ "swf", HTTP_HDR_SWF},
|
||||||
{ "xml", HTTP_HDR_XML}
|
{ "xml", HTTP_HDR_XML},
|
||||||
|
{ "xsl", HTTP_HDR_XML}
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
|
#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader))
|
||||||
|
|
||||||
#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */
|
#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__ */
|
#endif /* __HTTPD_STRUCTS_H__ */
|
||||||
|
@ -62,6 +62,7 @@
|
|||||||
|
|
||||||
/* define this to get the header variables we use to build HTTP headers */
|
/* define this to get the header variables we use to build HTTP headers */
|
||||||
#define LWIP_HTTPD_DYNAMIC_HEADERS 1
|
#define LWIP_HTTPD_DYNAMIC_HEADERS 1
|
||||||
|
#define LWIP_HTTPD_SSI 1
|
||||||
#include "../httpd_structs.h"
|
#include "../httpd_structs.h"
|
||||||
|
|
||||||
#include "../../../../lwip/src/core/inet_chksum.c"
|
#include "../../../../lwip/src/core/inet_chksum.c"
|
||||||
@ -103,6 +104,7 @@ char hdr_buf[4096];
|
|||||||
unsigned char processSubs = 1;
|
unsigned char processSubs = 1;
|
||||||
unsigned char includeHttpHeader = 1;
|
unsigned char includeHttpHeader = 1;
|
||||||
unsigned char useHttp11 = 0;
|
unsigned char useHttp11 = 0;
|
||||||
|
unsigned char supportSsi = 1;
|
||||||
unsigned char precalcChksum = 0;
|
unsigned char precalcChksum = 0;
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
@ -134,6 +136,8 @@ int main(int argc, char *argv[])
|
|||||||
includeHttpHeader = 0;
|
includeHttpHeader = 0;
|
||||||
} else if (strstr(argv[i], "-11")) {
|
} else if (strstr(argv[i], "-11")) {
|
||||||
useHttp11 = 1;
|
useHttp11 = 1;
|
||||||
|
} else if (strstr(argv[i], "-nossi")) {
|
||||||
|
supportSsi = 0;
|
||||||
} else if (strstr(argv[i], "-c")) {
|
} else if (strstr(argv[i], "-c")) {
|
||||||
precalcChksum = 1;
|
precalcChksum = 1;
|
||||||
} else if((argv[i][1] == 'f') && (argv[i][2] == ':')) {
|
} else if((argv[i][1] == 'f') && (argv[i][2] == ':')) {
|
||||||
@ -155,6 +159,7 @@ int main(int argc, char *argv[])
|
|||||||
printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE);
|
printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE);
|
||||||
printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE);
|
printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE);
|
||||||
printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE);
|
printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE);
|
||||||
|
printf(" switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE);
|
||||||
printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE);
|
printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE);
|
||||||
printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE);
|
printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE);
|
||||||
printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE);
|
printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE);
|
||||||
@ -463,6 +468,17 @@ int file_write_http_header(FILE *data_file, const char *filename, int file_size,
|
|||||||
u16_t acc;
|
u16_t acc;
|
||||||
const char *file_ext;
|
const char *file_ext;
|
||||||
int j;
|
int j;
|
||||||
|
u8_t keepalive = useHttp11;
|
||||||
|
|
||||||
|
if (keepalive) {
|
||||||
|
size_t loop;
|
||||||
|
for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) {
|
||||||
|
if (strstr(filename, g_pcSSIExtensions[loop])) {
|
||||||
|
/* no keepalive connection for SSI files */
|
||||||
|
keepalive = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
memset(hdr_buf, 0, sizeof(hdr_buf));
|
memset(hdr_buf, 0, sizeof(hdr_buf));
|
||||||
|
|
||||||
@ -529,18 +545,23 @@ int file_write_http_header(FILE *data_file, const char *filename, int file_size,
|
|||||||
|
|
||||||
if (useHttp11) {
|
if (useHttp11) {
|
||||||
char intbuf[MAX_PATH_LEN];
|
char intbuf[MAX_PATH_LEN];
|
||||||
|
int content_len = file_size;
|
||||||
memset(intbuf, 0, sizeof(intbuf));
|
memset(intbuf, 0, sizeof(intbuf));
|
||||||
|
|
||||||
|
if (!keepalive) {
|
||||||
|
content_len *= 2;
|
||||||
|
}
|
||||||
|
{
|
||||||
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
|
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
|
||||||
cur_len = strlen(cur_string);
|
cur_len = strlen(cur_string);
|
||||||
fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, file_size, cur_len+2);
|
fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, content_len, cur_len+2);
|
||||||
written += file_put_ascii(data_file, cur_string, cur_len, &i);
|
written += file_put_ascii(data_file, cur_string, cur_len, &i);
|
||||||
if (precalcChksum) {
|
if (precalcChksum) {
|
||||||
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
|
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
|
||||||
hdr_len += cur_len;
|
hdr_len += cur_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
_itoa(file_size, intbuf, 10);
|
_itoa(content_len, intbuf, 10);
|
||||||
strcat(intbuf, "\r\n");
|
strcat(intbuf, "\r\n");
|
||||||
cur_len = strlen(intbuf);
|
cur_len = strlen(intbuf);
|
||||||
written += file_put_ascii(data_file, intbuf, cur_len, &i);
|
written += file_put_ascii(data_file, intbuf, cur_len, &i);
|
||||||
@ -549,8 +570,13 @@ int file_write_http_header(FILE *data_file, const char *filename, int file_size,
|
|||||||
memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
|
memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
|
||||||
hdr_len += cur_len;
|
hdr_len += cur_len;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keepalive) {
|
||||||
|
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE];
|
||||||
|
} else {
|
||||||
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
|
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE];
|
||||||
|
}
|
||||||
cur_len = strlen(cur_string);
|
cur_len = strlen(cur_string);
|
||||||
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
|
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
|
||||||
written += file_put_ascii(data_file, cur_string, cur_len, &i);
|
written += file_put_ascii(data_file, cur_string, cur_len, &i);
|
||||||
|
Loading…
Reference in New Issue
Block a user