Embedded WebSockets Experiment

Dependencies:   mbed MD5

Committer:
nandgate
Date:
Tue Jul 26 05:30:53 2011 +0000
Revision:
0:6dee052a3fa4

        

Who changed what in which revision?

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