Self-configuring-page-scripts.xhtml 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:pls="http://www.w3.org/2005/01/pronunciation-lexicon" xmlns:ssml="http://www.w3.org/2001/10/synthesis" xmlns:svg="http://www.w3.org/2000/svg">
  3. <head>
  4. <title>Self-configuring web page scripts</title>
  5. <link rel="stylesheet" type="text/css" href="docbook-epub.css"/>
  6. <link rel="stylesheet" type="text/css" href="kawa.css"/>
  7. <script src="kawa-ebook.js" type="text/javascript"/>
  8. <meta name="generator" content="DocBook XSL-NS Stylesheets V1.79.1"/>
  9. <link rel="prev" href="Server-side-scripts.xhtml" title="Web page scripts"/>
  10. <link rel="next" href="Servlets.xhtml" title="Installing web page scripts as Servlets"/>
  11. </head>
  12. <body>
  13. <header/>
  14. <section class="sect1" title="Self-configuring web page scripts" epub:type="subchapter" id="Self-configuring-page-scripts">
  15. <div class="titlepage">
  16. <div>
  17. <div>
  18. <h2 class="title" style="clear: both">Self-configuring web page scripts</h2>
  19. </div>
  20. </div>
  21. </div>
  22. <p>Kawa makes it easy to set up a web site without configuration
  23. files. Instead, the mapping from request URL to web page script
  24. matches the layout of files in the application directory.
  25. </p>
  26. <p>Many web servers make it easy to execute a script using a script
  27. processor which is selected depending on the extension of the
  28. requested URL. That is why you see lots of URLs that end in
  29. <code class="literal">.cgi</code>, <code class="literal">.php</code>, or <code class="literal">.jsp</code>. This is bad, because it
  30. exposes the server-side implementation to the user: Not only are such
  31. URLs ugly, but they make it difficult to change the server without
  32. breaking people’s bookmarks and search engines. A server will usually
  33. provide a mechanism to use prettier URLs, but doing so requires extra
  34. effort, so many web-masters don’t.
  35. </p>
  36. <p>If you want a script to be executed in response to a URL
  37. <code class="literal">http://host/app/foo/bar</code> you give the script the name
  38. <code class="literal">app/foo/bar</code>, in the appropriate server “application”
  39. directory (as explained below). You get to pick the name <code class="literal">bar</code>.
  40. Or you can use the name <code class="literal">bar.html</code>, even though the file named
  41. <code class="literal">bar.html</code> isn’t actually
  42. an html file - rather it produces html when evaluated. Or better: just use
  43. a name without an extension at all.
  44. Kawa figures
  45. out what kind of script it is based on the content of the file,
  46. rather than the file name. Once Kawa has
  47. found a script, it looks at the first line to see if it can recognize
  48. the kind (language) of the script. Normally this would be a comment
  49. that contains the name of a programming language that Kawa
  50. knows about. For example:
  51. </p>
  52. <pre class="screen">;; Hello world page script written in -*- scheme -*-
  53. #&lt;p&gt;Hello, &lt;b&gt;&amp;(request-remote-host)&lt;/b&gt;!&lt;/p&gt;
  54. </pre>
  55. <p>(Using the funny-looking string <code class="literal">-*- scheme -*-</code> has the
  56. bonus is that it recognized by the Emacs text editor.)
  57. </p>
  58. <p>A script named <code class="literal">+default+</code> is run if there isn’t a matching script.
  59. For example assume the following is a file named <code class="literal">+default</code>.
  60. </p>
  61. <pre class="screen">;; This is -*- scheme -*-
  62. (make-element 'p "servlet-path: " (request-servlet-path))
  63. </pre>
  64. <p>This becomes the default script for HTTP requests that aren’t handled
  65. by a more specific script.
  66. The <code class="literal">request-servlet-path</code> function
  67. returns the "servlet path", which is the part of the requested URL
  68. that is relative to the current web application. Thus a request for
  69. <code class="literal">http://host:port/app/this/is/a/test</code> will return:
  70. </p>
  71. <pre class="screen">servlet-path: /this/is/a/test
  72. </pre>
  73. <section class="sect2" title="Using the OpenJDK built-in web server" epub:type="division" id="idm139667870414560">
  74. <div class="titlepage">
  75. <div>
  76. <div>
  77. <h3 class="title">Using the OpenJDK built-in web server</h3>
  78. </div>
  79. </div>
  80. </div>
  81. <p>The easiest way to run a Kawa web server is to
  82. use the web server built in to JDK 6 or later.
  83. </p>
  84. <pre class="screen">kawa --http-auto-handler <em class="replaceable"><code>context-path</code></em> <em class="replaceable"><code>appdir</code></em> --http-start <em class="replaceable"><code>port</code></em>
  85. </pre>
  86. <p>This starts a web server that listens on the given <em class="replaceable"><code>port</code></em>,
  87. using the files in directory <em class="replaceable"><code>appdir</code></em> to handle
  88. requests that start with the given <em class="replaceable"><code>context-path</code></em>.
  89. The <em class="replaceable"><code>context-path</code></em> must start with a <code class="literal">"/"</code> (one is added if
  90. needed), and it is recommended that it also end with a <code class="literal">"/"</code>
  91. (otherwise you might get some surprising behavior).
  92. </p>
  93. <p>You can specify multiple <code class="literal">--http-auto-handler</code> options.
  94. </p>
  95. <p>For example use the files in the current directory to handle
  96. all requests on the standard port 80 do:
  97. </p>
  98. <pre class="screen">kawa --http-auto-handler / . --http-start 80
  99. </pre>
  100. <p>There are some examples in the <code class="literal">testsuite/webtest</code> directory
  101. the Kawa source distribution. You can start the server thus:
  102. </p>
  103. <pre class="screen">bin/kawa --http-auto-handler / testsuite/webtest/ --http-start 8888
  104. </pre>
  105. <p>and then for example browse to <code class="literal">http://localhost:8888/adder.scm</code>.
  106. </p>
  107. <p>For lots of information about the HTTP request, browse to
  108. <code class="literal">http://localhost:8888/info/<em class="replaceable"><code>anything</code></em></code>.
  109. </p>
  110. </section>
  111. <section class="sect2" title="Using a servlet container" epub:type="division" id="idm139667870403088">
  112. <div class="titlepage">
  113. <div>
  114. <div>
  115. <h3 class="title">Using a servlet container</h3>
  116. </div>
  117. </div>
  118. </div>
  119. <p>You can also can use a “servlet container”
  120. such as Tomcat or Glassfish with self-configuring script.
  121. See <a class="link" href="Servlets.xhtml" title="Installing web page scripts as Servlets">Servlets</a> for information on how to install
  122. these servers, and the concept of web applications.
  123. Once you have these server installed, you create a
  124. web application with the following in the
  125. <code class="literal"><em class="replaceable"><code>appdir</code></em>/WEB-INF/web.xml</code> configuration file:
  126. </p>
  127. <pre class="screen">&lt;web-app&gt;
  128. &lt;display-name&gt;Kawa auto-servlet&lt;/display-name&gt;
  129. &lt;servlet&gt;
  130. &lt;servlet-name&gt;KawaPageServlet&lt;/servlet-name&gt;
  131. &lt;servlet-class&gt;gnu.kawa.servlet.KawaPageServlet&lt;/servlet-class&gt;
  132. &lt;/servlet&gt;
  133. &lt;servlet-mapping&gt;
  134. &lt;servlet-name&gt;KawaPageServlet&lt;/servlet-name&gt;
  135. &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
  136. &lt;/servlet-mapping&gt;
  137. &lt;/web-app&gt;
  138. </pre>
  139. <p>This creates a web application where all URLs
  140. are handled by the <code class="literal">gnu.kawa.servlet.KawaPageServlet</code> servlet class,
  141. which is included in the Kawa jar file.
  142. The <code class="literal">KawaPageServlet</code> class handles the searching
  143. and compiling described in this page.
  144. </p>
  145. </section>
  146. <section class="sect2" title="Finding a matching script" epub:type="division" id="idm139667870397552">
  147. <div class="titlepage">
  148. <div>
  149. <div>
  150. <h3 class="title">Finding a matching script</h3>
  151. </div>
  152. </div>
  153. </div>
  154. <p>When Kawa receives a request for:
  155. </p>
  156. <pre class="screen">http://host:port/appname/a/b/anything
  157. </pre>
  158. <p>it will look for a file:
  159. </p>
  160. <pre class="screen"><em class="replaceable"><code>appdir</code></em>/a/b/anything
  161. </pre>
  162. <p>If such a file exists, the script will be executed, as described
  163. below. If not, it will look for a file name <code class="literal">+default+</code> in the same
  164. directory. If that desn’t exist either, it will look for <code class="literal">+default+</code>
  165. in the parent
  166. directory, then the grand-parent directory, and so on until it gets to
  167. the appname web application root directory. So the default script is
  168. this: <code class="literal"><em class="replaceable"><code>appdir</code></em>/+default</code>.
  169. </p>
  170. <p>If that doesn’t exist then Kawa returns a 404 "page not found" error.
  171. </p>
  172. </section>
  173. <section class="sect2" title="Determining script language" epub:type="division" id="idm139667870392000">
  174. <div class="titlepage">
  175. <div>
  176. <div>
  177. <h3 class="title">Determining script language</h3>
  178. </div>
  179. </div>
  180. </div>
  181. <p>Once Kawa has found a script file corresponding to a request URL,
  182. it needs to determine if this is a data file or a web page script,
  183. and in the latter case, what language it is written in.
  184. </p>
  185. <p>Kawa recognizes the following "magic strings" in the first line of a script:
  186. </p>
  187. <div class="variablelist" epub:type="list">
  188. <dl class="variablelist">
  189. <dt class="term"><code class="literal">kawa:scheme</code>
  190. </dt>
  191. <dd>
  192. <p>The Scheme language.
  193. </p>
  194. </dd>
  195. <dt class="term"><code class="literal">kawa:xquery</code>
  196. </dt>
  197. <dd>
  198. <p>The XQuery language.
  199. </p>
  200. </dd>
  201. <dt class="term"><code class="literal">kawa:<em class="replaceable"><code>language</code></em></code>
  202. </dt>
  203. <dd>
  204. <p>Some other language known to Kawa.
  205. </p>
  206. </dd>
  207. </dl>
  208. </div>
  209. <p>Kawa also recognizes Emacs-style "mode specifiers":
  210. </p>
  211. <div class="variablelist" epub:type="list">
  212. <dl class="variablelist">
  213. <dt class="term"><code class="literal">-*- scheme -*-</code>
  214. </dt>
  215. <dd>
  216. <p>The Scheme language.
  217. </p>
  218. </dd>
  219. <dt class="term"><code class="literal">-*- xquery -*-</code>
  220. </dt>
  221. <dd>
  222. <p>The XQuery language (though Emacs doesn’t know about XQuery).
  223. </p>
  224. </dd>
  225. <dt class="term"><code class="literal">-*- emacs-lisp -*-</code>
  226. </dt>
  227. <dt class="term"><code class="literal">-*- elisp -*-</code>
  228. </dt>
  229. <dd>
  230. <p>The Emacs Lisp extension language.
  231. </p>
  232. </dd>
  233. <dt class="term"><code class="literal">-*- common-lisp -*-</code>
  234. </dt>
  235. <dt class="term"><code class="literal">-*- lisp -*-</code>
  236. </dt>
  237. <dd>
  238. <p>The Common Lisp language.
  239. </p>
  240. </dd>
  241. </dl>
  242. </div>
  243. <p>Also, it also recognizes comments in the first two columns of the line:
  244. </p>
  245. <div class="variablelist" epub:type="list">
  246. <dl class="variablelist">
  247. <dt class="term"><code class="literal">;;</code>
  248. </dt>
  249. <dd>
  250. <p>A Scheme or Lisp comment - assumed to be in the Scheme language.
  251. </p>
  252. </dd>
  253. <dt class="term"><code class="literal">(:</code>
  254. </dt>
  255. <dd>
  256. <p>Start of an XQuery comment, so assumed to be in the XQuery language.
  257. </p>
  258. </dd>
  259. </dl>
  260. </div>
  261. <p>If Kawa doesn’t recognize the language of a script (and it
  262. isn’t named +default+) then it assumes the file is a data file. It
  263. asks the servlet engine to figure out the content type (using the
  264. getMimeType method of ServletContext), and just copies the file into
  265. the response.
  266. </p>
  267. </section>
  268. <section class="sect2" title="Compilation and caching" epub:type="division" id="idm139667870375424">
  269. <div class="titlepage">
  270. <div>
  271. <div>
  272. <h3 class="title">Compilation and caching</h3>
  273. </div>
  274. </div>
  275. </div>
  276. <p>Kawa automatically compiles a script into a class. The
  277. class is internal to the server, and is not written out to
  278. disk. (There is an unsupported option to write the compiled file to a
  279. class file, but there is no support to use previously-compiled
  280. classes.) The server then creates a module instance to handle the
  281. actual request, and runs the body (the <code class="literal">run</code> method)
  282. of the script class. On subsequence
  283. requests for the same script, the same class and instance are reused;
  284. only the <code class="literal">run</code> is re-executed.
  285. </p>
  286. <p>If the script is changed, then it is re-compiled and a new module
  287. instance created. This makes it very easy to develop and modify a
  288. script. (Kawa for performance reasons doesn’t check more
  289. than once a second whether a script has been modified.)
  290. </p>
  291. </section>
  292. </section>
  293. <footer>
  294. <div class="navfooter">
  295. <ul>
  296. <li>
  297. <b class="toc">
  298. <a href="Self-configuring-page-scripts.xhtml#idm139667870414560">Using the OpenJDK built-in web server</a>
  299. </b>
  300. </li>
  301. <li>
  302. <b class="toc">
  303. <a href="Self-configuring-page-scripts.xhtml#idm139667870403088">Using a servlet container</a>
  304. </b>
  305. </li>
  306. <li>
  307. <b class="toc">
  308. <a href="Self-configuring-page-scripts.xhtml#idm139667870397552">Finding a matching script</a>
  309. </b>
  310. </li>
  311. <li>
  312. <b class="toc">
  313. <a href="Self-configuring-page-scripts.xhtml#idm139667870392000">Determining script language</a>
  314. </b>
  315. </li>
  316. <li>
  317. <b class="toc">
  318. <a href="Self-configuring-page-scripts.xhtml#idm139667870375424">Compilation and caching</a>
  319. </b>
  320. </li>
  321. </ul>
  322. <p>
  323. Up: <a accesskey="u" href="XML-tools.xhtml">Working with XML and HTML</a></p>
  324. <p>
  325. Previous: <a accesskey="p" href="Server-side-scripts.xhtml">Web page scripts</a></p>
  326. <p>
  327. Next: <a accesskey="n" href="Servlets.xhtml">Installing web page scripts as Servlets</a></p>
  328. </div>
  329. </footer>
  330. </body>
  331. </html>