LRSD stephane / Mbed 2 deprecated WEBserverv3

Dependencies:   mbed

Committer:
geiineuville
Date:
Thu Sep 08 08:57:21 2011 +0000
Revision:
0:9cf1d79ebe04
v0 v1 v2   \"v3\"

Who changed what in which revision?

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