bindutil.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning( disable : 4786)
  14. #ifdef _WIN32
  15. #define BINDUTIL_EXPORT _declspec(dllexport)
  16. #else
  17. #define BINDUTIL_EXPORT
  18. #endif
  19. #include <map>
  20. #include <string>
  21. #include "esp.hpp"
  22. #include "bindutil.hpp"
  23. #include "espcontext.hpp"
  24. #define URL_MAX 512
  25. static const unsigned char charmap[] = {
  26. 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
  27. 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
  28. 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
  29. 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
  30. 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
  31. 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
  32. 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
  33. 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
  34. 0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
  35. 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
  36. 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
  37. 0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
  38. 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
  39. 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
  40. 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
  41. 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
  42. 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
  43. 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
  44. 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
  45. 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
  46. 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
  47. 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
  48. 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
  49. 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
  50. 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
  51. 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
  52. 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
  53. 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
  54. 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
  55. 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
  56. 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
  57. 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
  58. };
  59. unsigned int Utils::hash (const char *str, unsigned int len)
  60. {
  61. static unsigned short asso_values[] =
  62. {
  63. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  64. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  65. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  66. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  67. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 0, 10,
  68. 125, 10, 360, 0, 65, 435, 555, 895, 4484, 4484,
  69. 4484, 4484, 4484, 4484, 4484, 0, 330, 0, 130, 0,
  70. 130, 0, 325, 0, 0, 400, 5, 315, 110, 0,
  71. 65, 0, 20, 1195, 5, 4484, 4484, 4484, 4484, 20,
  72. 5, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  73. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  74. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  75. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  76. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  77. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  78. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  79. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  80. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  81. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  82. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  83. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  84. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  85. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  86. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  87. 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484, 4484,
  88. 4484, 4484, 4484, 4484, 4484, 4484
  89. };
  90. unsigned int result = len;
  91. for(int i = len - 1; i >= 0; i--)
  92. {
  93. result += asso_values[(unsigned char)str[i]];
  94. }
  95. return result;
  96. }
  97. bool isLWS(char c)
  98. {
  99. if(c == ' ' || c== '\t' || c == 13 || c == 10)
  100. return true;
  101. return false;
  102. }
  103. // oneline must be NULL terminated
  104. const char* Utils::getWord(const char* oneline, StringBuffer& oneword)
  105. {
  106. if(*oneline == 0)
  107. return oneline;
  108. while(*oneline && isLWS(*oneline))
  109. oneline++;
  110. while(*oneline && !isLWS(*oneline))
  111. {
  112. oneword.append(*oneline);
  113. oneline++;
  114. }
  115. return oneline;
  116. }
  117. bool isSeparator(char c, const char* separators)
  118. {
  119. while(*separators != '\0')
  120. {
  121. if(*separators == c)
  122. return true;
  123. separators++;
  124. }
  125. return false;
  126. }
  127. // oneline must be NULL terminated
  128. char* Utils::getWord(char* oneline, char* & oneword, const char* separators, bool tws)
  129. {
  130. if(oneline == NULL || *oneline == 0)
  131. {
  132. oneword = NULL;
  133. return oneline;
  134. }
  135. while(*oneline != '\0' && (isSeparator(*oneline, separators) || (tws && isLWS(*oneline))))
  136. oneline++;
  137. oneword = oneline;
  138. while(*oneline != '\0' && !isSeparator(*oneline, separators))
  139. oneline++;
  140. if(*oneline != '\0')
  141. {
  142. *oneline = '\0';
  143. oneline++;
  144. }
  145. return oneline;
  146. }
  147. void Utils::parseNVPair(const char* nv, StringBuffer& name, StringBuffer& value)
  148. {
  149. name.clear();
  150. value.clear();
  151. if(nv == NULL || *nv == '\0')
  152. return;
  153. const char* ptr = nv;
  154. while(ptr != NULL && *ptr == ' ')
  155. {
  156. ptr++;
  157. }
  158. if(ptr == NULL || *ptr == '\0')
  159. return;
  160. const char* nptr = ptr;
  161. const char* vptr = NULL;
  162. int nlen = 0;
  163. while(ptr != NULL && *ptr != '\0' && *ptr != '=')
  164. {
  165. ptr++;
  166. nlen++;
  167. }
  168. if(nlen <= 0)
  169. return;
  170. if(ptr != NULL && *ptr != '\0')
  171. vptr = ptr + 1;
  172. while(vptr != NULL && *vptr == ' ')
  173. vptr++;
  174. while(nlen > 0 && nptr[nlen - 1] == ' ')
  175. nlen--;
  176. if(nlen > 0)
  177. name.append(nlen, nptr);
  178. if(!vptr)
  179. return;
  180. if(vptr[0] == '"')
  181. vptr++;
  182. int vlen = strlen(vptr);
  183. while(vlen > 0 && vptr[vlen - 1] == ' ')
  184. vlen--;
  185. if(vlen > 0 && vptr[vlen - 1] == '"')
  186. vlen--;
  187. if(vlen > 0)
  188. value.append(vlen, vptr);
  189. }
  190. // buf DOESN'T have to be NULL terminated
  191. int Utils::getLine(int total_len, int cur_pos, const char* buf, int& oneline_len)
  192. {
  193. oneline_len = 0;
  194. if(cur_pos >= total_len)
  195. {
  196. return total_len;
  197. }
  198. while(cur_pos < total_len && buf[cur_pos] != '\r' && buf[cur_pos] != '\n')
  199. {
  200. oneline_len++;
  201. cur_pos++;
  202. }
  203. if(cur_pos == total_len)
  204. return total_len;
  205. if(buf[cur_pos] == '\r')
  206. {
  207. cur_pos++;
  208. }
  209. if(cur_pos == total_len)
  210. return total_len;
  211. if(buf[cur_pos] == '\n')
  212. {
  213. cur_pos++;
  214. }
  215. return cur_pos;
  216. }
  217. __int64 Utils::getLine(__int64 total_len, __int64 cur_pos, const char* buf, int& oneline_len)
  218. {
  219. oneline_len = 0;
  220. if(cur_pos >= total_len)
  221. {
  222. return total_len;
  223. }
  224. while(cur_pos < total_len && buf[cur_pos] != '\r' && buf[cur_pos] != '\n')
  225. {
  226. oneline_len++;
  227. cur_pos++;
  228. }
  229. if(cur_pos == total_len)
  230. return total_len;
  231. if(buf[cur_pos] == '\r')
  232. {
  233. cur_pos++;
  234. }
  235. if(cur_pos == total_len)
  236. return total_len;
  237. if(buf[cur_pos] == '\n')
  238. {
  239. cur_pos++;
  240. }
  241. return cur_pos;
  242. }
  243. int Utils::strncasecmp(const char* s1, const char* s2, size32_t n)
  244. {
  245. bool s1isnull = (s1 == NULL);
  246. bool s2isnull = (s2 == NULL);
  247. if(s1isnull || s2isnull)
  248. return s1isnull - s2isnull;
  249. if (n != 0)
  250. {
  251. const unsigned char *cm = charmap,
  252. *us1 = (const unsigned char *)s1,
  253. *us2 = (const unsigned char *)s2;
  254. do
  255. {
  256. if (cm[*us1] != cm[*us2++])
  257. return (cm[*us1] - cm[*--us2]);
  258. }
  259. while ((*us1++ != '\0') && (--n != 0));
  260. }
  261. return (0);
  262. }
  263. const char *Utils::stristr(const char *haystack, const char *needle)
  264. {
  265. if(!haystack || !*haystack || !needle || !*needle)
  266. return NULL;
  267. int len = strlen(needle);
  268. for(const char* ptr = haystack; *ptr; ptr++)
  269. {
  270. if(strncasecmp(ptr, needle, len) == 0)
  271. return ptr;
  272. }
  273. return NULL;
  274. }
  275. int Utils::strcasecmp(const char* s1, const char* s2)
  276. {
  277. bool s1isnull = (s1 == NULL);
  278. bool s2isnull = (s2 == NULL);
  279. if(s1isnull || s2isnull)
  280. return s1isnull - s2isnull;
  281. const unsigned char *cm = charmap,
  282. *us1 = (const unsigned char *)s1,
  283. *us2 = (const unsigned char *)s2;
  284. do
  285. {
  286. if (cm[*us1] != cm[*us2++])
  287. return (cm[*us1] - cm[*--us2]);
  288. }
  289. while (*us1++ != '\0');
  290. return (0);
  291. }
  292. static const char BASE64_enc[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
  293. "abcdefghijklmnopqrstuvwxyz"
  294. "0123456789+/";
  295. static const char pad = '=';
  296. //
  297. // Encode the input in a base64 format
  298. //
  299. // const void * data -> data to be encoded
  300. // long length -> length in bytes of this data
  301. // returns StringBuffer& -> the encoded string
  302. //
  303. /*static*/
  304. StringBuffer& Utils::base64encode(const void *data, long length, StringBuffer& result)
  305. {
  306. double olend = 1.5 * (length + (length % 2));
  307. int olen = (int)olend;
  308. char *out = new char[olen + ((olen % 80) * 2) + 2];
  309. const unsigned char *in = static_cast<const unsigned char *>(data);
  310. unsigned char one;
  311. unsigned char two;
  312. unsigned char three;
  313. long i, j;
  314. for(i = 0, j = 0; i < length && length - i >= 3;)
  315. {
  316. one = *(in + i++);
  317. two = *(in + i++);
  318. three = *(in + i++);
  319. // 0x30 -> 0011 0000 b
  320. // 0x3c -> 0011 1100 b
  321. // 0x3f -> 0011 1111 b
  322. //
  323. out[j++] = BASE64_enc[one >> 2];
  324. out[j++] = BASE64_enc[((one << 4) & 0x30) | (two >> 4)];
  325. out[j++] = BASE64_enc[((two << 2) & 0x3c) | (three >> 6)];
  326. out[j++] = BASE64_enc[three & 0x3f];
  327. if(i % 54 == 0)
  328. {
  329. out[j++] = '\n';
  330. }
  331. }
  332. switch(length - i)
  333. {
  334. case 2:
  335. one = *(in + i++);
  336. two = *(in + i++);
  337. out[j++] = BASE64_enc[one >> 2];
  338. out[j++] = BASE64_enc[((one << 4) & 0x30) | (two >> 4)];
  339. out[j++] = BASE64_enc[(two << 2) & 0x3c];
  340. out[j++] = pad;
  341. break;
  342. case 1:
  343. one = *(in + i++);
  344. out[j++] = BASE64_enc[one >> 2];
  345. out[j++] = BASE64_enc[(one << 4) & 0x30];
  346. out[j++] = pad;
  347. out[j++] = pad;
  348. break;
  349. }
  350. out[j++] = '\n';
  351. out[j] = '\0';
  352. result.append(out);
  353. delete[] out;
  354. return result;
  355. }
  356. //
  357. // Decode the input in a base64 format
  358. //
  359. // const char *in -> NUL terminated string to be decoded
  360. // void * out -> Decoded string here
  361. //
  362. /*static*/
  363. int Utils::base64decode(int inlen, const char *in, StringBuffer& data)
  364. {
  365. static unsigned char BASE64_dec[256] = {0};
  366. static bool initialized = false;
  367. if(!initialized)
  368. {
  369. for(int i = 0; i < 64; ++i)
  370. {
  371. BASE64_dec[BASE64_enc[i]] = i;
  372. }
  373. initialized = true;
  374. }
  375. //unsigned char *data = static_cast<unsigned char *>(out);
  376. unsigned char c1, c2, c3, c4;
  377. unsigned char d1, d2, d3, d4;
  378. int len = strlen(in), count = 0;
  379. for(int i = 0; i < len; )
  380. {
  381. if(in[i] == '\n')
  382. {
  383. ++i;
  384. continue;
  385. }
  386. c1 = in[i++];
  387. c2 = in[i++];
  388. c3 = in[i++];
  389. c4 = in[i++];
  390. d1 = BASE64_dec[c1];
  391. d2 = BASE64_dec[c2];
  392. d3 = BASE64_dec[c3];
  393. d4 = BASE64_dec[c4];
  394. //data[count++] = (d1 << 2) | (d2 >> 4);
  395. data.appendf("%c", (d1 << 2) | (d2 >> 4));
  396. count++;
  397. if(c3 == pad)
  398. break;
  399. //data[count++] = (d2 << 4) | (d3 >> 2);
  400. data.appendf("%c", (d2 << 4) | (d3 >> 2));
  401. count++;
  402. if(c4 == pad)
  403. break;
  404. //data[count++] = (d3 << 6) | d4;
  405. data.appendf("%c", (d3 << 6) | d4);
  406. count++;
  407. }
  408. //data[count] = '\0';
  409. return count;
  410. }
  411. IPropertyTree *getBindingConfig(IPropertyTree *tree, const char *binding, const char *process)
  412. {
  413. if (tree==NULL)
  414. return NULL;
  415. const char *topname=tree->queryName();
  416. if (!strcmp("Environment", topname) || !strcmp("Software", topname))
  417. {
  418. if (process!=NULL && *process!=0 && binding!=NULL && *binding!=0)
  419. {
  420. StringBuffer xpath;
  421. xpath.appendf("//EspProcess[@name=\"%s\"]/EspBinding[@name=\"%s\"]", process, binding);
  422. return tree->getPropTree(xpath.str());
  423. }
  424. }
  425. else if (!strcmp(topname, "EspProcess"))
  426. {
  427. if (binding!=NULL && *binding!=0)
  428. {
  429. if (strcmp(tree->queryProp("@name"), process)==0)
  430. {
  431. StringBuffer xpath;
  432. xpath.appendf("EspBinding[@name=\"%s\"]", binding);
  433. return tree->getPropTree(xpath.str());
  434. }
  435. }
  436. }
  437. else if (!strcmp(topname, "EspBinding"))
  438. {
  439. if (strcmp(tree->queryProp("@name"), binding)==0)
  440. {
  441. tree->Link();
  442. return tree;
  443. }
  444. }
  445. return NULL;
  446. }
  447. IPropertyTree *getServiceConfig(IPropertyTree *tree, const char *srv, const char *process)
  448. {
  449. if (tree==NULL)
  450. return NULL;
  451. const char *topname=tree->queryName();
  452. if (!strcmp("Environment", topname) || !strcmp("Software", topname))
  453. {
  454. if (process!=NULL && *process!=0 && srv && *srv)
  455. {
  456. StringBuffer xpath;
  457. xpath.appendf("//EspProcess[@name=\"%s\"]/EspService[@name=\"%s\"]", process, srv);
  458. return tree->getPropTree(xpath.str());
  459. }
  460. }
  461. else if (!strcmp(topname, "EspProcess"))
  462. {
  463. if (srv!=NULL && *srv!=0)
  464. {
  465. if (strcmp(tree->queryProp("@name"), process)==0)
  466. {
  467. StringBuffer xpath;
  468. xpath.appendf("EspService[@name=\"%s\"]", srv);
  469. return tree->getPropTree(xpath.str());
  470. }
  471. }
  472. }
  473. else if (!strcmp(topname, "EspService"))
  474. {
  475. if (strcmp(tree->queryProp("@name"), srv)==0)
  476. {
  477. tree->Link();
  478. return tree;
  479. }
  480. }
  481. return NULL;
  482. }
  483. IPropertyTree *getProcessConfig(IPropertyTree *tree, const char *process)
  484. {
  485. if (tree==NULL)
  486. return NULL;
  487. const char *topname=tree->queryName();
  488. if (!strcmp("Environment", topname) || !strcmp("Software", topname))
  489. {
  490. if (process!=NULL && *process!=0)
  491. {
  492. StringBuffer xpath;
  493. xpath.appendf("//EspProcess[@name=\"%s\"]", process);
  494. return tree->getPropTree(xpath.str());
  495. }
  496. }
  497. else if (!strcmp(topname, "EspProcess"))
  498. {
  499. if (strcmp(tree->queryProp("@name"), process)==0)
  500. return LINK(tree);
  501. }
  502. return NULL;
  503. }
  504. IPropertyTree *getProtocolConfig(IPropertyTree *tree, const char *prot, const char *process)
  505. {
  506. if (tree==NULL)
  507. return NULL;
  508. const char *topname=tree->queryName();
  509. if (!strcmp("Environment", topname) || !strcmp("Software", topname))
  510. {
  511. if (process && *process && prot && *prot)
  512. {
  513. StringBuffer xpath;
  514. xpath.appendf("//EspProcess[@name=\"%s\"]/EspProtocol[@name=\"%s\"]", process, prot);
  515. return tree->getPropTree(xpath.str());
  516. }
  517. }
  518. else if (!strcmp(topname, "EspProcess"))
  519. {
  520. if (prot && *prot)
  521. {
  522. if (strcmp(tree->queryProp("@name"), process)==0)
  523. {
  524. StringBuffer xpath;
  525. xpath.appendf("EspProtocol[@name=\"%s\"]", prot);
  526. return tree->getPropTree(xpath.str());
  527. }
  528. }
  529. }
  530. else if (!strcmp(topname, "EspProtocol"))
  531. {
  532. if (strcmp(tree->queryProp("@name"), prot)==0)
  533. {
  534. tree->Link();
  535. return tree;
  536. }
  537. }
  538. return NULL;
  539. }
  540. static unsigned char isValidUrlChar[96] =
  541. {
  542. 0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x1,0x0,0x0,0x1,0x1,0x0, /* !"#$%&'()*+,-./ */
  543. 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0,0x0, /* 0123456789:;<=>? */
  544. 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, /* @ABCDEFGHIJKLMNO */
  545. 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x1, /* PQRSTUVWXYZ[\]^_ */
  546. 0x0,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1, /* `abcdefghijklmno */
  547. 0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x1,0x0,0x0,0x0,0x0,0x0 /* pqrstuvwxyz{\}~DEL */
  548. };
  549. StringBuffer &Utils::url_encode(const char* url, StringBuffer& encoded_url)
  550. {
  551. if(!url)
  552. return encoded_url;
  553. unsigned char c;
  554. int i = 0;
  555. while((c = url[i]) != 0)
  556. {
  557. if(c == ' ')
  558. encoded_url.append('+');
  559. else if(c >= 32 && c < 128 && isValidUrlChar[c - 32])
  560. encoded_url.append(c);
  561. else
  562. encoded_url.appendf("%%%02X", c);
  563. i++;
  564. }
  565. return encoded_url;
  566. }
  567. int Utils::url_decode(const char* url, StringBuffer& result)
  568. {
  569. appendDecodedURL(result, url);
  570. return 0;
  571. }
  572. void Utils::SplitURL(const char* url, StringBuffer& protocol,StringBuffer& UserName,StringBuffer& Password,StringBuffer& host, StringBuffer& port, StringBuffer& path)
  573. {
  574. int protlen = 0;
  575. if(!url || strlen(url) <= 7)
  576. throw MakeStringException(-1, "Invalid URL %s", url);
  577. else if(Utils::strncasecmp(url, "HTTP://", 7) == 0)
  578. {
  579. protocol.append("HTTP");
  580. protlen = 7;
  581. }
  582. else if(Utils::strncasecmp(url, "HTTPS://", 8) == 0)
  583. {
  584. protocol.append("HTTPS");
  585. protlen = 8;
  586. }
  587. else
  588. {
  589. throw MakeStringException(-1, "Please specify protocol HTTP or HTTPS");
  590. }
  591. char buf[URL_MAX+1];
  592. int len = strlen(url);
  593. const char *param = strchr(url + protlen, '?');
  594. if (param)
  595. len = param - url;
  596. if(len > URL_MAX)
  597. len = URL_MAX;
  598. strncpy(buf, url, len);
  599. buf[len] = 0;
  600. char* hostptr;
  601. char *username = NULL;
  602. char* atsign = strchr(buf, '@');
  603. if(atsign)
  604. {
  605. username = buf + protlen;
  606. hostptr = atsign + 1;
  607. *atsign = '\0';
  608. }
  609. else
  610. {
  611. hostptr = buf + protlen;
  612. }
  613. char* pathptr = strchr(hostptr, '/');
  614. if(pathptr)
  615. {
  616. *pathptr = 0;
  617. pathptr++;
  618. }
  619. char* portptr = strchr(hostptr, ':');
  620. if(portptr)
  621. {
  622. *portptr = 0;
  623. portptr++;
  624. }
  625. if(username)
  626. {
  627. char* semicln = strchr(username, ':');
  628. if(semicln)
  629. {
  630. Password.append(semicln+1);
  631. *semicln = '\0';
  632. }
  633. UserName.append(username);
  634. }
  635. if(hostptr)
  636. host.append(hostptr);
  637. if(portptr)
  638. port.append(portptr);
  639. path.append("/");
  640. if(pathptr)
  641. path.append(pathptr);
  642. if(param)
  643. path.append(param);
  644. }
  645. class CStringIntMap : public CInterface,
  646. implements IEspStringIntMap
  647. {
  648. std::map<std::string, int> c_map;
  649. public:
  650. IMPLEMENT_IINTERFACE;
  651. int queryValue(const char *key){return c_map[key];}
  652. void setValue(const char *key, int value){c_map[key]=value;}
  653. };
  654. IEspStringIntMap *createStringIntMap()
  655. {
  656. return new CStringIntMap;
  657. }
  658. void buildArrayHint(StringBuffer& s, int indents, const char* tag, const char* cls)
  659. {
  660. s.pad(indents).appendf("<%s>\\n", tag);
  661. s.pad(indents+1).append("<RawArray>\\n");
  662. if (cls)
  663. {
  664. s.pad(indents+2).append("<Item>\\n");
  665. s.append(cls);
  666. s.pad(indents+2).append("</Item>\\n");
  667. }
  668. else
  669. s.pad(indents+2).append("<Item></Item>\\n");
  670. s.pad(indents+1).append("</RawArray>\\n");
  671. s.pad(indents).appendf("</%s>\\n", tag);
  672. }
  673. void xslTransformHelper(IXslProcessor *xslp, const char* xml, const char* xslFile, StringBuffer& output, IProperties *params)
  674. {
  675. if (xslp)
  676. {
  677. Owned<IXslTransform> xform = xslp->createXslTransform();
  678. StringBuffer xslpath;
  679. if (!strnicmp(xslFile, "/esp/xslt/", 10))
  680. if (!checkFileExists(xslpath.append(getCFD()).append("smc_xslt/").append(xslFile+10).str()) && !checkFileExists(xslpath.append(getCFD()).append("xslt/").append(xslFile+10).str()))
  681. return;
  682. xform->loadXslFromFile((xslpath.length()) ? xslpath.str() : xslFile);
  683. xform->setXmlSource(xml, strlen(xml)+1);
  684. if (params) xform->copyParameters(params);
  685. xform->transform(output.clear());
  686. }
  687. }
  688. const char *mimeTypeFromFileExt(const char *ext)
  689. {
  690. if (!ext)
  691. return "application/octet-stream";
  692. if (*ext=='.')
  693. ext++;
  694. if (strieq(ext, "html") || strieq(ext, "htm"))
  695. return "text/html";
  696. if (strieq(ext, "xml") || strieq(ext, "xsl") || strieq(ext, "xslt"))
  697. return "application/xml";
  698. if (strieq(ext, "js"))
  699. return "text/javascript";
  700. if (strieq(ext, "css"))
  701. return "text/css";
  702. if (strieq(ext, "jpeg") || strieq(ext, "jpg"))
  703. return "image/jpeg";
  704. if (strieq(ext, "gif"))
  705. return "image/gif";
  706. if (strieq(ext, "png"))
  707. return "image/png";
  708. if (strieq(ext, "svg"))
  709. return "image/svg+xml";
  710. if (strieq(ext, "txt") || strieq(ext, "text"))
  711. return "text/plain";
  712. if (strieq(ext, "zip"))
  713. return "application/zip";
  714. if (strieq(ext, "pdf"))
  715. return "application/pdf";
  716. if (strieq(ext, "xpi"))
  717. return "application/x-xpinstall";
  718. if (strieq(ext, "exe") || strieq(ext, "class"))
  719. return "application/octet-stream";
  720. return "application/octet-stream";
  721. }
  722. class CEspHttpException: public CInterface, public IEspHttpException
  723. {
  724. public:
  725. IMPLEMENT_IINTERFACE;
  726. CEspHttpException(int code, const char *_msg, const char* _httpstatus) : errcode(code), msg(_msg), httpstatus(_httpstatus){ };
  727. int errorCode() const { return (errcode); };
  728. StringBuffer & errorMessage(StringBuffer &str) const
  729. {
  730. return str.append("CEspHttpException: (").append(msg).append(")");
  731. };
  732. MessageAudience errorAudience() const { return (MSGAUD_user); };
  733. virtual const char* getHttpStatus() {return httpstatus.get(); }
  734. private:
  735. int errcode;
  736. StringAttr msg;
  737. StringAttr httpstatus;
  738. };
  739. IEspHttpException* createEspHttpException(int code, const char *_msg, const char* _httpstatus)
  740. {
  741. return new CEspHttpException(code, _msg, _httpstatus);
  742. }