//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
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
	EspFsFile *file=connData->cgiData;
	int len;
	char buff[1024];
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	if (file==NULL) {
		//First call to this cgi. Open the file so we can read it.
		file=espFsOpen(connData->url);
		if (file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=file;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(file, buff, 1024);
	if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len);
	if (len!=1024) {
		//We're done.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
Example #2
0
void doWork(void *ignore) {

	char buff[5*1024];
	ESP_LOGD(tag, "Flash address is 0x%x", (int)flashAddress);
	if (espFsInit(flashAddress, 64*1024) != ESPFS_INIT_RESULT_OK) {
		ESP_LOGD(tag, "Failed to initialize espfs");
		return;
	}

	EspFsFile *fh = espFsOpen("files/test3.txt");;

	if (fh != NULL) {
		int sizeRead = 0;
		sizeRead = espFsRead(fh, buff, sizeof(buff));
		ESP_LOGD(tag, "Result: %.*s", sizeRead, buff);

		size_t fileSize;
		char *data;
		sizeRead = espFsAccess(fh, (void **)&data, &fileSize);
		ESP_LOGD(tag, "Result from access: %.*s", fileSize, data);

		espFsClose(fh);
		vTaskDelete(NULL);
	}
}
Example #3
0
/*
 * Load a file using the ESPFS file system.  The file to be loaded is specified
 * by the "path" parameter.  If the file can be loaded, then the full data
 * of the file is returned and the "fileSize" size pointer is updated.
 * If the file can't be loaded, NULL is returned.
 *
 * If data is returned, it does NOT need to be cleaned up because the nature of
 * the ESPFS file system is that the data is found in flash and addressable.  As
 * such there is no RAM cost for getting the data of such a file.
 *
 * Prior to calling this function, the espFsInit() function should have been
 * previously called to initialize the ESPFS environment.
 */
char *esp32_loadFileESPFS(char *path, size_t *fileSize) {
	EspFsFile *fh = espFsOpen((char *)path);
	if (fh == NULL) {
		*fileSize = 0;
		LOGD("ESPFS: Failed to open file %s", path);
		return NULL;
	}
  char *data;
  espFsAccess(fh, (void **)&data, fileSize);
  espFsClose(fh);
  // Note ... because data is mapped in memory from flash ... it will be good
  // past the file close.
  LOGD("esp32_loadFileESPFS: Read file %s for size %d", path, *fileSize);
  return data;
} // esp32_loadFileESPFS
Example #4
0
//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
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
	EspFsFile *file=connData->cgiData;
	int len;
	char buff[1024];
#ifdef GZIP_COMPRESSION
	const char *gzipSendResult = NULL;
#endif
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	if (file==NULL) {
		//First call to this cgi. Open the file so we can read it.
		file=espFsOpen(connData->url);
		if (file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=file;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
#ifdef GZIP_COMPRESSION
		gzipSendResult = sendGZIPEncodingIfNeeded(connData);
		if (gzipSendResult != NULL) {
			httpdEndHeaders(connData);
			httpdSend(connData, gzipSendResult, os_strlen(gzipSendResult));
			return HTTPD_CGI_DONE;
		}
#endif
		httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate");
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(file, buff, 1024);
	if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len);
	if (len!=1024) {
		//We're done.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
Example #5
0
int main(int argc, char **argv) {
	int f, out;
	int len;
	char buff[128];
	EspFsFile *ef;
	off_t size;

	if (argc!=3) {
		printf("Usage: %s espfs-image file\nExpands file from the espfs-image archive.\n", argv[0]);
		exit(0);
	}

	f=open(argv[1], O_RDONLY);
	if (f<=0) {
		perror(argv[1]);
		exit(1);
	}
	size=lseek(f, 0, SEEK_END);
	espFsData=mmap(NULL, size, PROT_READ, MAP_SHARED, f, 0);
	if (espFsData==MAP_FAILED) {
		perror("mmap");
		exit(1);
	}

	ef=espFsOpen(argv[2]);
	if (ef==NULL) {
		printf("Couldn't find %s in image.\n", argv[2]);
		exit(1);
	}

	out=open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0644);
	if (out<=0) {
		perror(argv[2]);
		exit(1);
	}
	
	while ((len=espFsRead(ef, buff, 128))!=0) {
		write(out, buff, len);
	}
	espFsClose(ef);
	//munmap, close, ... I can't be bothered.
}
//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
//webserver would do with static files.
int ICACHE_FLASH_ATTR cgiEspFsHook(HttpdConnData *connData) {
	EspFsFile *file=connData->cgiData;
	int len;
	char buff[1024];
	char acceptEncodingBuffer[64];
	int isGzip;
	
	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	if (file==NULL) {
		//First call to this cgi. Open the file so we can read it.
		file=espFsOpen(connData->url);
		if (file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}

		// The gzip checking code is intentionally without #ifdefs because checking
		// for FLAG_GZIP (which indicates gzip compressed file) is very easy, doesn't
		// mean additional overhead and is actually safer to be on at all times.
		// If there are no gzipped files in the image, the code bellow will not cause any harm.

		// Check if requested file was GZIP compressed
		isGzip = espFsFlags(file) & FLAG_GZIP;
		if (isGzip) {
			// Check the browser's "Accept-Encoding" header. If the client does not
			// advertise that he accepts GZIP send a warning message (telnet users for e.g.)
			httpdGetHeader(connData, "Accept-Encoding", acceptEncodingBuffer, 64);
			if (os_strstr(acceptEncodingBuffer, "gzip") == NULL) {
				//No Accept-Encoding: gzip header present
				httpdSend(connData, gzipNonSupportedMessage, -1);
				espFsClose(file);
				return HTTPD_CGI_DONE;
			}
		}

		connData->cgiData=file;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		if (isGzip) {
			httpdHeader(connData, "Content-Encoding", "gzip");
		}
		httpdHeader(connData, "Cache-Control", "max-age=3600, must-revalidate");
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(file, buff, 1024);
	if (len>0) espconn_sent(connData->conn, (uint8 *)buff, len);
	if (len!=1024) {
		//We're done.
		espFsClose(file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) {
	TplData *tpd=connData->cgiData;
	int len;
	int x, sp=0;
	char *e=NULL;
	char buff[1025];

	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		os_free(tpd);
		return HTTPD_CGI_DONE;
	}

	if (tpd==NULL) {
		//First call to this cgi. Open the file so we can read it.
		tpd=(TplData *)os_malloc(sizeof(TplData));
		tpd->file=espFsOpen(connData->url);
		tpd->tplArg=NULL;
		tpd->tokenPos=-1;
		if (tpd->file==NULL) {
			espFsClose(tpd->file);
			os_free(tpd);
			return HTTPD_CGI_NOTFOUND;
		}
		if (espFsFlags(tpd->file) & FLAG_GZIP) {
			debug("cgiEspFsTemplate: Trying to use gzip-compressed file %s as template!\n", connData->url);
			espFsClose(tpd->file);
			os_free(tpd);
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=tpd;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(tpd->file, buff, 1024);
	if (len>0) {
		sp=0;
		e=buff;
		for (x=0; x<len; x++) {
			if (tpd->tokenPos==-1) {
				//Inside ordinary text.
				if (buff[x]=='%') {
					//Send raw data up to now
					if (sp!=0) httpdSend(connData, e, sp);
					sp=0;
					//Go collect token chars.
					tpd->tokenPos=0;
				} else {
					sp++;
				}
			} else {
				if (buff[x]=='%') {
					if (tpd->tokenPos==0) {
						//This is the second % of a %% escape string.
						//Send a single % and resume with the normal program flow.
						httpdSend(connData, "%", 1);
					} else {
						//This is an actual token.
						tpd->token[tpd->tokenPos++]=0; //zero-terminate token
						((TplCallback)(connData->cgiArg))(connData, tpd->token, &tpd->tplArg);
					}
					//Go collect normal chars again.
					e=&buff[x+1];
					tpd->tokenPos=-1;
				} else {
					if (tpd->tokenPos<(sizeof(tpd->token)-1)) tpd->token[tpd->tokenPos++]=buff[x];
				}
			}
		}
	}
	//Send remaining bit.
	if (sp!=0) httpdSend(connData, e, sp);
	if (len!=1024) {
		//We're done.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		os_free(tpd);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
int ICACHE_FLASH_ATTR cgiEspFsTemplate(HttpdConnData *connData) {
	TplData *tpd=connData->cgiData;
	int len;
	int x, sp=0;
	char *e=NULL;
	char buff[1025];

	if (connData->conn==NULL) {
		//Connection aborted. Clean up.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		os_free(tpd);
		return HTTPD_CGI_DONE;
	}

	if (tpd==NULL) {
		//First call to this cgi. Open the file so we can read it.
		tpd=(TplData *)os_malloc(sizeof(TplData));
		tpd->file=espFsOpen(connData->url);
		tpd->tplArg=NULL;
		tpd->tokenPos=-1;
		if (tpd->file==NULL) {
			return HTTPD_CGI_NOTFOUND;
		}
		connData->cgiData=tpd;
		httpdStartResponse(connData, 200);
		httpdHeader(connData, "Content-Type", httpdGetMimetype(connData->url));
		httpdEndHeaders(connData);
		return HTTPD_CGI_MORE;
	}

	len=espFsRead(tpd->file, buff, 1024);
	if (len>0) {
		sp=0;
		e=buff;
		for (x=0; x<len; x++) {
			if (tpd->tokenPos==-1) {
				//Inside ordinary text.
				if (buff[x]=='%') {
					//Send raw data up to now
					if (sp!=0) espconn_sent(connData->conn, (uint8 *)e, sp);
					sp=0;
					//Go collect token chars.
					tpd->tokenPos=0;
				} else {
					sp++;
				}
			} else {
				if (buff[x]=='%') {
					tpd->token[tpd->tokenPos++]=0; //zero-terminate token
					((TplCallback)(connData->cgiArg))(connData, tpd->token, &tpd->tplArg);
					//Go collect normal chars again.
					e=&buff[x+1];
					tpd->tokenPos=-1;
				} else {
					if (tpd->tokenPos<(sizeof(tpd->token)-1)) tpd->token[tpd->tokenPos++]=buff[x];
				}
			}
		}
	}
	//Send remaining bit.
	if (sp!=0) espconn_sent(connData->conn, (uint8 *)e, sp);
	if (len!=1024) {
		//We're done.
		((TplCallback)(connData->cgiArg))(connData, NULL, &tpd->tplArg);
		espFsClose(tpd->file);
		return HTTPD_CGI_DONE;
	} else {
		//Ok, till next time.
		return HTTPD_CGI_MORE;
	}
}
Example #9
0
//cgiEspFsHtml is a simple HTML file that gets prefixed by head.tpl
int ICACHE_FLASH_ATTR cgiEspFsHtml(HttpdConnData *connData) {
  EspFsFile *file = connData->cgiData;
	char buff[2048];

	if (connData->conn==NULL) {
		// Connection aborted. Clean up.
		if (file != NULL) espFsClose(file);
		return HTTPD_CGI_DONE;
	}

	// The first time around we send the head template in one go and we open the file
	if (file == NULL) {
		int status = 200;
		// open file, return error on failure
		file = espFsOpen("/head.tpl");
		if (file == NULL) {
			os_strcpy(buff, "Header file 'head.tpl' not found\n");
			os_printf(buff);
			status = 500;
			goto error;
		}

		// read file and return it
		int len = espFsRead(file, buff, sizeof(buff));
		espFsClose(file);
		if (len == sizeof(buff)) {
			os_sprintf(buff, "Header file 'head.tpl' too large (%d>%d)!\n", len, sizeof(buff));
			os_printf(buff);
			status = 500;
			goto error;
		}

		// before returning, open the real file for next time around
		file = espFsOpen(connData->url);
		if (file == NULL) {
			os_strcpy(buff, connData->url);
			os_strcat(buff, " not found\n");
			os_printf(buff);
			status = 404;
			goto error;
		}

		connData->cgiData = file;
		httpdStartResponse(connData, status);
		httpdHeader(connData, "Content-Type", "text/html; charset=UTF-8");
		httpdEndHeaders(connData);
		httpdSend(connData, buff, len);
		printGlobalJSON(connData);
		return HTTPD_CGI_MORE;

error: // error response
		httpdStartResponse(connData, status);
		httpdHeader(connData, "Content-Type", "text/html; charset=UTF-8");
		httpdEndHeaders(connData);
		httpdSend(connData, buff, -1);
		return HTTPD_CGI_DONE;
	}

	// The second time around send actual file
	int len = espFsRead(file, buff, sizeof(buff));
	httpdSend(connData, buff, len);
	if (len == sizeof(buff)) {
		return HTTPD_CGI_MORE;
	} else {
		connData->cgiData = NULL;
		espFsClose(file);
		return HTTPD_CGI_DONE;
	}
}