summaryrefslogtreecommitdiffstats
path: root/web/server/h2o/libh2o/doc/configure/mruby.html
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--web/server/h2o/libh2o/doc/configure/mruby.html281
1 files changed, 281 insertions, 0 deletions
diff --git a/web/server/h2o/libh2o/doc/configure/mruby.html b/web/server/h2o/libh2o/doc/configure/mruby.html
new file mode 100644
index 00000000..d424351d
--- /dev/null
+++ b/web/server/h2o/libh2o/doc/configure/mruby.html
@@ -0,0 +1,281 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
+<base href="../" />
+
+<!-- oktavia -->
+<link rel="stylesheet" href="assets/searchstyle.css" type="text/css" />
+<script src="search/jquery-1.9.1.min.js"></script>
+<script src="search/oktavia-jquery-ui.js"></script>
+<script src="search/oktavia-english-search.js"></script>
+<!-- /oktavia -->
+
+<link rel="stylesheet" href="assets/style.css" type="text/css" />
+
+<title>Using Mruby - Configure - H2O - the optimized HTTP/2 server</title>
+</head>
+<body>
+<div id="body">
+<div id="top">
+
+<h1>
+<a href="index.html">H2O</a>
+</h1>
+<p class="description">the optimized HTTP/1.x, HTTP/2 server</p>
+
+<!-- oktavia -->
+<form id="searchform">
+<input class="search" type="search" name="search" id="search" results="5" value="" placeholder="Search" />
+<div id="searchresult_box">
+<div id="close_search_box">&times;</div>
+<div id="searchresult_summary"></div>
+<div id="searchresult"></div>
+<div id="searchresult_nav"></div>
+<span class="pr">Powered by <a href="https://github.com/shibukawa/oktavia">Oktavia</a></span>
+</div>
+</form>
+<!-- /oktavia -->
+
+</div>
+
+<table id="menu">
+<tr>
+<td><a href="index.html">Top</a></td>
+<td><a href="install.html">Install</a></td>
+<td class="selected">Configure</td>
+<td><a href="faq.html">FAQ</a></td>
+<td><a href="http://blog.kazuhooku.com/search/label/H2O" target="_blank">Blog</a></td>
+<td><a href="http://github.com/h2o/h2o/" target="_blank">Source</a></td>
+</tr>
+</table>
+
+<div id="main">
+
+<h2>
+<a href="configure.html">Configure</a> &gt;
+Using Mruby
+</h2>
+
+
+<p>
+<a href="https://github.com/mruby/mruby">mruby</a> is a lightweight implementation of the Ruby programming language.
+With H2O, users can implement their own request handling logic using mruby, either to generate responses or to fix-up the request / response.
+</p>
+
+<h3 id="programming-interface">Rack-based Programming Interface</h3>
+
+<p>
+The interface between the mruby program and the H2O server is based on <a href="http://www.rubydoc.info/github/rack/rack/master/file/SPEC">Rack interface specification</a>.
+Below is a simple configuration that returns <i>hello world</i>.
+</p>
+
+<div class="example">
+<div class="caption">Example. Hello-world in mruby</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ Proc.new do |env|
+ [200, {&#39;content-type&#39; =&gt; &#39;text/plain&#39;}, [&quot;Hello world\n&quot;]]
+ end
+</code></pre>
+</div>
+
+
+<p>
+It should be noted that as of H2O version 1.7.0, there are limitations when compared to ordinary web application server with support for Rack such as Unicorn:
+<ul>
+<li>no libraries provided as part of Rack is available (only the interface is compatible)
+</ul>
+</p>
+
+<p>
+In addition to the Rack interface specification, H2O recognizes status code <code>399</code> which can be used to delegate request to the next handler.
+The feature can be used to implement access control and response header modifiers.
+</p>
+
+<h3 id="access-control">Access Control</h3>
+
+<p>
+By using the <code>399</code> status code, it is possible to implement access control using mruby.
+The example below restricts access to requests from <code>192.168.</code> private address.
+</p>
+
+<div class="example">
+<div class="caption">Example. Restricting access to 192.168.</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ lambda do |env|
+ if /\A192\.168\./.match(env[&quot;REMOTE_ADDR&quot;])
+ return [399, {}, []]
+ end
+ [403, {&#39;content-type&#39; =&gt; &#39;text/plain&#39;}, [&quot;access forbidden\n&quot;]]
+ end
+</code></pre>
+</div>
+
+
+<p>
+Support for <a href="configure/basic_auth.html">Basic Authentication</a> is also provided by an mruby script.
+</p>
+
+<h3 id="delegating-request">Delegating the Request</h3>
+
+<p>
+When enabled using the <a href="configure/reproxy_directives.html#reproxy"><code>reproxy</code></a> directive, it is possible to delegate the request from the mruby handler to any other handler.
+</p>
+<p>
+<div class="example">
+<div class="caption">Example. Rewriting URL with delegation</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ lambda do |env|
+ if /\/user\/([^\/]+)/.match(env[&quot;PATH_INFO&quot;])
+ return [307, {&quot;x-reproxy-url&quot; =&gt; &quot;/user.php?user=#{$1}&quot;}, []]
+ end
+ return [399, {}, []]
+ end
+</code></pre>
+</div>
+
+
+<h3 id="modifying-response">Modifying the Response</h3>
+
+<p>
+When the mruby handler returns status code <code>399</code>, H2O delegates the request to the next handler while preserving the headers emitted by the handler.
+The feature can be used to add extra headers to the response.
+</p>
+<p>
+For example, the following example sets <code>cache-control</code> header for requests against <code>.css</code> and <code>.js</code> files.
+</p>
+
+<div class="example">
+<div class="caption">Example. Setting cache-control header for certain types of files</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ Proc.new do |env|
+ headers = {}
+ if /\.(css|js)\z/.match(env[&quot;PATH_INFO&quot;])
+ headers[&quot;cache-control&quot;] = &quot;max-age=86400&quot;
+ end
+ [399, headers, []]
+ end
+ file.dir: /path/to/doc-root
+</code></pre>
+</div>
+
+
+<p>
+Or in the example below, the handler triggers <a href="configure/http2_directives.html#server-push">HTTP/2 server push</a> with the use of <code>Link: rel=preload</code> headers, and then requests a FastCGI application to process the request.
+</p>
+
+<div class="example">
+<div class="caption">Example. Pushing asset files</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ Proc.new do |env|
+ push_paths = []
+ # push css and js when request is to dir root or HTML
+ if /(\/|\.html)\z/.match(env[&quot;PATH_INFO&quot;])
+ push_paths &lt;&lt; [&quot;/css/style.css&quot;, &quot;style&quot;]
+ push_paths &lt;&lt; [&quot;/js/app.js&quot;, &quot;script&quot;]
+ end
+ [399, push_paths.empty? ? {} : {&quot;link&quot; =&gt; push_paths.map{|p| &quot;&lt;#{p[0]}&gt;; rel=preload; as=#{p[1]}&quot;}.join(&quot;\n&quot;)}, []]
+ end
+ fastcgi.connect: ...
+</code></pre>
+</div>
+
+
+<h3 id="http-client">Using the HTTP Client</h3>
+
+<p>
+Starting from version 1.7, a HTTP client API is provided.
+HTTP requests issued through the API will be handled asynchronously; the client does not block the event loop of the HTTP server.
+</p>
+
+<div class="example">
+<div class="caption">Example. Mruby handler returning the response of http://example.com</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ Proc.new do |env|
+ req = http_request(&quot;http://example.com&quot;)
+ status, headers, body = req.join
+ [status, headers, body]
+ end
+</code></pre>
+</div>
+
+
+<p>
+<code>http_request</code> is the method that issues a HTTP request.
+</p>
+<p>
+The method takes two arguments.
+First argument is the target URI.
+Second argument is an optional hash; <code>method</code> (defaults to <code>GET</code>), <code>header</code>, <code>body</code> attributes are recognized.
+</p>
+<p>
+The method returns a promise object.
+When <code>#join</code> method of the promise is invoked, a three-argument array containing the status code, response headers, and the body is returned.
+The response body is also a promise.
+Applications can choose from three ways when dealing with the body: a) call <code>#each</code> method to receive the contents, b) call <code>#join</code> to retrieve the body as a string, c) return the object as the response body of the mruby handler.
+</p>
+<p>
+The header and the body object passed to <code>http_request</code> should conform to the requirements laid out by the Rack specification for request header and request body.
+The response header and the response body object returned by the <code>#join</code> method of the promise returned by <code>http_request</code> conforms to the requirements of the Rack specification.
+</p>
+<p>
+Since the API provides an asynchronous HTTP client, it is possible to effectively issue multiple HTTP requests concurrently and merge them into a single response.
+</p>
+<p>
+When HTTPS is used, servers are verified using the properties of <a href="configure/proxy_directives.html#proxy.ssl.cafile"><code>proxy.ssl.cafile</code></a> and <a href="configure/proxy_directives.html#proxy.ssl.verify-peer"><code>proxy.ssl.verify-peer</code></a> specified at the global level.
+</p>
+
+<h3 id="logging-arbitrary-variable">Logging Arbitrary Variable</h3>
+
+<p>
+In version 2.3, it is possible from mruby to set and log an arbitrary-named variable that is associated to a HTTP request.
+A HTTP response header that starts with <code>x-fallthru-set-</code> is handled specially by the H2O server. Instead of sending the header downstream, the server accepts the value as a request environment variable, taking the suffix of the header name as the name of the variable.
+</p>
+<p>
+This example shows how to read request data, parse json and then log data from mruby.
+</p>
+
+<div class="example">
+<div class="caption">Example. Logging the content of a POST request via request environment variable</div>
+<pre><code>paths:
+ &quot;/&quot;:
+ mruby.handler: |
+ Proc.new do |env|
+ input = env[&quot;rack.input&quot;] ? env[&quot;rack.input&quot;].read : &#39;{&quot;default&quot;: &quot;true&quot;}&#39;
+ parsed_json = JSON.parse(input)
+ parsed_json[&quot;time&quot;] = Time.now.to_i
+ logdata = parsed_json.to_s
+ [204, {&quot;x-fallthru-set-POSTDATA&quot; =&gt; logdata}, []]
+ end
+ access-log:
+ path: /path/to/access-log.json
+ escape: json
+ format: &#39;{&quot;POST&quot;: %{POSTDATA}e}&#39;
+</code></pre>
+</div>
+
+
+
+
+
+</div>
+<div id="footer">
+<p>
+Copyright &copy; 2015 <a href="http://dena.com/intl/">DeNA Co., Ltd.</a> et al.
+</p>
+</div>
+</body>
+</html>