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,729 @@
1
+ /* Part of SWI-Prolog
2
+
3
+ Author: Jan Wielemaker
4
+ E-mail: J.Wielemaker@vu.nl
5
+ WWW: http://www.swi-prolog.org
6
+ Copyright (c) 2014-2015, VU University Amsterdam
7
+ All rights reserved.
8
+
9
+ Redistribution and use in source and binary forms, with or without
10
+ modification, are permitted provided that the following conditions
11
+ are met:
12
+
13
+ 1. Redistributions of source code must retain the above copyright
14
+ notice, this list of conditions and the following disclaimer.
15
+
16
+ 2. Redistributions in binary form must reproduce the above copyright
17
+ notice, this list of conditions and the following disclaimer in
18
+ the documentation and/or other materials provided with the
19
+ distribution.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24
+ FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25
+ COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27
+ BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31
+ ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32
+ POSSIBILITY OF SUCH DAMAGE.
33
+ */
34
+
35
+ :- module(websocket,
36
+ [ http_open_websocket/3, % +URL, -WebSocket, +Options
37
+ http_upgrade_to_websocket/3, % :Goal, +Options, +Request
38
+ ws_send/2, % +WebSocket, +Message
39
+ ws_receive/2, % +WebSocket, -Message
40
+ ws_receive/3, % +WebSocket, -Message, +Options
41
+ ws_close/3, % +WebSocket, +Code, +Message
42
+ % Low level interface
43
+ ws_open/3, % +Stream, -WebSocket, +Options
44
+ ws_property/2 % +WebSocket, ?Property
45
+ ]).
46
+ :- use_module(library(debug),[debug/3]).
47
+ :- use_module(library(http/http_dispatch),[http_switch_protocol/2]).
48
+
49
+ :- autoload(library(base64),[base64//1]).
50
+ :- autoload(library(error),
51
+ [permission_error/3,must_be/2,type_error/2,domain_error/2]).
52
+ :- autoload(library(lists),[member/2]).
53
+ :- autoload(library(option),[select_option/3,option/2,option/3]).
54
+ :- autoload(library(sha),[sha_hash/3]).
55
+ :- autoload(library(http/http_open),[http_open/3]).
56
+ :- autoload(library(json),[json_write_dict/2,json_read_dict/3]).
57
+
58
+ :- meta_predicate
59
+ http_upgrade_to_websocket(1, +, +).
60
+
61
+ :- predicate_options(http_open_websocket/3, 3,
62
+ [ subprotocols(list(atom)),
63
+ pass_to(http_open:http_open/3, 3)
64
+ ]).
65
+ :- predicate_options(http_upgrade_to_websocket/3, 2,
66
+ [ guarded(boolean),
67
+ subprotocols(list(atom))
68
+ ]).
69
+
70
+ :- use_foreign_library(foreign(websocket)).
71
+
72
+ /** <module> WebSocket support
73
+
74
+ WebSocket is a lightweight message oriented protocol on top of TCP/IP
75
+ streams. It is typically used as an _upgrade_ of an HTTP connection to
76
+ provide bi-directional communication, but can also be used in isolation
77
+ over arbitrary (Prolog) streams.
78
+
79
+ The SWI-Prolog interface is based on _streams_ and provides ws_open/3 to
80
+ create a _websocket stream_ from any Prolog stream. Typically, both an
81
+ input and output stream are wrapped and then combined into a single
82
+ object using stream_pair/3.
83
+
84
+ The high-level interface provides http_upgrade_to_websocket/3 to realise
85
+ a websocket inside the HTTP server infrastructure and
86
+ http_open_websocket/3 as a layer over http_open/3 to realise a client
87
+ connection. After establishing a connection, ws_send/2 and ws_receive/2
88
+ can be used to send and receive messages. The predicate ws_close/3 is
89
+ provided to perform the closing handshake and dispose of the stream
90
+ objects.
91
+
92
+ @see RFC 6455, http://tools.ietf.org/html/rfc6455
93
+ @tbd Deal with protocol extensions.
94
+ */
95
+
96
+
97
+
98
+ /*******************************
99
+ * HTTP SUPPORT *
100
+ *******************************/
101
+
102
+ %! http_open_websocket(+URL, -WebSocket, +Options) is det.
103
+ %
104
+ % Establish a client websocket connection. This predicate calls
105
+ % http_open/3 with additional headers to negotiate a websocket
106
+ % connection. In addition to the options processed by http_open/3, the
107
+ % following options are recognised:
108
+ %
109
+ % - subprotocols(+List)
110
+ % List of subprotocols that are acceptable. The selected
111
+ % protocol is available as ws_property(WebSocket,
112
+ % subprotocol(Protocol).
113
+ %
114
+ % Note that clients often provide an `Origin` header and some servers
115
+ % require this field. See RFC 6455 for details. By default this
116
+ % predicate does not set `Origin`. It may be set using the
117
+ % `request_header` option of http_open/3, e.g. by passing this in the
118
+ % Options list:
119
+ %
120
+ % request_header('Origin' = 'https://www.swi-prolog.org')
121
+ %
122
+ % The following example exchanges a message with the
123
+ % html5rocks.websocket.org echo service:
124
+ %
125
+ % ```
126
+ % ?- URL = 'ws://html5rocks.websocket.org/echo',
127
+ % http_open_websocket(URL, WS, []),
128
+ % ws_send(WS, text('Hello World!')),
129
+ % ws_receive(WS, Reply),
130
+ % ws_close(WS, 1000, "Goodbye").
131
+ % URL = 'ws://html5rocks.websocket.org/echo',
132
+ % WS = <stream>(0xe4a440,0xe4a610),
133
+ % Reply = websocket{data:"Hello World!", opcode:text}.
134
+ % ```
135
+ %
136
+ % @arg WebSocket is a stream pair (see stream_pair/3)
137
+
138
+ http_open_websocket(URL, WebSocket, Options) :-
139
+ phrase(base64(`___SWI-Prolog___`), Bytes),
140
+ string_codes(Key, Bytes),
141
+ add_subprotocols(Options, Options1),
142
+ http_open(URL, In,
143
+ [ status_code(Status),
144
+ output(Out),
145
+ header(sec_websocket_protocol, Selected),
146
+ header(sec_websocket_accept, AcceptedKey),
147
+ connection('Keep-alive, Upgrade'),
148
+ request_header('Upgrade' = websocket),
149
+ request_header('Sec-WebSocket-Key' = Key),
150
+ request_header('Sec-WebSocket-Version' = 13)
151
+ | Options1
152
+ ]),
153
+ ( Status == 101,
154
+ sec_websocket_accept(_{key:Key}, AcceptedKey)
155
+ -> ws_client_options(Selected, WsOptions),
156
+ stream_pair(In, Read, Write), % Old API: In and Out
157
+ stream_pair(Out, Read, Write), % New API: In == Out (= pair)
158
+ ws_open(Read, WsIn, WsOptions),
159
+ ws_open(Write, WsOut, WsOptions),
160
+ stream_pair(WebSocket, WsIn, WsOut)
161
+ ; close(Out),
162
+ close(In),
163
+ permission_error(open, websocket, URL)
164
+ ).
165
+
166
+ ws_client_options('', [mode(client)]) :- !.
167
+ ws_client_options(null, [mode(client)]) :- !.
168
+ ws_client_options(Subprotocol, [mode(client), subprotocol(Subprotocol)]).
169
+
170
+ add_subprotocols(OptionsIn, OptionsOut) :-
171
+ select_option(subprotocols(Subprotocols), OptionsIn, Options1),
172
+ !,
173
+ must_be(list(atom), Subprotocols),
174
+ atomic_list_concat(Subprotocols, ', ', Value),
175
+ OptionsOut = [ request_header('Sec-WebSocket-Protocol' = Value)
176
+ | Options1
177
+ ].
178
+ add_subprotocols(Options, Options).
179
+
180
+
181
+ %! http_upgrade_to_websocket(:Goal, +Options, +Request)
182
+ %
183
+ % Create a websocket connection running call(Goal, WebSocket),
184
+ % where WebSocket is a socket-pair. Options:
185
+ %
186
+ % * guarded(+Boolean)
187
+ % If `true` (default), guard the execution of Goal and close
188
+ % the websocket on both normal and abnormal termination of Goal.
189
+ % If `false`, Goal itself is responsible for the created
190
+ % websocket if Goal succeeds. The websocket is closed if Goal
191
+ % fails or raises an exception. This can be used to create a single
192
+ % thread that manages multiple websockets using I/O multiplexing.
193
+ % See library(http/hub).
194
+ %
195
+ % * subprotocols(+List)
196
+ % List of acceptable subprotocols.
197
+ %
198
+ % * timeout(+TimeOut)
199
+ % Timeout to apply to the input stream. Default is =infinite=.
200
+ %
201
+ % Note that the Request argument is the last for cooperation with
202
+ % http_handler/3. A simple _echo_ server that can be accessed at
203
+ % =/ws/= can be implemented as:
204
+ %
205
+ % ==
206
+ % :- use_module(library(http/websocket)).
207
+ % :- use_module(library(http/thread_httpd)).
208
+ % :- use_module(library(http/http_dispatch)).
209
+ %
210
+ % :- http_handler(root(ws),
211
+ % http_upgrade_to_websocket(echo, []),
212
+ % [spawn([])]).
213
+ %
214
+ % echo(WebSocket) :-
215
+ % ws_receive(WebSocket, Message),
216
+ % ( Message.opcode == close
217
+ % -> true
218
+ % ; ws_send(WebSocket, Message),
219
+ % echo(WebSocket)
220
+ % ).
221
+ % ==
222
+ %
223
+ % @see http_switch_protocol/2.
224
+ % @throws switching_protocols(Goal, Options). The recovery from
225
+ % this exception causes the HTTP infrastructure to call
226
+ % call(Goal, WebSocket).
227
+
228
+ http_upgrade_to_websocket(Goal, Options, Request) :-
229
+ request_websocket_info(Request, Info),
230
+ debug(websocket(open), 'Websocket request: ~p', [Info]),
231
+ sec_websocket_accept(Info, AcceptKey),
232
+ choose_subprotocol(Info, Options, SubProtocol, ExtraHeaders),
233
+ debug(websocket(open), 'Subprotocol: ~p', [SubProtocol]),
234
+ http_switch_protocol(
235
+ open_websocket(Goal, SubProtocol, Options),
236
+ [ headers([ upgrade(websocket),
237
+ connection('Upgrade'),
238
+ sec_websocket_accept(AcceptKey)
239
+ | ExtraHeaders
240
+ ])
241
+ ]).
242
+
243
+ choose_subprotocol(Info, Options, SubProtocol, ExtraHeaders) :-
244
+ HdrValue = Info.get(subprotocols),
245
+ option(subprotocols(ServerProtocols), Options),
246
+ split_string(HdrValue, ",", " ", RequestProtocols),
247
+ member(Protocol, RequestProtocols),
248
+ member(SubProtocol, ServerProtocols),
249
+ atom_string(SubProtocol, Protocol),
250
+ !,
251
+ ExtraHeaders = [ 'Sec-WebSocket-Protocol'(SubProtocol) ].
252
+ choose_subprotocol(_, _, null, []).
253
+
254
+ open_websocket(Goal, SubProtocol, Options, HTTPIn, HTTPOut) :-
255
+ option(timeout(TimeOut), Options, infinite),
256
+ set_stream(HTTPIn, timeout(TimeOut)),
257
+ WsOptions = [mode(server), subprotocol(SubProtocol)],
258
+ ws_open(HTTPIn, WsIn, WsOptions),
259
+ ws_open(HTTPOut, WsOut, WsOptions),
260
+ stream_pair(WebSocket, WsIn, WsOut),
261
+ guard_websocket_server(Goal, WebSocket, Options).
262
+
263
+ guard_websocket_server(Goal, WebSocket, Options) :-
264
+ ( catch(call(Goal, WebSocket), E, true)
265
+ -> ( var(E)
266
+ -> ( option(guarded(false), Options, true)
267
+ -> Close = false
268
+ ; Msg = bye, Code = 1000
269
+ )
270
+ ; message_to_string(E, Msg),
271
+ Code = 1011
272
+ )
273
+ ; Msg = "goal failed", Code = 1011
274
+ ),
275
+ ( Close == false
276
+ -> true
277
+ ; catch(ws_close(WebSocket, Code, Msg), Error,
278
+ print_message(error, Error))
279
+ ).
280
+
281
+
282
+ request_websocket_info(Request, Info) :-
283
+ option(upgrade(Websocket), Request),
284
+ downcase_atom(Websocket, websocket),
285
+ option(connection(Connection), Request),
286
+ connection_contains_upgrade(Connection),
287
+ option(sec_websocket_key(ClientKey), Request),
288
+ option(sec_websocket_version(Version), Request),
289
+ Info0 = _{key:ClientKey, version:Version},
290
+ add_option(origin, Request, origin, Info0, Info1),
291
+ add_option(sec_websocket_protocol, Request, subprotocols, Info1, Info2),
292
+ add_option(sec_websocket_extensions, Request, extensions, Info2, Info).
293
+
294
+ connection_contains_upgrade(Connection) :-
295
+ split_string(Connection, ",", " ", Tokens),
296
+ member(Token, Tokens),
297
+ string_lower(Token, "upgrade"),
298
+ !.
299
+
300
+ add_option(OptionName, Request, Key, Dict0, Dict) :-
301
+ Option =.. [OptionName,Value],
302
+ option(Option, Request),
303
+ !,
304
+ Dict = Dict0.put(Key,Value).
305
+ add_option(_, _, _, Dict, Dict).
306
+
307
+ %! sec_websocket_accept(+Info, -AcceptKey) is det.
308
+ %
309
+ % Compute the accept key as per 4.2.2., point 5.4
310
+
311
+ sec_websocket_accept(Info, AcceptKey) :-
312
+ string_concat(Info.key, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11", Str),
313
+ sha_hash(Str, Hash, [ algorithm(sha1) ]),
314
+ phrase(base64(Hash), Encoded),
315
+ string_codes(AcceptKey, Encoded).
316
+
317
+
318
+ /*******************************
319
+ * HIGH LEVEL INTERFACE *
320
+ *******************************/
321
+
322
+ %! ws_send(+WebSocket, +Message) is det.
323
+ %
324
+ % Send a message over a websocket. The following terms are allowed
325
+ % for Message:
326
+ %
327
+ % - text(+Text)
328
+ % Send a text message. Text is serialized using write/1.
329
+ % - binary(+Content)
330
+ % As text(+Text), but all character codes produced by Content
331
+ % must be in the range [0..255]. Typically, Content will be
332
+ % an atom or string holding binary data.
333
+ % - prolog(+Term)
334
+ % Send a Prolog term as a text message. Text is serialized
335
+ % using write_canonical/1.
336
+ % - json(+JSON)
337
+ % Send the Prolog representation of a JSON term using
338
+ % json_write_dict/2.
339
+ % - string(+Text)
340
+ % Same as text(+Text), provided for consistency.
341
+ % - close(+Code, +Text)
342
+ % Send a close message. Code is 1000 for normal close. See
343
+ % websocket documentation for other values.
344
+ % - Dict
345
+ % A dict that minimally contains an =opcode= key. Other keys
346
+ % used are:
347
+ %
348
+ % - format:Format
349
+ % Serialization format used for Message.data. Format is
350
+ % one of =string=, =prolog= or =json=. See ws_receive/3.
351
+ %
352
+ % - data:Term
353
+ % If this key is present, it is serialized according
354
+ % to Message.format. Otherwise it is serialized using
355
+ % write/1, which implies that string and atoms are just
356
+ % sent verbatim.
357
+ %
358
+ % Note that ws_start_message/3 does not unlock the stream. This is
359
+ % done by ws_send/1. This implies that multiple threads can use
360
+ % ws_send/2 and the messages are properly serialized.
361
+ %
362
+ % @tbd Provide serialization details using options.
363
+
364
+ ws_send(WsStream, Message) :-
365
+ message_opcode(Message, OpCode),
366
+ setup_call_cleanup(
367
+ ws_start_message(WsStream, OpCode, 0),
368
+ write_message_data(WsStream, Message),
369
+ ws_send(WsStream)).
370
+
371
+ message_opcode(Message, OpCode) :-
372
+ is_dict(Message),
373
+ !,
374
+ to_opcode(Message.opcode, OpCode).
375
+ message_opcode(Message, OpCode) :-
376
+ functor(Message, Name, _),
377
+ ( text_functor(Name)
378
+ -> to_opcode(text, OpCode)
379
+ ; to_opcode(Name, OpCode)
380
+ ).
381
+
382
+ text_functor(json).
383
+ text_functor(string).
384
+ text_functor(prolog).
385
+
386
+ write_message_data(Stream, Message) :-
387
+ is_dict(Message),
388
+ !,
389
+ ( _{code:Code, data:Data} :< Message
390
+ -> write_message_data(Stream, close(Code, Data))
391
+ ; _{format:prolog, data:Data} :< Message
392
+ -> format(Stream, '~k .~n', [Data])
393
+ ; _{format:json, data:Data} :< Message
394
+ -> json_write_dict(Stream, Data)
395
+ ; _{data:Data} :< Message
396
+ -> format(Stream, '~w', Data)
397
+ ; true
398
+ ).
399
+ write_message_data(Stream, Message) :-
400
+ functor(Message, Format, 1),
401
+ !,
402
+ arg(1, Message, Data),
403
+ ( text_functor(Format)
404
+ -> write_text_message(Format, Stream, Data)
405
+ ; format(Stream, '~w', [Data])
406
+ ).
407
+ write_message_data(_, Message) :-
408
+ atom(Message),
409
+ !.
410
+ write_message_data(Stream, close(Code, Data)) :-
411
+ !,
412
+ High is (Code >> 8) /\ 0xff,
413
+ Low is Code /\ 0xff,
414
+ put_byte(Stream, High),
415
+ put_byte(Stream, Low),
416
+ stream_pair(Stream, _, Out),
417
+ set_stream(Out, encoding(utf8)),
418
+ format(Stream, '~w', [Data]).
419
+ write_message_data(_, Message) :-
420
+ type_error(websocket_message, Message).
421
+
422
+ write_text_message(json, Stream, Data) :-
423
+ !,
424
+ json_write_dict(Stream, Data).
425
+ write_text_message(prolog, Stream, Data) :-
426
+ !,
427
+ format(Stream, '~k .', [Data]).
428
+ write_text_message(_, Stream, Data) :-
429
+ format(Stream, '~w', [Data]).
430
+
431
+
432
+
433
+ %! ws_receive(+WebSocket, -Message:dict) is det.
434
+ %! ws_receive(+WebSocket, -Message:dict, +Options) is det.
435
+ %
436
+ % Receive the next message from WebSocket. Message is a dict
437
+ % containing the following keys:
438
+ %
439
+ % - opcode:OpCode
440
+ % OpCode of the message. This is an atom for known opcodes
441
+ % and an integer for unknown ones. If the peer closed the
442
+ % stream, OpCode is bound to =close= and data to the atom
443
+ % =end_of_file=.
444
+ % - data:String
445
+ % The data, represented as a string. This field is always
446
+ % present. String is the empty string if there is no data
447
+ % in the message.
448
+ % - rsv:RSV
449
+ % Present if the WebSocket RSV header is not 0. RSV is an
450
+ % integer in the range [1..7].
451
+ %
452
+ % If =ping= message is received and WebSocket is a stream pair,
453
+ % ws_receive/1 replies with a =pong= and waits for the next
454
+ % message.
455
+ %
456
+ % The predicate ws_receive/3 processes the following options:
457
+ %
458
+ % - format(+Format)
459
+ % Defines how _text_ messages are parsed. Format is one of
460
+ % - string
461
+ % Data is returned as a Prolog string (default)
462
+ % - json
463
+ % Data is parsed using json_read_dict/3, which also receives
464
+ % Options.
465
+ % - prolog
466
+ % Data is parsed using read_term/3, which also receives
467
+ % Options.
468
+ %
469
+ % @tbd Add a hook to allow for more data formats?
470
+
471
+ ws_receive(WsStream, Message) :-
472
+ ws_receive(WsStream, Message, []).
473
+
474
+ ws_receive(WsStream, Message, Options) :-
475
+ ws_read_header(WsStream, Code, RSV),
476
+ debug(websocket, 'ws_receive(~p): OpCode=~w, RSV=~w',
477
+ [WsStream, Code, RSV]),
478
+ ( Code == end_of_file
479
+ -> Message = websocket{opcode:close, data:end_of_file}
480
+ ; ( ws_opcode(OpCode, Code)
481
+ -> true
482
+ ; OpCode = Code
483
+ ),
484
+ read_data(OpCode, WsStream, Data, Options),
485
+ ( OpCode == ping,
486
+ reply_pong(WsStream, Data.data)
487
+ -> ws_receive(WsStream, Message, Options)
488
+ ; ( RSV == 0
489
+ -> Message = Data
490
+ ; Message = Data.put(rsv, RSV)
491
+ )
492
+ )
493
+ ),
494
+ debug(websocket, 'ws_receive(~p) --> ~p', [WsStream, Message]).
495
+
496
+ read_data(close, WsStream,
497
+ websocket{opcode:close, code:Code, format:string, data:Data}, _Options) :-
498
+ !,
499
+ get_byte(WsStream, High),
500
+ ( High == -1
501
+ -> Code = 1000,
502
+ Data = ""
503
+ ; get_byte(WsStream, Low),
504
+ Code is High<<8 \/ Low,
505
+ stream_pair(WsStream, In, _),
506
+ set_stream(In, encoding(utf8)),
507
+ read_string(WsStream, _Len, Data)
508
+ ).
509
+ read_data(text, WsStream, Data, Options) :-
510
+ !,
511
+ option(format(Format), Options, string),
512
+ read_text_data(Format, WsStream, Data, Options).
513
+ read_data(OpCode, WsStream, websocket{opcode:OpCode, format:string, data:Data}, _Options) :-
514
+ read_string(WsStream, _Len, Data).
515
+
516
+ %! read_text_data(+Format, +WsStream, -Dict, +Options) is det.
517
+ %
518
+ % Read a websocket message into a dict websocket{opcode:OpCode,
519
+ % data:Data}, where Data is parsed according to Format.
520
+
521
+ read_text_data(string, WsStream,
522
+ websocket{opcode:text, format:string, data:Data}, _Options) :-
523
+ !,
524
+ read_string(WsStream, _Len, Data).
525
+ read_text_data(json, WsStream,
526
+ websocket{opcode:text, format:json, data:Data}, Options) :-
527
+ !,
528
+ json_read_dict(WsStream, Data, Options).
529
+ read_text_data(prolog, WsStream,
530
+ websocket{opcode:text, format:prolog, data:Data}, Options) :-
531
+ !,
532
+ read_term(WsStream, Data, Options).
533
+ read_text_data(Format, _, _, _) :-
534
+ domain_error(format, Format).
535
+
536
+ reply_pong(WebSocket, Data) :-
537
+ stream_pair(WebSocket, _In, Out),
538
+ is_stream(Out),
539
+ ws_send(Out, pong(Data)).
540
+
541
+
542
+ %! ws_close(+WebSocket:stream_pair, +Code, +Data) is det.
543
+ %
544
+ % Close a WebSocket connection by sending a =close= message if
545
+ % this was not already sent and wait for the close reply.
546
+ %
547
+ % @arg Code is the numerical code indicating the close status.
548
+ % This is 16-bit integer. The codes are defined in
549
+ % section _|7.4.1. Defined Status Codes|_ of RFC6455.
550
+ % Notably, 1000 indicates a normal closure.
551
+ % @arg Data is currently interpreted as text.
552
+ % @error websocket_error(unexpected_message, Reply) if
553
+ % the other side did not send a close message in reply.
554
+
555
+ ws_close(WebSocket, Code, Data) :-
556
+ setup_call_cleanup(
557
+ true,
558
+ ws_close_(WebSocket, Code, Data),
559
+ close(WebSocket)).
560
+
561
+ ws_close_(WebSocket, Code, Data) :-
562
+ stream_pair(WebSocket, In, Out),
563
+ ( ( var(Out)
564
+ ; ws_property(Out, status, closed)
565
+ )
566
+ -> debug(websocket(close),
567
+ 'Output stream of ~p already closed', [WebSocket])
568
+ ; ws_send(WebSocket, close(Code, Data)),
569
+ close(Out),
570
+ debug(websocket(close), '~p: closed output', [WebSocket]),
571
+ ( ( var(In)
572
+ ; ws_property(In, status, closed)
573
+ )
574
+ -> debug(websocket(close),
575
+ 'Input stream of ~p already closed', [WebSocket])
576
+ ; ws_receive(WebSocket, Reply),
577
+ ( Reply.opcode == close
578
+ -> debug(websocket(close), '~p: close confirmed', [WebSocket])
579
+ ; throw(error(websocket_error(unexpected_message, Reply), _))
580
+ )
581
+ )
582
+ ).
583
+
584
+
585
+ %! ws_open(+Stream, -WSStream, +Options) is det.
586
+ %
587
+ % Turn a raw TCP/IP (or any other binary stream) into a websocket
588
+ % stream. Stream can be an input stream, output stream or a stream
589
+ % pair. Options includes
590
+ %
591
+ % * mode(+Mode)
592
+ % One of =server= or =client=. If =client=, messages are sent
593
+ % as _masked_.
594
+ %
595
+ % * buffer_size(+Count)
596
+ % Send partial messages for each Count bytes or when flushing
597
+ % the output. The default is to buffer the entire message before
598
+ % it is sent.
599
+ %
600
+ % * close_parent(+Boolean)
601
+ % If =true= (default), closing WSStream also closes Stream.
602
+ %
603
+ % * subprotocol(+Protocol)
604
+ % Set the subprotocol property of WsStream. This value can be
605
+ % retrieved using ws_property/2. Protocol is an atom. See
606
+ % also the =subprotocols= option of http_open_websocket/3 and
607
+ % http_upgrade_to_websocket/3.
608
+ %
609
+ % A typical sequence to turn a pair of streams into a WebSocket is
610
+ % here:
611
+ %
612
+ % ==
613
+ % ...,
614
+ % Options = [mode(server), subprotocol(chat)],
615
+ % ws_open(Input, WsInput, Options),
616
+ % ws_open(Output, WsOutput, Options),
617
+ % stream_pair(WebSocket, WsInput, WsOutput).
618
+ % ==
619
+
620
+ %! ws_start_message(+WSStream, +OpCode) is det.
621
+ %! ws_start_message(+WSStream, +OpCode, +RSV) is det.
622
+ %
623
+ % Prepare for sending a new message. OpCode is one of =text=,
624
+ % =binary=, =close=, =ping= or =pong=. RSV is reserved for
625
+ % extensions. After this call, the application usually writes data
626
+ % to WSStream and uses ws_send/1 to complete the message.
627
+ % Depending on OpCode, the stream is switched to _binary_ (for
628
+ % OpCode is =binary=) or _text_ using =utf8= encoding (all other
629
+ % OpCode values). For example, to a JSON message can be send
630
+ % using:
631
+ %
632
+ % ==
633
+ % ws_send_json(WSStream, JSON) :-
634
+ % ws_start_message(WSStream, text),
635
+ % json_write(WSStream, JSON),
636
+ % ws_send(WSStream).
637
+ % ==
638
+
639
+ %! ws_send(+WSStream) is det.
640
+ %
641
+ % Complete and send the WebSocket message. If the OpCode of the
642
+ % message is =close=, close the stream.
643
+
644
+ %! ws_read_header(+WSStream, -OpCode, -RSV) is det.
645
+ %
646
+ % Read the header of the WebSocket next message. After this call,
647
+ % WSStream is switched to the appropriate encoding and reading
648
+ % from the stream will signal end-of-file at the end of the
649
+ % message. Note that this end-of-file does *not* invalidate
650
+ % WSStream. Reading may perform various tasks on the background:
651
+ %
652
+ % - If the message has _Fin_ is =false=, it will wait for an
653
+ % additional message.
654
+ % - If a =ping= is received, it will reply with a =pong= on the
655
+ % matching output stream.
656
+ % - If a =pong= is received, it will be ignored.
657
+ % - If a =close= is received and a partial message is read,
658
+ % it generates an exception (TBD: which?). If no partial
659
+ % message is received, it unified OpCode with =close= and
660
+ % replies with a =close= message.
661
+ %
662
+ % If not all data has been read for the previous message, it will
663
+ % first read the remainder of the message. This input is silently
664
+ % discarded. This allows for trailing white space after proper
665
+ % text messages such as JSON, Prolog or XML terms. For example, to
666
+ % read a JSON message, use:
667
+ %
668
+ % ==
669
+ % ws_read_json(WSStream, JSON) :-
670
+ % ws_read_header(WSStream, OpCode, RSV),
671
+ % ( OpCode == text,
672
+ % RSV == 0
673
+ % -> json_read(WSStream, JSON)
674
+ % ; OpCode == close
675
+ % -> JSON = end_of_file
676
+ % ).
677
+ % ==
678
+
679
+ %! ws_property(+WebSocket, ?Property) is nondet.
680
+ %
681
+ % True if Property is a property WebSocket. Defined properties
682
+ % are:
683
+ %
684
+ % * subprotocol(Protocol)
685
+ % Protocol is the negotiated subprotocol. This is typically set
686
+ % as a property of the websocket by ws_open/3.
687
+
688
+ ws_property(WebSocket, Property) :-
689
+ ws_property_(Property, WebSocket).
690
+
691
+ ws_property_(subprotocol(Protocol), WebSocket) :-
692
+ ws_property(WebSocket, subprotocol, Protocol).
693
+
694
+ %! to_opcode(+Spec, -OpCode:int) is det.
695
+ %
696
+ % Convert a specification of an opcode into the numeric opcode.
697
+
698
+ to_opcode(In, Code) :-
699
+ integer(In),
700
+ !,
701
+ must_be(between(0, 15), In),
702
+ Code = In.
703
+ to_opcode(Name, Code) :-
704
+ must_be(atom, Name),
705
+ ( ws_opcode(Name, Code)
706
+ -> true
707
+ ; domain_error(ws_opcode, Name)
708
+ ).
709
+
710
+ %! ws_opcode(?Name, ?Code)
711
+ %
712
+ % Define symbolic names for the WebSocket opcodes.
713
+
714
+ ws_opcode(continuation, 0).
715
+ ws_opcode(text, 1).
716
+ ws_opcode(binary, 2).
717
+ ws_opcode(close, 8).
718
+ ws_opcode(ping, 9).
719
+ ws_opcode(pong, 10).
720
+
721
+
722
+ %! ws_mask(-Mask)
723
+ %
724
+ % Produce a good random number of the mask of a client message.
725
+
726
+ :- public ws_mask/1.
727
+
728
+ ws_mask(Mask) :-
729
+ Mask is 1+random(1<<32-1).