+++ /dev/null
-/**\r
- * @file HTTPDaemon.cpp\r
- *\r
- */\r
-\r
-#include <time.h>\r
-\r
-#define DBG_LEVEL 3\r
-#include "Raym/Log.h"\r
-\r
-#include "keys.h"\r
-#include "ry0/iPTd/HTTPD.h"\r
-#include "ry0/iPTd/Controller.h"\r
-\r
-using namespace Raym;\r
-using namespace NET;\r
-\r
-namespace ry0\r
-{\r
-namespace iPTd\r
-{\r
-\r
-HTTPD::HTTPD()\r
-{\r
- _controller = NULL;\r
- _tuners = NULL;\r
- _httpd = NULL;\r
- _port = -1;\r
- _path = NULL;\r
-}\r
-\r
-HTTPD::~HTTPD()\r
-{\r
- RELEASE(_httpd);\r
- RELEASE(_path);\r
-}\r
-\r
-HTTPD *HTTPD::alloc()\r
-{\r
- return new HTTPD();\r
-}\r
-\r
-HTTPD *HTTPD::initWithController(Controller *controller, int port, String *path)\r
-{\r
- _controller = controller;\r
- _tuners = controller->_tuners;\r
-\r
- _port = port;\r
- _path = path->retain();\r
-\r
- return this;\r
-}\r
-\r
-bool HTTPD::start()\r
-{\r
- if (_httpd == NULL)\r
- {\r
- _httpd = HTTPDaemon::alloc()->initWithPort(_port, 10);\r
- _httpd->setRootPath(_path);\r
- _httpd->setDelegate(this);\r
- }\r
- return _httpd->start();\r
-}\r
-\r
-void HTTPD::stop()\r
-{\r
- _httpd->stop();\r
-}\r
-\r
-HTTPResponse *HTTPD::request(HTTPRequest *request, SOCKADDR_IN *client)\r
-{\r
- DebugLog2("%s\n", __FUNCTION__);\r
-\r
- // 初期化チェック\r
- bool flag = false;\r
- RaymLock(_controller);\r
- flag = _controller->_initialized;\r
- RaymUnlock(_controller);\r
- if (!flag)\r
- {\r
- return NULL;\r
- }\r
-\r
- HTTPResponse *response = NULL;\r
-\r
- if (request->method()->isEqualToString("GET") ||\r
- request->method()->isEqualToString("HEAD"))\r
- {\r
- // URI\r
- String *uri = request->URI();\r
- DebugLog0("request: %s\n", uri->cString());\r
- if (uri->isMatch("^/config\\.xml$"))\r
- {\r
- RaymLock(_controller);\r
- response = responseWithDictionary(request, _controller->_props);\r
- RaymUnlock(_controller);\r
- }\r
- else if (uri->isMatch("^/status\\.xml$"))\r
- {\r
- RaymLock(_controller);\r
- response = responseWithDictionary(request, _controller->_status);\r
- RaymUnlock(_controller);\r
- }\r
- else if (uri->isMatch("^/iptv\\.m3u8$"))\r
- {\r
- return responseForPlaylist(request, client);\r
- }\r
- else if (uri->isMatch("^/regist\\.cgi"))\r
- {\r
- response = responseForRegistCGI(request, client);\r
- }\r
- else if (uri->isMatch("^/[0-9]{3}/"))\r
- {\r
- std::string s = uri->cString();\r
- int tuner = atoi(s.substr(1, 3).c_str());\r
- if ((0 <= tuner) && (tuner < _controller->_tuner_count))\r
- {\r
- response = requestTunerControl(request, client, tuner);\r
- }\r
- }\r
-\r
- else if (uri->isMatch("^/iptd\\.log$"))\r
- {\r
- String *path = _controller->_system_path->stringByAppendingPathComponent("log");\r
- if (path != NULL)\r
- {\r
- path = path->stringByAppendingPathComponent("iptd.log");\r
- if (path != NULL)\r
- {\r
- response = _httpd->responseWithPath(path, request);\r
- if (response != NULL)\r
- {\r
- if (response->message() != NULL)\r
- {\r
- if (response->message()->header() != NULL)\r
- {\r
- response->message()->header()->setFieldBodyWithName("text/plane; charset=UTF-8", "Content-Type");\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- return response;\r
-}\r
-\r
-HTTPResponse *HTTPD::requestTunerControl(HTTPRequest *request, SOCKADDR_IN *client, int tuner)\r
-{\r
- DebugLog0("%s\n", __FUNCTION__);\r
-\r
- HTTPResponse *result = NULL;\r
-\r
- // lock\r
- RaymLock(_controller);\r
-\r
- // URI取得\r
- String *uri = request->URI();\r
- while (uri != NULL)\r
- {\r
- // CGIリクエストとして解析\r
- Dictionary *cgi = request->parseAsCGI();\r
- if (cgi != NULL)\r
- {\r
- uri = cgi->stringForKey(HTTPRequest::KEY_CGI);\r
- if (uri == NULL)\r
- {\r
- break;\r
- }\r
- }\r
-\r
- //\r
- // チャンネル設定\r
- // /ttt/channel=nnn\r
- //\r
- if (uri->isMatch("^/[0-9]{3}/channel=[0-9]{1,3}$") && (cgi == NULL))\r
- {\r
- String *ch = uri->substringFromIndex(13);\r
- if (ch == NULL)\r
- {\r
- break;\r
- }\r
- int channel = ch->intValue();\r
- DebugLog2("set channel:%d(%s)\n", channel, ch->cString());\r
- if (_controller->setChannel(tuner, channel))\r
- {\r
- // success\r
- DebugLog2("success.\n");\r
- result = responseForSuccess(request);\r
- }\r
- else\r
- {\r
- // failed\r
- DebugLog2("failed.\n");\r
- result = responseForFailed(request);\r
- }\r
- }\r
-\r
- //\r
- // 録画開始(最大23:59まで)\r
- // /ttt/recording=on?hour=hh&min=mm[&channel=nnn]\r
- //\r
- else if (uri->isMatch("^/[0-9]{3}/recording=on$") && (cgi != NULL))\r
- {\r
- // パラメータがあるか\r
- Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
- if (params == NULL)\r
- {\r
- break;\r
- }\r
-\r
- // パラメータ数は2〜3か\r
- if ((params->count() != 2) && (params->count() != 3))\r
- {\r
- break;\r
- }\r
-\r
- // パラメータのチェック\r
- String *p_hour = NULL;\r
- String *p_min = NULL;\r
- String *p_channel = NULL;\r
-\r
- struct {\r
- const char *name;\r
- String **variable;\r
- const char *regex;\r
- }\r
- cgi[] =\r
- {\r
- {"hour", &p_hour, "^[0-2][0-9]$"},\r
- {"min", &p_min, "^[0-5][0-9]$"},\r
- {"channel", &p_channel, "^[0-9]{3}$"},\r
- {NULL, NULL, NULL}\r
- };\r
-\r
- for (uint i = 0; cgi[i].name != NULL; ++i)\r
- {\r
- *(cgi[i].variable) = NULL;\r
- for (uint j = 0; j < params->count(); ++j)\r
- {\r
- Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
- String *value = param->stringForKey(cgi[i].name);\r
- if ((value != NULL) && value->isMatch(cgi[i].regex))\r
- {\r
- *(cgi[i].variable) = value;\r
- }\r
- }\r
- }\r
-\r
- // パラメータは有効か\r
- if ((p_hour == NULL) || (p_min == NULL))\r
- {\r
- break;\r
- }\r
-\r
- // チャンネル設定\r
- int channel = 0;\r
- if (p_channel != NULL)\r
- {\r
- channel = p_channel->intValue();\r
- }\r
- else\r
- {\r
- channel = _tuners[tuner]->channel();\r
- }\r
-\r
- if (channel >= 0)\r
- {\r
- // recording on\r
- int hour = p_hour->intValue();\r
- int min = p_min->intValue();\r
- if (hour < 24)\r
- {\r
- // EPG生成\r
- Dictionary *epg = Dictionary::dictionaryWithCapacity(0);\r
- while (true)\r
- {\r
- time_t now;\r
- time(&now);\r
- now += 1; // margin\r
- TM tm;\r
- if (localtime_s(&tm, &now) != 0)\r
- {\r
- epg = NULL;\r
- break;\r
- }\r
- TM end;\r
- end = tm;\r
- end.tm_hour += hour;\r
- end.tm_min += min;\r
- end.tm_sec += 1; // margin\r
- if (mktime(&end) == -1)\r
- {\r
- epg = NULL;\r
- break;\r
- }\r
-\r
- char tmp[16];\r
-\r
- // Date\r
- sprintf_s(tmp, sizeof(tmp), "%04d/%02d/%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);\r
- epg->setString(tmp, KEY_EPG_DATE);\r
-\r
- // Start\r
- sprintf_s(tmp, sizeof(tmp), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);\r
- epg->setString(tmp, KEY_EPG_START);\r
-\r
- // End\r
- sprintf_s(tmp, sizeof(tmp), "%02d:%02d:%02d", end.tm_hour, end.tm_min, end.tm_sec);\r
- epg->setString(tmp, KEY_EPG_END);\r
-\r
- // Channel\r
- sprintf_s(tmp, sizeof(tmp), "%d", channel);\r
- epg->setString(tmp, KEY_EPG_CHANNEL);\r
-\r
- // 繰り返し\r
- epg->setString("off", KEY_EPG_REPEAT); \r
-\r
- // Status\r
- epg->setString("ready", KEY_EPG_STATUS);\r
-\r
- break;\r
- }\r
- \r
- if (epg != NULL)\r
- {\r
- // 録画開始&結果生成\r
- if (_controller->_reservation->reserve(tuner, epg))\r
- {\r
- result = responseForSuccess(request);\r
- }\r
- else\r
- {\r
- result = responseForFailed(request);\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- //\r
- // 録画停止\r
- // /ttt/recording=off\r
- //\r
- else if (uri->isMatch("^/[0-9]{3}/recording=off$") && (cgi == NULL))\r
- {\r
- // recording off\r
- DebugLog2("recording off: %s\n", uri->cString());\r
- if (_controller->_reservation->cancel(tuner, -1))\r
- {\r
- // success\r
- DebugLog2("success.\n");\r
- result = responseForSuccess(request);\r
- }\r
- else\r
- {\r
- // failed\r
- DebugLog2("failed.\n");\r
- result = responseForFailed(request);\r
- }\r
- }\r
-\r
- //\r
- // ストリーミング開始\r
- // /ttt/streaming=on?udp=nnnnn(&host=aaaaaa)\r
- //\r
- else if (uri->isMatch("^/[0-9]{3}/streaming=on$") && (cgi != NULL))\r
- {\r
- // パラメータがあるか\r
- Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
- if (params == NULL)\r
- {\r
- break;\r
- }\r
-\r
- // パラメータ数は1〜2か\r
- if ((params->count() != 1) && (params->count() != 2))\r
- {\r
- break;\r
- }\r
-\r
- // パラメータのチェック\r
- String *p_udp = NULL;\r
- String *p_host = NULL;\r
-\r
- struct {\r
- const char *name;\r
- String **variable;\r
- const char *regex;\r
- }\r
- cgi[] =\r
- {\r
- {"udp", &p_udp, "^[0-9]{1,5}$"},\r
- {"host", &p_host, "^.+$"},\r
- {NULL, NULL, NULL}\r
- };\r
-\r
- for (uint i = 0; cgi[i].name != NULL; ++i)\r
- {\r
- *(cgi[i].variable) = NULL;\r
- for (uint j = 0; j < params->count(); ++j)\r
- {\r
- Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
- String *value = param->stringForKey(cgi[i].name);\r
- if ((value != NULL) && value->isMatch(cgi[i].regex))\r
- {\r
- *(cgi[i].variable) = value;\r
- }\r
- }\r
- }\r
-\r
- // パラメータチェック\r
- if (p_udp == NULL)\r
- {\r
- break;\r
- }\r
-\r
- SOCKADDR_IN dst_addr;\r
- \r
- if (p_host != NULL)\r
- {\r
- #if 0\r
- std::string host = udpstr.substr(idx + 5);\r
- udpstr = udpstr.substr(0, idx - 1);\r
- DebugLog2("udp: %s\n", udpstr.c_str());\r
- DebugLog2("host: %s\n", host.c_str());\r
- struct hostent *ent = gethostbyname(host.c_str());\r
- #endif\r
- }\r
- else\r
- {\r
- memcpy(&dst_addr, client, sizeof(SOCKADDR_IN));\r
- }\r
- dst_addr.sin_port = htons(p_udp->intValue());\r
- \r
- if (_tuners[tuner]->startStreaming(&dst_addr))\r
- {\r
- // success\r
- DebugLog2("success.\n");\r
- result = responseForSuccess(request);\r
- }\r
- else\r
- {\r
- // failed\r
- DebugLog2("failed.\n");\r
- result = responseForFailed(request);\r
- }\r
- }\r
-\r
- //\r
- // ストリーミング停止\r
- // /ttt/streaming=off(?host=aaaa)\r
- //\r
- else if (uri->isMatch("^/[0-9]{3}/streaming=off$"))\r
- {\r
- // パラメータ\r
- String *p_host = NULL;\r
-\r
- // パラメータがあるか\r
- if (cgi != NULL)\r
- {\r
- Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
- if (params == NULL)\r
- {\r
- break;\r
- }\r
-\r
- // パラメータ数は0〜1か\r
- if ((params->count() != 0) && (params->count() != 1))\r
- {\r
- break;\r
- }\r
-\r
- struct {\r
- const char *name;\r
- String **variable;\r
- const char *regex;\r
- }\r
- cgi[] =\r
- {\r
- {"host", &p_host, "^.+$"},\r
- {NULL, NULL, NULL}\r
- };\r
-\r
- for (uint i = 0; cgi[i].name != NULL; ++i)\r
- {\r
- *(cgi[i].variable) = NULL;\r
- for (uint j = 0; j < params->count(); ++j)\r
- {\r
- Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
- String *value = param->stringForKey(cgi[i].name);\r
- if ((value != NULL) && value->isMatch(cgi[i].regex))\r
- {\r
- *(cgi[i].variable) = value;\r
- }\r
- }\r
- }\r
- }\r
-\r
-// SOCKADDR_IN dst_addr;\r
- if (p_host != NULL)\r
- {\r
- }\r
- else\r
- {\r
- }\r
-\r
- _tuners[tuner]->stopStreaming();\r
- \r
- // success\r
- DebugLog2("success.\n");\r
- result = responseForSuccess(request);\r
- }\r
-\r
- //\r
- // HLS制御\r
- //\r
- else if (uri->isMatch("^/[0-9]{3}/[0-9]{3}/streaming(-[^\\.]+)?.m3u8$") && (cgi == NULL))\r
- {\r
- DebugLog0("uri: %s", uri->cString());\r
-/*\r
- // URIからチャンネル番号を抽出\r
- // Range実装したい...\r
- int ch = uri->substringFromIndex(5)->substringToIndex(3)->intValue();\r
- DebugLog0("ch: %d", ch);\r
-\r
- // presetが指定されている場合、presetを抽出\r
- String *preset = NULL;\r
- if (uri->isMatch("streaming-"))\r
- {\r
- preset = uri->substringFromIndex(19);\r
- preset = preset->substringToIndex(preset->length() - 5);\r
- DebugLog0("opt: preset: %s", preset->cString());\r
- }\r
- else\r
- {\r
- // なければ "default"\r
- preset = NSString::stringWithUTF8String(KEY_DEFAULT);\r
- }\r
-\r
- // チャンネル/presetが有効か確認\r
- if (isChannelEnabled(tuner, ch) &&\r
- (_props->dictionaryForKey(KEY_PRESETS) != NULL) &&\r
- (_props->dictionaryForKey(KEY_PRESETS)->objectForKey(preset) != NULL))\r
- {\r
- // \r
- result = responseForHLSControl(request, client, tuner, ch, preset);\r
- }\r
- else\r
- {\r
- result = responseForFailed(request);\r
- }\r
- DebugLog0("hls req. done");\r
-*/\r
- }\r
- else if (uri->isMatch("^/[0-9]{3}/[0-9]{3}/streaming-[0-9]+.ts$") && (cgi == NULL))\r
- {\r
- // 分割されたTS\r
- DebugLog0("uri: %s", uri->cString());\r
- }\r
-\r
- break;\r
- }\r
-\r
- // unlock\r
- RaymUnlock(_controller);\r
-\r
- return result;\r
-}\r
-\r
-HTTPResponse *HTTPD::responseForRegistCGI(HTTPRequest *request, SOCKADDR_IN *client)\r
-{\r
- DebugLog2("Controller::responseForRegistCGI()");\r
-\r
- HTTPResponse *result = NULL;\r
-\r
- // CGIリクエストとして解析\r
- Dictionary *cgi = request->parseAsCGI();\r
- if (cgi != NULL)\r
- {\r
- // CGIパスが一致しているか\r
- if ((cgi->stringForKey(HTTPRequest::KEY_CGI) != NULL) && (cgi->stringForKey(HTTPRequest::KEY_CGI)->isEqualToString("/regist.cgi")))\r
- {\r
- // パラメータがあるか\r
- Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
- if (params != NULL)\r
- {\r
- // パラメータ数が2か\r
- if (params->count() == 2)\r
- {\r
- // パラメータのチェック\r
- String *service_id = NULL;\r
- String *event_id = NULL;\r
-\r
- for (uint i = 0; i < params->count(); ++i)\r
- {\r
- Dictionary *param = (Dictionary *)params->objectAtIndex(i);\r
- String *value = param->stringForKey("service_id");\r
- if ((value != NULL) && value->isMatch("^\\d+$"))\r
- {\r
- service_id = value;\r
- }\r
- value = param->stringForKey("event_id");\r
- if ((value != NULL) && value->isMatch("^\\d+$"))\r
- {\r
- event_id = value;\r
- }\r
- }\r
-\r
- // 有効なパラメータか\r
- if ((service_id != NULL) && (event_id != NULL))\r
- {\r
- DebugLog2("valid request");\r
-\r
- if (_controller->_reservation->reserve(service_id->intValue(), event_id->intValue()))\r
- {\r
- result = responseForSuccess(request);\r
- }\r
- else\r
- {\r
- result = responseForFailed(request);\r
- }\r
- }\r
- }\r
-\r
- // パラメータ数が9か\r
- else if (params->count() == 9)\r
- {\r
- // パラメータのチェック\r
- String *service_id = NULL;\r
- String *year = NULL;\r
- String *month = NULL;\r
- String *day = NULL;\r
- String *start_hour = NULL;\r
- String *start_min = NULL;\r
- String *end_hour = NULL;\r
- String *end_min = NULL;\r
- String *repeat = NULL;\r
-\r
- struct {\r
- const char *name;\r
- String **variable;\r
- const char *regex;\r
- }\r
- cgi[] =\r
- {\r
- {"service_id", &service_id, "^\\d+$"},\r
- {"year", &year, "^\\d{4}$"},\r
- {"month", &month, "^([1-9]|1[0-2])$"},\r
- {"day", &day, "^([1-9]|[12][0-9]|3[01])$"},\r
- {"start_hour", &start_hour, "^\\d{2}$"},\r
- {"start_min", &start_min, "^\\d{2}$"},\r
- {"end_hour", &end_hour, "^\\d{2}$"},\r
- {"end_min", &end_min, "^\\d{2}$"},\r
- {"repeat", &repeat, "^(off|everyday|weekly|weekday)$"},\r
- {NULL, NULL, NULL}\r
- };\r
-\r
- for (uint i = 0; cgi[i].name != NULL; ++i)\r
- {\r
- for (uint j = 0; j < params->count(); ++j)\r
- {\r
- Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
- String *value = param->stringForKey(cgi[i].name);\r
- if ((value != NULL) && value->isMatch(cgi[i].regex))\r
- {\r
- *(cgi[i].variable) = value;\r
- break;\r
- }\r
- }\r
- }\r
-\r
- // 有効なパラメータか\r
- if ((service_id != NULL) && (year != NULL) && (month != NULL) && (day != NULL) &&\r
- (start_hour != NULL) && (start_min != NULL) && (end_hour != NULL) && (end_min != NULL) && (repeat != NULL))\r
- {\r
- //\r
- DebugLog1("valid param");\r
-\r
- Dictionary *epg = Dictionary::dictionaryWithCapacity(0);\r
-\r
- // 日付\r
- epg->setString(String::stringWithFormat("%s/%02d/%02d", year->cString(), month->intValue(), day->intValue()), KEY_EPG_DATE);\r
-\r
- // 開始時刻\r
- epg->setString(String::stringWithFormat("%s:%s:00", start_hour->cString(), start_min->cString()), KEY_EPG_START);\r
-\r
- // 終了時刻\r
- epg->setString(String::stringWithFormat("%s:%s:00", end_hour->cString(), end_min->cString()), KEY_EPG_END);\r
-\r
- // 繰り返し\r
- epg->setString(repeat, KEY_EPG_REPEAT);\r
-\r
- // Service ID\r
- epg->setString(service_id, KEY_EPG_SERVICE_ID);\r
-\r
- // Status\r
- epg->setString("ready", KEY_EPG_STATUS);\r
-\r
- if (_controller->_reservation->reserve(epg))\r
- {\r
- result = responseForSuccess(request);\r
- }\r
- else\r
- {\r
- result = responseForFailed(request);\r
- }\r
- }\r
- }\r
- }\r
- }\r
- }\r
-\r
- return result;\r
-}\r
-\r
-\r
-HTTPResponse *HTTPD::responseForPlaylist(HTTPRequest *request, SOCKADDR_IN *client)\r
-{\r
- HTTPResponse *result = NULL;\r
-\r
- std::string contents;\r
- contents = "#EXTM3U\r\n";\r
- contents += "\r\n";\r
-\r
- contents += "#EXTINF:-1, video\r\n";\r
- contents += "http://172.19.29.9:50080/iptv/video.m3u8\r\n";\r
- contents += "#EXTINF:-1, TV\r\n";\r
- contents += "http://172.19.29.9:50080/iptv/tv.m3u8\r\n";\r
-\r
- String *text = String::stringWithUTF8String(contents.c_str());\r
- if (text != NULL)\r
- {\r
- result = responseWithUTF8Text(request, text);\r
- }\r
-\r
- return result;\r
-}\r
-\r
-// positive response by XML\r
-HTTPResponse *HTTPD::responseForSuccess(HTTPRequest *request)\r
-{\r
- Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
- dict->setString("Success", KEY_RESULT);\r
- return responseWithDictionary(request, dict);\r
-}\r
-\r
-// negative response by XML\r
-HTTPResponse *HTTPD::responseForFailed(HTTPRequest *request)\r
-{\r
- Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
- dict->setString("Failed", KEY_RESULT);\r
- return responseWithDictionary(request, dict);\r
-}\r
-\r
-HTTPResponse *HTTPD::responseWithDictionary(HTTPRequest *request, Dictionary *dictionary)\r
-{\r
- HTTPResponse *result = NULL;\r
- if ((request != NULL) && (dictionary != NULL))\r
- {\r
- std::string xml = dictionary->toString();\r
-\r
- // header\r
- InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->init();\r
- // Date\r
- // Server\r
- // Content-Encoding\r
- // Last-Modified\r
- // Content-Type\r
- header->setFieldBodyWithName("application/xml", "Content-Type");\r
- // Connection\r
- // Tranfer-Encoding\r
- // Content-Length\r
- header->setFieldBodyWithName(String::stringWithFormat("%I64u", xml.length()), "Content-Length");\r
-\r
- // body\r
- InternetTextMessageBody *body = InternetTextMessageBody::alloc()->initWithString(String::stringWithUTF8String(xml.c_str()));\r
-\r
- // message\r
- InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);\r
- RELEASE(header);\r
- RELEASE(body);\r
- if (message != NULL)\r
- {\r
- result = HTTPResponse::alloc()->init();\r
- result->autorelease();\r
- result->setVersion(request->version());\r
- result->setReason(NET::HTTPDaemon::reasonForStatus(200));\r
- result->setStatus(200);\r
- result->setMessage(message);\r
- RELEASE(message);\r
- }\r
- }\r
- return result;\r
-}\r
-\r
-HTTPResponse *HTTPD::responseWithUTF8Text(HTTPRequest *request, String *text)\r
-{\r
- HTTPResponse *result = NULL;\r
- if ((text != NULL) && (request != NULL))\r
- {\r
- // header\r
- InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->init();\r
- // Date\r
- // Server\r
- // Content-Encoding\r
- // Last-Modified\r
- // Content-Type\r
- header->setFieldBodyWithName("text/plane; charset=UTF-8", "Content-Type");\r
- // Connection\r
- // Tranfer-Encoding\r
- // Content-Length\r
- header->setFieldBodyWithName(String::stringWithFormat("%I64u", text->length()), "Content-Length");\r
-\r
- // body\r
- InternetTextMessageBody *body = InternetTextMessageBody::alloc()->initWithString(text);\r
-\r
- // message\r
- InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);\r
- RELEASE(header);\r
- RELEASE(body);\r
- if (message != NULL)\r
- {\r
-// result = HTTPResponse::response();\r
- result = HTTPResponse::alloc()->init();\r
- result->setVersion(request->version());\r
- result->setReason(NET::HTTPDaemon::reasonForStatus(200));\r
- result->setStatus(200);\r
- result->setMessage(message);\r
- result->autorelease();\r
- RELEASE(message);\r
- }\r
- }\r
- return result;\r
-}\r
-\r
-} // iPTd\r
-} // ry0\r