OSDN Git Service

07d8e1bd4175aeeb3d5b65f59e0c147e08ca8a59
[iptd/iPTd.git] / src / ry0 / iPTd / HTTPD.cpp
1 /**\r
2  * @file HTTPDaemon.cpp\r
3  *\r
4  */\r
5 \r
6 #include <time.h>\r
7 \r
8 #define DBG_LEVEL 3\r
9 #include "Raym/Log.h"\r
10 \r
11 #include "keys.h"\r
12 #include "ry0/iPTd/HTTPD.h"\r
13 #include "ry0/iPTd/Controller.h"\r
14 \r
15 using namespace Raym;\r
16 using namespace NET;\r
17 \r
18 namespace ry0\r
19 {\r
20 namespace iPTd\r
21 {\r
22 \r
23 HTTPD::HTTPD()\r
24 {\r
25     _controller  = NULL;\r
26     _tuner_count = -1;\r
27     _tuners      = NULL;\r
28     _httpd       = NULL;\r
29     _port        = -1;\r
30     _path        = NULL;\r
31 }\r
32 \r
33 HTTPD::~HTTPD()\r
34 {\r
35     RELEASE(_httpd);\r
36     RELEASE(_path);\r
37 }\r
38 \r
39 HTTPD *HTTPD::alloc()\r
40 {\r
41     return new HTTPD();\r
42 }\r
43 \r
44 HTTPD *HTTPD::initWithController(Controller *controller, int port, String *path)\r
45 {\r
46     _controller  = controller;\r
47     _tuner_count = controller->_tuner_count;\r
48     _tuners      = controller->_tuners;\r
49 \r
50     _port        = port;\r
51     _path        = path->retain();\r
52 \r
53     return this;\r
54 }\r
55 \r
56 bool HTTPD::start()\r
57 {\r
58     if (_httpd == NULL)\r
59     {\r
60         _httpd = HTTPDaemon::alloc()->initWithPort(_port, 10);\r
61         _httpd->setRootPath(_path);\r
62         _httpd->setDelegate(this);\r
63     }\r
64     return _httpd->start();\r
65 }\r
66 \r
67 void HTTPD::stop()\r
68 {\r
69     _httpd->stop();\r
70 }\r
71 \r
72 HTTPResponse *HTTPD::request(HTTPRequest *request, SOCKADDR_IN *client)\r
73 {\r
74     DebugLog2("%s\n", __FUNCTION__);\r
75 \r
76     // 初期化チェック\r
77     bool flag = false;\r
78     EnterCriticalSection(&_cs);\r
79 //    flag = _initialized;\r
80     LeaveCriticalSection(&_cs);\r
81     if (!flag)\r
82     {\r
83 //        return NULL;\r
84     }\r
85 \r
86     HTTPResponse *response = NULL;\r
87 \r
88     if (request->method()->isEqualToString("GET") ||\r
89         request->method()->isEqualToString("HEAD"))\r
90     {\r
91         // URI\r
92         String *uri = request->URI();\r
93         DebugLog0("request: %s\n", uri->cString());\r
94         if (uri->isMatch("^/config.xml$"))\r
95         {\r
96             RaymLock(_controller);\r
97             response = responseWithDictionary(request, _controller->_props);\r
98             RaymUnlock(_controller);\r
99         }\r
100         else if (uri->isMatch("^/status.xml$"))\r
101         {\r
102             RaymLock(_controller);\r
103             response = responseWithDictionary(request, _controller->_status);\r
104             RaymUnlock(_controller);\r
105         }\r
106         //\r
107         // tuner control\r
108         //\r
109         else if (uri->isMatch("^/[0-9]{3}/"))\r
110         {\r
111             // String::substringWithRange() の実装は後回しなので。。\r
112             std::string s = uri->cString();\r
113             int tuner = atoi(s.substr(1, 3).c_str());\r
114             if ((0 <= tuner) && (tuner < _tuner_count))\r
115             {\r
116                 response = requestTunerControl(request, client, tuner);\r
117             }\r
118         }\r
119     }\r
120 \r
121     return response;\r
122 }\r
123 \r
124 HTTPResponse *HTTPD::requestTunerControl(HTTPRequest *request, SOCKADDR_IN *client, int tuner)\r
125 {\r
126     DebugLog0("%s\n", __FUNCTION__);\r
127 \r
128     HTTPResponse *result = NULL;\r
129 \r
130     // lock\r
131     RaymLock(_controller);\r
132 \r
133     // URI取得\r
134     String *uri = request->URI();\r
135     while (uri != NULL)\r
136     {\r
137         // CGIリクエストとして解析\r
138         Dictionary *cgi = request->parseAsCGI();\r
139         if (cgi != NULL)\r
140         {\r
141             uri = cgi->stringForKey(HTTPRequest::KEY_CGI);\r
142             if (uri == NULL)\r
143             {\r
144                 break;\r
145             }\r
146         }\r
147 \r
148         if (uri->isMatch("^/iptv.m3u8$"))\r
149         {\r
150             return responseForPlaylist(request, client);\r
151         }\r
152 \r
153         //\r
154         // チャンネル設定\r
155         //   /ttt/channel=nnn\r
156         //\r
157         else if (uri->isMatch("^/[0-9]{3}/channel=[0-9]{1,3}$") && (cgi == NULL))\r
158         {\r
159             String *ch = uri->substringFromIndex(13);\r
160             if (ch == NULL)\r
161             {\r
162                 break;\r
163             }\r
164             int channel = ch->intValue();\r
165             DebugLog2("set channel:%d(%s)\n", channel, ch->cString());\r
166             if (_controller->setChannel(tuner, channel))\r
167             {\r
168                 // success\r
169                 DebugLog2("success.\n");\r
170                 result = responseForSuccess(request);\r
171             }\r
172             else\r
173             {\r
174                 // failed\r
175                 DebugLog2("failed.\n");\r
176                 result = responseForFailed(request);\r
177             }\r
178         }\r
179 \r
180         //\r
181         // 録画開始(最大23:59まで)\r
182         //   /ttt/recording=on?hour=hh&min=mm[&channel=nnn]\r
183         //\r
184         else if (uri->isMatch("^/[0-9]{3}/recording=on$") && (cgi != NULL))\r
185         {\r
186             // パラメータがあるか\r
187             Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
188             if (params == NULL)\r
189             {\r
190                 break;\r
191             }\r
192 \r
193             // パラメータ数は2〜3か\r
194             if ((params->count() != 2) && (params->count() != 3))\r
195             {\r
196                 break;\r
197             }\r
198 \r
199             // パラメータのチェック\r
200             String *p_hour    = NULL;\r
201             String *p_min     = NULL;\r
202             String *p_channel = NULL;\r
203 \r
204             struct {\r
205                 const char *name;\r
206                 String **variable;\r
207                 const char *regex;\r
208             }\r
209             cgi[] =\r
210             {\r
211                 {"hour",    &p_hour,    "^[0-2][0-9]$"},\r
212                 {"min",     &p_min,     "^[0-5][0-9]$"},\r
213                 {"channel", &p_channel, "^[0-9]{3}$"},\r
214                 {NULL, NULL, NULL}\r
215             };\r
216 \r
217             for (uint i = 0; cgi[i].name != NULL; ++i)\r
218             {\r
219                 *(cgi[i].variable) = NULL;\r
220                 for (uint j = 0; j < params->count(); ++j)\r
221                 {\r
222                     Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
223                     String *value = param->stringForKey(cgi[i].name);\r
224                     if ((value != NULL) && value->isMatch(cgi[i].regex))\r
225                     {\r
226                         *(cgi[i].variable) = value;\r
227                     }\r
228                 }\r
229             }\r
230 \r
231             // パラメータは有効か\r
232             if ((p_hour == NULL) || (p_min == NULL))\r
233             {\r
234                 break;\r
235             }\r
236 \r
237             // チャンネル設定\r
238             int channel = 0;\r
239             if (p_channel != NULL)\r
240             {\r
241                 channel = p_channel->intValue();\r
242             }\r
243             else\r
244             {\r
245                 channel = _tuners[tuner]->channel();\r
246             }\r
247 \r
248             if (channel >= 0)\r
249             {\r
250                 // recording on\r
251                 int hour = p_hour->intValue();\r
252                 int min = p_min->intValue();\r
253                 if (hour < 24)\r
254                 {\r
255                     // EPG生成\r
256                     Dictionary *epg = Dictionary::dictionaryWithCapacity(0);\r
257                     while (true)\r
258                     {\r
259                         time_t now;\r
260                         time(&now);\r
261                         now += 1; // margin\r
262                         TM tm;\r
263                         if (localtime_s(&tm, &now) != 0)\r
264                         {\r
265                             epg = NULL;\r
266                             break;\r
267                         }\r
268                         TM end;\r
269                         end = tm;\r
270                         end.tm_hour += hour;\r
271                         end.tm_min += min;\r
272                         end.tm_sec += 1; // margin\r
273                         if (mktime(&end) == -1)\r
274                         {\r
275                             epg = NULL;\r
276                             break;\r
277                         }\r
278 \r
279                         char tmp[16];\r
280 \r
281                         // Date\r
282                         sprintf_s(tmp, sizeof(tmp), "%04d/%02d/%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday);\r
283                         epg->setString(tmp, KEY_EPG_DATE);\r
284 \r
285                         // Start\r
286                         sprintf_s(tmp, sizeof(tmp), "%02d:%02d:%02d", tm.tm_hour, tm.tm_min, tm.tm_sec);\r
287                         epg->setString(tmp, KEY_EPG_START);\r
288 \r
289                         // End\r
290                         sprintf_s(tmp, sizeof(tmp), "%02d:%02d:%02d", end.tm_hour, end.tm_min, end.tm_sec);\r
291                         epg->setString(tmp, KEY_EPG_END);\r
292 \r
293                         // Channel\r
294                         sprintf_s(tmp, sizeof(tmp), "%d", channel);\r
295                         epg->setString(tmp, KEY_EPG_CHANNEL);\r
296 \r
297                         // 繰り返し\r
298                         epg->setString("off", KEY_EPG_REPEAT); \r
299 \r
300                         // Status\r
301                         epg->setString("ready", KEY_EPG_STATUS);\r
302 \r
303                         break;\r
304                     }\r
305                 \r
306                     if (epg != NULL)\r
307                     {\r
308                         // 録画開始&結果生成\r
309                         if (_controller->_reservation->reserve(tuner, epg))\r
310                         {\r
311                             result = responseForSuccess(request);\r
312                         }\r
313                         else\r
314                         {\r
315                             result = responseForFailed(request);\r
316                         }\r
317                     }\r
318                 }\r
319             }\r
320         }\r
321 \r
322         //\r
323         // 録画停止\r
324         //   /ttt/recording=off\r
325         //\r
326         else if (uri->isMatch("^/[0-9]{3}/recording=off$") && (cgi == NULL))\r
327         {\r
328             // recording off\r
329             DebugLog2("recording off: %s\n", uri->cString());\r
330             if (_controller->_reservation->cancel(tuner, -1))\r
331             {\r
332                 // success\r
333                 DebugLog2("success.\n");\r
334                 result = responseForSuccess(request);\r
335             }\r
336             else\r
337             {\r
338                 // failed\r
339                 DebugLog2("failed.\n");\r
340                 result = responseForFailed(request);\r
341             }\r
342         }\r
343 \r
344         //\r
345         // ストリーミング開始\r
346         //   /ttt/streaming=on?udp=nnnnn(&host=aaaaaa)\r
347         //\r
348         else if (uri->isMatch("^/[0-9]{3}/streaming=on$") && (cgi != NULL))\r
349         {\r
350             // パラメータがあるか\r
351             Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
352             if (params == NULL)\r
353             {\r
354                 break;\r
355             }\r
356 \r
357             // パラメータ数は1〜2か\r
358             if ((params->count() != 1) && (params->count() != 2))\r
359             {\r
360                 break;\r
361             }\r
362 \r
363             // パラメータのチェック\r
364             String *p_udp  = NULL;\r
365             String *p_host = NULL;\r
366 \r
367             struct {\r
368                 const char *name;\r
369                 String **variable;\r
370                 const char *regex;\r
371             }\r
372             cgi[] =\r
373             {\r
374                 {"udp",  &p_udp,  "^[0-9]{1,5}$"},\r
375                 {"host", &p_host, "^.+$"},\r
376                 {NULL, NULL, NULL}\r
377             };\r
378 \r
379             for (uint i = 0; cgi[i].name != NULL; ++i)\r
380             {\r
381                 *(cgi[i].variable) = NULL;\r
382                 for (uint j = 0; j < params->count(); ++j)\r
383                 {\r
384                     Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
385                     String *value = param->stringForKey(cgi[i].name);\r
386                     if ((value != NULL) && value->isMatch(cgi[i].regex))\r
387                     {\r
388                         *(cgi[i].variable) = value;\r
389                     }\r
390                 }\r
391             }\r
392 \r
393             // パラメータチェック\r
394             if (p_udp == NULL)\r
395             {\r
396                 break;\r
397             }\r
398 \r
399             SOCKADDR_IN dst_addr;\r
400             \r
401             if (p_host != NULL)\r
402             {\r
403     #if 0\r
404                 std::string host = udpstr.substr(idx + 5);\r
405                 udpstr = udpstr.substr(0, idx - 1);\r
406                 DebugLog2("udp: %s\n", udpstr.c_str());\r
407                 DebugLog2("host: %s\n", host.c_str());\r
408                 struct hostent *ent = gethostbyname(host.c_str());\r
409     #endif\r
410             }\r
411             else\r
412             {\r
413                 memcpy(&dst_addr, client, sizeof(SOCKADDR_IN));\r
414             }\r
415             dst_addr.sin_port = htons(p_udp->intValue());\r
416             \r
417             if (_tuners[tuner]->startStreaming(&dst_addr))\r
418             {\r
419                 // success\r
420                 DebugLog2("success.\n");\r
421                 result = responseForSuccess(request);\r
422             }\r
423             else\r
424             {\r
425                 // failed\r
426                 DebugLog2("failed.\n");\r
427                 result = responseForFailed(request);\r
428             }\r
429         }\r
430 \r
431         //\r
432         // ストリーミング停止\r
433         //   /ttt/streaming=off(?host=aaaa)\r
434         //\r
435         else if (uri->isMatch("^/[0-9]{3}/streaming=off$"))\r
436         {\r
437             // パラメータ\r
438             String *p_host = NULL;\r
439 \r
440             // パラメータがあるか\r
441             if (cgi != NULL)\r
442             {\r
443                 Array *params = cgi->arrayForKey(HTTPRequest::KEY_PARAMS);\r
444                 if (params == NULL)\r
445                 {\r
446                     break;\r
447                 }\r
448 \r
449                 // パラメータ数は0〜1か\r
450                 if ((params->count() != 0) && (params->count() != 1))\r
451                 {\r
452                     break;\r
453                 }\r
454 \r
455                 struct {\r
456                     const char *name;\r
457                     String **variable;\r
458                     const char *regex;\r
459                 }\r
460                 cgi[] =\r
461                 {\r
462                     {"host", &p_host, "^.+$"},\r
463                     {NULL, NULL, NULL}\r
464                 };\r
465 \r
466                 for (uint i = 0; cgi[i].name != NULL; ++i)\r
467                 {\r
468                     *(cgi[i].variable) = NULL;\r
469                     for (uint j = 0; j < params->count(); ++j)\r
470                     {\r
471                         Dictionary *param = (Dictionary *)params->objectAtIndex(j);\r
472                         String *value = param->stringForKey(cgi[i].name);\r
473                         if ((value != NULL) && value->isMatch(cgi[i].regex))\r
474                         {\r
475                             *(cgi[i].variable) = value;\r
476                         }\r
477                     }\r
478                 }\r
479             }\r
480 \r
481             SOCKADDR_IN dst_addr;\r
482             if (p_host != NULL)\r
483             {\r
484             }\r
485             else\r
486             {\r
487             }\r
488 \r
489             _tuners[tuner]->stopStreaming();\r
490             \r
491             // success\r
492             DebugLog2("success.\n");\r
493             result = responseForSuccess(request);\r
494         }\r
495 \r
496         //\r
497         // HLS制御\r
498         //\r
499         else if (uri->isMatch("^/[0-9]{3}/[0-9]{3}/streaming(-[^\\.]+)?.m3u8$") && (cgi == NULL))\r
500         {\r
501             DebugLog0("uri: %s", uri->cString());\r
502 /*\r
503             // URIからチャンネル番号を抽出\r
504             //   Range実装したい...\r
505             int ch = uri->substringFromIndex(5)->substringToIndex(3)->intValue();\r
506             DebugLog0("ch: %d", ch);\r
507 \r
508             // presetが指定されている場合、presetを抽出\r
509             String *preset = NULL;\r
510             if (uri->isMatch("streaming-"))\r
511             {\r
512                 preset = uri->substringFromIndex(19);\r
513                 preset = preset->substringToIndex(preset->length() - 5);\r
514                 DebugLog0("opt: preset: %s", preset->cString());\r
515             }\r
516             else\r
517             {\r
518                 // なければ "default"\r
519                 preset = NSString::stringWithUTF8String(KEY_DEFAULT);\r
520             }\r
521 \r
522             // チャンネル/presetが有効か確認\r
523             if (isChannelEnabled(tuner, ch) &&\r
524                 (_props->dictionaryForKey(KEY_PRESETS) != NULL) &&\r
525                 (_props->dictionaryForKey(KEY_PRESETS)->objectForKey(preset) != NULL))\r
526             {\r
527                 // \r
528                 result = responseForHLSControl(request, client, tuner, ch, preset);\r
529             }\r
530             else\r
531             {\r
532                 result = responseForFailed(request);\r
533             }\r
534             DebugLog0("hls req. done");\r
535 */\r
536         }\r
537         else if (uri->isMatch("^/[0-9]{3}/[0-9]{3}/streaming-[0-9]+.ts$") && (cgi == NULL))\r
538         {\r
539             // 分割されたTS\r
540             DebugLog0("uri: %s", uri->cString());\r
541         }\r
542 \r
543         break;\r
544     }\r
545 \r
546     // unlock\r
547     RaymUnlock(_controller);\r
548 \r
549     return result;\r
550 }\r
551 \r
552 HTTPResponse *HTTPD::responseForPlaylist(HTTPRequest *request, SOCKADDR_IN *client)\r
553 {\r
554     HTTPResponse *result = NULL;\r
555     // http://bit.ly/iptv_feb2015\r
556 \r
557 #if 0\r
558 \r
559 #EXTM3U\r
560 \r
561 #EXTINF:-1, [COLOR yellow]Updated 15/04/2015 @ 03:45 [/COLOR]  \r
562 plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
563 #EXTINF:-1, [COLOR green] --Uk Live Tv--[/COLOR]  \r
564 plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
565 #EXTINF:-1, [COLOR green] --Free Collection of IPTV sports links--[/COLOR]  \r
566 plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
567 #EXTINF:-1, [COLOR red] --Links will go down. Please note that it will take time to update--[/COLOR]\r
568 plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
569 #EXTINF:-1, [COLOR red] --Please contact me at the husham.com website--[/COLOR]\r
570 plugin://plugin.video.youtube/?action=play_video&videoid=eMduu81gNgM\r
571 \r
572 #EXTINF:-1, Sky sports news\r
573 rtmp://89.248.172.159:443/liverepeater playpath=35 swfUrl=http://popeoftheplayers.eu/atdedead.swf pageUrl=http://popeoftheplayers.eu/crichd.php?id=35&width=600&height=450 token=#atd%#$ZH\r
574 #EXTINF:-1,Bt sports 1\r
575 rtmp://80.82.78.87:443/liverepeater/starsp pageUrl=http://xxxxxxxxxxxxxxxx.xx/rtmpe://strm.dcast.tv:1935/live/asdfadfaa/pageUrl=http://xxxxx.xx/rtmp://80.82.64.90:443/liverepeater/79/pageUrl=http://filotv.pw/rtmpe://strm.ukcast.tv:1935/redirect/FUNKTSN/pageUrl=http://ukcast.tv/rtmp://173.192.81.176:443/liverepeater/stream1/token%ZZri(nKa@#Z/pageUrl=http://hdcast.org/cdn.kingofplayers.com/rtmpe://46.246.29.152:1935/redirect/HDMNBC playpath=41?18?49?33?48?38?11 pageUrl=http://popeoftheplayers.eu/hdcast.org/rtmp://31.220.0.134:1935/live/tsn2/pageUrl=http://www.eucast.tv/rtmp://195.154.236.152:80/liverepeater/141449/pageUrl=http://goodcast.pw/rtmp://77.81.98.134/tv/bt1h28qn?v=pageUrl=http://castok.com/rtmp://89.46.102.70:443/liveedge/bt1pageUrl=http://hqstreams.tv/rtmpe://play.finecast.tv/live/hqbt1page/playpath=42?finecast.tv/rtmpe://cdn.hdcast.org:1935/redirect/swfUrl=http://www.hdcast.org/aplayer/jwplayer.flash.swfpageUrl=http://www.hdcast.org/token=Fo5_n0w?U.rA6l3-70w47ch@#8x12pX@ token=#atd%#$ZH\r
576 \r
577 #endif\r
578 \r
579 \r
580     std::string contents;\r
581     contents = "#EXTM3U\r\n";\r
582     contents += "\r\n";\r
583 \r
584 /*\r
585     Dictionary *tuner_channel_to_udp = _streaming_ctrls->dictionaryForKey(KEY_MAPPING_TUNER_CHANNEL_TO_UDP);\r
586     if (tuner_channel_to_udp != NULL)\r
587     {\r
588         Tuner::Type types[] = {Tuner::ISDB_T, Tuner::ISDB_S};\r
589         for (int t = 0; t < sizeof(types) / sizeof(Tuner::Type); ++t)\r
590         {\r
591             for (int i = 0; i < _tunerCount; ++i)\r
592             {\r
593                 if (isTunerInitialized(i) && (_tuners[i]->type() == types[t]))\r
594                 {\r
595                     uint ch_max = ((types[t] == Tuner::ISDB_T) ? Tuner::MAX_CHANNELS_ISDB_T : Tuner::MAX_CHANNELS_ISDB_S);\r
596                     for (uint ch = 0; ch <= ch_max; ++ch)\r
597                     {\r
598                         if (isChannelEnabled(i, ch))\r
599                         {\r
600                             char tuner_and_channel[10];\r
601                             sprintf_s(tuner_and_channel, "%d,%d", i, ch);\r
602                             char *chstr = strchr(tuner_and_channel, ',');\r
603                             if (chstr != NULL)\r
604                             {\r
605                                 ++chstr;\r
606                             }\r
607 \r
608                             NSString *udp_str = tuner_channel_to_udp->stringForKey(tuner_and_channel);\r
609                             if (udp_str != NULL)\r
610                             {\r
611                                 contents += "#EXTINF:-1 tvg-id=\"";\r
612                                 contents += tuner_and_channel;\r
613                                 contents += "\" tvg-logo=\"";\r
614                                 contents += ((types[t] == Tuner::ISDB_T) ? "t_" : "s_");\r
615                                 if (chstr != NULL)\r
616                                 {\r
617                                     contents += chstr;\r
618                                 }\r
619                                 else\r
620                                 {\r
621                                     contents += "ffff";\r
622                                 }\r
623                                 contents += "\" group-title=\"";\r
624                                 contents += _tuners[i]->name();\r
625                                 contents += "\", ";\r
626                                 NSString *station_name = stationName(types[t], ch);\r
627                                 if (station_name != NULL)\r
628                                 {\r
629                                     contents += station_name->cString();\r
630                                 }\r
631                                 else\r
632                                 {\r
633                                     contents += tuner_and_channel;\r
634                                 }\r
635                                 contents += "\r\n";\r
636                                 contents += "udp://0.0.0.0:";\r
637                                 contents += udp_str->cString();\r
638                                 contents += "\r\n";\r
639                             }\r
640                         }\r
641                     }\r
642                 }\r
643             }\r
644         }\r
645 \r
646     }\r
647 */\r
648     String *text = String::stringWithUTF8String(contents.c_str());\r
649     if (text != NULL)\r
650     {\r
651         result = responseWithUTF8Text(request, text);\r
652     }\r
653 \r
654     return result;\r
655 }\r
656 \r
657 // positive response by XML\r
658 HTTPResponse *HTTPD::responseForSuccess(HTTPRequest *request)\r
659 {\r
660     Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
661     dict->setString("Success", KEY_RESULT);\r
662     return responseWithDictionary(request, dict);\r
663 }\r
664 \r
665 // negative response by XML\r
666 HTTPResponse *HTTPD::responseForFailed(HTTPRequest *request)\r
667 {\r
668     Dictionary *dict = Dictionary::dictionaryWithCapacity(0);\r
669     dict->setString("Failed", KEY_RESULT);\r
670     return responseWithDictionary(request, dict);\r
671 }\r
672 \r
673 HTTPResponse *HTTPD::responseWithDictionary(HTTPRequest *request, Dictionary *dictionary)\r
674 {\r
675     HTTPResponse *result = NULL;\r
676     if ((request != NULL) && (dictionary != NULL))\r
677     {\r
678         std::string xml = dictionary->toString();\r
679 \r
680         // header\r
681         InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->init();\r
682         // Date\r
683         // Server\r
684         // Content-Encoding\r
685         // Last-Modified\r
686         // Content-Type\r
687         header->setFieldBodyWithName("application/xml", "Content-Type");\r
688         // Connection\r
689         // Tranfer-Encoding\r
690         // Content-Length\r
691         header->setFieldBodyWithName(String::stringWithFormat("%I64u", xml.length()), "Content-Length");\r
692 \r
693         // body\r
694         InternetTextMessageBody *body = InternetTextMessageBody::alloc()->initWithString(String::stringWithUTF8String(xml.c_str()));\r
695 \r
696         // message\r
697         InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);\r
698         RELEASE(header);\r
699         RELEASE(body);\r
700         if (message != NULL)\r
701         {\r
702             result = HTTPResponse::alloc()->init();\r
703             result->autorelease();\r
704             result->setVersion(request->version());\r
705             result->setReason(NET::HTTPDaemon::reasonForStatus(200));\r
706             result->setStatus(200);\r
707             result->setMessage(message);\r
708             RELEASE(message);\r
709         }\r
710     }\r
711     return result;\r
712 }\r
713 \r
714 HTTPResponse *HTTPD::responseWithUTF8Text(HTTPRequest *request, String *text)\r
715 {\r
716     HTTPResponse *result = NULL;\r
717     if ((text != NULL) && (request != NULL))\r
718     {\r
719         // header\r
720         InternetTextMessageHeader *header = InternetTextMessageHeader::alloc()->init();\r
721         // Date\r
722         // Server\r
723         // Content-Encoding\r
724         // Last-Modified\r
725         // Content-Type\r
726         header->setFieldBodyWithName("text/plane; charset=UTF-8", "Content-Type");\r
727         // Connection\r
728         // Tranfer-Encoding\r
729         // Content-Length\r
730         header->setFieldBodyWithName(String::stringWithFormat("%I64u", text->length()), "Content-Length");\r
731 \r
732         // body\r
733         InternetTextMessageBody *body = InternetTextMessageBody::alloc()->initWithString(text);\r
734 \r
735         // message\r
736         InternetTextMessage *message = InternetTextMessage::alloc()->initWithHeaderAndBody(header, body);\r
737         RELEASE(header);\r
738         RELEASE(body);\r
739         if (message != NULL)\r
740         {\r
741 //            result = HTTPResponse::response();\r
742             result = HTTPResponse::alloc()->init();\r
743             result->setVersion(request->version());\r
744             result->setReason(NET::HTTPDaemon::reasonForStatus(200));\r
745             result->setStatus(200);\r
746             result->setMessage(message);\r
747             result->autorelease();\r
748             RELEASE(message);\r
749         }\r
750     }\r
751     return result;\r
752 }\r
753 \r
754 } // iPTd\r
755 } // ry0\r