Use iterators in espfs

pull/193/head
Karai Csaba 9 years ago committed by Thorsten von Eicken
parent 1ef8f5be2c
commit 8414a87981
  1. 6
      Makefile
  2. 3
      esp-link/main.c
  3. 96
      espfs/espfs.c
  4. 12
      espfs/espfs.h
  5. 10
      httpd/httpdespfs.c
  6. 2
      httpd/httpdespfs.h
  7. 34
      web-server/web-server.c
  8. 9
      web-server/web-server.h

@ -101,7 +101,7 @@ LED_SERIAL_PIN ?= 14
# --------------- esp-link modules config options --------------- # --------------- esp-link modules config options ---------------
# Optional Modules mqtt # Optional Modules mqtt
MODULES ?= mqtt rest syslog MODULES ?= mqtt rest syslog web-server
# --------------- esphttpd config options --------------- # --------------- esphttpd config options ---------------
@ -220,6 +220,10 @@ ifneq (,$(findstring syslog,$(MODULES)))
CFLAGS += -DSYSLOG CFLAGS += -DSYSLOG
endif endif
ifneq (,$(findstring web-server,$(MODULES)))
CFLAGS += -DWEBSERVER
endif
# which modules (subdirectories) of the project to include in compiling # which modules (subdirectories) of the project to include in compiling
LIBRARIES_DIR = libraries LIBRARIES_DIR = libraries
MODULES += espfs httpd user serial cmd esp-link MODULES += espfs httpd user serial cmd esp-link

@ -31,6 +31,7 @@
#include "log.h" #include "log.h"
#include "gpio.h" #include "gpio.h"
#include "cgiservices.h" #include "cgiservices.h"
#include "web-server.h"
#ifdef SYSLOG #ifdef SYSLOG
#include "syslog.h" #include "syslog.h"
@ -157,7 +158,7 @@ void user_init(void) {
//os_printf("espFsInit %s\n", res?"ERR":"ok"); //os_printf("espFsInit %s\n", res?"ERR":"ok");
// mount the http handlers // mount the http handlers
httpdInit(builtInUrls, 80); httpdInit(builtInUrls, 80);
httpdespfsInit(); webServerInit();
// init the wifi-serial transparent bridge (port 23) // init the wifi-serial transparent bridge (port 23)
serbridgeInit(23, 2323); serbridgeInit(23, 2323);

@ -155,54 +155,78 @@ int ICACHE_FLASH_ATTR espFsFlags(EspFsFile *fh) {
return (int)flags; return (int)flags;
} }
void ICACHE_FLASH_ATTR espFsIteratorInit(EspFsContext *ctx, EspFsIterator *iterator)
{
if( ctx->data == NULL )
{
iterator->ctx = NULL;
return;
}
iterator->ctx = ctx;
iterator->p = ctx->data;
}
int ICACHE_FLASH_ATTR espFsIteratorNext(EspFsIterator *iterator)
{
if( iterator->ctx == NULL )
return 0;
char * p = iterator->p;
iterator->node = p;
EspFsHeader * hdr = &iterator->header;
espfs_memcpy(iterator->ctx, hdr, p, sizeof(EspFsHeader));
if (hdr->magic!=ESPFS_MAGIC) {
#ifdef ESPFS_DBG
os_printf("Magic mismatch. EspFS image broken.\n");
#endif
return 0;
}
if (hdr->flags&FLAG_LASTFILE) {
//os_printf("End of image.\n");
return 0;
}
p += sizeof(EspFsHeader);
//Grab the name of the file.
espfs_memcpy(iterator->ctx, iterator->name, p, sizeof(iterator->name));
p+=hdr->nameLen+hdr->fileLenComp;
if ((int)p&3) p+=4-((int)p&3); //align to next 32bit val
iterator->p = p;
return 1;
}
//Open a file and return a pointer to the file desc struct. //Open a file and return a pointer to the file desc struct.
EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) { EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) {
if (ctx->data == NULL) { EspFsIterator it;
espFsIteratorInit(ctx, &it);
if (it.ctx == NULL) {
#ifdef ESPFS_DBG #ifdef ESPFS_DBG
os_printf("Call espFsInit first!\n"); os_printf("Call espFsInit first!\n");
#endif #endif
return NULL; return NULL;
} }
char *p=ctx->data;
char *hpos;
char namebuf[256];
EspFsHeader h;
EspFsFile *r;
//Strip initial slashes //Strip initial slashes
while(fileName[0]=='/') fileName++; while(fileName[0]=='/') fileName++;
//Go find that file!
while(1) { //Search the file
hpos=p; while( espFsIteratorNext(&it) )
//Grab the next file header. {
espfs_memcpy(ctx, &h, p, sizeof(EspFsHeader)); if (os_strcmp(it.name, fileName)==0) {
if (h.magic!=ESPFS_MAGIC) {
#ifdef ESPFS_DBG
os_printf("Magic mismatch. EspFS image broken.\n");
#endif
return NULL;
}
if (h.flags&FLAG_LASTFILE) {
//os_printf("End of image.\n");
return NULL;
}
//Grab the name of the file.
p+=sizeof(EspFsHeader);
espfs_memcpy(ctx, namebuf, p, sizeof(namebuf));
// os_printf("Found file '%s'. Namelen=%x fileLenComp=%x, compr=%d flags=%d\n",
// namebuf, (unsigned int)h.nameLen, (unsigned int)h.fileLenComp, h.compression, h.flags);
if (os_strcmp(namebuf, fileName)==0) {
//Yay, this is the file we need! //Yay, this is the file we need!
p+=h.nameLen; //Skip to content. EspFsFile * r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem
r=(EspFsFile *)os_malloc(sizeof(EspFsFile)); //Alloc file desc mem
//os_printf("Alloc %p[%d]\n", r, sizeof(EspFsFile)); //os_printf("Alloc %p[%d]\n", r, sizeof(EspFsFile));
if (r==NULL) return NULL; if (r==NULL) return NULL;
r->ctx = ctx; r->ctx = ctx;
r->header=(EspFsHeader *)hpos; r->header=(EspFsHeader *)it.node;
r->decompressor=h.compression; r->decompressor=it.header.compression;
r->posComp=p; r->posComp=it.node + it.header.nameLen + sizeof(EspFsHeader);
r->posStart=p; r->posStart=it.node + it.header.nameLen + sizeof(EspFsHeader);
r->posDecomp=0; r->posDecomp=0;
if (h.compression==COMPRESS_NONE) { if (it.header.compression==COMPRESS_NONE) {
r->decompData=NULL; r->decompData=NULL;
} else { } else {
#ifdef ESPFS_DBG #ifdef ESPFS_DBG
@ -212,10 +236,8 @@ EspFsFile ICACHE_FLASH_ATTR *espFsOpen(EspFsContext *ctx, char *fileName) {
} }
return r; return r;
} }
//We don't need this file. Skip name and file
p+=h.nameLen+h.fileLenComp;
if ((int)p&3) p+=4-((int)p&3); //align to next 32bit val
} }
return NULL;
} }
//Read len bytes from the given file into buff. Returns the actual amount of bytes read. //Read len bytes from the given file into buff. Returns the actual amount of bytes read.

@ -1,6 +1,8 @@
#ifndef ESPFS_H #ifndef ESPFS_H
#define ESPFS_H #define ESPFS_H
#include "espfsformat.h"
typedef enum { typedef enum {
ESPFS_INIT_RESULT_OK, ESPFS_INIT_RESULT_OK,
ESPFS_INIT_RESULT_NO_IMAGE, ESPFS_INIT_RESULT_NO_IMAGE,
@ -15,6 +17,14 @@ typedef enum {
typedef struct EspFsFile EspFsFile; typedef struct EspFsFile EspFsFile;
typedef struct EspFsContext EspFsContext; typedef struct EspFsContext EspFsContext;
typedef struct {
EspFsHeader header;
EspFsContext *ctx;
char name[256];
char *node;
char * p;
} EspFsIterator;
extern EspFsContext * espLinkCtx; extern EspFsContext * espLinkCtx;
extern EspFsContext * userPageCtx; extern EspFsContext * userPageCtx;
@ -25,5 +35,7 @@ int espFsFlags(EspFsFile *fh);
int espFsRead(EspFsFile *fh, char *buff, int len); int espFsRead(EspFsFile *fh, char *buff, int len);
void espFsClose(EspFsFile *fh); void espFsClose(EspFsFile *fh);
void espFsIteratorInit(EspFsContext *ctx, EspFsIterator *iterator);
int espFsIteratorNext(EspFsIterator *iterator);
#endif #endif

@ -13,21 +13,11 @@ Connector to let httpd use the espfs filesystem to serve the files in it.
* ---------------------------------------------------------------------------- * ----------------------------------------------------------------------------
*/ */
#include "httpdespfs.h" #include "httpdespfs.h"
#include "config.h"
// The static files marked with FLAG_GZIP are compressed and will be served with GZIP compression. // The static files marked with FLAG_GZIP are compressed and will be served with GZIP compression.
// If the client does not advertise that he accepts GZIP send following warning message (telnet users for e.g.) // If the client does not advertise that he accepts GZIP send following warning message (telnet users for e.g.)
static const char *gzipNonSupportedMessage = "HTTP/1.0 501 Not implemented\r\nServer: esp8266-httpd/"HTTPDVER"\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 52\r\n\r\nYour browser does not accept gzip-compressed data.\r\n"; static const char *gzipNonSupportedMessage = "HTTP/1.0 501 Not implemented\r\nServer: esp8266-httpd/"HTTPDVER"\r\nConnection: close\r\nContent-Type: text/plain\r\nContent-Length: 52\r\n\r\nYour browser does not accept gzip-compressed data.\r\n";
void ICACHE_FLASH_ATTR httpdespfsInit()
{
espFsInit(userPageCtx, (void *)getUserPageSectionStart(), ESPFS_FLASH);
if( espFsIsValid( userPageCtx ) )
os_printf("Valid user file system found!\n");
else
os_printf("No user file system found!\n");
}
//This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding //This is a catch-all cgi function. It takes the url passed to it, looks up the corresponding
//path in the filesystem and if it exists, passes the file through. This simulates what a normal //path in the filesystem and if it exists, passes the file through. This simulates what a normal
//webserver would do with static files. //webserver would do with static files.

@ -7,8 +7,6 @@
#include "cgi.h" #include "cgi.h"
#include "httpd.h" #include "httpd.h"
void httpdespfsInit();
int cgiEspFsHook(HttpdConnData *connData); int cgiEspFsHook(HttpdConnData *connData);
//int cgiEspFsTemplate(HttpdConnData *connData); //int cgiEspFsTemplate(HttpdConnData *connData);
//int ICACHE_FLASH_ATTR cgiEspFsHtml(HttpdConnData *connData); //int ICACHE_FLASH_ATTR cgiEspFsHtml(HttpdConnData *connData);

@ -0,0 +1,34 @@
#include "web-server.h"
#include "espfs.h"
#include "config.h"
void ICACHE_FLASH_ATTR webServerBrowseFiles()
{
EspFsIterator it;
espFsIteratorInit(userPageCtx, &it);
{
while( espFsIteratorNext(&it) )
{
if( strlen(it.name) >= 6 )
{
if( os_strcmp( it.name + strlen(it.name)-5, ".html" ) == 0 )
{
os_printf("%s\n", it.name); // TODO
}
}
}
}
}
void ICACHE_FLASH_ATTR webServerInit()
{
espFsInit(userPageCtx, (void *)getUserPageSectionStart(), ESPFS_FLASH);
if( espFsIsValid( userPageCtx ) ) {
os_printf("Valid user file system found!\n");
webServerBrowseFiles();
}
else
os_printf("No user file system found!\n");
}

@ -0,0 +1,9 @@
#ifndef WEB_SERVER_H
#define WEB_SERVER_H
#include <esp8266.h>
void webServerInit();
#endif /* WEB_SERVER_H */
Loading…
Cancel
Save