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