1 // ------------------------------------------------
6 // HTML protocol handling
8 // (c) 2002 peercast.org
9 // ------------------------------------------------
10 // This program is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU General Public License as published by
12 // the Free Software Foundation; either version 2 of the License, or
13 // (at your option) any later version.
15 // This program is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 // GNU General Public License for more details.
19 // ------------------------------------------------
33 #include "chkMemoryLeak.h"
34 #define DEBUG_NEW new(__FILE__, __LINE__)
39 // --------------------------------------
40 HTML::HTML(const char *t, Stream &o)
43 out = new WriteBufferStream(8192, &o);
44 out->writeCRLF = false;
55 } catch (StreamException &) {}
59 // --------------------------------------
60 void HTML::writeOK(const char *content)
62 out->writeLine(HTTP_SC_OK);
63 out->writeLineF("%s %s",HTTP_HS_SERVER,PCX_AGENT);
64 //out->writeLine("%s %s",HTTP_HS_CACHE,"no-cache");
65 out->writeLineF("%s %s",HTTP_HS_CONNECTION,"close");
66 out->writeLineF("%s %s",HTTP_HS_CONTENT,content);
69 // --------------------------------------
70 void HTML::writeVariable(Stream &s,const String &varName, int loop)
73 if (varName.startsWith("servMgr."))
74 r=servMgr->writeVariable(s,varName+8);
75 else if (varName.startsWith("chanMgr."))
76 r=chanMgr->writeVariable(s,varName+8,loop);
77 else if (varName.startsWith("stats."))
78 r=stats.writeVariable(s,varName+6);
79 else if (varName.startsWith("sys."))
81 if (varName == "sys.log.dumpHTML")
83 sys->logBuf->dumpHTML(s);
87 else if (varName.startsWith("loop."))
89 if (varName.startsWith("loop.channel."))
91 Channel *ch = chanMgr->findChannelByIndex(loop);
93 r = ch->writeVariable(s,varName+13,loop);
94 }else if (varName.startsWith("loop.servent."))
96 Servent *sv = servMgr->findServentByIndex(loop);
98 r = sv->writeVariable(s,varName+13);
99 }else if (varName.startsWith("loop.filter."))
101 ServFilter *sf = &servMgr->filters[loop];
102 r = sf->writeVariable(s,varName+12);
104 }else if (varName.startsWith("loop.bcid."))
106 BCID *bcid = servMgr->findValidBCID(loop);
108 r = bcid->writeVariable(s,varName+10);
110 }else if (varName == "loop.indexEven")
112 s.writeStringF("%d",(loop&1)==0);
114 }else if (varName == "loop.index")
116 s.writeStringF("%d",loop);
118 }else if (varName.startsWith("loop.hit."))
120 char *idstr = getCGIarg(tmplArgs,"id=");
125 ChanHitList *chl = chanMgr->findHitListByID(id);
129 ChanHit *ch = chl->hit;
132 if (ch->host.ip && !ch->dead)
136 r = ch->writeVariable(s,varName+9);
149 else if (varName.startsWith("page."))
151 if (varName.startsWith("page.channel."))
153 char *idstr = getCGIarg(tmplArgs,"id=");
158 Channel *ch = chanMgr->findChannelByID(id);
160 r = ch->writeVariable(s,varName+13,loop);
165 String v = varName+5;
167 char *a = getCGIarg(tmplArgs,v);
178 s.writeString(varName);
180 // --------------------------------------
181 int HTML::getIntVariable(const String &varName,int loop)
184 LOG_DEBUG("AAA %d %d %d %d", val[0], val[1], val[2], val[3]);
185 MemoryStream mem(val.cstr(),String::MAX_LEN);
187 writeVariable(mem,varName,loop);
189 LOG_DEBUG("AAA %d %d %d %d", val[0], val[1], val[2], val[3]);
190 return atoi(val.cstr());
192 // --------------------------------------
193 bool HTML::getBoolVariable(const String &varName,int loop)
196 MemoryStream mem(val.cstr(),String::MAX_LEN);
198 writeVariable(mem,varName,loop);
202 LOG_DEBUG("*** %s : %c", tmp.cstr(), val[0]);
205 if ((val[0] >= '0') && (val[0] <= '9'))
206 return atoi(val.cstr()) != 0;
215 // --------------------------------------
216 void HTML::readIf(Stream &in,Stream *outp,int loop)
223 char c = in.readChar();
227 if (getBoolVariable(var,loop)==varCond)
229 LOG_DEBUG("==varCond, loop = %d", loop);
230 if (readTemplate(in,outp,loop))
231 readTemplate(in,NULL,loop);
233 LOG_DEBUG("!=varCond, loop = %d", loop);
234 if (readTemplate(in,NULL,loop))
235 readTemplate(in,outp,loop);
249 // --------------------------------------
250 void HTML::readLoop(Stream &in,Stream *outp,int loop)
255 char c = in.readChar();
259 int cnt = getIntVariable(var,loop);
261 LOG_DEBUG("loop_cnt : %s = %d", var.cstr(), cnt);
265 int spos = in.getPosition();
266 for(int i=0; i<cnt; i++)
269 readTemplate(in,outp,i);
273 readTemplate(in,NULL,0);
285 // --------------------------------------
286 int HTML::readCmd(Stream &in,Stream *outp,int loop)
290 int tmpl = TMPL_UNKNOWN;
294 char c = in.readChar();
296 if (String::isWhitespace(c) || (c=='}'))
300 readLoop(in,outp,loop);
302 }else if (cmd == "if")
304 readIf(in,outp,loop);
306 }else if (cmd == "end")
310 else if (cmd == "else")
323 // --------------------------------------
324 void HTML::readVariable(Stream &in,Stream *outp,int loop)
329 char c = in.readChar();
333 writeVariable(*outp,var,loop);
342 // --------------------------------------
343 bool HTML::readTemplate(Stream &in,Stream *outp,int loop)
347 char c = in.readChar();
354 readVariable(in,outp,loop);
358 int t = readCmd(in,outp,loop);
361 else if (t == TMPL_ELSE)
370 throw StreamException("Unknown template escape");
380 // --------------------------------------
381 void HTML::writeTemplate(const char *fileName, const char *args)
387 file.openReadOnly(fileName);
388 mm.readFromFile(file);
391 readTemplate(mm,out,0);
393 }catch(StreamException &e)
395 out->writeString(e.msg);
396 out->writeString(" : ");
397 out->writeString(fileName);
403 // --------------------------------------
404 void HTML::writeRawFile(const char *fileName)
409 file.openReadOnly(fileName);
411 file.writeTo(*out,file.length());
413 }catch(StreamException &)
420 // --------------------------------------
421 void HTML::locateTo(const char *url)
423 out->writeLine(HTTP_SC_FOUND);
424 out->writeLineF("Location: %s",url);
427 // --------------------------------------
428 void HTML::startHTML()
432 // --------------------------------------
433 void HTML::startBody()
437 // --------------------------------------
442 startTagEnd("title",title.cstr());
443 startTagEnd("meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\"");
445 if (!refreshURL.isEmpty())
447 sprintf(buf,"meta http-equiv=\"refresh\" content=\"%d;URL=%s\"",refresh,refreshURL.cstr());
451 sprintf(buf,"meta http-equiv=\"refresh\" content=\"%d\"",refresh);
458 // --------------------------------------
459 void HTML::addContent(const char *s)
463 // --------------------------------------
464 void HTML::startNode(const char *tag, const char *data)
467 char *o = &currTag[tagLevel][0];
470 for(i=0; i<MAX_TAGLEN-1; i++)
473 if ((c==0) || (c==' '))
480 out->writeString("<");
481 out->writeString(tag);
482 out->writeString(">");
484 out->writeString(data);
487 if (tagLevel >= MAX_TAGLEVEL)
488 throw StreamException("HTML too deep!");
490 // --------------------------------------
495 throw StreamException("HTML premature end!");
497 out->writeString("</");
498 out->writeString(&currTag[tagLevel][0]);
499 out->writeString(">");
501 // --------------------------------------
502 void HTML::addLink(const char *url, const char *text, bool toblank)
506 sprintf(buf,"a href=\"%s\" %s",url,toblank?"target=\"_blank\"":"");
510 // --------------------------------------
511 void HTML::startTag(const char *tag, const char *fmt,...)
520 vsprintf(tmp,fmt,ap);
528 // --------------------------------------
529 void HTML::startTagEnd(const char *tag, const char *fmt,...)
538 vsprintf(tmp,fmt,ap);
547 // --------------------------------------
548 void HTML::startSingleTagEnd(const char *fmt,...)
554 vsprintf(tmp,fmt,ap);
561 // --------------------------------------
562 void HTML::startTableRow(int i)
565 startTag("tr bgcolor=\"#dddddd\" align=\"left\"");
567 startTag("tr bgcolor=\"#eeeeee\" align=\"left\"");