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
00031
00032 #ifdef HAVE_CONFIG_H
00033 #include "autoconfig.h"
00034 #endif
00035
00036 #include "server.h"
00037 #include <sys/types.h>
00038 #include <sys/stat.h>
00039 #include <unistd.h>
00040 #include <string.h>
00041 #include <stdio.h>
00042 #include "common.h"
00043 #include "storage.h"
00044 #include "cds_objects.h"
00045 #include "process.h"
00046 #include "update_manager.h"
00047 #include "ixml.h"
00048 #include "file_io_handler.h"
00049 #include "dictionary.h"
00050 #include "serve_request_handler.h"
00051 #include "tools.h"
00052
00053
00054 using namespace zmm;
00055 using namespace mxml;
00056
00057 ServeRequestHandler::ServeRequestHandler() : RequestHandler()
00058 {
00059 }
00060
00062 void ServeRequestHandler::get_info(IN const char *filename, OUT struct File_Info *info)
00063 {
00064 struct stat statbuf;
00065 int ret = 0;
00066 int len = 0;
00067
00068 log_debug("got filename: %s\n", filename);
00069
00070 String url_path, parameters;
00071 split_url(filename, URL_PARAM_SEPARATOR, url_path, parameters);
00072
00073 log_debug("url_path: %s, parameters: %s\n", url_path.c_str(), parameters.c_str());
00074
00075 len = (_("/") + SERVER_VIRTUAL_DIR + _("/") + CONTENT_SERVE_HANDLER).length();
00076
00077 if (len > url_path.length())
00078 {
00079 throw _Exception(_("There is something wrong with the link ") + url_path);
00080 }
00081
00082 String path = ConfigManager::getInstance()->getOption(CFG_SERVER_SERVEDIR)
00083 + url_path.substring(len, url_path.length()) +
00084 _("/") + parameters;
00085
00086 log_debug("Constructed new path: %s\n", path.c_str());
00087
00088 ret = stat(path.c_str(), &statbuf);
00089 if (ret != 0)
00090 {
00091 throw _Exception(_("Failed to stat ") + path);
00092 }
00093
00094 if (S_ISREG(statbuf.st_mode))
00095 {
00096 String mimetype = _(MIMETYPE_DEFAULT);
00097 #ifdef HAVE_MAGIC
00098 magic_set *ms = NULL;
00099 ms = magic_open(MAGIC_MIME);
00100 if (ms != NULL)
00101 {
00102 if (magic_load(ms, NULL) == -1)
00103 {
00104 log_warning("magic_load: %s\n", magic_error(ms));
00105 magic_close(ms);
00106 ms = NULL;
00107 }
00108 else
00109 {
00111 Ref<RExp> reMimetype;
00112 reMimetype = Ref<RExp>(new RExp());
00113 reMimetype->compile(_(MIMETYPE_REGEXP));
00114
00115 String mime = get_mime_type(ms, reMimetype, path);
00116 if (string_ok(mime))
00117 mimetype = mime;
00118
00119 magic_close(ms);
00120 }
00121 }
00122 #endif // HAVE_MAGIC
00123
00124 info->file_length = statbuf.st_size;
00125 info->last_modified = statbuf.st_mtime;
00126 info->is_directory = S_ISDIR(statbuf.st_mode);
00127
00128 if (access(path.c_str(), R_OK) == 0)
00129 {
00130 info->is_readable = 1;
00131 }
00132 else
00133 {
00134 info->is_readable = 0;
00135 }
00136
00137 info->content_type = ixmlCloneDOMString(mimetype.c_str());
00138 }
00139 else
00140 {
00141 throw _Exception(_("Not a regular file: ") + path);
00142 }
00143 }
00144
00145 Ref<IOHandler> ServeRequestHandler::open(IN const char *filename, OUT struct File_Info *info,
00146 IN enum UpnpOpenFileMode mode)
00147 {
00148 struct stat statbuf;
00149 int ret = 0;
00150 int len = 0;
00151
00152
00153
00154 if (mode != UPNP_READ)
00155 throw _Exception(_("UPNP_WRITE unsupported"));
00156
00157 len = (_("/") + SERVER_VIRTUAL_DIR + _("/") + CONTENT_SERVE_HANDLER).length();
00158 String url_path, parameters;
00159 split_url(filename, URL_PARAM_SEPARATOR, url_path, parameters);
00160
00161 log_debug("url_path: %s, parameters: %s\n", url_path.c_str(), parameters.c_str());
00162
00163 len = (_("/") + SERVER_VIRTUAL_DIR + _("/") + CONTENT_SERVE_HANDLER).length();
00164
00165 if (len > url_path.length())
00166 {
00167 throw _Exception(_("There is something wrong with the link ") +
00168 url_path);
00169 }
00170
00171 String path = ConfigManager::getInstance()->getOption(CFG_SERVER_SERVEDIR)
00172 + url_path.substring(len, url_path.length()) +
00173 _("/") + parameters;
00174
00175 log_debug("Constructed new path: %s\n", path.c_str());
00176 ret = stat(path.c_str(), &statbuf);
00177 if (ret != 0)
00178 {
00179 throw _Exception(_("Failed to stat ") + path);
00180 }
00181
00182 if (S_ISREG(statbuf.st_mode))
00183 {
00184 String mimetype = _(MIMETYPE_DEFAULT);
00185 #ifdef HAVE_MAGIC
00186 magic_set *ms = NULL;
00187 ms = magic_open(MAGIC_MIME);
00188 if (ms != NULL)
00189 {
00190 if (magic_load(ms, NULL) == -1)
00191 {
00192 log_warning("magic_load: %s\n", magic_error(ms));
00193 magic_close(ms);
00194 ms = NULL;
00195 }
00196 else
00197 {
00199 Ref<RExp> reMimetype;
00200 reMimetype = Ref<RExp>(new RExp());
00201 reMimetype->compile(_(MIMETYPE_REGEXP));
00202
00203 String mime = get_mime_type(ms, reMimetype, path);
00204 if (string_ok(mime))
00205 mimetype = mime;
00206
00207 magic_close(ms);
00208 }
00209 }
00210 #endif // HAVE_MAGIC
00211
00212 info->file_length = statbuf.st_size;
00213 info->last_modified = statbuf.st_mtime;
00214 info->is_directory = S_ISDIR(statbuf.st_mode);
00215
00216 if (access(path.c_str(), R_OK) == 0)
00217 {
00218 info->is_readable = 1;
00219 }
00220 else
00221 {
00222 info->is_readable = 0;
00223 }
00224
00225 info->content_type = ixmlCloneDOMString(mimetype.c_str());
00226 }
00227 else
00228 {
00229 throw _Exception(_("Not a regular file: ") + path);
00230 }
00231 Ref<IOHandler> io_handler(new FileIOHandler(path));
00232 io_handler->open(mode);
00233
00234 return io_handler;
00235 }