John Lowe
/
WebSockets2
Embedded WebSockets Experiment
Embed:
(wiki syntax)
Show/hide line numbers
HTTPFS.h
00001 #ifndef HTTPFILESYSTEM_H 00002 #define HTTPFILESYSTEM_H 00003 00004 #include "mbed.h" 00005 00006 #include "HTTPServer.h" 00007 00008 #define HTTP_BUFFER_SIZE 700 00009 #define FILENAMELANGTH 100 00010 00011 /** 00012 * This class will store the data which are required for an request. 00013 * We are not in every case able to return all data at once, that means we have to store 00014 * the actual level of transmission. 00015 */ 00016 class HTTPFileSystemData : public HTTPData { 00017 public: 00018 int fleft; 00019 int bleft; 00020 int offset; 00021 FILE *file; 00022 char buffer[HTTP_BUFFER_SIZE]; 00023 00024 virtual ~HTTPFileSystemData() { 00025 if(file) { 00026 fclose(file); 00027 file = 0; 00028 } 00029 } 00030 }; 00031 00032 /** 00033 * This class will deliver files form the virtual file system. 00034 * Furthermore it is a simple example how to implement an HTTPHandler for big data requests. 00035 */ 00036 class HTTPFileSystemHandler : public HTTPHandler { 00037 public: 00038 /** 00039 * Create a new HTTPFileSzstemHandler. 00040 * @param prefix The Prefix is the URL Proefix in witch the Handler will work. 00041 * @param dir The Prefix will be directly mappt on the dir. 00042 */ 00043 HTTPFileSystemHandler(const char *path, const char *dir) : HTTPHandler(path), _dir(dir) {} 00044 HTTPFileSystemHandler(HTTPServer *server, const char *path, const char *dir) : HTTPHandler(path), _dir(dir) { server->addHandler(this); } 00045 00046 private: 00047 /** 00048 * Check if a requested file exists. 00049 * If it exists open it and store the data back in the HTTPConnection. 00050 * We would not store connection specific data into the Handler. 00051 * If the file exists and we cann serve a page return HTTP_OK else HTTP_NotFound. 00052 * @param con The Connection which will be handled. 00053 */ 00054 virtual HTTPStatus init(HTTPConnection *con) const { 00055 char filename[FILENAMELANGTH]; 00056 HTTPFileSystemData *data = new HTTPFileSystemData(); 00057 printf("FS: %s\n", con->getURL()); 00058 snprintf(filename, FILENAMELANGTH, "%s%s\0", _dir, con->getURL() + strlen(_prefix)); 00059 00060 printf("filename: %s\n", filename); 00061 00062 data->file = fopen(filename, "r"); 00063 if(!data->file) { 00064 delete data; 00065 return HTTP_NotFound; 00066 } 00067 data->fleft = fleft(data->file); 00068 data->bleft = 0; 00069 data->offset = 0; 00070 00071 con->data = data; 00072 con->setLength(data->fleft); 00073 loadFromFile(con); 00074 return HTTP_OK; 00075 } 00076 00077 /** 00078 * Send the maximum available data chunk to the Client. 00079 * If it is the last chunk close connection by returning HTTP_SuccessEnded 00080 * @param con The connection to handle 00081 * @param maximum The maximal available sendbuffer size. 00082 * @return HTTP_Success when mor data is available or HTTP_SuccessEnded when the file is complete. 00083 */ 00084 virtual HTTPHandle send(HTTPConnection *con, int maximum) const { 00085 HTTPFileSystemData *data = static_cast<HTTPFileSystemData *>(con->data); 00086 err_t err; 00087 u16_t len = min(data->bleft, maximum); 00088 if(len) { 00089 do { 00090 err = con->write( 00091 &data->buffer[data->offset], len, (((!data->fleft)&&(data->bleft==len))? 00092 (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE) : (TCP_WRITE_FLAG_COPY))); 00093 if(err == ERR_MEM) { 00094 len /= 2; 00095 } 00096 } while (err == ERR_MEM && len > 1); 00097 00098 if(err == ERR_OK) { 00099 data->offset += len; 00100 data->bleft -= len; 00101 } 00102 } 00103 return loadFromFile(con); 00104 } 00105 00106 /** 00107 * Returns the left size of a file. 00108 * @param fd The filehandler of which we want to know the filesize. 00109 * @return The filesize of fd. 00110 */ 00111 long fleft(FILE *fd) const { 00112 long len, cur; 00113 cur = ftell(fd); 00114 fseek(fd, 0, SEEK_END); 00115 len = ftell(fd); 00116 fseek(fd, cur, SEEK_SET); 00117 return len; 00118 } 00119 00120 /** 00121 * Fill the buffer if the buffer is empty. 00122 * If the file is complete close the filehandler and return HTTP_SuccessEnded. 00123 */ 00124 HTTPHandle loadFromFile(HTTPConnection *con) const { 00125 HTTPFileSystemData *data = static_cast<HTTPFileSystemData *>(con->data); 00126 if(!data->bleft) { 00127 if(data->fleft) { 00128 int len = fread(&data->buffer[0], sizeof(char), HTTP_BUFFER_SIZE, data->file); 00129 data->fleft -= len; 00130 data->bleft = len; 00131 data->offset = 0; 00132 } else { 00133 if(data->file) { 00134 fclose(data->file); 00135 data->file = 0; 00136 } 00137 return HTTP_SuccessEnded; 00138 } 00139 } 00140 return HTTP_Success; 00141 } 00142 00143 /** The Directory which will replace the prefix of the URL */ 00144 const char *_dir; 00145 }; 00146 00147 #endif
Generated on Wed Jul 13 2022 23:42:33 by 1.7.2