PageRenderTime 64ms CodeModel.GetById 33ms RepoModel.GetById 1ms app.codeStats 0ms

/WtCookie.c

http://mod-wtcl.googlecode.com/
C | 925 lines | 750 code | 129 blank | 46 comment | 205 complexity | fd2908fcc0d6396d76f0787db4184b2e MD5 | raw file
Possible License(s): Apache-2.0
  1. /*
  2. * Copyright 2001 Alexander Boverman and the original authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "WtCookie.h"
  17. #include "WtContext.h"
  18. #include "WtUtil.h"
  19. #include "WtTable.h"
  20. #include "WtTableUtil.h"
  21. #include "WtMultiTable.h"
  22. #include "WtCollectionCmds.h"
  23. #include "WtBasicCmds.h"
  24. /* Create a new cookie */
  25. Tcl_Obj *WtNewCookieObj()
  26. {
  27. Tcl_Obj *obj = WtNewTableObj();
  28. WtTableSetStrToStr(obj, "name", "");
  29. WtTableSetStrToObj(obj, "values", Tcl_NewListObj(0, NULL));
  30. WtTableSetStrToStr(obj, "expires", "");
  31. WtTableSetStrToStr(obj, "domain", "");
  32. WtTableSetStrToStr(obj, "path", "");
  33. WtTableSetStrToObj(obj, "secure", Tcl_NewBooleanObj(0));
  34. return obj;
  35. }
  36. /* Get the name */
  37. Tcl_Obj *WtCookieGetName(Tcl_Obj *cookie, Tcl_Interp *interp)
  38. {
  39. Tcl_Obj *name = WtTableGetObjFromStr(cookie, "name", NULL);
  40. if (!name) {
  41. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  42. }
  43. return name;
  44. }
  45. /* Set the name */
  46. int WtCookieSetName(Tcl_Obj *cookie, Tcl_Obj *name, Tcl_Interp *interp)
  47. {
  48. WtTableSetStrToObj(cookie, "name", name);
  49. return 1;
  50. }
  51. /* Get the value */
  52. int WtCookieGetValue(Tcl_Obj *cookie, Tcl_Obj **value, Tcl_Interp *interp)
  53. {
  54. int ret = 0;
  55. Tcl_Obj *key = WtNewString("values"), *list;
  56. *value = NULL;
  57. if (WtTableGetList(cookie, key, &list, interp)) {
  58. if (!list) {
  59. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  60. } else if (Tcl_ListObjIndex(interp, list, 0, value) == TCL_OK) {
  61. ret = 1;
  62. }
  63. }
  64. Tcl_DecrRefCount(key);
  65. return ret;
  66. }
  67. /* Set the value */
  68. int WtCookieSetValue(Tcl_Obj *cookie, Tcl_Obj *value, Tcl_Interp *interp)
  69. {
  70. WtTableSetStrToObj(cookie, "values",
  71. Tcl_NewListObj(1, &value));
  72. return 1;
  73. }
  74. /* Get all values */
  75. int WtCookieGetAllValues(Tcl_Obj *cookie, Tcl_Obj **values, Tcl_Interp *interp)
  76. {
  77. int ret = 0;
  78. Tcl_Obj *key = WtNewString("values");
  79. if (WtTableGetList(cookie, key, values, interp)) {
  80. if (!*values) {
  81. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  82. } else {
  83. ret = 1;
  84. }
  85. }
  86. Tcl_DecrRefCount(key);
  87. return ret;
  88. }
  89. /* Set all values */
  90. int WtCookieSetAllValues(Tcl_Obj *cookie, Tcl_Obj *values, Tcl_Interp *interp)
  91. {
  92. WtTableSetStrToObj(cookie, "values", values);
  93. return 1;
  94. }
  95. /* Get expiration time */
  96. Tcl_Obj *WtCookieGetExpires(Tcl_Obj *cookie, Tcl_Interp *interp)
  97. {
  98. Tcl_Obj *expires = WtTableGetObjFromStr(cookie, "expires", NULL);
  99. if (!expires) {
  100. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  101. }
  102. return expires;
  103. }
  104. /* Set the expiration time */
  105. int WtCookieSetExpires(Tcl_Obj *cookie, Tcl_Obj *expires, Tcl_Interp *interp)
  106. {
  107. int ret = 0;
  108. const char *str;
  109. WtContext *w = WtGetAssocContext(interp);
  110. str = ApacheUtil_expires(w->web->apReq->pool,
  111. WtToString(expires), EXPIRES_COOKIE);
  112. if (!str) {
  113. Tcl_AppendResult(interp, "Expiration time string is invalid.");
  114. } else {
  115. WtTableSetStrToStr(cookie, "expires", str);
  116. ret = 1;
  117. }
  118. return ret;
  119. }
  120. int WtCookieMarkExpired(Tcl_Obj *cookie, Tcl_Interp *interp)
  121. {
  122. int ok = 0;
  123. Tcl_Obj *epoch = WtNewString(wtCookieEpoch);
  124. Tcl_IncrRefCount(epoch);
  125. ok = WtCookieSetExpires(cookie, epoch, interp);
  126. Tcl_DecrRefCount(epoch);
  127. return ok;
  128. }
  129. /* Get the domain */
  130. Tcl_Obj *WtCookieGetDomain(Tcl_Obj *cookie, Tcl_Interp *interp)
  131. {
  132. Tcl_Obj *domain = WtTableGetObjFromStr(cookie, "domain", NULL);
  133. if (!domain) {
  134. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  135. }
  136. return domain;
  137. }
  138. /* Set the domain */
  139. int WtCookieSetDomain(Tcl_Obj *cookie, Tcl_Obj *domain, Tcl_Interp *interp)
  140. {
  141. WtTableSetStrToObj(cookie, "domain", domain);
  142. return 1;
  143. }
  144. /* Get the path */
  145. Tcl_Obj *WtCookieGetPath(Tcl_Obj *cookie, Tcl_Interp *interp)
  146. {
  147. Tcl_Obj *path = WtTableGetObjFromStr(cookie, "path", NULL);
  148. if (!path) {
  149. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  150. }
  151. return path;
  152. }
  153. /* Set the path */
  154. int WtCookieSetPath(Tcl_Obj *cookie, Tcl_Obj *path, Tcl_Interp *interp)
  155. {
  156. WtTableSetStrToObj(cookie, "path", path);
  157. return 1;
  158. }
  159. /* Get the secure option */
  160. Tcl_Obj *WtCookieGetSecure(Tcl_Obj *cookie, Tcl_Interp *interp)
  161. {
  162. Tcl_Obj *secure = WtTableGetObjFromStr(cookie, "secure", NULL);
  163. if (!secure) {
  164. Tcl_AppendResult(interp, "Invalid cookie object.", NULL);
  165. }
  166. return secure;
  167. }
  168. /* Set the secure option */
  169. int WtCookieSetSecure(Tcl_Obj *cookie, Tcl_Obj *secure, Tcl_Interp *interp)
  170. {
  171. int intVal;
  172. if (Tcl_GetBooleanFromObj(interp, secure, &intVal) != TCL_OK) {
  173. Tcl_AppendResult(interp, "Secure value must be boolean.", NULL);
  174. return 0;
  175. }
  176. WtTableSetStrToObj(cookie, "secure", Tcl_NewBooleanObj(intVal));
  177. return 1;
  178. }
  179. /* cookie command */
  180. int WtCookieCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  181. Tcl_Obj *const objv[])
  182. {
  183. int ret = TCL_ERROR;
  184. char *subCmd;
  185. if (objc < 2) {
  186. WtCookieUsage(interp, objv[0]);
  187. } else {
  188. subCmd = WtToString(objv[1]);
  189. if (!strcmp(subCmd, "create")) {
  190. ret = WtCookieCreateCmd(clientData, interp, objc, objv);
  191. } else if (!strcmp(subCmd, "name")) {
  192. ret = WtCookieNameCmd(clientData, interp, objc, objv);
  193. } else if (!strcmp(subCmd, "value")) {
  194. ret = WtCookieValueCmd(clientData, interp, objc, objv);
  195. } else if (!strcmp(subCmd, "allValues")) {
  196. ret = WtCookieAllValuesCmd(clientData, interp, objc, objv);
  197. } else if (!strcmp(subCmd, "expires")) {
  198. ret = WtCookieExpiresCmd(clientData, interp, objc, objv);
  199. } else if (!strcmp(subCmd, "markExpired")) {
  200. ret = WtCookieMarkExpiredCmd(clientData, interp, objc, objv);
  201. } else if (!strcmp(subCmd, "domain")) {
  202. ret = WtCookieDomainCmd(clientData, interp, objc, objv);
  203. } else if (!strcmp(subCmd, "path")) {
  204. ret = WtCookiePathCmd(clientData, interp, objc, objv);
  205. } else if (!strcmp(subCmd, "secure")) {
  206. ret = WtCookieSecureCmd(clientData, interp, objc, objv);
  207. } else {
  208. WtCookieUsage(interp, objv[0]);
  209. }
  210. }
  211. return ret;
  212. }
  213. /* cookie create command */
  214. int WtCookieCreateCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  215. Tcl_Obj *const objv[])
  216. {
  217. char *argStr;
  218. int ret = TCL_ERROR, i, optsDone = 0, intVal, error = 0;
  219. Tcl_Obj *cookie = WtNewCookieObj(), *boolObj;
  220. Tcl_IncrRefCount(cookie);
  221. for (i = 2; i < objc; i++) {
  222. argStr = WtToString(objv[i]);
  223. if (!strcmp(argStr, "-expires")) {
  224. if (i + 1 >= objc) {
  225. Tcl_AppendResult(interp,
  226. "The \"-expires\" option requires a value.", NULL);
  227. error = 1;
  228. break;
  229. } else if (!WtCookieSetExpires(cookie, objv[i + 1], interp)) {
  230. error = 1;
  231. break;
  232. } else {
  233. i++;
  234. }
  235. } else if (!strcmp(argStr, "-domain")) {
  236. if (i + 1 >= objc) {
  237. Tcl_AppendResult(interp,
  238. "The \"-domain\" option requires a value.", NULL);
  239. error = 1;
  240. break;
  241. } else {
  242. WtCookieSetDomain(cookie, objv[i + 1], interp);
  243. i++;
  244. }
  245. } else if (!strcmp(argStr, "-path")) {
  246. if (i + 1 >= objc) {
  247. Tcl_AppendResult(interp, "The \"-path\" option requires a value.",
  248. NULL);
  249. error = 1;
  250. break;
  251. } else {
  252. WtCookieSetPath(cookie, objv[i + 1], interp);
  253. i++;
  254. }
  255. } else if (!strcmp(argStr, "-secure")) {
  256. if (i + 1 >= objc) {
  257. Tcl_AppendResult(interp,
  258. "The \"-secure\" option requires a value.", NULL);
  259. error = 1;
  260. break;
  261. } else if (Tcl_GetBooleanFromObj(interp, objv[2], &intVal) != TCL_OK) {
  262. error = 1;
  263. break;
  264. } else {
  265. boolObj = Tcl_NewBooleanObj(0);
  266. Tcl_IncrRefCount(boolObj);
  267. if (!WtCookieSetSecure(cookie, boolObj, interp)) {
  268. error = 1;
  269. }
  270. Tcl_DecrRefCount(boolObj);
  271. if (error) {
  272. break;
  273. } else {
  274. i++;
  275. }
  276. }
  277. } else if (!strcmp(argStr, "--")) {
  278. optsDone = 1;
  279. break;
  280. } else if (argStr && argStr[0] == '-') {
  281. Tcl_AppendResult(interp, "Option \"", argStr, "\" is invalid. ",
  282. NULL);
  283. WtCookieUsage(interp, objv[0]);
  284. error = 1;
  285. break;
  286. } else {
  287. optsDone = 1;
  288. break;
  289. }
  290. }
  291. if (!error) {
  292. if (i + 2 < objc) {
  293. Tcl_AppendResult(interp, "Extra parameters found at the end. ");
  294. WtCookieUsage(interp, objv[0]);
  295. error = 1;
  296. } else if (i < objc) {
  297. if (!WtCookieSetName(cookie, objv[i], interp)) {
  298. error = 1;
  299. } else if (i + 1 < objc) {
  300. if (!WtCookieSetValue(cookie, objv[i + 1], interp)) {
  301. error = 1;
  302. }
  303. }
  304. }
  305. }
  306. if (!error) {
  307. Tcl_SetObjResult(interp, cookie);
  308. ret = TCL_OK;
  309. }
  310. Tcl_DecrRefCount(cookie);
  311. return ret;
  312. }
  313. /* cookie name command */
  314. int WtCookieNameCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  315. Tcl_Obj *const objv[])
  316. {
  317. int ret = TCL_ERROR, created;
  318. Tcl_Obj *cookie, *name;
  319. if (objc == 3) {
  320. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  321. if (name = WtCookieGetName(cookie, interp)) {
  322. Tcl_SetObjResult(interp, name);
  323. ret = TCL_OK;
  324. }
  325. }
  326. } else if (objc == 4) {
  327. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  328. if (WtCookieSetName(cookie, objv[3], interp)) {
  329. if (name = WtCookieGetName(cookie, interp)) {
  330. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  331. Tcl_SetObjResult(interp, name);
  332. ret = TCL_OK;
  333. }
  334. }
  335. }
  336. if (created) {
  337. Tcl_DecrRefCount(cookie);
  338. }
  339. ret = TCL_OK;
  340. }
  341. } else {
  342. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  343. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  344. " cookieVal\n",
  345. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  346. " cookieVar name\n",
  347. NULL);
  348. }
  349. return ret;
  350. }
  351. /* cookie value command */
  352. int WtCookieValueCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  353. Tcl_Obj *const objv[])
  354. {
  355. int ret = TCL_ERROR, created;
  356. Tcl_Obj *cookie, *value;
  357. if (objc == 3) {
  358. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  359. if (WtCookieGetValue(cookie, &value, interp)) {
  360. Tcl_SetObjResult(interp, value ? value : WtNewString(NULL));
  361. ret = TCL_OK;
  362. }
  363. }
  364. } else if (objc == 4) {
  365. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  366. if (WtCookieSetValue(cookie, objv[3], interp)) {
  367. if (WtCookieGetValue(cookie, &value, interp)) {
  368. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  369. Tcl_SetObjResult(interp, value ? value : WtNewString(NULL));
  370. ret = TCL_OK;
  371. }
  372. }
  373. }
  374. if (created) {
  375. Tcl_DecrRefCount(cookie);
  376. }
  377. }
  378. } else {
  379. Tcl_AppendResult(interp, wtBadUsagePrefix,
  380. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  381. " cookieVal\n",
  382. WtToString(objv[0]), " ", WtToString(objv[2]), " ",
  383. " cookieVar value\n",
  384. NULL);
  385. }
  386. return ret;
  387. }
  388. /* cookie allValues command */
  389. int WtCookieAllValuesCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  390. Tcl_Obj *const objv[])
  391. {
  392. int ret = TCL_ERROR, created;
  393. Tcl_Obj *cookie, *values;
  394. if (objc == 3) {
  395. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  396. if (WtCookieGetAllValues(cookie, &values, interp)) {
  397. Tcl_SetObjResult(interp, values);
  398. ret = TCL_OK;
  399. }
  400. }
  401. } else if (objc == 4) {
  402. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  403. if (WtCookieSetAllValues(cookie, objv[3], interp)) {
  404. if (WtCookieGetAllValues(cookie, &values, interp)) {
  405. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  406. Tcl_SetObjResult(interp, values);
  407. ret = TCL_OK;
  408. }
  409. }
  410. }
  411. if (created) {
  412. Tcl_DecrRefCount(cookie);
  413. }
  414. }
  415. } else {
  416. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  417. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  418. " cookieVal\n",
  419. WtToString(objv[0]), " ", WtToString(objv[2]), " ",
  420. " cookieVar values\n",
  421. NULL);
  422. }
  423. return ret;
  424. }
  425. /* cookie expires command */
  426. int WtCookieExpiresCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  427. Tcl_Obj *const objv[])
  428. {
  429. int ret = TCL_ERROR, created;
  430. Tcl_Obj *cookie, *expires;
  431. if (objc == 3) {
  432. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  433. if (expires = WtCookieGetExpires(cookie, interp)) {
  434. Tcl_SetObjResult(interp, expires);
  435. ret = TCL_OK;
  436. }
  437. }
  438. } else if (objc == 4) {
  439. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  440. if (WtCookieSetExpires(cookie, objv[3], interp)) {
  441. if (expires = WtCookieGetExpires(cookie, interp)) {
  442. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  443. Tcl_SetObjResult(interp, expires);
  444. ret = TCL_OK;
  445. }
  446. }
  447. }
  448. if (created) {
  449. Tcl_DecrRefCount(cookie);
  450. }
  451. }
  452. } else {
  453. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  454. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  455. " cookieVal\n",
  456. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  457. " cookieVar expirationDate\n",
  458. NULL);
  459. }
  460. return ret;
  461. }
  462. /* cookie markExpired command */
  463. int WtCookieMarkExpiredCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  464. Tcl_Obj *const objv[])
  465. {
  466. int ret = TCL_ERROR, created;
  467. Tcl_Obj *cookie, *expires;
  468. if (objc == 3) {
  469. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  470. if (WtCookieMarkExpired(cookie, interp)) {
  471. if (expires = WtCookieGetExpires(cookie, interp)) {
  472. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  473. Tcl_SetObjResult(interp, expires);
  474. ret = TCL_OK;
  475. }
  476. }
  477. }
  478. if (created) {
  479. Tcl_DecrRefCount(cookie);
  480. }
  481. }
  482. } else {
  483. Tcl_AppendResult(interp, wtBadUsagePrefix,
  484. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  485. " cookieVar",
  486. NULL);
  487. }
  488. return ret;
  489. }
  490. /* cookie domain command */
  491. int WtCookieDomainCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  492. Tcl_Obj *const objv[])
  493. {
  494. int ret = TCL_ERROR, created;
  495. Tcl_Obj *cookie, *domain;
  496. if (objc == 3) {
  497. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  498. if (domain = WtCookieGetDomain(cookie, interp)) {
  499. Tcl_SetObjResult(interp, domain);
  500. ret = TCL_OK;
  501. }
  502. }
  503. } else if (objc == 4) {
  504. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  505. if (WtCookieSetDomain(cookie, objv[3], interp)) {
  506. if (domain = WtCookieGetDomain(cookie, interp)) {
  507. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  508. Tcl_SetObjResult(interp, domain);
  509. ret = TCL_OK;
  510. }
  511. }
  512. }
  513. if (created) {
  514. Tcl_DecrRefCount(cookie);
  515. }
  516. }
  517. } else {
  518. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  519. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  520. " cookieVal\n",
  521. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  522. " cookieVar domain\n",
  523. NULL);
  524. }
  525. return ret;
  526. }
  527. /* cookie path command */
  528. int WtCookiePathCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  529. Tcl_Obj *const objv[])
  530. {
  531. int ret = TCL_ERROR, created;
  532. Tcl_Obj *cookie, *path;
  533. if (objc == 3) {
  534. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  535. if (path = WtCookieGetPath(cookie, interp)) {
  536. Tcl_SetObjResult(interp, path);
  537. ret = TCL_OK;
  538. }
  539. }
  540. } else if (objc == 4) {
  541. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  542. if (WtCookieSetPath(cookie, objv[3], interp)) {
  543. if (path = WtCookieGetPath(cookie, interp)) {
  544. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  545. Tcl_SetObjResult(interp, path);
  546. ret = TCL_OK;
  547. }
  548. }
  549. }
  550. if (created) {
  551. Tcl_DecrRefCount(cookie);
  552. }
  553. }
  554. } else {
  555. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  556. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  557. " cookieVal\n",
  558. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  559. " cookieVar path\n",
  560. NULL);
  561. }
  562. return ret;
  563. }
  564. /* cookie secure command */
  565. int WtCookieSecureCmd(ClientData clientData, Tcl_Interp *interp, int objc,
  566. Tcl_Obj *const objv[])
  567. {
  568. int ret = TCL_ERROR, created;
  569. Tcl_Obj *cookie, *secure;
  570. if (objc == 3) {
  571. if (cookie = WtCookieCmdGetVal(objv[2], interp)) {
  572. if (secure = WtCookieGetSecure(cookie, interp)) {
  573. Tcl_SetObjResult(interp, secure);
  574. ret = TCL_OK;
  575. }
  576. }
  577. } else if (objc == 4) {
  578. if (WtCookieCmdOwnVar(objv[2], &cookie, &created, interp)) {
  579. if (WtCookieSetSecure(cookie, objv[3], interp)) {
  580. if (secure = WtCookieGetSecure(cookie, interp)) {
  581. if (WtCookieCmdSetVar(objv[2], cookie, interp)) {
  582. Tcl_SetObjResult(interp, secure);
  583. ret = TCL_OK;
  584. }
  585. }
  586. }
  587. if (created) {
  588. Tcl_DecrRefCount(cookie);
  589. }
  590. }
  591. } else {
  592. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  593. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  594. " cookieVal\n",
  595. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  596. " cookieVar secure\n",
  597. NULL);
  598. }
  599. return ret;
  600. }
  601. void WtCookieUsage(Tcl_Interp *interp, Tcl_Obj *cmd)
  602. {
  603. char *cmdStr = WtToString(cmd);
  604. Tcl_AppendResult(interp, wtBadUsagePrefix, "\n",
  605. cmdStr, " create\n",
  606. cmdStr, " name cookieVal\n",
  607. cmdStr, " name cookieVar name\n",
  608. cmdStr, " value cookieVal\n",
  609. cmdStr, " value cookieVar value\n",
  610. cmdStr, " allValues cookieVal\n",
  611. cmdStr, " allValues cookieVar values\n",
  612. cmdStr, " expires cookieVal\n",
  613. cmdStr, " expires cookieVar expires\n",
  614. cmdStr, " domain cookieVal\n",
  615. cmdStr, " domain cookieVar domain\n",
  616. cmdStr, " path cookieVal\n",
  617. cmdStr, " path cookieVar path\n",
  618. cmdStr, " secure cookieVal\n",
  619. cmdStr, " secure cookieVar secure\n",
  620. NULL);
  621. }
  622. Tcl_Obj *WtCookieCmdGetVal(Tcl_Obj *val, Tcl_Interp *interp)
  623. {
  624. return WtCmdGetVal(val, &WtTableType, interp);
  625. }
  626. int WtCookieCmdGetVar(Tcl_Obj *var, Tcl_Obj **val,
  627. Tcl_Interp *interp)
  628. {
  629. return WtCmdGetVar(var, val, &WtTableType, interp);
  630. }
  631. int WtCookieCmdOwnVar(Tcl_Obj *var, Tcl_Obj **val,
  632. int *created, Tcl_Interp *interp)
  633. {
  634. int ok = WtCmdOwnVar(var, val, &WtTableType, created, interp);
  635. if (ok && !*val) {
  636. *val = WtNewCookieObj();
  637. Tcl_IncrRefCount(*val);
  638. *created = 1;
  639. }
  640. return ok;
  641. }
  642. Tcl_Obj *WtCookieCmdSetVar(Tcl_Obj *var, Tcl_Obj *val, Tcl_Interp *interp)
  643. {
  644. return WtCmdSetVar(var, val, interp);
  645. }
  646. /* Cookie collection object */
  647. Tcl_Obj *WtNewCookieClnObj()
  648. {
  649. Tcl_Obj *obj = WtNewClnObj(&WtCookieClnType, &WtCookieClnItemType);
  650. return obj;
  651. }
  652. struct Tcl_ObjType WtCookieClnType =
  653. {
  654. "cookieCollection",
  655. WtCookieClnFree,
  656. WtCookieClnDup,
  657. WtCookieClnUpdateString,
  658. WtCookieClnSetFromAny
  659. };
  660. void WtCookieClnFree(Tcl_Obj *cln)
  661. {
  662. WtClnObjFree(cln);
  663. }
  664. void WtCookieClnDup(Tcl_Obj *src, Tcl_Obj *dst)
  665. {
  666. WtClnObjDup(src, dst);
  667. }
  668. void WtCookieClnUpdateString(Tcl_Obj *cln)
  669. {
  670. WtClnObjUpdateString(cln);
  671. }
  672. int WtCookieClnSetFromAny(Tcl_Interp *interp, Tcl_Obj *obj)
  673. {
  674. return WtClnObjSetFromAny(interp, obj, &WtCookieClnType);
  675. }
  676. WtClnItemType WtCookieClnItemType = {
  677. WtCookieClnCompare,
  678. WtCookieClnGetKey,
  679. WtCookieClnGetValue
  680. };
  681. int WtCookieClnCompare(Tcl_Obj *item, Tcl_Obj *key, int *result,
  682. Tcl_Interp *interp)
  683. {
  684. Tcl_Obj *name = WtCookieGetName(item, interp);
  685. if (name) {
  686. *result = strcmp(WtToString(name), WtToString(key));
  687. return 1;
  688. }
  689. return 0;
  690. }
  691. int WtCookieClnGetKey(Tcl_Obj *item, Tcl_Obj **key,
  692. Tcl_Interp *interp)
  693. {
  694. *key = WtCookieGetName(item, interp);
  695. if (*key) {
  696. return 1;
  697. }
  698. return 0;
  699. }
  700. int WtCookieClnGetValue(Tcl_Obj *item, Tcl_Obj **value,
  701. Tcl_Interp *interp)
  702. {
  703. *value = item;
  704. return 1;
  705. }
  706. /* responseCookies command */
  707. int WtResponseCookiesCmd(ClientData clientData, Tcl_Interp *interp,
  708. int objc, Tcl_Obj *const objv[])
  709. {
  710. int ret, ok = 1;
  711. WtContext *w = WtGetAssocContext(interp);
  712. Tcl_Obj *cookie, *val;
  713. int status = WtClnMethodHelper(clientData, interp, objc,
  714. objv, &ret, &w->web->clientResponse.cookies,
  715. &WtCookieClnType, 0, 0);
  716. if (status == WT_CLN_CMD_MISSING) {
  717. /* No command */
  718. WtResponseCookiesUsage(interp, objv[0]);
  719. } else if (status == WT_CLN_CMD_NOT_FOUND) {
  720. /* deleteFromClient command */
  721. if (!strcmp(WtToString(objv[1]), "deleteFromClient")) {
  722. if (objc < 3) {
  723. Tcl_AppendResult(interp, wtBadUsagePrefix,
  724. WtToString(objv[0]), " ", WtToString(objv[1]), " ",
  725. " name", NULL);
  726. } else if (cookie = WtNewCookieObj()) {
  727. Tcl_IncrRefCount(cookie);
  728. if (!WtCookieSetName(cookie, objv[2], interp)) {
  729. ok = 0;
  730. }
  731. if (ok && objc > 3 && !WtCookieSetPath(
  732. cookie, objv[3], interp)) {
  733. ok = 0;
  734. }
  735. if (ok && objc > 4 && !WtCookieSetDomain(
  736. cookie, objv[4], interp)) {
  737. ok = 0;
  738. }
  739. if (ok && objc > 5 && !WtCookieSetSecure(
  740. cookie, objv[5], interp)) {
  741. ok = 0;
  742. }
  743. if (ok) {
  744. val = WtNewString(NULL);
  745. Tcl_IncrRefCount(val);
  746. if (WtCookieSetValue(cookie, val, interp)) {
  747. if (WtCookieMarkExpired(cookie, interp)) {
  748. if (WtOwnCookieCln(&w->web->clientResponse.cookies,
  749. interp)) {
  750. if (WtAppendClnItem(w->web->clientResponse.cookies,
  751. cookie, interp)) {
  752. Tcl_SetObjResult(interp, cookie);
  753. ret = TCL_OK;
  754. }
  755. }
  756. }
  757. }
  758. Tcl_DecrRefCount(val);
  759. }
  760. Tcl_DecrRefCount(cookie);
  761. }
  762. } else {
  763. /* Unknown command */
  764. WtResponseCookiesUsage(interp, objv[0]);
  765. }
  766. }
  767. return ret;
  768. }
  769. void WtResponseCookiesUsage(Tcl_Interp *interp, Tcl_Obj *cmd)
  770. {
  771. Tcl_AppendResult(interp, wtBadUsagePrefix2, NULL);
  772. WtClnMethodAppendUsage(interp, cmd, 0);
  773. Tcl_AppendResult(interp, WtToString(cmd), " deleteFromClient key\n",
  774. NULL);
  775. }
  776. /* Initialize cookie commands */
  777. void WtInitCookieCommands(Tcl_Interp *interp)
  778. {
  779. WtContext *w = Tcl_GetAssocData(interp, "wt::context", NULL);
  780. WtLog(HERE, APLOG_DEBUG | APLOG_NOERRNO, w,
  781. "Wtcl: WtInitCookieCommands.");
  782. Tcl_CreateObjCommand(interp, "::wt::response::cookie",
  783. WtCookieCmd, NULL, NULL);
  784. Tcl_CreateObjCommand(interp, "::wt::response::responseCookies",
  785. WtResponseCookiesCmd, NULL, NULL);
  786. }
  787. int WtConvertToCookieCln(Tcl_Obj *obj, Tcl_Interp *interp)
  788. {
  789. return WtConvertToClnObj(obj, &WtCookieClnType, interp);
  790. }
  791. int WtOwnCookieCln(Tcl_Obj **objPtr, Tcl_Interp *interp)
  792. {
  793. WtCopyOnWrite(objPtr);
  794. return WtConvertToCookieCln(*objPtr, interp);
  795. }
  796. const char *wtCookieEpoch = "Thu, 01-Jan-1970 00:00:01 GMT";