A version of LWIP, provided for backwards compatibility.

Dependents:   AA_DemoBoard DemoBoard HelloServerDemo DemoBoard_RangeIndicator ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers HTTPFS.h Source File

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       snprintf(filename, FILENAMELANGTH, "%s%s\0", _dir, con->getURL() + strlen(_prefix));
00058       data->file = fopen(filename, "r");
00059       if(!data->file) {
00060         delete data;
00061         return HTTP_NotFound;
00062       }
00063       data->fleft  = fleft(data->file);
00064       data->bleft  = 0;
00065       data->offset = 0;
00066       
00067       con->data = data;
00068       con->setLength(data->fleft);
00069       loadFromFile(con);
00070       return HTTP_OK;
00071     }
00072 
00073     /**
00074      * Send the maximum available data chunk to the Client.
00075      * If it is the last chunk close connection by returning HTTP_SuccessEnded
00076      * @param con The connection to handle
00077      * @param maximum The maximal available sendbuffer size.
00078      * @return HTTP_Success when mor data is available or HTTP_SuccessEnded when the file is complete.
00079      */
00080     virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
00081       HTTPFileSystemData *data = static_cast<HTTPFileSystemData *>(con->data);
00082       err_t err;
00083       u16_t len = min(data->bleft, maximum);
00084 //      printf("Send File\n");
00085       if(len) {
00086         do {
00087           err = con->write(
00088             &data->buffer[data->offset], len, (((!data->fleft)&&(data->bleft==len))? 
00089             (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE) : (TCP_WRITE_FLAG_COPY)));
00090           if(err == ERR_MEM) {
00091             len /= 2;
00092           }
00093         } while (err == ERR_MEM && len > 1);  
00094   
00095         if(err == ERR_OK) {
00096           data->offset += len;
00097           data->bleft  -= len;
00098         }
00099       }
00100       return loadFromFile(con);
00101     }
00102 
00103     /**
00104      * Returns the left size of a file.
00105      * @param fd The filehandler of which we want to know the filesize.
00106      * @return The filesize of fd.
00107      */
00108     long fleft(FILE *fd) const {
00109       long len, cur;
00110       cur = ftell(fd);
00111       fseek(fd, 0, SEEK_END);
00112       len = ftell(fd);
00113       fseek(fd, cur, SEEK_SET);
00114       return len;
00115     }
00116     
00117     /**
00118      * Fill the buffer if the buffer is empty.
00119      * If the file is complete close the filehandler and return HTTP_SuccessEnded.
00120      */
00121     HTTPHandle loadFromFile(HTTPConnection *con) const {
00122       HTTPFileSystemData *data = static_cast<HTTPFileSystemData *>(con->data);
00123       if(!data->bleft) {
00124         if(data->fleft) {
00125           int len = fread(&data->buffer[0], sizeof(char), HTTP_BUFFER_SIZE, data->file);
00126           data->fleft -= len;
00127           data->bleft  = len;
00128           data->offset = 0;
00129         } else {
00130           if(data->file) {
00131             fclose(data->file);
00132             data->file = 0;
00133           }
00134           return HTTP_SuccessEnded;
00135         }
00136       }
00137       return HTTP_Success;
00138     }
00139     
00140     /** The Directory which will replace the prefix of the URL */
00141     const char *_dir;
00142 };
00143 
00144 #endif