kibi-swipl-linux-x64-gnu 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (550) hide show
  1. package/README.md +29 -0
  2. package/bin/swipl +0 -0
  3. package/bin/swipl-win +0 -0
  4. package/build-manifest.json +70 -0
  5. package/lib/cmake/swipl/SWIPLConfig.cmake +21 -0
  6. package/lib/cmake/swipl/SWIPLConfigVersion.cmake +65 -0
  7. package/lib/cmake/swipl/SWIPLTargets-release.cmake +28 -0
  8. package/lib/cmake/swipl/SWIPLTargets.cmake +109 -0
  9. package/lib/swipl/ABI +1 -0
  10. package/lib/swipl/LICENSE +41 -0
  11. package/lib/swipl/README.md +116 -0
  12. package/lib/swipl/app/README.md +25 -0
  13. package/lib/swipl/app/app.pl +87 -0
  14. package/lib/swipl/app/pack.pl +350 -0
  15. package/lib/swipl/app/qlf.pl +521 -0
  16. package/lib/swipl/app/splfr.pl +177 -0
  17. package/lib/swipl/app/sys.pl +310 -0
  18. package/lib/swipl/bin/swipl.home +1 -0
  19. package/lib/swipl/boot/apply.pl +73 -0
  20. package/lib/swipl/boot/attvar.pl +344 -0
  21. package/lib/swipl/boot/autoload.pl +1226 -0
  22. package/lib/swipl/boot/bags.pl +283 -0
  23. package/lib/swipl/boot/dcg.pl +388 -0
  24. package/lib/swipl/boot/dicts.pl +193 -0
  25. package/lib/swipl/boot/dwim.pl +485 -0
  26. package/lib/swipl/boot/engines.pl +152 -0
  27. package/lib/swipl/boot/expand.pl +1628 -0
  28. package/lib/swipl/boot/gc.pl +65 -0
  29. package/lib/swipl/boot/history.pl +304 -0
  30. package/lib/swipl/boot/init.pl +4682 -0
  31. package/lib/swipl/boot/iri.pl +64 -0
  32. package/lib/swipl/boot/license.pl +390 -0
  33. package/lib/swipl/boot/load.pl +81 -0
  34. package/lib/swipl/boot/messages.pl +2521 -0
  35. package/lib/swipl/boot/packs.pl +306 -0
  36. package/lib/swipl/boot/predopts.pl +154 -0
  37. package/lib/swipl/boot/qlf.pl +141 -0
  38. package/lib/swipl/boot/rc.pl +263 -0
  39. package/lib/swipl/boot/syspred.pl +1634 -0
  40. package/lib/swipl/boot/tabling.pl +2321 -0
  41. package/lib/swipl/boot/threads.pl +42 -0
  42. package/lib/swipl/boot/toplevel.pl +2248 -0
  43. package/lib/swipl/boot/topvars.pl +261 -0
  44. package/lib/swipl/boot.prc +0 -0
  45. package/lib/swipl/cmake/swipl.cmake +131 -0
  46. package/lib/swipl/customize/README.md +23 -0
  47. package/lib/swipl/customize/edit +101 -0
  48. package/lib/swipl/customize/init.pl +164 -0
  49. package/lib/swipl/demo/README.md +33 -0
  50. package/lib/swipl/demo/likes.pl +44 -0
  51. package/lib/swipl/doc/packages/examples/chr/bool.chr +281 -0
  52. package/lib/swipl/doc/packages/examples/chr/chrdif.chr +87 -0
  53. package/lib/swipl/doc/packages/examples/chr/chrfreeze.chr +6 -0
  54. package/lib/swipl/doc/packages/examples/chr/family.chr +116 -0
  55. package/lib/swipl/doc/packages/examples/chr/fib.chr +24 -0
  56. package/lib/swipl/doc/packages/examples/chr/fibonacci.chr +31 -0
  57. package/lib/swipl/doc/packages/examples/chr/gcd.chr +28 -0
  58. package/lib/swipl/doc/packages/examples/chr/leq.chr +34 -0
  59. package/lib/swipl/doc/packages/examples/chr/listdom.chr +138 -0
  60. package/lib/swipl/doc/packages/examples/chr/primes.chr +29 -0
  61. package/lib/swipl/doc/packages/examples/http/README.md +98 -0
  62. package/lib/swipl/doc/packages/examples/http/calc.pl +92 -0
  63. package/lib/swipl/doc/packages/examples/http/demo_body.pl +232 -0
  64. package/lib/swipl/doc/packages/examples/http/demo_client.pl +165 -0
  65. package/lib/swipl/doc/packages/examples/http/demo_daemon.pl +38 -0
  66. package/lib/swipl/doc/packages/examples/http/demo_files.pl +50 -0
  67. package/lib/swipl/doc/packages/examples/http/demo_hello.pl +15 -0
  68. package/lib/swipl/doc/packages/examples/http/demo_login.pl +280 -0
  69. package/lib/swipl/doc/packages/examples/http/demo_openid.pl +177 -0
  70. package/lib/swipl/doc/packages/examples/http/demo_pwp.pl +20 -0
  71. package/lib/swipl/doc/packages/examples/http/demo_rest.pl +56 -0
  72. package/lib/swipl/doc/packages/examples/http/demo_threads.pl +52 -0
  73. package/lib/swipl/doc/packages/examples/http/linux-init-script +126 -0
  74. package/lib/swipl/doc/packages/examples/http/pwp/context.pwp +23 -0
  75. package/lib/swipl/doc/packages/examples/http/pwp/index.pwp +25 -0
  76. package/lib/swipl/doc/packages/examples/http/pwp/pwp1.pwp +12 -0
  77. package/lib/swipl/doc/packages/examples/http/pwp/pwp2.pwp +10 -0
  78. package/lib/swipl/doc/packages/examples/http/pwp/pwp3.pwp +25 -0
  79. package/lib/swipl/doc/packages/examples/http/pwp/pwp4.pwp +23 -0
  80. package/lib/swipl/doc/packages/examples/http/pwp/pwp5.pwp +11 -0
  81. package/lib/swipl/doc/packages/examples/http/pwp/pwp6.pwp +3 -0
  82. package/lib/swipl/doc/packages/examples/http/pwp/pwp7.pwp +3 -0
  83. package/lib/swipl/doc/packages/examples/http/pwp/pwp8.pwp +3 -0
  84. package/lib/swipl/doc/packages/examples/http/pwp/pwpdb.pl +12 -0
  85. package/lib/swipl/doc/packages/examples/http/systemd-script.service +18 -0
  86. package/lib/swipl/doc/packages/examples/http/upstart-script.conf +20 -0
  87. package/lib/swipl/doc/packages/examples/plunit/read.pl +17 -0
  88. package/lib/swipl/doc/packages/examples/plunit/simple.pl +33 -0
  89. package/lib/swipl/doc/packages/examples/ssl/client.pl +83 -0
  90. package/lib/swipl/doc/packages/examples/ssl/etc/README +52 -0
  91. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.p12 +0 -0
  92. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-cert.pem +85 -0
  93. package/lib/swipl/doc/packages/examples/ssl/etc/client/client-key.pem +30 -0
  94. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/cacert.pem +82 -0
  95. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/careq.pem +18 -0
  96. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/crlnumber +1 -0
  97. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt +3 -0
  98. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/index.txt.attr +1 -0
  99. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7C.pem +85 -0
  100. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/newcerts/9DC08797A0F63F7D.pem +85 -0
  101. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/private/cakey.pem +30 -0
  102. package/lib/swipl/doc/packages/examples/ssl/etc/demoCA/serial +1 -0
  103. package/lib/swipl/doc/packages/examples/ssl/etc/server/server-cert.pem +85 -0
  104. package/lib/swipl/doc/packages/examples/ssl/etc/server/server-key.pem +30 -0
  105. package/lib/swipl/doc/packages/examples/ssl/https.pl +267 -0
  106. package/lib/swipl/doc/packages/examples/ssl/server.pl +106 -0
  107. package/lib/swipl/include/SWI-Prolog.h +1544 -0
  108. package/lib/swipl/include/SWI-Stream.h +537 -0
  109. package/lib/swipl/include/Yap/YapInterface.h +283 -0
  110. package/lib/swipl/include/sicstus/sicstus.h +452 -0
  111. package/lib/swipl/lib/x86_64-linux/cgi.so +0 -0
  112. package/lib/swipl/lib/x86_64-linux/crypt.so +0 -0
  113. package/lib/swipl/lib/x86_64-linux/crypto4pl.so +0 -0
  114. package/lib/swipl/lib/x86_64-linux/double_metaphone.so +0 -0
  115. package/lib/swipl/lib/x86_64-linux/files.so +0 -0
  116. package/lib/swipl/lib/x86_64-linux/hashstream.so +0 -0
  117. package/lib/swipl/lib/x86_64-linux/http_stream.so +0 -0
  118. package/lib/swipl/lib/x86_64-linux/isub.so +0 -0
  119. package/lib/swipl/lib/x86_64-linux/json.so +0 -0
  120. package/lib/swipl/lib/x86_64-linux/libswipl.so.10 +0 -0
  121. package/lib/swipl/lib/x86_64-linux/mallocinfo.so +0 -0
  122. package/lib/swipl/lib/x86_64-linux/md54pl.so +0 -0
  123. package/lib/swipl/lib/x86_64-linux/memfile.so +0 -0
  124. package/lib/swipl/lib/x86_64-linux/ntriples.so +0 -0
  125. package/lib/swipl/lib/x86_64-linux/pcre4pl.so +0 -0
  126. package/lib/swipl/lib/x86_64-linux/porter_stem.so +0 -0
  127. package/lib/swipl/lib/x86_64-linux/process.so +0 -0
  128. package/lib/swipl/lib/x86_64-linux/prolog_stream.so +0 -0
  129. package/lib/swipl/lib/x86_64-linux/rdf_db.so +0 -0
  130. package/lib/swipl/lib/x86_64-linux/readutil.so +0 -0
  131. package/lib/swipl/lib/x86_64-linux/rlimit.so +0 -0
  132. package/lib/swipl/lib/x86_64-linux/sched.so +0 -0
  133. package/lib/swipl/lib/x86_64-linux/sgml2pl.so +0 -0
  134. package/lib/swipl/lib/x86_64-linux/sha4pl.so +0 -0
  135. package/lib/swipl/lib/x86_64-linux/snowball.so +0 -0
  136. package/lib/swipl/lib/x86_64-linux/socket.so +0 -0
  137. package/lib/swipl/lib/x86_64-linux/ssl4pl.so +0 -0
  138. package/lib/swipl/lib/x86_64-linux/streaminfo.so +0 -0
  139. package/lib/swipl/lib/x86_64-linux/syslog.so +0 -0
  140. package/lib/swipl/lib/x86_64-linux/time.so +0 -0
  141. package/lib/swipl/lib/x86_64-linux/turtle.so +0 -0
  142. package/lib/swipl/lib/x86_64-linux/uid.so +0 -0
  143. package/lib/swipl/lib/x86_64-linux/unix.so +0 -0
  144. package/lib/swipl/lib/x86_64-linux/uri.so +0 -0
  145. package/lib/swipl/lib/x86_64-linux/websocket.so +0 -0
  146. package/lib/swipl/lib/x86_64-linux/zlib4pl.so +0 -0
  147. package/lib/swipl/library/INDEX.pl +1020 -0
  148. package/lib/swipl/library/aggregate.pl +755 -0
  149. package/lib/swipl/library/ansi_term.pl +653 -0
  150. package/lib/swipl/library/apply.pl +426 -0
  151. package/lib/swipl/library/apply_macros.pl +497 -0
  152. package/lib/swipl/library/arithmetic.pl +320 -0
  153. package/lib/swipl/library/assoc.pl +522 -0
  154. package/lib/swipl/library/atom.pl +169 -0
  155. package/lib/swipl/library/backcomp.pl +688 -0
  156. package/lib/swipl/library/base32.pl +291 -0
  157. package/lib/swipl/library/base64.pl +441 -0
  158. package/lib/swipl/library/broadcast.pl +161 -0
  159. package/lib/swipl/library/build/cmake.pl +137 -0
  160. package/lib/swipl/library/build/conan.pl +232 -0
  161. package/lib/swipl/library/build/make.pl +168 -0
  162. package/lib/swipl/library/build/tools.pl +825 -0
  163. package/lib/swipl/library/charsio.pl +195 -0
  164. package/lib/swipl/library/check.pl +1097 -0
  165. package/lib/swipl/library/check_installation.pl +912 -0
  166. package/lib/swipl/library/clp/INDEX.pl +157 -0
  167. package/lib/swipl/library/clp/bounds.pl +2036 -0
  168. package/lib/swipl/library/clp/clp_distinct.pl +263 -0
  169. package/lib/swipl/library/clp/clp_events.pl +92 -0
  170. package/lib/swipl/library/clp/clpb.pl +1896 -0
  171. package/lib/swipl/library/clp/clpfd.pl +7906 -0
  172. package/lib/swipl/library/clp/simplex.pl +1580 -0
  173. package/lib/swipl/library/codesio.pl +182 -0
  174. package/lib/swipl/library/coinduction.pl +183 -0
  175. package/lib/swipl/library/console_input.pl +289 -0
  176. package/lib/swipl/library/csv.pl +611 -0
  177. package/lib/swipl/library/ctypes.pl +161 -0
  178. package/lib/swipl/library/date.pl +370 -0
  179. package/lib/swipl/library/dcg/INDEX.pl +35 -0
  180. package/lib/swipl/library/dcg/basics.pl +514 -0
  181. package/lib/swipl/library/dcg/high_order.pl +227 -0
  182. package/lib/swipl/library/debug.pl +499 -0
  183. package/lib/swipl/library/dialect/bim.pl +186 -0
  184. package/lib/swipl/library/dialect/commons.pl +77 -0
  185. package/lib/swipl/library/dialect/eclipse/test_util_iso.pl +355 -0
  186. package/lib/swipl/library/dialect/hprolog/format.pl +44 -0
  187. package/lib/swipl/library/dialect/hprolog.pl +314 -0
  188. package/lib/swipl/library/dialect/ifprolog.pl +1317 -0
  189. package/lib/swipl/library/dialect/iso/iso_predicates.pl +277 -0
  190. package/lib/swipl/library/dialect/sicstus/README.TXT +1 -0
  191. package/lib/swipl/library/dialect/sicstus/arrays.pl +121 -0
  192. package/lib/swipl/library/dialect/sicstus/block.pl +278 -0
  193. package/lib/swipl/library/dialect/sicstus/lists.pl +167 -0
  194. package/lib/swipl/library/dialect/sicstus/ordsets.pl +52 -0
  195. package/lib/swipl/library/dialect/sicstus/sockets.pl +174 -0
  196. package/lib/swipl/library/dialect/sicstus/system.pl +262 -0
  197. package/lib/swipl/library/dialect/sicstus/terms.pl +57 -0
  198. package/lib/swipl/library/dialect/sicstus/timeout.pl +92 -0
  199. package/lib/swipl/library/dialect/sicstus.pl +582 -0
  200. package/lib/swipl/library/dialect/sicstus4/aggregate.pl +60 -0
  201. package/lib/swipl/library/dialect/sicstus4/between.pl +62 -0
  202. package/lib/swipl/library/dialect/sicstus4/clpfd.pl +75 -0
  203. package/lib/swipl/library/dialect/sicstus4/file_systems.pl +413 -0
  204. package/lib/swipl/library/dialect/sicstus4/lists.pl +274 -0
  205. package/lib/swipl/library/dialect/sicstus4/ordsets.pl +54 -0
  206. package/lib/swipl/library/dialect/sicstus4/samsort.pl +86 -0
  207. package/lib/swipl/library/dialect/sicstus4/sets.pl +124 -0
  208. package/lib/swipl/library/dialect/sicstus4/sockets.pl +164 -0
  209. package/lib/swipl/library/dialect/sicstus4/system.pl +80 -0
  210. package/lib/swipl/library/dialect/sicstus4/terms.pl +89 -0
  211. package/lib/swipl/library/dialect/sicstus4/timeout.pl +43 -0
  212. package/lib/swipl/library/dialect/sicstus4/types.pl +103 -0
  213. package/lib/swipl/library/dialect/sicstus4.pl +200 -0
  214. package/lib/swipl/library/dialect/swi/syspred_options.pl +250 -0
  215. package/lib/swipl/library/dialect/xsb/README.md +20 -0
  216. package/lib/swipl/library/dialect/xsb/basics.pl +318 -0
  217. package/lib/swipl/library/dialect/xsb/consult.pl +87 -0
  218. package/lib/swipl/library/dialect/xsb/curr_sym.pl +57 -0
  219. package/lib/swipl/library/dialect/xsb/error_handler.pl +111 -0
  220. package/lib/swipl/library/dialect/xsb/gensym.pl +53 -0
  221. package/lib/swipl/library/dialect/xsb/gpp.pl +138 -0
  222. package/lib/swipl/library/dialect/xsb/intern.pl +48 -0
  223. package/lib/swipl/library/dialect/xsb/lists.pl +47 -0
  224. package/lib/swipl/library/dialect/xsb/machine.pl +295 -0
  225. package/lib/swipl/library/dialect/xsb/ordsets.pl +53 -0
  226. package/lib/swipl/library/dialect/xsb/setof.pl +54 -0
  227. package/lib/swipl/library/dialect/xsb/source.pl +308 -0
  228. package/lib/swipl/library/dialect/xsb/standard.pl +169 -0
  229. package/lib/swipl/library/dialect/xsb/storage.pl +70 -0
  230. package/lib/swipl/library/dialect/xsb/string.pl +76 -0
  231. package/lib/swipl/library/dialect/xsb/thread.pl +62 -0
  232. package/lib/swipl/library/dialect/xsb/timed_call.pl +158 -0
  233. package/lib/swipl/library/dialect/xsb.pl +688 -0
  234. package/lib/swipl/library/dialect/yap/README.TXT +8 -0
  235. package/lib/swipl/library/dialect/yap.pl +283 -0
  236. package/lib/swipl/library/dialect.pl +123 -0
  237. package/lib/swipl/library/dicts.pl +399 -0
  238. package/lib/swipl/library/dif.pl +426 -0
  239. package/lib/swipl/library/edinburgh.pl +138 -0
  240. package/lib/swipl/library/edit.pl +783 -0
  241. package/lib/swipl/library/error.pl +495 -0
  242. package/lib/swipl/library/exceptions.pl +231 -0
  243. package/lib/swipl/library/explain.pl +543 -0
  244. package/lib/swipl/library/ext/RDF/INDEX.pl +25 -0
  245. package/lib/swipl/library/ext/RDF/rdf.pl +450 -0
  246. package/lib/swipl/library/ext/RDF/rdf_parser.pl +649 -0
  247. package/lib/swipl/library/ext/RDF/rdf_triple.pl +448 -0
  248. package/lib/swipl/library/ext/RDF/rdf_write.pl +701 -0
  249. package/lib/swipl/library/ext/RDF/rewrite_term.pl +177 -0
  250. package/lib/swipl/library/ext/chr/chr/a_star.pl +80 -0
  251. package/lib/swipl/library/ext/chr/chr/binomialheap.pl +142 -0
  252. package/lib/swipl/library/ext/chr/chr/builtins.pl +629 -0
  253. package/lib/swipl/library/ext/chr/chr/chr_compiler_errors.pl +179 -0
  254. package/lib/swipl/library/ext/chr/chr/chr_compiler_options.pl +382 -0
  255. package/lib/swipl/library/ext/chr/chr/chr_compiler_utility.pl +338 -0
  256. package/lib/swipl/library/ext/chr/chr/chr_debug.pl +59 -0
  257. package/lib/swipl/library/ext/chr/chr/chr_hashtable_store.pl +425 -0
  258. package/lib/swipl/library/ext/chr/chr/chr_integertable_store.pl +139 -0
  259. package/lib/swipl/library/ext/chr/chr/chr_messages.pl +176 -0
  260. package/lib/swipl/library/ext/chr/chr/chr_op.pl +53 -0
  261. package/lib/swipl/library/ext/chr/chr/chr_runtime.pl +1016 -0
  262. package/lib/swipl/library/ext/chr/chr/chr_translate.pl +25424 -0
  263. package/lib/swipl/library/ext/chr/chr/clean_code.pl +252 -0
  264. package/lib/swipl/library/ext/chr/chr/find.pl +78 -0
  265. package/lib/swipl/library/ext/chr/chr/guard_entailment.pl +19432 -0
  266. package/lib/swipl/library/ext/chr/chr/listmap.pl +108 -0
  267. package/lib/swipl/library/ext/chr/chr/pairlist.pl +78 -0
  268. package/lib/swipl/library/ext/chr/chr.pl +686 -0
  269. package/lib/swipl/library/ext/clib/INDEX.pl +158 -0
  270. package/lib/swipl/library/ext/clib/cgi.pl +86 -0
  271. package/lib/swipl/library/ext/clib/crypt.pl +44 -0
  272. package/lib/swipl/library/ext/clib/filesex.pl +644 -0
  273. package/lib/swipl/library/ext/clib/hash_stream.pl +119 -0
  274. package/lib/swipl/library/ext/clib/mallocinfo.pl +138 -0
  275. package/lib/swipl/library/ext/clib/md5.pl +68 -0
  276. package/lib/swipl/library/ext/clib/memfile.pl +61 -0
  277. package/lib/swipl/library/ext/clib/process.pl +573 -0
  278. package/lib/swipl/library/ext/clib/prolog_server.pl +157 -0
  279. package/lib/swipl/library/ext/clib/prolog_stream.pl +80 -0
  280. package/lib/swipl/library/ext/clib/rlimit.pl +54 -0
  281. package/lib/swipl/library/ext/clib/sched.pl +85 -0
  282. package/lib/swipl/library/ext/clib/sha.pl +162 -0
  283. package/lib/swipl/library/ext/clib/socket.pl +1102 -0
  284. package/lib/swipl/library/ext/clib/streaminfo.pl +103 -0
  285. package/lib/swipl/library/ext/clib/streampool.pl +136 -0
  286. package/lib/swipl/library/ext/clib/syslog.pl +180 -0
  287. package/lib/swipl/library/ext/clib/time.pl +194 -0
  288. package/lib/swipl/library/ext/clib/udp_broadcast.pl +975 -0
  289. package/lib/swipl/library/ext/clib/uid.pl +220 -0
  290. package/lib/swipl/library/ext/clib/unix.pl +317 -0
  291. package/lib/swipl/library/ext/clib/uri.pl +530 -0
  292. package/lib/swipl/library/ext/clib/uuid.pl +207 -0
  293. package/lib/swipl/library/ext/http/http/INDEX.pl +266 -0
  294. package/lib/swipl/library/ext/http/http/README.md +34 -0
  295. package/lib/swipl/library/ext/http/http/ax.pl +189 -0
  296. package/lib/swipl/library/ext/http/http/dcg_basics.pl +49 -0
  297. package/lib/swipl/library/ext/http/http/graphql.pl +1367 -0
  298. package/lib/swipl/library/ext/http/http/html_decl.pl +416 -0
  299. package/lib/swipl/library/ext/http/http/html_head.pl +654 -0
  300. package/lib/swipl/library/ext/http/http/html_quasiquotations.pl +120 -0
  301. package/lib/swipl/library/ext/http/http/html_write.pl +1425 -0
  302. package/lib/swipl/library/ext/http/http/htmx.pl +139 -0
  303. package/lib/swipl/library/ext/http/http/http_authenticate.pl +364 -0
  304. package/lib/swipl/library/ext/http/http/http_client.pl +412 -0
  305. package/lib/swipl/library/ext/http/http/http_cookie.pl +245 -0
  306. package/lib/swipl/library/ext/http/http/http_cors.pl +176 -0
  307. package/lib/swipl/library/ext/http/http/http_digest.pl +820 -0
  308. package/lib/swipl/library/ext/http/http/http_dirindex.pl +296 -0
  309. package/lib/swipl/library/ext/http/http/http_dispatch.pl +1552 -0
  310. package/lib/swipl/library/ext/http/http/http_dyn_workers.pl +214 -0
  311. package/lib/swipl/library/ext/http/http/http_error.pl +126 -0
  312. package/lib/swipl/library/ext/http/http/http_exception.pl +225 -0
  313. package/lib/swipl/library/ext/http/http/http_files.pl +163 -0
  314. package/lib/swipl/library/ext/http/http/http_header.pl +2820 -0
  315. package/lib/swipl/library/ext/http/http/http_hook.pl +106 -0
  316. package/lib/swipl/library/ext/http/http/http_host.pl +204 -0
  317. package/lib/swipl/library/ext/http/http/http_load.pl +113 -0
  318. package/lib/swipl/library/ext/http/http/http_log.pl +738 -0
  319. package/lib/swipl/library/ext/http/http/http_multipart_plugin.pl +232 -0
  320. package/lib/swipl/library/ext/http/http/http_open.pl +1821 -0
  321. package/lib/swipl/library/ext/http/http/http_openid.pl +1561 -0
  322. package/lib/swipl/library/ext/http/http/http_parameters.pl +504 -0
  323. package/lib/swipl/library/ext/http/http/http_path.pl +380 -0
  324. package/lib/swipl/library/ext/http/http/http_proxy.pl +80 -0
  325. package/lib/swipl/library/ext/http/http/http_pwp.pl +351 -0
  326. package/lib/swipl/library/ext/http/http/http_redis_plugin.pl +332 -0
  327. package/lib/swipl/library/ext/http/http/http_server.pl +105 -0
  328. package/lib/swipl/library/ext/http/http/http_server_files.pl +126 -0
  329. package/lib/swipl/library/ext/http/http/http_server_health.pl +186 -0
  330. package/lib/swipl/library/ext/http/http/http_session.pl +1040 -0
  331. package/lib/swipl/library/ext/http/http/http_sgml_plugin.pl +137 -0
  332. package/lib/swipl/library/ext/http/http/http_stream.pl +376 -0
  333. package/lib/swipl/library/ext/http/http/http_unix_daemon.pl +989 -0
  334. package/lib/swipl/library/ext/http/http/http_wrapper.pl +559 -0
  335. package/lib/swipl/library/ext/http/http/hub.pl +600 -0
  336. package/lib/swipl/library/ext/http/http/js_write.pl +461 -0
  337. package/lib/swipl/library/ext/http/http/mimepack.pl +224 -0
  338. package/lib/swipl/library/ext/http/http/mimetype.pl +276 -0
  339. package/lib/swipl/library/ext/http/http/term_html.pl +797 -0
  340. package/lib/swipl/library/ext/http/http/thread_httpd.pl +1181 -0
  341. package/lib/swipl/library/ext/http/http/web/css/dirindex.css +24 -0
  342. package/lib/swipl/library/ext/http/http/web/css/openid.css +57 -0
  343. package/lib/swipl/library/ext/http/http/web/icons/back.png +0 -0
  344. package/lib/swipl/library/ext/http/http/web/icons/c.png +0 -0
  345. package/lib/swipl/library/ext/http/http/web/icons/compressed.png +0 -0
  346. package/lib/swipl/library/ext/http/http/web/icons/folder.png +0 -0
  347. package/lib/swipl/library/ext/http/http/web/icons/generic.png +0 -0
  348. package/lib/swipl/library/ext/http/http/web/icons/layout.png +0 -0
  349. package/lib/swipl/library/ext/http/http/web/icons/openid-logo-square.png +0 -0
  350. package/lib/swipl/library/ext/http/http/web/icons/openid-logo-tiny.png +0 -0
  351. package/lib/swipl/library/ext/http/http/websocket.pl +729 -0
  352. package/lib/swipl/library/ext/http/http/yadis.pl +205 -0
  353. package/lib/swipl/library/ext/json/INDEX.pl +36 -0
  354. package/lib/swipl/library/ext/json/http/INDEX.pl +16 -0
  355. package/lib/swipl/library/ext/json/http/http_json.pl +490 -0
  356. package/lib/swipl/library/ext/json/http/js_grammar.pl +53 -0
  357. package/lib/swipl/library/ext/json/http/json.pl +48 -0
  358. package/lib/swipl/library/ext/json/http/json_convert.pl +48 -0
  359. package/lib/swipl/library/ext/json/json.pl +1215 -0
  360. package/lib/swipl/library/ext/json/json_convert.pl +681 -0
  361. package/lib/swipl/library/ext/json/json_grammar.pl +349 -0
  362. package/lib/swipl/library/ext/json/json_rpc_client.pl +423 -0
  363. package/lib/swipl/library/ext/json/json_rpc_common.pl +104 -0
  364. package/lib/swipl/library/ext/json/json_rpc_server.pl +489 -0
  365. package/lib/swipl/library/ext/json/json_schema.pl +2111 -0
  366. package/lib/swipl/library/ext/nlp/INDEX.pl +15 -0
  367. package/lib/swipl/library/ext/nlp/double_metaphone.pl +86 -0
  368. package/lib/swipl/library/ext/nlp/isub.pl +162 -0
  369. package/lib/swipl/library/ext/nlp/porter_stem.pl +50 -0
  370. package/lib/swipl/library/ext/nlp/snowball.pl +97 -0
  371. package/lib/swipl/library/ext/pcre/INDEX.pl +17 -0
  372. package/lib/swipl/library/ext/pcre/pcre.pl +974 -0
  373. package/lib/swipl/library/ext/plunit/INDEX.pl +20 -0
  374. package/lib/swipl/library/ext/plunit/plunit.pl +2631 -0
  375. package/lib/swipl/library/ext/plunit/test_wizard.pl +249 -0
  376. package/lib/swipl/library/ext/semweb/semweb/INDEX.pl +288 -0
  377. package/lib/swipl/library/ext/semweb/semweb/rdf11.pl +2106 -0
  378. package/lib/swipl/library/ext/semweb/semweb/rdf11_containers.pl +299 -0
  379. package/lib/swipl/library/ext/semweb/semweb/rdf_cache.pl +278 -0
  380. package/lib/swipl/library/ext/semweb/semweb/rdf_compare.pl +132 -0
  381. package/lib/swipl/library/ext/semweb/semweb/rdf_db.pl +3468 -0
  382. package/lib/swipl/library/ext/semweb/semweb/rdf_edit.pl +1145 -0
  383. package/lib/swipl/library/ext/semweb/semweb/rdf_http_plugin.pl +274 -0
  384. package/lib/swipl/library/ext/semweb/semweb/rdf_library.pl +1021 -0
  385. package/lib/swipl/library/ext/semweb/semweb/rdf_litindex.pl +1035 -0
  386. package/lib/swipl/library/ext/semweb/semweb/rdf_ntriples.pl +422 -0
  387. package/lib/swipl/library/ext/semweb/semweb/rdf_persistency.pl +1576 -0
  388. package/lib/swipl/library/ext/semweb/semweb/rdf_portray.pl +182 -0
  389. package/lib/swipl/library/ext/semweb/semweb/rdf_prefixes.pl +681 -0
  390. package/lib/swipl/library/ext/semweb/semweb/rdf_sandbox.pl +153 -0
  391. package/lib/swipl/library/ext/semweb/semweb/rdf_turtle.pl +54 -0
  392. package/lib/swipl/library/ext/semweb/semweb/rdf_turtle_write.pl +1587 -0
  393. package/lib/swipl/library/ext/semweb/semweb/rdf_zlib_plugin.pl +52 -0
  394. package/lib/swipl/library/ext/semweb/semweb/rdfa.pl +1510 -0
  395. package/lib/swipl/library/ext/semweb/semweb/rdfs.pl +475 -0
  396. package/lib/swipl/library/ext/semweb/semweb/sparql_client.pl +643 -0
  397. package/lib/swipl/library/ext/semweb/semweb/turtle.pl +455 -0
  398. package/lib/swipl/library/ext/sgml/DTD/HTML4.dcl +88 -0
  399. package/lib/swipl/library/ext/sgml/DTD/HTML4.dtd +1092 -0
  400. package/lib/swipl/library/ext/sgml/DTD/HTML4.soc +6 -0
  401. package/lib/swipl/library/ext/sgml/DTD/HTML5.dtd +906 -0
  402. package/lib/swipl/library/ext/sgml/DTD/HTMLlat1.ent +195 -0
  403. package/lib/swipl/library/ext/sgml/DTD/HTMLspec.ent +77 -0
  404. package/lib/swipl/library/ext/sgml/DTD/HTMLsym.ent +241 -0
  405. package/lib/swipl/library/ext/sgml/INDEX.pl +64 -0
  406. package/lib/swipl/library/ext/sgml/c14n2.pl +203 -0
  407. package/lib/swipl/library/ext/sgml/iso_639.pl +631 -0
  408. package/lib/swipl/library/ext/sgml/pwp.pl +705 -0
  409. package/lib/swipl/library/ext/sgml/sgml.pl +815 -0
  410. package/lib/swipl/library/ext/sgml/sgml_write.pl +1003 -0
  411. package/lib/swipl/library/ext/sgml/xpath.pl +620 -0
  412. package/lib/swipl/library/ext/sgml/xsdp_types.pl +232 -0
  413. package/lib/swipl/library/ext/ssl/INDEX.pl +60 -0
  414. package/lib/swipl/library/ext/ssl/crypto.pl +1015 -0
  415. package/lib/swipl/library/ext/ssl/http/INDEX.pl +5 -0
  416. package/lib/swipl/library/ext/ssl/http/http_ssl_plugin.pl +296 -0
  417. package/lib/swipl/library/ext/ssl/saml.pl +609 -0
  418. package/lib/swipl/library/ext/ssl/ssl.pl +647 -0
  419. package/lib/swipl/library/ext/ssl/xmldsig.pl +391 -0
  420. package/lib/swipl/library/ext/ssl/xmlenc.pl +354 -0
  421. package/lib/swipl/library/ext/zlib/INDEX.pl +8 -0
  422. package/lib/swipl/library/ext/zlib/zlib.pl +112 -0
  423. package/lib/swipl/library/fastrw.pl +105 -0
  424. package/lib/swipl/library/files.pl +80 -0
  425. package/lib/swipl/library/gensym.pl +111 -0
  426. package/lib/swipl/library/git.pl +1027 -0
  427. package/lib/swipl/library/hashtable.pl +365 -0
  428. package/lib/swipl/library/heaps.pl +252 -0
  429. package/lib/swipl/library/hotfix.pl +239 -0
  430. package/lib/swipl/library/http/jquery.pl +103 -0
  431. package/lib/swipl/library/http/web/js/jquery-3.6.0.min.js +2 -0
  432. package/lib/swipl/library/increval.pl +217 -0
  433. package/lib/swipl/library/intercept.pl +263 -0
  434. package/lib/swipl/library/iostream.pl +237 -0
  435. package/lib/swipl/library/iri_scheme/file.pl +70 -0
  436. package/lib/swipl/library/lazy_lists.pl +481 -0
  437. package/lib/swipl/library/listing.pl +1362 -0
  438. package/lib/swipl/library/lists.pl +860 -0
  439. package/lib/swipl/library/lynx/INDEX.pl +14 -0
  440. package/lib/swipl/library/lynx/format.pl +380 -0
  441. package/lib/swipl/library/lynx/html_style.pl +129 -0
  442. package/lib/swipl/library/lynx/html_text.pl +865 -0
  443. package/lib/swipl/library/lynx/pldoc_style.pl +87 -0
  444. package/lib/swipl/library/macros.pl +451 -0
  445. package/lib/swipl/library/main.pl +1200 -0
  446. package/lib/swipl/library/make.pl +197 -0
  447. package/lib/swipl/library/modules.pl +129 -0
  448. package/lib/swipl/library/nb_rbtrees.pl +267 -0
  449. package/lib/swipl/library/nb_set.pl +203 -0
  450. package/lib/swipl/library/obfuscate.pl +115 -0
  451. package/lib/swipl/library/occurs.pl +241 -0
  452. package/lib/swipl/library/operators.pl +182 -0
  453. package/lib/swipl/library/option.pl +388 -0
  454. package/lib/swipl/library/optparse.pl +966 -0
  455. package/lib/swipl/library/ordsets.pl +518 -0
  456. package/lib/swipl/library/oset.pl +160 -0
  457. package/lib/swipl/library/pairs.pl +187 -0
  458. package/lib/swipl/library/persistency.pl +713 -0
  459. package/lib/swipl/library/pio.pl +47 -0
  460. package/lib/swipl/library/portray_text.pl +277 -0
  461. package/lib/swipl/library/pprint.pl +940 -0
  462. package/lib/swipl/library/predicate_options.pl +975 -0
  463. package/lib/swipl/library/prolog_autoload.pl +233 -0
  464. package/lib/swipl/library/prolog_breakpoints.pl +396 -0
  465. package/lib/swipl/library/prolog_clause.pl +1104 -0
  466. package/lib/swipl/library/prolog_code.pl +416 -0
  467. package/lib/swipl/library/prolog_codewalk.pl +1248 -0
  468. package/lib/swipl/library/prolog_colour.pl +3301 -0
  469. package/lib/swipl/library/prolog_colour.qlf +0 -0
  470. package/lib/swipl/library/prolog_config.pl +154 -0
  471. package/lib/swipl/library/prolog_coverage.pl +1333 -0
  472. package/lib/swipl/library/prolog_debug.pl +404 -0
  473. package/lib/swipl/library/prolog_deps.pl +675 -0
  474. package/lib/swipl/library/prolog_evaluable.pl +234 -0
  475. package/lib/swipl/library/prolog_format.pl +219 -0
  476. package/lib/swipl/library/prolog_history.pl +161 -0
  477. package/lib/swipl/library/prolog_jiti.pl +333 -0
  478. package/lib/swipl/library/prolog_locale.pl +61 -0
  479. package/lib/swipl/library/prolog_metainference.pl +307 -0
  480. package/lib/swipl/library/prolog_pack.pl +3906 -0
  481. package/lib/swipl/library/prolog_profile.pl +346 -0
  482. package/lib/swipl/library/prolog_qlfmake.pl +533 -0
  483. package/lib/swipl/library/prolog_source.pl +1188 -0
  484. package/lib/swipl/library/prolog_stack.pl +794 -0
  485. package/lib/swipl/library/prolog_trace.pl +365 -0
  486. package/lib/swipl/library/prolog_versions.pl +347 -0
  487. package/lib/swipl/library/prolog_wrap.pl +164 -0
  488. package/lib/swipl/library/prolog_xref.pl +3090 -0
  489. package/lib/swipl/library/prolog_xref.qlf +0 -0
  490. package/lib/swipl/library/pure_input.pl +266 -0
  491. package/lib/swipl/library/qpforeign.pl +695 -0
  492. package/lib/swipl/library/qsave.pl +1516 -0
  493. package/lib/swipl/library/quasi_quotations.pl +300 -0
  494. package/lib/swipl/library/quintus.pl +437 -0
  495. package/lib/swipl/library/random.pl +459 -0
  496. package/lib/swipl/library/rbtrees.pl +1153 -0
  497. package/lib/swipl/library/readln.pl +256 -0
  498. package/lib/swipl/library/readutil.pl +304 -0
  499. package/lib/swipl/library/record.pl +544 -0
  500. package/lib/swipl/library/rwlocks.pl +172 -0
  501. package/lib/swipl/library/sandbox.pl +1384 -0
  502. package/lib/swipl/library/semweb/dc.rdfs +198 -0
  503. package/lib/swipl/library/semweb/eor.rdfs +95 -0
  504. package/lib/swipl/library/semweb/owl.owl +287 -0
  505. package/lib/swipl/library/semweb/rdf_library.ttl +90 -0
  506. package/lib/swipl/library/semweb/rdfs.rdfs +251 -0
  507. package/lib/swipl/library/settings.pl +755 -0
  508. package/lib/swipl/library/shell.pl +462 -0
  509. package/lib/swipl/library/shlib.pl +670 -0
  510. package/lib/swipl/library/solution_sequences.pl +439 -0
  511. package/lib/swipl/library/sort.pl +119 -0
  512. package/lib/swipl/library/statistics.pl +541 -0
  513. package/lib/swipl/library/streams.pl +118 -0
  514. package/lib/swipl/library/strings.pl +469 -0
  515. package/lib/swipl/library/system.pl +95 -0
  516. package/lib/swipl/library/tables.pl +381 -0
  517. package/lib/swipl/library/tableutil.pl +771 -0
  518. package/lib/swipl/library/tabling.pl +42 -0
  519. package/lib/swipl/library/terms.pl +457 -0
  520. package/lib/swipl/library/theme/auto.pl +61 -0
  521. package/lib/swipl/library/theme/dark.pl +455 -0
  522. package/lib/swipl/library/theme/light.pl +45 -0
  523. package/lib/swipl/library/thread.pl +810 -0
  524. package/lib/swipl/library/thread_pool.pl +508 -0
  525. package/lib/swipl/library/threadutil.pl +574 -0
  526. package/lib/swipl/library/tty.pl +316 -0
  527. package/lib/swipl/library/ugraphs.pl +644 -0
  528. package/lib/swipl/library/unicode/INDEX.pl +6 -0
  529. package/lib/swipl/library/unicode/blocks.pl +414 -0
  530. package/lib/swipl/library/url.pl +1129 -0
  531. package/lib/swipl/library/utf8.pl +145 -0
  532. package/lib/swipl/library/varnumbers.pl +221 -0
  533. package/lib/swipl/library/vm.pl +251 -0
  534. package/lib/swipl/library/wfs.pl +205 -0
  535. package/lib/swipl/library/when.pl +263 -0
  536. package/lib/swipl/library/writef.pl +278 -0
  537. package/lib/swipl/library/www_browser.pl +251 -0
  538. package/lib/swipl/library/yall.pl +574 -0
  539. package/lib/swipl/library/zip.pl +211 -0
  540. package/lib/swipl/swipl.home +1 -0
  541. package/lib/vendor/libcrypto.so.3 +0 -0
  542. package/lib/vendor/libpcre2-8.so.0 +0 -0
  543. package/lib/vendor/libssl.so.3 +0 -0
  544. package/lib/vendor/libz.so.1 +0 -0
  545. package/licenses/OpenSSL-LICENSE.txt +177 -0
  546. package/licenses/PCRE2-COPYING +5 -0
  547. package/licenses/README.md +12 -0
  548. package/licenses/SWI-Prolog-LICENSE +41 -0
  549. package/licenses/zlib-LICENSE +22 -0
  550. package/package.json +27 -0
@@ -0,0 +1,1040 @@
1
+ /* Part of SWI-Prolog
2
+
3
+ Author: Jan Wielemaker, Matt Lilley
4
+ E-mail: J.Wielemaker@cs.vu.nl
5
+ WWW: http://www.swi-prolog.org
6
+ Copyright (c) 2006-2025, University of Amsterdam
7
+ VU University Amsterdam
8
+ CWI, Amsterdam
9
+ SWI-Prolog Solutions b.v.
10
+ All rights reserved.
11
+
12
+ Redistribution and use in source and binary forms, with or without
13
+ modification, are permitted provided that the following conditions
14
+ are met:
15
+
16
+ 1. Redistributions of source code must retain the above copyright
17
+ notice, this list of conditions and the following disclaimer.
18
+
19
+ 2. Redistributions in binary form must reproduce the above copyright
20
+ notice, this list of conditions and the following disclaimer in
21
+ the documentation and/or other materials provided with the
22
+ distribution.
23
+
24
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
28
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
29
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
30
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
31
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
32
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
34
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35
+ POSSIBILITY OF SUCH DAMAGE.
36
+ */
37
+
38
+ :- module(http_session,
39
+ [ http_set_session_options/1, % +Options
40
+ http_set_session/1, % +Option
41
+ http_set_session/2, % +SessionId, +Option
42
+ http_session_option/1, % ?Option
43
+
44
+ http_session_id/1, % -SessionId
45
+ http_in_session/1, % -SessionId
46
+ http_current_session/2, % ?SessionId, ?Data
47
+ http_close_session/1, % +SessionId
48
+ http_open_session/2, % -SessionId, +Options
49
+
50
+ http_session_cookie/1, % -Cookie
51
+
52
+ http_session_asserta/1, % +Data
53
+ http_session_assert/1, % +Data
54
+ http_session_retract/1, % ?Data
55
+ http_session_retractall/1, % +Data
56
+ http_session_data/1, % ?Data
57
+
58
+ http_session_asserta/2, % +Data, +SessionId
59
+ http_session_assert/2, % +Data, +SessionId
60
+ http_session_retract/2, % ?Data, +SessionId
61
+ http_session_retractall/2, % +Data, +SessionId
62
+ http_session_data/2 % ?Data, +SessionId
63
+ ]).
64
+ :- use_module(http_wrapper).
65
+ :- use_module(http_stream).
66
+ :- use_module(library(error)).
67
+ :- use_module(library(debug)).
68
+ :- use_module(library(socket)).
69
+ :- use_module(library(broadcast)).
70
+ :- use_module(library(lists)).
71
+ :- use_module(library(option)).
72
+
73
+ :- predicate_options(http_open_session/2, 2, [renew(boolean)]).
74
+
75
+ /** <module> HTTP Session management
76
+
77
+ This library defines session management based on HTTP cookies. Session
78
+ management is enabled simply by loading this module. Details can be
79
+ modified using http_set_session_options/1. By default, this module
80
+ creates a session whenever a request is processes that is inside the
81
+ hierarchy defined for session handling (see path option in
82
+ http_set_session_options/1). Automatic creation of a session can be
83
+ stopped using the option create(noauto). The predicate
84
+ http_open_session/2 must be used to create a session if =noauto= is
85
+ enabled. Sessions can be closed using http_close_session/1.
86
+
87
+ If a session is active, http_in_session/1 returns the current session
88
+ and http_session_assert/1 and friends maintain data about the session.
89
+ If the session is reclaimed, all associated data is reclaimed too.
90
+
91
+ Begin and end of sessions can be monitored using library(broadcast). The
92
+ broadcasted messages are:
93
+
94
+ * http_session(begin(SessionID, Peer))
95
+ Broadcasted if a session is started
96
+ * http_session(end(SessionId, Peer))
97
+ Broadcasted if a session is ended. See http_close_session/1.
98
+
99
+ For example, the following calls end_session(SessionId) whenever a
100
+ session terminates. Please note that sessions ends are not scheduled to
101
+ happen at the actual timeout moment of the session. Instead, creating a
102
+ new session scans the active list for timed-out sessions. This may
103
+ change in future versions of this library.
104
+
105
+ ==
106
+ :- listen(http_session(end(SessionId, Peer)),
107
+ end_session(SessionId)).
108
+ ==
109
+ */
110
+
111
+ :- dynamic
112
+ session_setting/1, % Name(Value)
113
+ current_session/2, % SessionId, Peer
114
+ last_used/2, % SessionId, Time
115
+ session_data/2. % SessionId, Data
116
+
117
+ :- multifile
118
+ hooked/0,
119
+ hook/1, % +Term
120
+ session_setting/1,
121
+ session_option/2.
122
+
123
+ session_setting(timeout(600)). % timeout in seconds
124
+ session_setting(granularity(60)). % granularity for timeout
125
+ session_setting(cookie('swipl_session')).
126
+ session_setting(path(/)).
127
+ session_setting(enabled(true)).
128
+ session_setting(create(auto)).
129
+ session_setting(proxy_enabled(false)).
130
+ session_setting(gc(passive)).
131
+ session_setting(samesite(lax)).
132
+ session_setting(http_only(false)).
133
+ session_setting(secure(false)).
134
+
135
+ session_option(timeout, integer).
136
+ session_option(granularity, integer).
137
+ session_option(cookie, atom).
138
+ session_option(path, atom).
139
+ session_option(create, oneof([auto,noauto])).
140
+ session_option(route, atom).
141
+ session_option(enabled, boolean).
142
+ session_option(proxy_enabled, boolean).
143
+ session_option(gc, oneof([active,passive])).
144
+ session_option(samesite, oneof([none,lax,strict])).
145
+ session_option(http_only, boolean).
146
+ session_option(secure, boolean).
147
+
148
+ %! http_set_session_options(+Options) is det.
149
+ %
150
+ % Set options for the session library. Provided options are:
151
+ %
152
+ % * timeout(+Seconds)
153
+ % Session timeout in seconds. Default is 600 (10 min).
154
+ % A timeout of `0` (zero) disables timeout.
155
+ %
156
+ % * cookie(+Cookiekname)
157
+ % Name to use for the cookie to identify the session.
158
+ % Default =swipl_session=.
159
+ %
160
+ % * path(+Path)
161
+ % Path to which the cookie is associated. Default is
162
+ % =|/|=. Cookies are only sent if the HTTP request path
163
+ % is a refinement of Path.
164
+ %
165
+ % * route(+Route)
166
+ % Set the route name. Default is the unqualified
167
+ % hostname. To cancel adding a route, use the empty
168
+ % atom. See route/1.
169
+ %
170
+ % * enabled(+Boolean)
171
+ % Enable/disable session management. Session management
172
+ % is enabled by default after loading this file.
173
+ %
174
+ % * create(+Atom)
175
+ % Defines when a session is created. This is one of =auto=
176
+ % (default), which creates a session if there is a request
177
+ % whose path matches the defined session path or =noauto=,
178
+ % in which cases sessions are only created by calling
179
+ % http_open_session/2 explicitly.
180
+ %
181
+ % * proxy_enabled(+Boolean)
182
+ % Enable/disable proxy session management. Proxy session
183
+ % management associates the _originating_ IP address of
184
+ % the client to the session rather than the _proxy_ IP
185
+ % address. Default is false.
186
+ %
187
+ % * gc(+When)
188
+ % When is one of `active`, which starts a thread that
189
+ % performs session cleanup at close to the moment of the
190
+ % timeout or `passive`, which runs session GC when a new
191
+ % session is created.
192
+ %
193
+ % * samesite(+Restriction)
194
+ % One of `none`, `lax` (default), or `strict` - The
195
+ % SameSite attribute prevents the CSRF vulnerability.
196
+ % strict has best security, but prevents links from
197
+ % external sites from operating properly. lax stops most
198
+ % CSRF attacks against REST endpoints but rarely interferes
199
+ % with legit image operations. `none` removes the samesite
200
+ % attribute entirely. __Caution: The value `none` exposes the
201
+ % entire site to CSRF attacks__.
202
+ %
203
+ % * http_only(+Boolean)
204
+ % If `true` (default `false`), add the ``HttpOnly`` property
205
+ % to the session cookie. This causes the browser to deny
206
+ % access from JavaScript.
207
+ %
208
+ % * secure(+Boolean)
209
+ % If `true`, (default `false`), add the ``Secure`` property
210
+ % to the session cookie. This causes the browser to report
211
+ % the cookie only over HTTPS connections.
212
+ %
213
+ % * granularity(+Integer)
214
+ % Granularity for updating that the session is active. Default
215
+ % is 60 (seconds). Smaller values lead to more precise session
216
+ % timeout at the cost of more database updates. This may
217
+ % notably a problem when using Redis.
218
+ %
219
+ % In addition, extension libraries can define session_option/2 to make
220
+ % this predicate support more options. In particular,
221
+ % library(http/http_redis_plugin) defines the following additional
222
+ % options:
223
+ %
224
+ % - redis_db(+DB)
225
+ % Alias name of the redis database to access. See redis_server/3.
226
+ % - redis_ro(+DB)
227
+ % Alias name of the redis database for read-only access. See
228
+ % redis_server/3.
229
+ % - redis_prefix(+Atom)
230
+ % Prefix to use for all HTTP session related keys. Default is
231
+ % `'swipl:http:session'`
232
+
233
+ http_set_session_options([]) => true.
234
+ http_set_session_options([H|T]) =>
235
+ http_set_session_option(H),
236
+ http_set_session_options(T).
237
+
238
+ http_set_session_option(Option), Option =.. [Name,Value] =>
239
+ ( session_option(Name, Type)
240
+ -> must_be(Type, Value)
241
+ ; domain_error(http_session_option, Option)
242
+ ),
243
+ functor(Free, Name, 1),
244
+ ( clause(session_setting(Free), _, Ref)
245
+ -> ( Free \== Value
246
+ -> asserta(session_setting(Option)),
247
+ erase(Ref),
248
+ updated_session_setting(Name, Free, Value)
249
+ ; true
250
+ )
251
+ ; asserta(session_setting(Option))
252
+ ).
253
+
254
+ %! http_session_option(?Option) is nondet.
255
+ %
256
+ % True if Option is a current option of the session system.
257
+
258
+ http_session_option(Option) :-
259
+ session_setting(Option).
260
+
261
+ %! session_setting(+SessionID, ?Setting) is semidet.
262
+ %
263
+ % Find setting for SessionID. It is possible to overrule some
264
+ % session settings using http_session_set(Setting).
265
+
266
+ :- public session_setting/2.
267
+
268
+ session_setting(SessionID, Setting) :-
269
+ nonvar(Setting),
270
+ get_session_option(SessionID, Setting),
271
+ !.
272
+ session_setting(_, Setting) :-
273
+ session_setting(Setting).
274
+
275
+ get_session_option(SessionID, Setting) :-
276
+ hooked,
277
+ !,
278
+ hook(get_session_option(SessionID, Setting)).
279
+ get_session_option(SessionID, Setting) :-
280
+ functor(Setting, Name, 1),
281
+ local_option(Name, Value, Term),
282
+ session_data(SessionID, '$setting'(Term)),
283
+ !,
284
+ arg(1, Setting, Value).
285
+
286
+
287
+ updated_session_setting(gc, _, passive) :-
288
+ stop_session_gc_thread, !.
289
+ updated_session_setting(_, _, _). % broadcast?
290
+
291
+
292
+ %! http_set_session(Setting) is det.
293
+ %! http_set_session(SessionId, Setting) is det.
294
+ %
295
+ % Overrule a setting for the current or specified session.
296
+ % Currently, the only setting that can be overruled is =timeout=.
297
+ %
298
+ % @error permission_error(set, http_session, Setting) if setting
299
+ % a setting that is not supported on per-session basis.
300
+
301
+ http_set_session(Setting) :-
302
+ http_session_id(SessionId),
303
+ http_set_session(SessionId, Setting).
304
+
305
+ http_set_session(SessionId, Setting) :-
306
+ functor(Setting, Name, _),
307
+ ( local_option(Name, _, _)
308
+ -> true
309
+ ; permission_error(set, http_session, Setting)
310
+ ),
311
+ arg(1, Setting, Value),
312
+ ( session_option(Name, Type)
313
+ -> must_be(Type, Value)
314
+ ; domain_error(http_session_option, Setting)
315
+ ),
316
+ set_session_option(SessionId, Setting).
317
+
318
+ set_session_option(SessionId, Setting) :-
319
+ hooked,
320
+ !,
321
+ hook(set_session_option(SessionId, Setting)).
322
+ set_session_option(SessionId, Setting) :-
323
+ functor(Setting, Name, Arity),
324
+ functor(Free, Name, Arity),
325
+ retractall(session_data(SessionId, '$setting'(Free))),
326
+ assert(session_data(SessionId, '$setting'(Setting))).
327
+
328
+ local_option(timeout, X, timeout(X)).
329
+
330
+ %! http_session_id(-SessionId) is det.
331
+ %
332
+ % True if SessionId is an identifier for the current session.
333
+ %
334
+ % @arg SessionId is an atom.
335
+ % @error existence_error(http_session, _)
336
+ % @see http_in_session/1 for a version that fails if there is
337
+ % no session.
338
+
339
+ http_session_id(SessionID) :-
340
+ ( http_in_session(ID)
341
+ -> SessionID = ID
342
+ ; throw(error(existence_error(http_session, _), _))
343
+ ).
344
+
345
+ %! http_in_session(-SessionId) is semidet.
346
+ %
347
+ % True if SessionId is an identifier for the current session. The
348
+ % current session is extracted from session(ID) from the current
349
+ % HTTP request (see http_current_request/1). The value is cached
350
+ % in a backtrackable global variable =http_session_id=. Using a
351
+ % backtrackable global variable is safe because continuous worker
352
+ % threads use a failure driven loop and spawned threads start
353
+ % without any global variables. This variable can be set from the
354
+ % commandline to fake running a goal from the commandline in the
355
+ % context of a session.
356
+ %
357
+ % @see http_session_id/1
358
+
359
+ http_in_session(SessionID) :-
360
+ nb_current(http_session_id, ID),
361
+ ID \== [],
362
+ !,
363
+ debug(http_session, 'Session id from global variable: ~q', [ID]),
364
+ ID \== no_session,
365
+ SessionID = ID.
366
+ http_in_session(SessionID) :-
367
+ http_current_request(Request),
368
+ http_in_session(Request, SessionID).
369
+
370
+ http_in_session(Request, SessionID) :-
371
+ memberchk(session(ID), Request),
372
+ !,
373
+ debug(http_session, 'Session id from request: ~q', [ID]),
374
+ b_setval(http_session_id, ID),
375
+ SessionID = ID.
376
+ http_in_session(Request, SessionID) :-
377
+ memberchk(cookie(Cookies), Request),
378
+ session_setting(cookie(Cookie)),
379
+ member(Cookie=SessionID0, Cookies),
380
+ debug(http_session, 'Session id from cookie: ~q', [SessionID0]),
381
+ peer(Request, Peer),
382
+ valid_session_id(SessionID0, Peer),
383
+ !,
384
+ b_setval(http_session_id, SessionID0),
385
+ SessionID = SessionID0.
386
+
387
+
388
+ %! http_session(+RequestIn, -RequestOut, -SessionID) is semidet.
389
+ %
390
+ % Maintain the notion of a session using a client-side cookie.
391
+ % This must be called first when handling a request that wishes to
392
+ % do session management, after which the possibly modified request
393
+ % must be used for further processing.
394
+ %
395
+ % This predicate creates a session if the setting create is
396
+ % =auto=. If create is =noauto=, the application must call
397
+ % http_open_session/1 to create a session.
398
+
399
+ http_session(Request, Request, SessionID) :-
400
+ memberchk(session(SessionID0), Request),
401
+ !,
402
+ SessionID = SessionID0.
403
+ http_session(Request0, Request, SessionID) :-
404
+ memberchk(cookie(Cookies), Request0),
405
+ session_setting(cookie(Cookie)),
406
+ member(Cookie=SessionID0, Cookies),
407
+ peer(Request0, Peer),
408
+ valid_session_id(SessionID0, Peer),
409
+ !,
410
+ SessionID = SessionID0,
411
+ Request = [session(SessionID)|Request0],
412
+ b_setval(http_session_id, SessionID).
413
+ http_session(Request0, Request, SessionID) :-
414
+ session_setting(create(auto)),
415
+ session_setting(path(Path)),
416
+ memberchk(path(ReqPath), Request0),
417
+ sub_atom(ReqPath, 0, _, _, Path),
418
+ !,
419
+ create_session(Request0, Request, SessionID).
420
+
421
+ create_session(Request0, Request, SessionID) :-
422
+ http_gc_sessions,
423
+ http_session_cookie(SessionID),
424
+ session_setting(cookie(Cookie)),
425
+ session_setting(path(Path)),
426
+ cookie_attributes(Attrs),
427
+ atomics_to_string([''|Attrs], '; ', AttrString),
428
+ debug(http_session, 'Created session ~q at path=~q', [SessionID, Path]),
429
+ format('Set-Cookie: ~w=~w; Path=~w; Version=1~w\r\n',
430
+ [ Cookie, SessionID, Path, AttrString ]),
431
+ Request = [session(SessionID)|Request0],
432
+ peer(Request0, Peer),
433
+ open_session(SessionID, Peer).
434
+
435
+ cookie_attributes([SameSite|Attrs]) :-
436
+ session_setting(samesite(Value)),
437
+ Value \== none,
438
+ !,
439
+ string_concat('SameSite=', Value, SameSite),
440
+ cookie_attributes1(Attrs).
441
+ cookie_attributes(Attrs) :-
442
+ cookie_attributes1(Attrs).
443
+
444
+ cookie_attributes1(['HttpOnly'|Attrs]) :-
445
+ session_setting(http_only(true)),
446
+ !,
447
+ cookie_attributes2(Attrs).
448
+ cookie_attributes1(Attrs) :-
449
+ cookie_attributes2(Attrs).
450
+
451
+ cookie_attributes2(['Secure']) :-
452
+ session_setting(secure(true)),
453
+ !.
454
+ cookie_attributes2([]).
455
+
456
+
457
+ %! http_open_session(-SessionID, +Options) is det.
458
+ %
459
+ % Establish a new session. This is normally used if the create
460
+ % option is set to =noauto=. Options:
461
+ %
462
+ % * renew(+Boolean)
463
+ % If =true= (default =false=) and the current request is part
464
+ % of a session, generate a new session-id. By default, this
465
+ % predicate returns the current session as obtained with
466
+ % http_in_session/1.
467
+ %
468
+ % @see http_set_session_options/1 to control the =create= option.
469
+ % @see http_close_session/1 for closing the session.
470
+ % @error permission_error(open, http_session, CGI) if this call
471
+ % is used after closing the CGI header.
472
+
473
+ http_open_session(SessionID, Options) :-
474
+ http_in_session(SessionID0),
475
+ \+ option(renew(true), Options, false),
476
+ !,
477
+ SessionID = SessionID0.
478
+ http_open_session(SessionID, _Options) :-
479
+ ( in_header_state
480
+ -> true
481
+ ; current_output(CGI),
482
+ permission_error(open, http_session, CGI)
483
+ ),
484
+ ( http_in_session(ActiveSession)
485
+ -> http_close_session(ActiveSession, false)
486
+ ; true
487
+ ),
488
+ http_current_request(Request),
489
+ create_session(Request, _, SessionID).
490
+
491
+
492
+ :- multifile
493
+ http:request_expansion/2.
494
+
495
+ http:request_expansion(Request0, Request) :-
496
+ session_setting(enabled(true)),
497
+ http_session(Request0, Request, _SessionID).
498
+
499
+ %! peer(+Request, -Peer) is det.
500
+ %
501
+ % Find peer for current request. If unknown we leave it unbound.
502
+ % Alternatively we should treat this as an error.
503
+
504
+ peer(Request, Peer) :-
505
+ ( session_setting(proxy_enabled(true)),
506
+ http_peer(Request, Peer)
507
+ -> true
508
+ ; memberchk(peer(Peer), Request)
509
+ -> true
510
+ ; true
511
+ ).
512
+
513
+ %! open_session(+SessionID, +Peer)
514
+ %
515
+ % Open a new session. Uses broadcast/1 with the term
516
+ % http_session(begin(SessionID, Peer)).
517
+
518
+ open_session(SessionID, Peer) :-
519
+ assert_session(SessionID, Peer),
520
+ b_setval(http_session_id, SessionID),
521
+ broadcast(http_session(begin(SessionID, Peer))).
522
+
523
+ assert_session(SessionID, Peer) :-
524
+ hooked,
525
+ !,
526
+ hook(assert_session(SessionID, Peer)).
527
+ assert_session(SessionID, Peer) :-
528
+ get_time(Now),
529
+ assert(current_session(SessionID, Peer)),
530
+ assert(last_used(SessionID, Now)).
531
+
532
+ %! valid_session_id(+SessionID, +Peer) is semidet.
533
+ %
534
+ % Check if this sessionID is known. If so, check the idle time and
535
+ % update the last_used for this session.
536
+
537
+ valid_session_id(SessionID, Peer) :-
538
+ active_session(SessionID, SessionPeer, LastUsed),
539
+ get_time(Now),
540
+ ( session_setting(SessionID, timeout(Timeout)),
541
+ Timeout > 0
542
+ -> Idle is Now - LastUsed,
543
+ ( Idle =< Timeout
544
+ -> true
545
+ ; http_close_session(SessionID),
546
+ fail
547
+ )
548
+ ; Peer \== SessionPeer
549
+ -> http_close_session(SessionID),
550
+ fail
551
+ ; true
552
+ ),
553
+ set_last_used(SessionID, Now, Timeout).
554
+
555
+ active_session(SessionID, Peer, LastUsed) :-
556
+ hooked,
557
+ !,
558
+ hook(active_session(SessionID, Peer, LastUsed)).
559
+ active_session(SessionID, Peer, LastUsed) :-
560
+ current_session(SessionID, Peer),
561
+ get_last_used(SessionID, LastUsed).
562
+
563
+ get_last_used(SessionID, Last) :-
564
+ atom(SessionID),
565
+ !,
566
+ once(last_used(SessionID, Last)).
567
+ get_last_used(SessionID, Last) :-
568
+ last_used(SessionID, Last).
569
+
570
+ %! set_last_used(+SessionID, +Now, +TimeOut)
571
+ %
572
+ % Set the last-used notion for SessionID from the current time stamp.
573
+ % The time is rounded down to 10 second intervals to avoid many
574
+ % updates and simplify the scheduling of session GC.
575
+
576
+ set_last_used(SessionID, Now, TimeOut) :-
577
+ hooked,
578
+ !,
579
+ hook(set_last_used(SessionID, Now, TimeOut)).
580
+ set_last_used(SessionID, Now, _TimeOut) :-
581
+ session_setting(granularity(TimeGranularity)),
582
+ LastUsed is floor(Now/TimeGranularity)*TimeGranularity,
583
+ ( clause(last_used(SessionID, CurrentLast), _, Ref)
584
+ -> ( CurrentLast == LastUsed
585
+ -> true
586
+ ; asserta(last_used(SessionID, LastUsed)),
587
+ erase(Ref)
588
+ )
589
+ ; asserta(last_used(SessionID, LastUsed))
590
+ ).
591
+
592
+
593
+ /*******************************
594
+ * SESSION DATA *
595
+ *******************************/
596
+
597
+ %! http_session_asserta(+Data) is det.
598
+ %! http_session_assert(+Data) is det.
599
+ %! http_session_retract(?Data) is nondet.
600
+ %! http_session_retractall(?Data) is det.
601
+ %
602
+ % Versions of assert/1, retract/1 and retractall/1 that associate
603
+ % data with the current HTTP session.
604
+
605
+ http_session_asserta(Data) :-
606
+ http_session_id(SessionId),
607
+ ( hooked
608
+ -> hook(asserta(session_data(SessionId, Data)))
609
+ ; asserta(session_data(SessionId, Data))
610
+ ).
611
+
612
+ http_session_assert(Data) :-
613
+ http_session_id(SessionId),
614
+ ( hooked
615
+ -> hook(assertz(session_data(SessionId, Data)))
616
+ ; assertz(session_data(SessionId, Data))
617
+ ).
618
+
619
+ http_session_retract(Data) :-
620
+ http_session_id(SessionId),
621
+ ( hooked
622
+ -> hook(retract(session_data(SessionId, Data)))
623
+ ; retract(session_data(SessionId, Data))
624
+ ).
625
+
626
+ http_session_retractall(Data) :-
627
+ http_session_id(SessionId),
628
+ ( hooked
629
+ -> hook(retractall(session_data(SessionId, Data)))
630
+ ; retractall(session_data(SessionId, Data))
631
+ ).
632
+
633
+ %! http_session_data(?Data) is nondet.
634
+ %
635
+ % True if Data is associated using http_session_assert/1 to the
636
+ % current HTTP session.
637
+ %
638
+ % @error existence_error(http_session,_)
639
+
640
+ http_session_data(Data) :-
641
+ http_session_id(SessionId),
642
+ ( hooked
643
+ -> hook(session_data(SessionId, Data))
644
+ ; session_data(SessionId, Data)
645
+ ).
646
+
647
+ %! http_session_asserta(+Data, +SessionID) is det.
648
+ %! http_session_assert(+Data, +SessionID) is det.
649
+ %! http_session_retract(?Data, +SessionID) is nondet.
650
+ %! http_session_retractall(@Data, +SessionID) is det.
651
+ %! http_session_data(?Data, +SessionID) is det.
652
+ %
653
+ % Versions of assert/1, retract/1 and retractall/1 that associate data
654
+ % with an explicit HTTP session.
655
+ %
656
+ % @see http_current_session/2.
657
+
658
+ http_session_asserta(Data, SessionId) :-
659
+ must_be(atom, SessionId),
660
+ ( hooked
661
+ -> hook(asserta(session_data(SessionId, Data)))
662
+ ; asserta(session_data(SessionId, Data))
663
+ ).
664
+
665
+ http_session_assert(Data, SessionId) :-
666
+ must_be(atom, SessionId),
667
+ ( hooked
668
+ -> hook(assertz(session_data(SessionId, Data)))
669
+ ; assertz(session_data(SessionId, Data))
670
+ ).
671
+
672
+ http_session_retract(Data, SessionId) :-
673
+ must_be(atom, SessionId),
674
+ ( hooked
675
+ -> hook(retract(session_data(SessionId, Data)))
676
+ ; retract(session_data(SessionId, Data))
677
+ ).
678
+
679
+ http_session_retractall(Data, SessionId) :-
680
+ must_be(atom, SessionId),
681
+ ( hooked
682
+ -> hook(retractall(session_data(SessionId, Data)))
683
+ ; retractall(session_data(SessionId, Data))
684
+ ).
685
+
686
+ http_session_data(Data, SessionId) :-
687
+ must_be(atom, SessionId),
688
+ ( hooked
689
+ -> hook(session_data(SessionId, Data))
690
+ ; session_data(SessionId, Data)
691
+ ).
692
+
693
+
694
+ /*******************************
695
+ * ENUMERATE *
696
+ *******************************/
697
+
698
+ %! http_current_session(?SessionID, ?Data) is nondet.
699
+ %
700
+ % Enumerate the current sessions and associated data. There are
701
+ % two _pseudo_ data elements:
702
+ %
703
+ % * idle(Seconds)
704
+ % Session has been idle for Seconds.
705
+ %
706
+ % * peer(Peer)
707
+ % Peer of the connection.
708
+
709
+ http_current_session(SessionID, Data) :-
710
+ hooked,
711
+ !,
712
+ hook(current_session(SessionID, Data)).
713
+ http_current_session(SessionID, Data) :-
714
+ get_time(Now),
715
+ get_last_used(SessionID, Last), % binds SessionID
716
+ Idle is Now - Last,
717
+ ( session_setting(SessionID, timeout(Timeout)),
718
+ Timeout > 0
719
+ -> Idle =< Timeout
720
+ ; true
721
+ ),
722
+ ( Data = idle(Idle)
723
+ ; Data = peer(Peer),
724
+ current_session(SessionID, Peer)
725
+ ; session_data(SessionID, Data)
726
+ ).
727
+
728
+
729
+ /*******************************
730
+ * GC SESSIONS *
731
+ *******************************/
732
+
733
+ %! http_close_session(+SessionID) is det.
734
+ %
735
+ % Closes an HTTP session. This predicate can be called from any
736
+ % thread to terminate a session. It uses the broadcast/1 service
737
+ % with the message below.
738
+ %
739
+ % http_session(end(SessionId, Peer))
740
+ %
741
+ % The broadcast is done *before* the session data is destroyed and
742
+ % the listen-handlers are executed in context of the session that
743
+ % is being closed. Here is an example that destroys a Prolog
744
+ % thread that is associated to a thread:
745
+ %
746
+ % ==
747
+ % :- listen(http_session(end(SessionId, _Peer)),
748
+ % kill_session_thread(SessionID)).
749
+ %
750
+ % kill_session_thread(SessionID) :-
751
+ % http_session_data(thread(ThreadID)),
752
+ % thread_signal(ThreadID, throw(session_closed)).
753
+ % ==
754
+ %
755
+ % Succeed without any effect if SessionID does not refer to an
756
+ % active session.
757
+ %
758
+ % If http_close_session/1 is called from a handler operating in
759
+ % the current session and the CGI stream is still in state
760
+ % =header=, this predicate emits a =|Set-Cookie|= to expire the
761
+ % cookie.
762
+ %
763
+ % @error type_error(atom, SessionID)
764
+ % @see listen/2 for acting upon closed sessions
765
+
766
+ http_close_session(SessionId) :-
767
+ http_close_session(SessionId, true).
768
+
769
+ http_close_session(SessionId, Expire) :-
770
+ hooked,
771
+ !,
772
+ forall(hook(close_session(SessionId)),
773
+ expire_session_cookie(Expire)).
774
+ http_close_session(SessionId, Expire) :-
775
+ must_be(atom, SessionId),
776
+ ( current_session(SessionId, Peer),
777
+ ( b_setval(http_session_id, SessionId),
778
+ broadcast(http_session(end(SessionId, Peer))),
779
+ fail
780
+ ; true
781
+ ),
782
+ expire_session_cookie(Expire),
783
+ retractall(current_session(SessionId, _)),
784
+ retractall(last_used(SessionId, _)),
785
+ retractall(session_data(SessionId, _)),
786
+ fail
787
+ ; true
788
+ ).
789
+
790
+
791
+ %! expire_session_cookie(+Expire) is det.
792
+ %
793
+ % Emit a request to delete a session cookie. This is only done if
794
+ % http_close_session/1 is still in `header mode'.
795
+
796
+ expire_session_cookie(true) :-
797
+ !,
798
+ expire_session_cookie.
799
+ expire_session_cookie(_).
800
+
801
+ expire_session_cookie :-
802
+ in_header_state,
803
+ session_setting(cookie(Cookie)),
804
+ session_setting(path(Path)),
805
+ !,
806
+ format('Set-Cookie: ~w=; \c
807
+ expires=Tue, 01-Jan-1970 00:00:00 GMT; \c
808
+ path=~w\r\n',
809
+ [Cookie, Path]).
810
+ expire_session_cookie.
811
+
812
+ in_header_state :-
813
+ current_output(CGI),
814
+ is_cgi_stream(CGI),
815
+ cgi_property(CGI, state(header)),
816
+ !.
817
+
818
+
819
+ %! http_gc_sessions is det.
820
+ %! http_gc_sessions(+TimeOut) is det.
821
+ %
822
+ % Delete dead sessions. There are two modes. if gc(passive) is active
823
+ % (default), session GC is executed if a new session is created and if
824
+ % the last GC was more than `granularity` ago. If gc(active) is on, a
825
+ % thread is created that runs the session GC every `granularity`
826
+ % seconds.
827
+ %
828
+ % http_gc_sessions/0 is called each time when a session is created.
829
+
830
+ :- dynamic
831
+ last_gc/1.
832
+
833
+ http_gc_sessions :-
834
+ session_setting(gc(active)),
835
+ !,
836
+ start_session_gc_thread.
837
+ http_gc_sessions :-
838
+ session_setting(granularity(TimeGranularity)),
839
+ http_gc_sessions(TimeGranularity).
840
+
841
+ http_gc_sessions(TimeOut) :-
842
+ ( with_mutex(http_session_gc, need_sesion_gc(TimeOut))
843
+ -> do_http_gc_sessions
844
+ ; true
845
+ ).
846
+
847
+ need_sesion_gc(TimeOut) :-
848
+ get_time(Now),
849
+ ( last_gc(LastGC),
850
+ Now-LastGC < TimeOut
851
+ -> fail
852
+ ; retractall(last_gc(_)),
853
+ asserta(last_gc(Now))
854
+ ).
855
+
856
+ do_http_gc_sessions :-
857
+ hooked,
858
+ !,
859
+ hook(gc_sessions).
860
+ do_http_gc_sessions :-
861
+ debug(http_session(gc), 'Running HTTP session GC', []),
862
+ get_time(Now),
863
+ ( session_setting(SessionID, timeout(Timeout)),
864
+ last_used(SessionID, Last),
865
+ Timeout > 0,
866
+ Idle is Now - Last,
867
+ Idle > Timeout,
868
+ http_close_session(SessionID, false),
869
+ fail
870
+ ; true
871
+ ).
872
+
873
+ %! start_session_gc_thread is det.
874
+ %! stop_session_gc_thread is det.
875
+ %
876
+ % Create/stop a thread that listens for timeout-at timing and wakes up
877
+ % to run http_gc_sessions/1 shortly after a session is scheduled to
878
+ % timeout.
879
+
880
+ :- dynamic
881
+ session_gc_queue/1.
882
+
883
+ start_session_gc_thread :-
884
+ session_gc_queue(_),
885
+ !.
886
+ start_session_gc_thread :-
887
+ session_setting(gc(active)),
888
+ !,
889
+ catch(thread_create(session_gc_loop, _,
890
+ [ alias('__http_session_gc'),
891
+ at_exit(retractall(session_gc_queue(_))),
892
+ inherit_from(main)
893
+ ]),
894
+ error(permission_error(create, thread, _),_),
895
+ true).
896
+ start_session_gc_thread.
897
+
898
+ stop_session_gc_thread :-
899
+ retract(session_gc_queue(Id)),
900
+ !,
901
+ thread_send_message(Id, done),
902
+ thread_join(Id, _).
903
+ stop_session_gc_thread.
904
+
905
+ session_gc_loop :-
906
+ thread_self(GcQueue),
907
+ asserta(session_gc_queue(GcQueue)),
908
+ session_gc_loop_.
909
+
910
+ session_gc_loop_ :-
911
+ session_setting(gc(active)),
912
+ session_setting(granularity(TimeGranularity)),
913
+ get_time(Now),
914
+ At is Now+TimeGranularity,
915
+ thread_self(GcQueue),
916
+ repeat,
917
+ ( thread_get_message(GcQueue, Message, [deadline(At)])
918
+ -> ( Message == done
919
+ -> !
920
+ ; fail
921
+ )
922
+ ; !,
923
+ http_gc_sessions(10), % short time, so it runs
924
+ session_gc_loop_
925
+ ).
926
+
927
+
928
+ /*******************************
929
+ * UTIL *
930
+ *******************************/
931
+
932
+ %! http_session_cookie(-Cookie) is det.
933
+ %
934
+ % Generate a random cookie that can be used by a browser to
935
+ % identify the current session. The cookie has the format
936
+ % XXXX-XXXX-XXXX-XXXX[.<route>], where XXXX are random hexadecimal
937
+ % numbers and [.<route>] is the optionally added routing
938
+ % information.
939
+
940
+ http_session_cookie(Cookie) :-
941
+ route(Route),
942
+ !,
943
+ random_4(R1,R2,R3,R4),
944
+ format(atom(Cookie),
945
+ '~`0t~16r~4|-~`0t~16r~9|-~`0t~16r~14|-~`0t~16r~19|.~w',
946
+ [R1,R2,R3,R4,Route]).
947
+ http_session_cookie(Cookie) :-
948
+ random_4(R1,R2,R3,R4),
949
+ format(atom(Cookie),
950
+ '~`0t~16r~4|-~`0t~16r~9|-~`0t~16r~14|-~`0t~16r~19|',
951
+ [R1,R2,R3,R4]).
952
+
953
+ :- thread_local
954
+ route_cache/1.
955
+
956
+ %! route(-RouteID) is semidet.
957
+ %
958
+ % Fetch the route identifier. This value is added as .<route> to
959
+ % the session cookie and used by -for example- the Apache load
960
+ % balancing module. The default route is the local name of the
961
+ % host. Alternatives may be provided using
962
+ % http_set_session_options/1.
963
+
964
+ route(Route) :-
965
+ route_cache(Route),
966
+ !,
967
+ Route \== ''.
968
+ route(Route) :-
969
+ route_no_cache(Route),
970
+ assert(route_cache(Route)),
971
+ Route \== ''.
972
+
973
+ route_no_cache(Route) :-
974
+ session_setting(route(Route)),
975
+ !.
976
+ route_no_cache(Route) :-
977
+ gethostname(Host),
978
+ ( sub_atom(Host, Before, _, _, '.')
979
+ -> sub_atom(Host, 0, Before, _, Route)
980
+ ; Route = Host
981
+ ).
982
+
983
+ :- if(\+current_prolog_flag(windows, true)).
984
+ %! urandom(-Handle) is semidet.
985
+ %
986
+ % Handle is a stream-handle for ``/dev/urandom``. Originally, this
987
+ % simply tried to open ``/dev/urandom``, failing if this device does
988
+ % not exist. It turns out that trying to open ``/dev/urandom`` can
989
+ % block indefinitely on some Windows installations, so we no longer
990
+ % try this on Windows.
991
+
992
+ :- dynamic
993
+ urandom_handle/1.
994
+
995
+ urandom(Handle) :-
996
+ urandom_handle(Handle),
997
+ !,
998
+ Handle \== [].
999
+ urandom(Handle) :-
1000
+ catch(open('/dev/urandom', read, In, [type(binary)]), _, fail),
1001
+ !,
1002
+ assert(urandom_handle(In)),
1003
+ Handle = In.
1004
+ urandom(_) :-
1005
+ assert(urandom_handle([])),
1006
+ fail.
1007
+
1008
+ get_pair(In, Value) :-
1009
+ get_byte(In, B1),
1010
+ get_byte(In, B2),
1011
+ Value is B1<<8+B2.
1012
+ :- endif.
1013
+
1014
+ %! random_4(-R1,-R2,-R3,-R4) is det.
1015
+ %
1016
+ % Generate 4 2-byte random numbers. Uses ``/dev/urandom`` when
1017
+ % available to make prediction of the session IDs hard.
1018
+
1019
+ :- if(current_predicate(urandom/1)).
1020
+ random_4(R1,R2,R3,R4) :-
1021
+ urandom(In),
1022
+ !,
1023
+ get_pair(In, R1),
1024
+ get_pair(In, R2),
1025
+ get_pair(In, R3),
1026
+ get_pair(In, R4).
1027
+ :- endif.
1028
+ random_4(R1,R2,R3,R4) :-
1029
+ R1 is random(65536),
1030
+ R2 is random(65536),
1031
+ R3 is random(65536),
1032
+ R4 is random(65536).
1033
+
1034
+ %! hooked is semidet.
1035
+ %! hook(+Goal).
1036
+ %
1037
+ % These multifile predicates may be used to hook the data storage of
1038
+ % this library. An example is implemented by
1039
+ % library(http/http_redis_plugin), storing all session data in a redis
1040
+ % database.