00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00032
00033 #ifdef HAVE_CONFIG_H
00034 #include "autoconfig.h"
00035 #endif
00036
00037 #include "common.h"
00038 #include "tools.h"
00039 #include "web_callbacks.h"
00040 #include "server.h"
00041 #include <unistd.h>
00042 #include <string.h>
00043 #include <stdio.h>
00044 #include "storage.h"
00045 #include "cds_objects.h"
00046 #include "process.h"
00047 #include "update_manager.h"
00048 #include "ixml.h"
00049 #include "io_handler.h"
00050 #include "request_handler.h"
00051 #include "file_request_handler.h"
00052 #ifdef HAVE_CURL
00053 #include "url_request_handler.h"
00054 #endif
00055 #include "web_request_handler.h"
00056 #include "serve_request_handler.h"
00057 #include "web/pages.h"
00058 #include "dictionary.h"
00059
00060 #include <sys/types.h>
00061 #include <sys/stat.h>
00062
00063 using namespace zmm;
00064 using namespace mxml;
00065
00066 static Ref<RequestHandler> create_request_handler(const char *filename)
00067 {
00068 String path, parameters;
00069
00070 String link = url_unescape((char *) filename);
00071
00072 log_debug("Filename: %s, Path: %s\n", filename, path.c_str());
00073
00074
00075 RequestHandler *ret = NULL;
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088 if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
00089 CONTENT_MEDIA_HANDLER))
00090 {
00091 ret = new FileRequestHandler();
00092 }
00093 else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
00094 CONTENT_UI_HANDLER))
00095 {
00096 RequestHandler::split_url(filename, URL_UI_PARAM_SEPARATOR, path,
00097 parameters);
00098 Ref<Dictionary> dict(new Dictionary());
00099 dict->decode(parameters);
00100
00101 String r_type = dict->get(_(URL_REQUEST_TYPE));
00102 if (r_type != nil)
00103 {
00104 ret = create_web_request_handler(r_type);
00105 }
00106 else
00107 {
00108 ret = create_web_request_handler(_("index"));
00109 }
00110 }
00111 else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
00112 CONTENT_SERVE_HANDLER))
00113 {
00114 if (string_ok(ConfigManager::getInstance()->getOption(CFG_SERVER_SERVEDIR)))
00115 ret = new ServeRequestHandler();
00116 else
00117 throw _Exception(_("Serving directories is not enabled in configuration"));
00118 }
00120 #if defined(HAVE_CURL)
00121 else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
00122 CONTENT_ONLINE_HANDLER))
00123 {
00124 ret = new URLRequestHandler();
00125 }
00126 #endif
00127 #if defined(HAVE_LIBDVDREAD_DISABLED)
00128 else if (link.startsWith(_("/") + SERVER_VIRTUAL_DIR + "/" +
00129 CONTENT_DVD_HANDLER))
00130 {
00131 ret = new DVDRequestHandler();
00132 }
00133 #endif
00134 else
00135 {
00136 throw _Exception(_("no valid handler type in ") + filename);
00137 }
00138 return Ref<RequestHandler>(ret);
00139 }
00140
00153 static int web_get_info(IN const char *filename, OUT struct File_Info *info)
00154 {
00155 try
00156 {
00157 Ref<RequestHandler> reqHandler = create_request_handler(filename);
00158 reqHandler->get_info(filename, info);
00159 }
00160 catch (ServerShutdownException se)
00161 {
00162 return -1;
00163 }
00164 catch (SubtitlesNotFoundException sex)
00165 {
00166 log_info("%s\n", sex.getMessage().c_str());
00167 return -1;
00168 }
00169 catch (Exception e)
00170 {
00171 log_error("%s\n", e.getMessage().c_str());
00172 return -1;
00173 }
00174
00175 return 0;
00176 }
00177
00192 static UpnpWebFileHandle web_open(IN const char *filename, OUT struct File_Info *info,
00193 IN enum UpnpOpenFileMode mode)
00194 {
00195 try
00196 {
00197 Ref<RequestHandler> reqHandler = create_request_handler(filename);
00198 Ref<IOHandler> ioHandler = reqHandler->open(filename, info, mode);
00199 ioHandler->retain();
00200 return (UpnpWebFileHandle) ioHandler.getPtr();
00201 }
00202 catch (ServerShutdownException se)
00203 {
00204 return NULL;
00205 }
00206 catch (SubtitlesNotFoundException sex)
00207 {
00208 log_info("%s\n", sex.getMessage().c_str());
00209 return NULL;
00210 }
00211 catch (Exception ex)
00212 {
00213 log_error("%s\n", ex.getMessage().c_str());
00214 return NULL;
00215 }
00216 }
00217
00218
00231 static int web_read(IN UpnpWebFileHandle f, OUT char *buf,
00232 IN size_t length)
00233 {
00234 if (Server::getInstance()->getShutdownStatus())
00235 return -1;
00236
00237 IOHandler *handler = (IOHandler *)f;
00238 return handler->read(buf, length);
00239 }
00240
00255 static int web_write(IN UpnpWebFileHandle f, IN char *buf,
00256 IN size_t length)
00257 {
00258 return 0;
00259 }
00260
00274 static int web_seek(IN UpnpWebFileHandle f, IN off_t offset, IN int whence)
00275 {
00276 try
00277 {
00278 IOHandler *handler = (IOHandler *)f;
00279 handler->seek(offset, whence);
00280 }
00281 catch(Exception e)
00282 {
00283 log_error("web_seek(): Exception during seek: %s\n", e.getMessage().c_str());
00284 e.printStackTrace();
00285 return -1;
00286 }
00287
00288 return 0;
00289 }
00290
00297 static int web_close( IN UpnpWebFileHandle f)
00298 {
00299
00300 Ref<IOHandler> handler((IOHandler *)f);
00301 handler->release();
00302 try
00303 {
00304 handler->close();
00305 }
00306 catch(Exception e)
00307 {
00308 log_error("web_seek(): Exception during seek: %s\n", e.getMessage().c_str());
00309 e.printStackTrace();
00310 return -1;
00311 }
00312 return 0;
00313 }
00314
00327 int register_web_callbacks()
00328 {
00329 int ret = UPNP_E_SUCCESS;
00330
00331 struct UpnpVirtualDirCallbacks cb;
00332 cb.get_info = web_get_info;
00333 cb.open = web_open;
00334 cb.read = web_read;
00335 cb.write = web_write;
00336 cb.seek = web_seek;
00337 cb.close = web_close;
00338
00339 ret = UpnpSetVirtualDirCallbacks(&cb);
00340 return ret;
00341 }