html.cpp
上传用户:chn_coc
上传日期:2007-12-20
资源大小:563k
文件大小:10k
源码类别:

P2P编程

开发平台:

Windows_Unix

  1. // ------------------------------------------------ // File : html.cpp // Date: 4-apr-2002 // Author: giles // Desc:  // HTML protocol handling // // (c) 2002 peercast.org // ------------------------------------------------ // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 2 of the License, or // (at your option) any later version. // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the // GNU General Public License for more details. // ------------------------------------------------ #include <stdarg.h> #include <stdlib.h>
  2. #include "html.h" #include "http.h" #include "stream.h" #include "gnutella.h" #include "servmgr.h" #include "channel.h" #include "stats.h"
  3. #include "version2.h"
  4. // -------------------------------------- HTML::HTML(const char *t, Stream &o) { out = &o; out->writeCRLF = false; title.set(t); tagLevel = 0; refresh = 0; } // -------------------------------------- void HTML::writeOK(const char *content) { out->writeLine(HTTP_SC_OK); out->writeLineF("%s %s",HTTP_HS_SERVER,PCX_AGENT); //out->writeLine("%s %s",HTTP_HS_CACHE,"no-cache"); out->writeLineF("%s %s",HTTP_HS_CONNECTION,"close");     out->writeLineF("%s %s",HTTP_HS_CONTENT,content);
  5. out->writeLine(""); } // -------------------------------------- void HTML::writeVariable(Stream &s,const String &varName, int loop) { bool r=false; if (varName.startsWith("servMgr.")) r=servMgr->writeVariable(s,varName+8); else if (varName.startsWith("chanMgr.")) r=chanMgr->writeVariable(s,varName+8,loop); else if (varName.startsWith("stats.")) r=stats.writeVariable(s,varName+6);
  6. else if (varName.startsWith("sys."))
  7. {
  8. if (varName == "sys.log.dumpHTML")
  9. {
  10. sys->logBuf->dumpHTML(s);
  11. r=true;
  12. }
  13. }
  14. else if (varName.startsWith("loop."))
  15. {
  16. if (varName.startsWith("loop.channel."))
  17. {
  18. Channel *ch = chanMgr->findChannelByIndex(loop);
  19. if (ch)
  20. r = ch->writeVariable(s,varName+13,loop);
  21. }else if (varName.startsWith("loop.servent."))
  22. {
  23. Servent *sv = servMgr->findServentByIndex(loop);
  24. if (sv)
  25. r = sv->writeVariable(s,varName+13);
  26. }else if (varName.startsWith("loop.filter."))
  27. {
  28. ServFilter *sf = &servMgr->filters[loop];
  29. r = sf->writeVariable(s,varName+12);
  30. }else if (varName.startsWith("loop.bcid."))
  31. {
  32. BCID *bcid = servMgr->findValidBCID(loop);
  33. if (bcid)
  34. r = bcid->writeVariable(s,varName+10);
  35. }else if (varName == "loop.indexEven")
  36. {
  37. s.writeStringF("%d",(loop&1)==0);
  38. r = true;
  39. }else if (varName == "loop.index")
  40. {
  41. s.writeStringF("%d",loop);
  42. r = true;
  43. }else if (varName.startsWith("loop.hit."))
  44. {
  45. char *idstr = getCGIarg(tmplArgs,"id=");
  46. if (idstr)
  47. {
  48. GnuID id;
  49. id.fromStr(idstr);
  50. ChanHitList *chl = chanMgr->findHitListByID(id);
  51. if (chl)
  52. {
  53. int cnt=0;
  54. ChanHit *ch = chl->hit;
  55. while (ch)
  56. {
  57. if (ch->host.ip && !ch->dead)
  58. {
  59. if (cnt == loop)
  60. {
  61. r = ch->writeVariable(s,varName+9);
  62. break;
  63. }
  64. cnt++;
  65. }
  66. ch=ch->next;
  67. }
  68. }
  69. }
  70. }
  71. }
  72. else if (varName.startsWith("page."))
  73. {
  74. if (varName.startsWith("page.channel."))
  75. {
  76. char *idstr = getCGIarg(tmplArgs,"id=");
  77. if (idstr)
  78. {
  79. GnuID id;
  80. id.fromStr(idstr);
  81. Channel *ch = chanMgr->findChannelByID(id);
  82. if (ch)
  83. r = ch->writeVariable(s,varName+13,loop);
  84. }
  85. }else
  86. {
  87. String v = varName+5;
  88. v.append('=');
  89. char *a = getCGIarg(tmplArgs,v);
  90. if (a)
  91. {
  92. s.writeString(a);
  93. r=true;
  94. }
  95. }
  96. }
  97. if (!r) s.writeString(varName); } // --------------------------------------
  98. int HTML::getIntVariable(const String &varName,int loop)
  99. {
  100. String val;
  101. MemoryStream mem(val.cstr(),String::MAX_LEN);
  102. writeVariable(mem,varName,loop);
  103. return atoi(val.cstr());
  104. }
  105. // --------------------------------------
  106. bool HTML::getBoolVariable(const String &varName,int loop)
  107. {
  108. String val;
  109. MemoryStream mem(val.cstr(),String::MAX_LEN);
  110. writeVariable(mem,varName,loop);
  111. // integer
  112. if ((val[0] >= '0') && (val[0] <= '9'))
  113. return atoi(val.cstr()) != 0;
  114. // string
  115. if (val[0]!=0)
  116. return true;
  117. return false;
  118. }
  119. // --------------------------------------
  120. void HTML::readIf(Stream &in,Stream *outp,int loop)
  121. {
  122. String var;
  123. bool varCond=true;
  124. while (!in.eof())
  125. {
  126. char c = in.readChar();
  127. if (c == '}')
  128. {
  129. if (getBoolVariable(var,loop)==varCond)
  130. {
  131. if (readTemplate(in,outp,loop))
  132. readTemplate(in,NULL,loop);
  133. }else{
  134. if (readTemplate(in,NULL,loop))
  135. readTemplate(in,outp,loop);
  136. }
  137. return;
  138. }else if (c == '!')
  139. {
  140. varCond = !varCond;
  141. }else
  142. {
  143. var.append(c);
  144. }
  145. }
  146. }
  147. // --------------------------------------
  148. void HTML::readLoop(Stream &in,Stream *outp,int loop)
  149. {
  150. String var;
  151. while (!in.eof())
  152. {
  153. char c = in.readChar();
  154. if (c == '}')
  155. {
  156. int cnt = getIntVariable(var,loop);
  157. if (cnt)
  158. {
  159. int spos = in.getPosition();
  160. for(int i=0; i<cnt; i++)
  161. {
  162. in.seekTo(spos);
  163. readTemplate(in,outp,i);
  164. }
  165. }else
  166. {
  167. readTemplate(in,NULL,0);
  168. }
  169. return;
  170. }else
  171. {
  172. var.append(c);
  173. }
  174. }
  175. }
  176. // --------------------------------------
  177. int HTML::readCmd(Stream &in,Stream *outp,int loop)
  178. {
  179. String cmd;
  180. int tmpl = TMPL_UNKNOWN;
  181. while (!in.eof())
  182. {
  183. char c = in.readChar();
  184. if (String::isWhitespace(c) || (c=='}'))
  185. {
  186. if (cmd == "loop")
  187. {
  188. readLoop(in,outp,loop);
  189. tmpl = TMPL_LOOP;
  190. }else if (cmd == "if")
  191. {
  192. readIf(in,outp,loop);
  193. tmpl = TMPL_IF;
  194. }else if (cmd == "end")
  195. {
  196. tmpl = TMPL_END;
  197. }
  198. else if (cmd == "else")
  199. {
  200. tmpl = TMPL_ELSE;
  201. }
  202. break;
  203. }else
  204. {
  205. cmd.append(c);
  206. }
  207. }
  208. return tmpl;
  209. }
  210. // --------------------------------------
  211. void HTML::readVariable(Stream &in,Stream *outp,int loop)
  212. {
  213. String var;
  214. while (!in.eof())
  215. {
  216. char c = in.readChar();
  217. if (c == '}')
  218. {
  219. if (outp)
  220. writeVariable(*outp,var,loop);
  221. return;
  222. }else
  223. {
  224. var.append(c);
  225. }
  226. }
  227. }
  228. // --------------------------------------
  229. bool HTML::readTemplate(Stream &in,Stream *outp,int loop)
  230. {
  231. while (!in.eof())
  232. {
  233. char c = in.readChar();
  234. if (c == '{')
  235. {
  236. c = in.readChar();
  237. if (c == '$')
  238. {
  239. readVariable(in,outp,loop);
  240. }
  241. else if (c == '@')
  242. {
  243. int t = readCmd(in,outp,loop);
  244. if (t == TMPL_END)
  245. return false;
  246. else if (t == TMPL_ELSE)
  247. return true;
  248. }
  249. else
  250. throw StreamException("Unknown template escape");
  251. }else
  252. {
  253. if (outp)
  254. outp->writeChar(c);
  255. }
  256. }
  257. return false;
  258. }
  259. // -------------------------------------- void HTML::writeTemplate(const char *fileName, const char *args) {
  260. FileStream file; try { file.openReadOnly(fileName);
  261. tmplArgs = args;
  262. readTemplate(file,out,0);
  263. }catch(StreamException &e) { out->writeString(e.msg); out->writeString(" : "); out->writeString(fileName);
  264. } file.close(); } // --------------------------------------
  265. void HTML::writeRawFile(const char *fileName)
  266. {
  267. FileStream file;
  268. try
  269. {
  270. file.openReadOnly(fileName);
  271. file.writeTo(*out,file.length());
  272. }catch(StreamException &)
  273. {
  274. }
  275. file.close();
  276. }
  277. // -------------------------------------- void HTML::locateTo(const char *url) { out->writeLine(HTTP_SC_FOUND); out->writeLineF("Location: %s",url); out->writeLine(""); } // -------------------------------------- void HTML::startHTML() { startNode("html"); } // -------------------------------------- void HTML::startBody() { startNode("body"); } // -------------------------------------- void HTML::addHead() { char buf[512]; startNode("head"); startTagEnd("title",title.cstr()); startTagEnd("meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1""); if (!refreshURL.isEmpty()) { sprintf(buf,"meta http-equiv="refresh" content="%d;URL=%s"",refresh,refreshURL.cstr()); startTagEnd(buf); }else if (refresh) { sprintf(buf,"meta http-equiv="refresh" content="%d"",refresh); startTagEnd(buf); } end(); } // -------------------------------------- void HTML::addContent(const char *s) { out->writeString(s); } // -------------------------------------- void HTML::startNode(const char *tag, const char *data) { const char *p = tag; char *o = &currTag[tagLevel][0]; int i; for(i=0; i<MAX_TAGLEN-1; i++) { char c = *p++; if ((c==0) || (c==' ')) break; else *o++ = c; } *o = 0; out->writeString("<"); out->writeString(tag); out->writeString(">"); if (data) out->writeString(data); tagLevel++; if (tagLevel >= MAX_TAGLEVEL) throw StreamException("HTML too deep!"); } // -------------------------------------- void HTML::end() { tagLevel--; if (tagLevel < 0) throw StreamException("HTML premature end!"); out->writeString("</"); out->writeString(&currTag[tagLevel][0]); out->writeString(">"); } // -------------------------------------- void HTML::addLink(const char *url, const char *text, bool toblank) { char buf[1024]; sprintf(buf,"a href="%s" %s",url,toblank?"target="_blank"":""); startNode(buf,text); end(); } // -------------------------------------- void HTML::startTag(const char *tag, const char *fmt,...) { if (fmt) { va_list ap;    va_start(ap, fmt); char tmp[512]; vsprintf(tmp,fmt,ap); startNode(tag,tmp);     va_end(ap); }else{ startNode(tag,NULL); } } // -------------------------------------- void HTML::startTagEnd(const char *tag, const char *fmt,...) { if (fmt) { va_list ap;    va_start(ap, fmt); char tmp[512]; vsprintf(tmp,fmt,ap); startNode(tag,tmp);     va_end(ap); }else{ startNode(tag,NULL); } end(); } // -------------------------------------- void HTML::startSingleTagEnd(const char *fmt,...) { va_list ap; va_start(ap, fmt); char tmp[512]; vsprintf(tmp,fmt,ap); startNode(tmp); va_end(ap); end(); } // -------------------------------------- void HTML::startTableRow(int i) { if (i & 1) startTag("tr bgcolor="#dddddd" align="left""); else startTag("tr bgcolor="#eeeeee" align="left""); }