#include #include #include "ContentTransposer.h" class TextFileTransposer : public ContentTransposer { public: TextFileTransposer(HttpRequestListener* l); ~TextFileTransposer(); bool data(const HttpRequest*, const char* data, int len); bool finished(const HttpRequest*); bool header(const HttpRequest* r, const HttpHeader *header); static bool contentTypeMatches(const gchar* contentType); private: bool html_sent; }; class ImageTransposer : public ContentTransposer { public: ImageTransposer(HttpRequestListener* l); ~ImageTransposer(); bool data(const HttpRequest*, const char* data, int len); bool finished(const HttpRequest*); bool header(const HttpRequest* r, const HttpHeader *header); static bool contentTypeMatches(const gchar* contentType); private: bool html_sent; }; ContentTransposer::ContentTransposer(HttpRequestListener* aforwardee) :forwardee(aforwardee) ,switched(false) { } ContentTransposer::~ContentTransposer() { delete forwardee; } void ContentTransposer::attached(const HttpRequest* r) { return forwardee->attached(r); } void ContentTransposer::detached(const HttpRequest* r) { return forwardee->detached(r); } bool ContentTransposer::started(const HttpRequest* r) { return forwardee->started(r); } bool ContentTransposer::finished(const HttpRequest* r) { return forwardee->finished(r); } bool ContentTransposer::headersEnd(const HttpRequest* r, int status) { return forwardee->headersEnd(r, status); } bool ContentTransposer::data(const HttpRequest* r, const char* data, int len) { return forwardee->data(r, data,len); } bool ContentTransposer::error(const HttpRequest* r) { return forwardee->error(r); } bool ContentTransposer::header(const HttpRequest* r, const HttpHeader *header) { switch (header->type()){ case HttpHeader::ContentType: { const HttpHeaderContentType* ct = static_cast(header); const gchar* contentType = ct->contentType(); if (!switched) { if (TextFileTransposer::contentTypeMatches(contentType)) { forwardee = new TextFileTransposer(forwardee); } else if (ImageTransposer::contentTypeMatches(contentType)) { forwardee = new ImageTransposer(forwardee); } // avoid multpile level of forwarding switched = true; } break; } default: break; } return forwardee->header(r, header); } bool ContentTransposer::resolving(const HttpRequest*r) { return forwardee->resolving(r); } bool ContentTransposer::authenticate(HttpRequest* r) { return forwardee->authenticate(r); } TextFileTransposer::TextFileTransposer(HttpRequestListener* l) : ContentTransposer(l) ,html_sent(false) { } TextFileTransposer::~TextFileTransposer() { } bool TextFileTransposer::data(const HttpRequest* r, const char* data, int len) { if (!html_sent) { static const gchar *pre_content = "%s/title><body><pre>\n"; const gchar* content = g_strdup_printf(pre_content, r->url()); int content_len = strlen(content); html_sent=true; forwardee->data(r, content, content_len); } return forwardee->data(r, data, len); } bool TextFileTransposer::finished(const HttpRequest* r) { static const gchar *content = "</pre></body></html>\n"; static int content_len = strlen(content); forwardee->data(r, content, content_len); return forwardee->finished(r); } bool TextFileTransposer::contentTypeMatches(const gchar* contentType) { if (strcmp(contentType, "text/plain")==0) return true; return false; } bool TextFileTransposer::header(const HttpRequest* r, const HttpHeader *header) { switch (header->type()){ case HttpHeader::ContentType: { HttpHeaderContentType fakeHeader("text/html"); return forwardee->header(r, &fakeHeader); } default: break; } // dont forward any other headers (we might get for example content length..) return false; } ImageTransposer::ImageTransposer(HttpRequestListener* l) : ContentTransposer(l) ,html_sent(false) { } ImageTransposer::~ImageTransposer() { } bool ImageTransposer::data(const HttpRequest* r, const char* data, int len) { if (!html_sent) { static const gchar *pre_content = "<html><head><title>Image: %s \n"; const gchar* content = g_strdup_printf(pre_content, r->url(), r->url()); int content_len = strlen(content); html_sent=true; forwardee->data(r, content, content_len); } // discard the data return true; } bool ImageTransposer::finished(const HttpRequest* r) { forwardee->finished(r); return true; } bool ImageTransposer::header(const HttpRequest* r, const HttpHeader *header) { switch (header->type()){ case HttpHeader::ContentType: { HttpHeaderContentType fakeHeader("text/html"); return forwardee->header(r, &fakeHeader); } default: break; } // dont forward any other headers (we might get for example content length..) return false; } bool ImageTransposer::contentTypeMatches(const gchar* contentType) { if (g_str_has_prefix(contentType, "image/") == TRUE) return true; return false; }