Example of HTTPServer with additional features: * SNTPClient, DST rules * Link status indication * Local or SDCard-based WebServer * RPC-able class * Static and Dynamic HTML page

Dependencies:   mbed

Committer:
iva2k
Date:
Tue Jan 12 07:41:55 2010 +0000
Revision:
2:360fda42fefd
Parent:
0:886e4b3119ad

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
iva2k 0:886e4b3119ad 1 #ifndef HTTPFILESYSTEM_H
iva2k 0:886e4b3119ad 2 #define HTTPFILESYSTEM_H
iva2k 0:886e4b3119ad 3
iva2k 0:886e4b3119ad 4 #include "mbed.h"
iva2k 0:886e4b3119ad 5
iva2k 0:886e4b3119ad 6 #include "HTTPServer.h"
iva2k 0:886e4b3119ad 7
iva2k 0:886e4b3119ad 8 #define HTTP_BUFFER_SIZE 700
iva2k 0:886e4b3119ad 9 #define FILENAMELANGTH 100
iva2k 0:886e4b3119ad 10
iva2k 0:886e4b3119ad 11 /**
iva2k 0:886e4b3119ad 12 * This class will store the data which are required for an request.
iva2k 0:886e4b3119ad 13 * We are not in every case able to return all data at once, that means we have to store
iva2k 0:886e4b3119ad 14 * the actual level of transmission.
iva2k 0:886e4b3119ad 15 */
iva2k 0:886e4b3119ad 16 class HTTPFileSystemData : public HTTPData {
iva2k 0:886e4b3119ad 17 public:
iva2k 0:886e4b3119ad 18 int fleft;
iva2k 0:886e4b3119ad 19 int bleft;
iva2k 0:886e4b3119ad 20 int offset;
iva2k 0:886e4b3119ad 21 FILE *file;
iva2k 0:886e4b3119ad 22 char buffer[HTTP_BUFFER_SIZE];
iva2k 0:886e4b3119ad 23
iva2k 0:886e4b3119ad 24 virtual ~HTTPFileSystemData() {
iva2k 0:886e4b3119ad 25 if(file) {
iva2k 0:886e4b3119ad 26 fclose(file);
iva2k 0:886e4b3119ad 27 file = 0;
iva2k 0:886e4b3119ad 28 }
iva2k 0:886e4b3119ad 29 }
iva2k 0:886e4b3119ad 30 };
iva2k 0:886e4b3119ad 31
iva2k 0:886e4b3119ad 32 /**
iva2k 0:886e4b3119ad 33 * This class will deliver files form the virtual file system.
iva2k 0:886e4b3119ad 34 * Furthermore it is a simple example how to implement an HTTPHandler for big data requests.
iva2k 0:886e4b3119ad 35 */
iva2k 0:886e4b3119ad 36 class HTTPFileSystemHandler : public HTTPHandler {
iva2k 0:886e4b3119ad 37 public:
iva2k 0:886e4b3119ad 38 /**
iva2k 0:886e4b3119ad 39 * Create a new HTTPFileSzstemHandler.
iva2k 0:886e4b3119ad 40 * @param prefix The Prefix is the URL Proefix in witch the Handler will work.
iva2k 0:886e4b3119ad 41 * @param dir The Prefix will be directly mappt on the dir.
iva2k 0:886e4b3119ad 42 */
iva2k 0:886e4b3119ad 43 HTTPFileSystemHandler(const char *path, const char *dir) : HTTPHandler(path), _dir(dir) {}
iva2k 0:886e4b3119ad 44 HTTPFileSystemHandler(HTTPServer *server, const char *path, const char *dir) : HTTPHandler(path), _dir(dir) { server->addHandler(this); }
iva2k 0:886e4b3119ad 45
iva2k 0:886e4b3119ad 46 private:
iva2k 0:886e4b3119ad 47 /**
iva2k 0:886e4b3119ad 48 * Check if a requested file exists.
iva2k 0:886e4b3119ad 49 * If it exists open it and store the data back in the HTTPConnection.
iva2k 0:886e4b3119ad 50 * We would not store connection specific data into the Handler.
iva2k 0:886e4b3119ad 51 * If the file exists and we cann serve a page return HTTP_OK else HTTP_NotFound.
iva2k 0:886e4b3119ad 52 * @param con The Connection which will be handled.
iva2k 0:886e4b3119ad 53 */
iva2k 0:886e4b3119ad 54 virtual HTTPStatus init(HTTPConnection *con) const {
iva2k 0:886e4b3119ad 55 char filename[FILENAMELANGTH];
iva2k 0:886e4b3119ad 56 HTTPFileSystemData *data = new HTTPFileSystemData();
iva2k 0:886e4b3119ad 57 snprintf(filename, FILENAMELANGTH, "%s%s\0", _dir, con->getURL() + strlen(_prefix));
iva2k 0:886e4b3119ad 58 data->file = fopen(filename, "r");
iva2k 0:886e4b3119ad 59 if(!data->file) {
iva2k 0:886e4b3119ad 60 delete data;
iva2k 0:886e4b3119ad 61 return HTTP_NotFound;
iva2k 0:886e4b3119ad 62 }
iva2k 0:886e4b3119ad 63 data->fleft = fleft(data->file);
iva2k 0:886e4b3119ad 64 data->bleft = 0;
iva2k 0:886e4b3119ad 65 data->offset = 0;
iva2k 0:886e4b3119ad 66
iva2k 0:886e4b3119ad 67 con->data = data;
iva2k 0:886e4b3119ad 68 con->setLength(data->fleft);
iva2k 0:886e4b3119ad 69 loadFromFile(con);
iva2k 0:886e4b3119ad 70 return HTTP_OK;
iva2k 0:886e4b3119ad 71 }
iva2k 0:886e4b3119ad 72
iva2k 0:886e4b3119ad 73 /**
iva2k 0:886e4b3119ad 74 * Send the maximum available data chunk to the Client.
iva2k 0:886e4b3119ad 75 * If it is the last chunk close connection by returning HTTP_SuccessEnded
iva2k 0:886e4b3119ad 76 * @param con The connection to handle
iva2k 0:886e4b3119ad 77 * @param maximum The maximal available sendbuffer size.
iva2k 0:886e4b3119ad 78 * @return HTTP_Success when mor data is available or HTTP_SuccessEnded when the file is complete.
iva2k 0:886e4b3119ad 79 */
iva2k 0:886e4b3119ad 80 virtual HTTPHandle send(HTTPConnection *con, int maximum) const {
iva2k 0:886e4b3119ad 81 HTTPFileSystemData *data = static_cast<HTTPFileSystemData *>(con->data);
iva2k 0:886e4b3119ad 82 err_t err;
iva2k 0:886e4b3119ad 83 u16_t len = min(data->bleft, maximum);
iva2k 0:886e4b3119ad 84 // printf("Send File\n");
iva2k 0:886e4b3119ad 85 if(len) {
iva2k 0:886e4b3119ad 86 do {
iva2k 0:886e4b3119ad 87 err = con->write(
iva2k 0:886e4b3119ad 88 &data->buffer[data->offset], len, (((!data->fleft)&&(data->bleft==len))?
iva2k 0:886e4b3119ad 89 (TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE) : (TCP_WRITE_FLAG_COPY)));
iva2k 0:886e4b3119ad 90 if(err == ERR_MEM) {
iva2k 0:886e4b3119ad 91 len /= 2;
iva2k 0:886e4b3119ad 92 }
iva2k 0:886e4b3119ad 93 } while (err == ERR_MEM && len > 1);
iva2k 0:886e4b3119ad 94
iva2k 0:886e4b3119ad 95 if(err == ERR_OK) {
iva2k 0:886e4b3119ad 96 data->offset += len;
iva2k 0:886e4b3119ad 97 data->bleft -= len;
iva2k 0:886e4b3119ad 98 }
iva2k 0:886e4b3119ad 99 }
iva2k 0:886e4b3119ad 100 return loadFromFile(con);
iva2k 0:886e4b3119ad 101 }
iva2k 0:886e4b3119ad 102
iva2k 0:886e4b3119ad 103 /**
iva2k 0:886e4b3119ad 104 * Returns the left size of a file.
iva2k 0:886e4b3119ad 105 * @param fd The filehandler of which we want to know the filesize.
iva2k 0:886e4b3119ad 106 * @return The filesize of fd.
iva2k 0:886e4b3119ad 107 */
iva2k 0:886e4b3119ad 108 long fleft(FILE *fd) const {
iva2k 0:886e4b3119ad 109 long len, cur;
iva2k 0:886e4b3119ad 110 cur = ftell(fd);
iva2k 0:886e4b3119ad 111 fseek(fd, 0, SEEK_END);
iva2k 0:886e4b3119ad 112 len = ftell(fd);
iva2k 0:886e4b3119ad 113 fseek(fd, cur, SEEK_SET);
iva2k 0:886e4b3119ad 114 return len;
iva2k 0:886e4b3119ad 115 }
iva2k 0:886e4b3119ad 116
iva2k 0:886e4b3119ad 117 /**
iva2k 0:886e4b3119ad 118 * Fill the buffer if the buffer is empty.
iva2k 0:886e4b3119ad 119 * If the file is complete close the filehandler and return HTTP_SuccessEnded.
iva2k 0:886e4b3119ad 120 */
iva2k 0:886e4b3119ad 121 HTTPHandle loadFromFile(HTTPConnection *con) const {
iva2k 0:886e4b3119ad 122 HTTPFileSystemData *data = static_cast<HTTPFileSystemData *>(con->data);
iva2k 0:886e4b3119ad 123 if(!data->bleft) {
iva2k 0:886e4b3119ad 124 if(data->fleft) {
iva2k 0:886e4b3119ad 125 int len = fread(&data->buffer[0], sizeof(char), HTTP_BUFFER_SIZE, data->file);
iva2k 0:886e4b3119ad 126 data->fleft -= len;
iva2k 0:886e4b3119ad 127 data->bleft = len;
iva2k 0:886e4b3119ad 128 data->offset = 0;
iva2k 0:886e4b3119ad 129 } else {
iva2k 0:886e4b3119ad 130 if(data->file) {
iva2k 0:886e4b3119ad 131 fclose(data->file);
iva2k 0:886e4b3119ad 132 data->file = 0;
iva2k 0:886e4b3119ad 133 }
iva2k 0:886e4b3119ad 134 return HTTP_SuccessEnded;
iva2k 0:886e4b3119ad 135 }
iva2k 0:886e4b3119ad 136 }
iva2k 0:886e4b3119ad 137 return HTTP_Success;
iva2k 0:886e4b3119ad 138 }
iva2k 0:886e4b3119ad 139
iva2k 0:886e4b3119ad 140 /** The Directory which will replace the prefix of the URL */
iva2k 0:886e4b3119ad 141 const char *_dir;
iva2k 0:886e4b3119ad 142 };
iva2k 0:886e4b3119ad 143
iva2k 0:886e4b3119ad 144 #endif