My fork of the HTTPServer (working)

Dependents:   DGWWebServer LAN2

Committer:
screamer
Date:
Tue Nov 20 12:18:53 2012 +0000
Revision:
1:284f2df30cf9
Parent:
0:7a64fbb4069d
local changes

Who changed what in which revision?

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