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
|
||||
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 */
|
||||
|
||||
/*-----------------------------------------------------------------------------------*/
|
||||
|
@ -151,14 +155,27 @@ fs_close(struct fs_file *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
|
||||
fs_read(struct fs_file *file, char *buffer, int count)
|
||||
#endif /* LWIP_HTTPD_FS_ASYNC_READ */
|
||||
{
|
||||
int read;
|
||||
|
||||
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;
|
||||
if(read > count) {
|
||||
|
@ -170,8 +187,27 @@ fs_read(struct fs_file *file, char *buffer, int count)
|
|||
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -45,6 +45,14 @@
|
|||
#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.
|
||||
*/
|
||||
|
@ -59,6 +67,16 @@
|
|||
#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;
|
||||
|
@ -85,9 +103,22 @@ struct fs_file {
|
|||
#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);
|
||||
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
|
||||
|
|
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",
|
||||
"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"
|
||||
};
|
||||
|
@ -83,8 +84,9 @@ static const char * const g_psHTTPHeaderStrings[] =
|
|||
#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_SERVER 24 /* Server: HTTPD_SERVER_AGENT */
|
||||
#define DEFAULT_404_HTML 25 /* default 404 body */
|
||||
#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[] =
|
||||
|
@ -105,11 +107,19 @@ const static tHTTPHeader g_psHTTPHeaders[] =
|
|||
{ "ram", HTTP_HDR_RA},
|
||||
{ "css", HTTP_HDR_CSS},
|
||||
{ "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))
|
||||
|
||||
#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__ */
|
||||
|
|
|
@ -62,6 +62,7 @@
|
|||
|
||||
/* define this to get the header variables we use to build HTTP headers */
|
||||
#define LWIP_HTTPD_DYNAMIC_HEADERS 1
|
||||
#define LWIP_HTTPD_SSI 1
|
||||
#include "../httpd_structs.h"
|
||||
|
||||
#include "../../../../lwip/src/core/inet_chksum.c"
|
||||
|
@ -103,6 +104,7 @@ char hdr_buf[4096];
|
|||
unsigned char processSubs = 1;
|
||||
unsigned char includeHttpHeader = 1;
|
||||
unsigned char useHttp11 = 0;
|
||||
unsigned char supportSsi = 1;
|
||||
unsigned char precalcChksum = 0;
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
|
@ -134,6 +136,8 @@ int main(int argc, char *argv[])
|
|||
includeHttpHeader = 0;
|
||||
} else if (strstr(argv[i], "-11")) {
|
||||
useHttp11 = 1;
|
||||
} else if (strstr(argv[i], "-nossi")) {
|
||||
supportSsi = 0;
|
||||
} else if (strstr(argv[i], "-c")) {
|
||||
precalcChksum = 1;
|
||||
} 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 -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 -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 -f: target filename (default is \"fsdata.c\")" 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;
|
||||
const char *file_ext;
|
||||
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));
|
||||
|
||||
|
@ -529,28 +545,38 @@ int file_write_http_header(FILE *data_file, const char *filename, int file_size,
|
|||
|
||||
if (useHttp11) {
|
||||
char intbuf[MAX_PATH_LEN];
|
||||
int content_len = file_size;
|
||||
memset(intbuf, 0, sizeof(intbuf));
|
||||
|
||||
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
|
||||
cur_len = strlen(cur_string);
|
||||
fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, file_size, cur_len+2);
|
||||
written += file_put_ascii(data_file, cur_string, cur_len, &i);
|
||||
if (precalcChksum) {
|
||||
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
|
||||
hdr_len += cur_len;
|
||||
if (!keepalive) {
|
||||
content_len *= 2;
|
||||
}
|
||||
{
|
||||
cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH];
|
||||
cur_len = strlen(cur_string);
|
||||
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);
|
||||
if (precalcChksum) {
|
||||
memcpy(&hdr_buf[hdr_len], cur_string, cur_len);
|
||||
hdr_len += cur_len;
|
||||
}
|
||||
|
||||
_itoa(content_len, intbuf, 10);
|
||||
strcat(intbuf, "\r\n");
|
||||
cur_len = strlen(intbuf);
|
||||
written += file_put_ascii(data_file, intbuf, cur_len, &i);
|
||||
i = 0;
|
||||
if (precalcChksum) {
|
||||
memcpy(&hdr_buf[hdr_len], intbuf, cur_len);
|
||||
hdr_len += cur_len;
|
||||
}
|
||||
}
|
||||
|
||||
_itoa(file_size, intbuf, 10);
|
||||
strcat(intbuf, "\r\n");
|
||||
cur_len = strlen(intbuf);
|
||||
written += file_put_ascii(data_file, intbuf, cur_len, &i);
|
||||
i = 0;
|
||||
if (precalcChksum) {
|
||||
memcpy(&hdr_buf[hdr_len], intbuf, 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);
|
||||
fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len);
|
||||
written += file_put_ascii(data_file, cur_string, cur_len, &i);
|
||||
|
|
Loading…
Reference in New Issue