httpkit 0.6.0.pre.5 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.gitignore +0 -2
- data/.travis.yml +1 -1
- data/Gemfile +2 -0
- data/README.md +32 -25
- data/Rakefile +5 -0
- data/config/flay.yml +1 -1
- data/doc/api/httpkit.html +50 -0
- data/doc/api/httpkit/body.html +149 -0
- data/doc/api/httpkit/client.html +50 -0
- data/doc/api/httpkit/client/body_handler.html +50 -0
- data/doc/api/httpkit/client/keep_alive_handler.html +79 -0
- data/doc/api/httpkit/client/mandatory_handler.html +50 -0
- data/doc/api/httpkit/client/timeouts_handler.html +82 -0
- data/doc/api/httpkit/connection/eventmachine.html +157 -0
- data/doc/api/httpkit/connection/status.html +50 -0
- data/doc/api/httpkit/promise.html +50 -0
- data/doc/api/httpkit/request.html +123 -0
- data/doc/api/httpkit/response.html +209 -0
- data/doc/api/httpkit/serializer.html +150 -0
- data/doc/api/httpkit/server.html +50 -0
- data/doc/api/httpkit/server/block_handler.html +50 -0
- data/doc/api/httpkit/server/body_handler.html +50 -0
- data/doc/api/httpkit/server/keep_alive_handler.html +145 -0
- data/doc/api/httpkit/server/mandatory_handler.html +50 -0
- data/doc/api/httpkit/server/timeouts_handler.html +81 -0
- data/doc/api/httpkit/support/handler_manager.html +95 -0
- data/doc/api/httpkit/support/message.html +50 -0
- data/doc/api/httpkit/version.html +50 -0
- data/doc/examples/echo_server.html +101 -0
- data/doc/examples/error_handling.html +176 -0
- data/doc/examples/getting_started.html +161 -0
- data/doc/examples/streaming.html +108 -0
- data/doc/index.html +165 -0
- data/examples/echo_server.rb +14 -6
- data/examples/error_handling.rb +56 -0
- data/examples/getting_started.rb +10 -18
- data/examples/streaming.rb +41 -0
- data/lib/httpkit.rb +22 -0
- data/lib/httpkit/body.rb +4 -0
- data/lib/httpkit/client.rb +1 -9
- data/lib/httpkit/client/keep_alive_handler.rb +1 -0
- data/lib/httpkit/connection/eventmachine.rb +2 -1
- data/lib/httpkit/server/block_handler.rb +13 -0
- data/lib/httpkit/server/keep_alive_handler.rb +1 -0
- data/lib/httpkit/version.rb +1 -1
- data/spec/integration/timeouts_spec.rb +3 -2
- data/spec/support/helper.rb +1 -8
- data/spec/unit/client_spec.rb +2 -21
- data/spec/unit/server_spec.rb +11 -1
- metadata +34 -5
- data/Procfile +0 -1
@@ -0,0 +1,108 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>streaming.rb</title>
|
6
|
+
<link rel="stylesheet" href="http://jashkenas.github.io/docco/resources/linear/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<div id="jump_to">
|
12
|
+
Jump To …
|
13
|
+
<div id="jump_wrapper">
|
14
|
+
<div id="jump_page">
|
15
|
+
<a class="source" href="echo_server.html">echo_server.rb</a>
|
16
|
+
<a class="source" href="error_handling.html">error_handling.rb</a>
|
17
|
+
<a class="source" href="getting_started.html">getting_started.rb</a>
|
18
|
+
<a class="source" href="streaming.html">streaming.rb</a>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<table cellspacing=0 cellpadding=0>
|
23
|
+
<thead>
|
24
|
+
<tr>
|
25
|
+
<th class=docs><h1>streaming.rb</h1></th>
|
26
|
+
<th class=code></th>
|
27
|
+
</tr>
|
28
|
+
</thead>
|
29
|
+
<tbody>
|
30
|
+
<tr id='section-1'>
|
31
|
+
<td class=docs>
|
32
|
+
<div class="pilwrap">
|
33
|
+
<a class="pilcrow" href="#section-1">¶</a>
|
34
|
+
</div>
|
35
|
+
|
36
|
+
</td>
|
37
|
+
<td class=code>
|
38
|
+
<div class='highlight'><pre><span class="nb">require</span> <span class="s1">'httpkit'</span>
|
39
|
+
|
40
|
+
<span class="k">class</span> <span class="nc">Streaming</span>
|
41
|
+
<span class="k">def</span> <span class="nf">serve</span><span class="p">(</span><span class="n">_request</span><span class="p">,</span> <span class="n">served</span><span class="p">)</span>
|
42
|
+
<span class="n">response</span> <span class="o">=</span> <span class="n">streaming_response</span>
|
43
|
+
<span class="n">served</span><span class="o">.</span><span class="n">fulfill</span><span class="p">(</span><span class="n">response</span><span class="p">)</span>
|
44
|
+
|
45
|
+
<span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'Doing stuff...'</span><span class="p">)</span>
|
46
|
+
<span class="no">EM</span><span class="o">.</span><span class="n">add_timer</span><span class="p">(</span><span class="mi">1</span><span class="o">.</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'More stuff...'</span><span class="p">)</span> <span class="p">}</span>
|
47
|
+
<span class="no">EM</span><span class="o">.</span><span class="n">add_timer</span><span class="p">(</span><span class="mi">2</span><span class="o">.</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s1">'Done!'</span><span class="p">)</span> <span class="p">}</span>
|
48
|
+
<span class="no">EM</span><span class="o">.</span><span class="n">add_timer</span><span class="p">(</span><span class="mi">3</span><span class="o">.</span><span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="n">response</span><span class="o">.</span><span class="n">close</span> <span class="p">}</span>
|
49
|
+
<span class="k">end</span>
|
50
|
+
|
51
|
+
<span class="kp">private</span></pre></div>
|
52
|
+
</td>
|
53
|
+
</tr>
|
54
|
+
<tr id='section-2'>
|
55
|
+
<td class=docs>
|
56
|
+
<div class="pilwrap">
|
57
|
+
<a class="pilcrow" href="#section-2">¶</a>
|
58
|
+
</div>
|
59
|
+
<p>When passing a Body without source, i.e. nil, the response is being kept
|
60
|
+
open for further body chunks.</p>
|
61
|
+
</td>
|
62
|
+
<td class=code>
|
63
|
+
<div class='highlight'><pre> <span class="k">def</span> <span class="nf">streaming_response</span>
|
64
|
+
<span class="ss">HTTPkit</span><span class="p">:</span><span class="ss">:Response</span><span class="o">.</span><span class="n">new</span><span class="p">(</span><span class="mi">200</span><span class="p">,</span>
|
65
|
+
<span class="p">{</span> <span class="s1">'Content-Type'</span> <span class="o">=></span> <span class="s1">'application/octet-stream'</span> <span class="p">},</span>
|
66
|
+
<span class="ss">HTTPkit</span><span class="p">:</span><span class="ss">:Body</span><span class="o">.</span><span class="n">new</span><span class="p">)</span>
|
67
|
+
<span class="k">end</span>
|
68
|
+
<span class="k">end</span>
|
69
|
+
|
70
|
+
<span class="no">HTTPkit</span><span class="o">.</span><span class="n">run</span> <span class="k">do</span>
|
71
|
+
<span class="n">address</span> <span class="o">=</span> <span class="s1">'127.0.0.1'</span>
|
72
|
+
<span class="n">port</span> <span class="o">=</span> <span class="no">HTTPkit</span><span class="o">.</span><span class="n">random_port</span><span class="p">(</span><span class="n">address</span><span class="p">)</span>
|
73
|
+
|
74
|
+
<span class="ss">HTTPkit</span><span class="p">:</span><span class="ss">:Server</span><span class="o">.</span><span class="n">start</span><span class="p">(</span><span class="ss">address</span><span class="p">:</span> <span class="n">address</span><span class="p">,</span> <span class="ss">port</span><span class="p">:</span> <span class="n">port</span><span class="p">,</span>
|
75
|
+
<span class="ss">handlers</span><span class="p">:</span> <span class="o">[</span><span class="no">Streaming</span><span class="o">.</span><span class="n">new</span><span class="o">]</span><span class="p">)</span>
|
76
|
+
|
77
|
+
<span class="n">response</span> <span class="o">=</span> <span class="no">HTTPkit</span><span class="o">.</span><span class="n">request</span><span class="p">(</span><span class="ss">:get</span><span class="p">,</span> <span class="s2">"http://</span><span class="si">#{</span><span class="n">address</span><span class="si">}</span><span class="s2">:</span><span class="si">#{</span><span class="n">port</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span></pre></div>
|
78
|
+
</td>
|
79
|
+
</tr>
|
80
|
+
<tr id='section-3'>
|
81
|
+
<td class=docs>
|
82
|
+
<div class="pilwrap">
|
83
|
+
<a class="pilcrow" href="#section-3">¶</a>
|
84
|
+
</div>
|
85
|
+
<p>Yields in the Fiber that wrote the chunk, does not block, a.k.a. async.
|
86
|
+
Only yields for future chunks, so we need to explicitly grab past ones.</p>
|
87
|
+
</td>
|
88
|
+
<td class=code>
|
89
|
+
<div class='highlight'><pre> <span class="nb">puts</span> <span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">chunks</span>
|
90
|
+
<span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">closed</span><span class="o">.</span><span class="n">on_progress</span> <span class="p">{</span> <span class="o">|</span><span class="n">chunk</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">chunk</span> <span class="p">}</span></pre></div>
|
91
|
+
</td>
|
92
|
+
</tr>
|
93
|
+
<tr id='section-4'>
|
94
|
+
<td class=docs>
|
95
|
+
<div class="pilwrap">
|
96
|
+
<a class="pilcrow" href="#section-4">¶</a>
|
97
|
+
</div>
|
98
|
+
<p>Yields all past and future chunks here, blocks.</p>
|
99
|
+
|
100
|
+
</td>
|
101
|
+
<td class=code>
|
102
|
+
<div class='highlight'><pre> <span class="n">response</span><span class="o">.</span><span class="n">body</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">chunk</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">chunk</span> <span class="p">}</span>
|
103
|
+
<span class="k">end</span></pre></div>
|
104
|
+
</td>
|
105
|
+
</tr>
|
106
|
+
</table>
|
107
|
+
</div>
|
108
|
+
</body>
|
data/doc/index.html
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta http-equiv="content-type" content="text/html;charset=utf-8">
|
5
|
+
<title>README.md</title>
|
6
|
+
<link rel="stylesheet" href="https://raw.githubusercontent.com/jashkenas/docco/master/resources/linear/docco.css">
|
7
|
+
</head>
|
8
|
+
<body>
|
9
|
+
<div id='container'>
|
10
|
+
<div id="background"></div>
|
11
|
+
<table cellspacing=0 cellpadding=0>
|
12
|
+
<thead>
|
13
|
+
<tr>
|
14
|
+
<th class=docs><h1>README.md</h1></th>
|
15
|
+
<th class=code></th>
|
16
|
+
</tr>
|
17
|
+
</thead>
|
18
|
+
<tbody>
|
19
|
+
<tr id='section-1'>
|
20
|
+
<td class=docs>
|
21
|
+
<div class="pilwrap">
|
22
|
+
<a class="pilcrow" href="#section-1">¶</a>
|
23
|
+
</div>
|
24
|
+
<p>The HTTP toolkit for Ruby</p>
|
25
|
+
</td>
|
26
|
+
<td class=code>
|
27
|
+
<div class='highlight'><pre><span class="n">HTTPkit</span> <span class="k">is</span> <span class="n">a</span> <span class="n">Ruby</span> <span class="n">toolkit</span> <span class="k">for</span> <span class="n">building</span> <span class="n">HTTP</span> <span class="n">clients</span> <span class="n">and</span> <span class="n">servers</span><span class="p">,</span>
|
28
|
+
<span class="k">as</span> <span class="n">well</span> <span class="k">as</span> <span class="n">compositions</span> <span class="n">of</span> <span class="n">them</span><span class="p">.</span>
|
29
|
+
|
30
|
+
<span class="p">[![</span><span class="n">Build</span> <span class="n">Status</span><span class="p">](</span><span class="n">https</span><span class="p">:</span><span class="c1">//travis-ci.org/lgierth/httpkit.png?branch=master)](https://travis-ci.org/lgierth/httpkit) [![Code Climate](https://codeclimate.com/github/lgierth/httpkit.png)](https://codeclimate.com/github/lgierth/httpkit) [![Coverage Status](https://coveralls.io/repos/lgierth/httpkit/badge.png?branch=master)](https://coveralls.io/r/lgierth/httpkit?branch=master)</span>
|
31
|
+
|
32
|
+
<span class="p">-</span> <span class="p">\#</span><span class="mi">1</span> <span class="n">feature</span><span class="p">:</span> <span class="n">consistent</span><span class="p">,</span> <span class="n">high</span><span class="p">-</span><span class="n">quality</span><span class="p">,</span> <span class="n">extendable</span> <span class="n">codebase</span> <span class="k">with</span> <span class="mf">71.88</span><span class="p">%</span> <span class="n">mutation</span> <span class="n">coverage</span> <span class="p">(</span><span class="n">wip</span><span class="p">)</span>
|
33
|
+
<span class="p">-</span> <span class="p">\#</span><span class="mi">2</span> <span class="n">feature</span><span class="p">:</span> <span class="n">sophisticated</span> <span class="n">request</span> <span class="n">and</span> <span class="n">response</span> <span class="n">streaming</span>
|
34
|
+
<span class="p">-</span> <span class="p">\#</span><span class="mi">3</span> <span class="n">feature</span><span class="p">:</span> <span class="n">compatible</span> <span class="k">with</span> <span class="n">Rack</span><span class="p">,</span> <span class="n">Faraday</span><span class="p">,</span> <span class="n">and</span> <span class="n">VCR</span> <span class="p">(</span><span class="n">all</span> <span class="n">todo</span><span class="p">),</span> <span class="n">and</span> <span class="n">Webmachine</span> <span class="k">for</span> <span class="n">Ruby</span>
|
35
|
+
<span class="p">-</span> <span class="p">\#</span><span class="mi">4</span> <span class="n">feature</span><span class="p">:</span> <span class="n">backed</span> <span class="n">by</span> <span class="n">Celluloid</span> <span class="p">(</span><span class="n">wip</span><span class="p">)</span> <span class="n">or</span> <span class="n">Eventmachine</span>
|
36
|
+
<span class="p">-</span> <span class="p">\#</span><span class="mi">5</span> <span class="n">feature</span><span class="p">:</span> <span class="n">compatible</span> <span class="k">with</span> <span class="n">MRuby</span> <span class="p">(</span><span class="n">todo</span><span class="p">)</span>
|
37
|
+
|
38
|
+
<span class="n">Before</span> <span class="n">v0</span><span class="p">.</span><span class="mf">6.0</span><span class="p">,</span> <span class="n">HTTPkit</span> <span class="n">was</span> <span class="n">called</span> <span class="n">Hatetepe</span> <span class="n">and</span> <span class="n">then</span> <span class="n">underwent</span> <span class="n">a</span> <span class="n">ground</span><span class="p">-</span><span class="n">up</span> <span class="n">rewrite</span><span class="p">.</span> <span class="n">Look</span> <span class="n">at</span> <span class="n">the</span> <span class="p">[</span><span class="mf">0.5</span><span class="p">.</span><span class="n">x</span> <span class="n">branch</span><span class="p">](</span><span class="n">https</span><span class="p">:</span><span class="c1">//github.com/lgierth/httpkit/tree/0.5.x) for the old code.</span>
|
39
|
+
|
40
|
+
|
41
|
+
<span class="p">#</span> <span class="n">DIVIDER</span>
|
42
|
+
|
43
|
+
|
44
|
+
<span class="n">Add</span> <span class="k">this</span> <span class="n">line</span> <span class="n">to</span> <span class="n">your</span> <span class="n">application</span><span class="err">'</span><span class="n">s</span> <span class="n">Gemfile</span><span class="p">:</span>
|
45
|
+
|
46
|
+
<span class="n">gem</span> <span class="err">'</span><span class="n">httpkit</span><span class="err">'</span><span class="p">,</span> <span class="err">'</span><span class="mf">0.6</span><span class="p">.</span><span class="mf">0</span><span class="p">.</span><span class="n">pre</span><span class="p">.</span><span class="mi">3</span><span class="err">'</span>
|
47
|
+
|
48
|
+
<span class="n">And</span> <span class="n">then</span> <span class="n">execute</span><span class="p">:</span>
|
49
|
+
|
50
|
+
<span class="p">$</span> <span class="n">bundle</span>
|
51
|
+
|
52
|
+
<span class="n">Or</span> <span class="n">install</span> <span class="n">it</span> <span class="n">yourself</span> <span class="k">as</span><span class="p">:</span>
|
53
|
+
|
54
|
+
<span class="p">$</span> <span class="n">gem</span> <span class="n">install</span> <span class="n">httpkit</span> <span class="p">--</span><span class="n">pre</span>
|
55
|
+
|
56
|
+
|
57
|
+
<span class="p">#</span> <span class="n">DIVIDER</span>
|
58
|
+
|
59
|
+
|
60
|
+
<span class="n">Code</span> <span class="n">examples</span>
|
61
|
+
|
62
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">Getting</span> <span class="n">started</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/file/examples/getting_started.rb)</span>
|
63
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTP</span> <span class="n">echo</span> <span class="n">server</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/file/examples/echo_server.rb)</span>
|
64
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">Streaming</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/file/examples/streaming.rb)</span>
|
65
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">Error</span> <span class="n">handling</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/file/examples/error_handling.rb)</span>
|
66
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">Connection</span> <span class="n">status</span><span class="p">]()</span>
|
67
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">Custom</span> <span class="n">handlers</span><span class="p">]()</span>
|
68
|
+
|
69
|
+
<span class="n">API</span> <span class="n">Reference</span>
|
70
|
+
|
71
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit)</span>
|
72
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Request</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Request)</span>
|
73
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Response</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Response)</span>
|
74
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Body</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Body)</span>
|
75
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Client</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Client)</span>
|
76
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Server</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Server)</span>
|
77
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Promise</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Promise)</span>
|
78
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">Serializer</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Serializer)</span>
|
79
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">ClientHandler</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Client/Handler)</span>
|
80
|
+
<span class="p">-</span> <span class="p">[</span><span class="n">HTTPkit</span><span class="p">::</span><span class="n">ServerHandler</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//rubydoc.info/github/lgierth/httpkit/master/HTTPkit/Server/Handler)</span>
|
81
|
+
|
82
|
+
|
83
|
+
<span class="p">#</span> <span class="n">DIVIDER</span>
|
84
|
+
|
85
|
+
|
86
|
+
<span class="n">Here</span><span class="p">:</span> <span class="n">https</span><span class="p">:</span><span class="c1">//trello.com/b/OoxEq1ze/httpkit</span>
|
87
|
+
|
88
|
+
|
89
|
+
<span class="p">#</span> <span class="n">DIVIDER</span>
|
90
|
+
|
91
|
+
|
92
|
+
<span class="n">HTTPkit</span> <span class="k">is</span> <span class="n">free</span> <span class="n">and</span> <span class="n">unencumbered</span> <span class="n">public</span> <span class="n">domain</span> <span class="n">software</span><span class="p">.</span> <span class="n">For</span> <span class="n">more</span>
|
93
|
+
<span class="n">information</span><span class="p">,</span> <span class="n">see</span> <span class="p">[</span><span class="n">unlicense</span><span class="p">.</span><span class="n">org</span><span class="p">](</span><span class="n">http</span><span class="p">:</span><span class="c1">//unlicense.org/) or the accompanying</span>
|
94
|
+
<span class="n">UNLICENSE</span> <span class="n">file</span><span class="p">.</span>
|
95
|
+
|
96
|
+
|
97
|
+
<span class="p">#</span> <span class="n">DIVIDER</span>
|
98
|
+
|
99
|
+
|
100
|
+
<span class="mf">1</span><span class="p">.</span> <span class="n">Fork</span> <span class="n">it</span>
|
101
|
+
<span class="mf">2</span><span class="p">.</span> <span class="n">Create</span> <span class="n">your</span> <span class="n">feature</span> <span class="n">branch</span> <span class="p">(</span><span class="err">`</span><span class="n">git</span> <span class="n">checkout</span> <span class="p">-</span><span class="n">b</span> <span class="n">my</span><span class="p">-</span><span class="n">new</span><span class="p">-</span><span class="n">feature</span><span class="err">`</span><span class="p">)</span>
|
102
|
+
<span class="mf">3</span><span class="p">.</span> <span class="n">Commit</span> <span class="n">your</span> <span class="n">changes</span> <span class="p">(</span><span class="err">`</span><span class="n">git</span> <span class="n">commit</span> <span class="p">-</span><span class="n">am</span> <span class="err">'</span><span class="n">Add</span> <span class="n">some</span> <span class="n">feature</span><span class="err">'`</span><span class="p">)</span>
|
103
|
+
<span class="mf">4</span><span class="p">.</span> <span class="n">Push</span> <span class="n">to</span> <span class="n">the</span> <span class="n">branch</span> <span class="p">(</span><span class="err">`</span><span class="n">git</span> <span class="n">push</span> <span class="n">origin</span> <span class="n">my</span><span class="p">-</span><span class="n">new</span><span class="p">-</span><span class="n">feature</span><span class="err">`</span><span class="p">)</span>
|
104
|
+
<span class="mf">5</span><span class="p">.</span> <span class="n">Create</span> <span class="n">new</span> <span class="n">Pull</span> <span class="n">Request</span></pre></div>
|
105
|
+
</td>
|
106
|
+
</tr>
|
107
|
+
<tr id='section-Installation'>
|
108
|
+
<td class=docs>
|
109
|
+
<div class="pilwrap">
|
110
|
+
<a class="pilcrow" href="#section-Installation">¶</a>
|
111
|
+
</div>
|
112
|
+
<h1>Installation</h1>
|
113
|
+
</td>
|
114
|
+
<td class=code>
|
115
|
+
<div class='highlight'><pre></pre></div>
|
116
|
+
</td>
|
117
|
+
</tr>
|
118
|
+
<tr id='section-Usage'>
|
119
|
+
<td class=docs>
|
120
|
+
<div class="pilwrap">
|
121
|
+
<a class="pilcrow" href="#section-Usage">¶</a>
|
122
|
+
</div>
|
123
|
+
<h1>Usage</h1>
|
124
|
+
</td>
|
125
|
+
<td class=code>
|
126
|
+
<div class='highlight'><pre></pre></div>
|
127
|
+
</td>
|
128
|
+
</tr>
|
129
|
+
<tr id='section-To_do'>
|
130
|
+
<td class=docs>
|
131
|
+
<div class="pilwrap">
|
132
|
+
<a class="pilcrow" href="#section-To_do">¶</a>
|
133
|
+
</div>
|
134
|
+
<h1>To do</h1>
|
135
|
+
</td>
|
136
|
+
<td class=code>
|
137
|
+
<div class='highlight'><pre></pre></div>
|
138
|
+
</td>
|
139
|
+
</tr>
|
140
|
+
<tr id='section-License'>
|
141
|
+
<td class=docs>
|
142
|
+
<div class="pilwrap">
|
143
|
+
<a class="pilcrow" href="#section-License">¶</a>
|
144
|
+
</div>
|
145
|
+
<h1>License</h1>
|
146
|
+
</td>
|
147
|
+
<td class=code>
|
148
|
+
<div class='highlight'><pre></pre></div>
|
149
|
+
</td>
|
150
|
+
</tr>
|
151
|
+
<tr id='section-Contributing'>
|
152
|
+
<td class=docs>
|
153
|
+
<div class="pilwrap">
|
154
|
+
<a class="pilcrow" href="#section-Contributing">¶</a>
|
155
|
+
</div>
|
156
|
+
<h1>Contributing</h1>
|
157
|
+
|
158
|
+
</td>
|
159
|
+
<td class=code>
|
160
|
+
<div class='highlight'><pre></pre></div>
|
161
|
+
</td>
|
162
|
+
</tr>
|
163
|
+
</table>
|
164
|
+
</div>
|
165
|
+
</body>
|
data/examples/echo_server.rb
CHANGED
@@ -5,6 +5,10 @@ require 'httpkit'
|
|
5
5
|
class EchoServer
|
6
6
|
def serve(request, served)
|
7
7
|
response = streaming_response
|
8
|
+
|
9
|
+
# We start sending the response even we started writing its body. This is
|
10
|
+
# not mandatory, but it delivers the response to client as quickly as
|
11
|
+
# possible.
|
8
12
|
served.fulfill(response)
|
9
13
|
|
10
14
|
serialize(request, response)
|
@@ -14,10 +18,12 @@ class EchoServer
|
|
14
18
|
private
|
15
19
|
|
16
20
|
def streaming_response
|
17
|
-
HTTPkit::Response.new(200,
|
21
|
+
HTTPkit::Response.new(200,
|
22
|
+
{ 'Content-Type' => 'application/octet-stream' },
|
18
23
|
HTTPkit::Body.new)
|
19
24
|
end
|
20
25
|
|
26
|
+
# This re-serializes the whole request directly into the response body.
|
21
27
|
def serialize(request, response)
|
22
28
|
writer = response.body.method(:write)
|
23
29
|
serializer = HTTPkit::Serializer.new(request, writer)
|
@@ -25,12 +31,14 @@ class EchoServer
|
|
25
31
|
end
|
26
32
|
end
|
27
33
|
|
28
|
-
HTTPkit.
|
29
|
-
|
30
|
-
|
34
|
+
HTTPkit.run do
|
35
|
+
address = '127.0.0.1'
|
36
|
+
port = HTTPkit.random_port(address)
|
37
|
+
|
38
|
+
HTTPkit::Server.start(address: address, port: port,
|
31
39
|
handlers: [HTTPkit::Server::KeepAliveHandler.new,
|
32
40
|
EchoServer.new])
|
33
41
|
|
34
|
-
|
35
|
-
|
42
|
+
body = HTTPkit.request(:get, "http://#{address}:#{port}").body
|
43
|
+
body.to_s.each_line { |line| p line }
|
36
44
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'httpkit'
|
4
|
+
|
5
|
+
class Failwhale
|
6
|
+
# TODO: Rejecting the served promise on the server side currently has no
|
7
|
+
# effect, except for the response simply not being sent. This has the
|
8
|
+
# potential of mixing up responses, so we should instead just send
|
9
|
+
# a 500 response for every rejected served promise. The same should
|
10
|
+
# happen for errors raised from handlers' #serve.
|
11
|
+
def serve(request, served)
|
12
|
+
raise if request.uri == '/raise'
|
13
|
+
|
14
|
+
served.fulfill(HTTPkit::Response.new(500))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
HTTPkit.run do
|
19
|
+
address = '127.0.0.1'
|
20
|
+
port = HTTPkit.random_port(address)
|
21
|
+
uri = "http://#{address}:#{port}"
|
22
|
+
|
23
|
+
HTTPkit.server(uri) do |request, served|
|
24
|
+
raise if request.uri == '/raise'
|
25
|
+
served.fulfill(HTTPkit::Response.new(500))
|
26
|
+
end
|
27
|
+
|
28
|
+
# 5xx responses are just normal responses.
|
29
|
+
response = HTTPkit.request(:get, uri)
|
30
|
+
p response.status
|
31
|
+
# => 500
|
32
|
+
|
33
|
+
# Let's crash the server and make it close the connection.
|
34
|
+
begin
|
35
|
+
HTTPkit.request(:get, uri + '/raise')
|
36
|
+
rescue Promise::Error => ex
|
37
|
+
puts ex.backtrace
|
38
|
+
# Connection error. Below we see how to find out more.
|
39
|
+
end
|
40
|
+
|
41
|
+
client = HTTPkit::Client.start(address: address, port: port)
|
42
|
+
request = HTTPkit::Request.new(:get, '/raise')
|
43
|
+
served = client.perform(request)
|
44
|
+
|
45
|
+
# Instead of getting fulfilled with a response, we see that the served
|
46
|
+
# promise gets rejected. Calling #sync on served would raise the rejection
|
47
|
+
# reason, in this case Promise::Error.
|
48
|
+
served.wait
|
49
|
+
p served.state
|
50
|
+
# => :rejected
|
51
|
+
p served.reason
|
52
|
+
# => Promise::Error if the connection was closed properly (in the TCP sense),
|
53
|
+
# otherwise one of the Errno:: constants.
|
54
|
+
p client.closed?
|
55
|
+
# => true
|
56
|
+
end
|
data/examples/getting_started.rb
CHANGED
@@ -2,39 +2,31 @@
|
|
2
2
|
|
3
3
|
require 'httpkit'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
HTTPkit.run do
|
6
|
+
# This is short-hand for the HTTPkit::Server.start dance.
|
7
|
+
HTTPkit.server('http://127.0.0.1:3000') do |request, served|
|
7
8
|
p request.http_method
|
8
9
|
# => :get
|
9
10
|
p request.uri
|
10
11
|
# => "/"
|
11
12
|
p request.headers
|
12
|
-
# => {"
|
13
|
+
# => {"User-Agent"=>"httpkit/0.6.0.pre.5", "Host"=>"127.0.0.1:3000"}
|
13
14
|
p request.body.to_s
|
14
15
|
# => ""
|
15
16
|
|
16
|
-
served.fulfill(
|
17
|
-
end
|
18
|
-
|
19
|
-
def response
|
20
|
-
HTTPkit::Response.new(200, { 'Content-Type' => 'text/plain' }, 'hello')
|
17
|
+
served.fulfill(HTTPkit::Response.new(200, {}, 'hello!'))
|
21
18
|
end
|
22
|
-
end
|
23
|
-
|
24
|
-
HTTPkit.run do
|
25
|
-
HTTPkit::Server.start(address: '127.0.0.1', port: 3000,
|
26
|
-
handlers: [HelloServer.new])
|
27
|
-
|
28
|
-
client = HTTPkit::Client.start(address: '127.0.0.1', port: 3000)
|
29
19
|
|
30
|
-
|
20
|
+
# Same here, but for HTTPkit::Client.start.
|
21
|
+
response = HTTPkit.request(:get, 'http://127.0.0.1:3000')
|
31
22
|
|
32
23
|
p response.status
|
33
24
|
# => 200
|
34
25
|
p response.status_name
|
35
26
|
# => "OK"
|
36
27
|
p response.headers
|
37
|
-
# => {"
|
28
|
+
# => {"Connection"=>"keep-alive", "Server"=>"httpkit/0.6.0.pre.5",
|
29
|
+
# "Date"=>"Sat, 19 Jul 2014 16:13:30 GMT", "Content-Length"=>"6"}
|
38
30
|
p response.body.to_s
|
39
|
-
# => "hello"
|
31
|
+
# => "hello!"
|
40
32
|
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'httpkit'
|
4
|
+
|
5
|
+
class Streaming
|
6
|
+
def serve(_request, served)
|
7
|
+
response = streaming_response
|
8
|
+
served.fulfill(response)
|
9
|
+
|
10
|
+
response.body.write('Doing stuff...')
|
11
|
+
EM.add_timer(1.0) { response.body.write('More stuff...') }
|
12
|
+
EM.add_timer(2.0) { response.body.write('Done!') }
|
13
|
+
EM.add_timer(3.0) { response.close }
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
# When passing a Body without source, i.e. nil, the response is being kept
|
19
|
+
# open for further body chunks.
|
20
|
+
def streaming_response
|
21
|
+
HTTPkit::Response.new(200,
|
22
|
+
{ 'Content-Type' => 'application/octet-stream' },
|
23
|
+
HTTPkit::Body.new)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
HTTPkit.run do
|
28
|
+
address = '127.0.0.1'
|
29
|
+
port = HTTPkit.random_port(address)
|
30
|
+
|
31
|
+
HTTPkit::Server.start(address: address, port: port,
|
32
|
+
handlers: [Streaming.new])
|
33
|
+
|
34
|
+
response = HTTPkit.request(:get, "http://#{address}:#{port}")
|
35
|
+
# Yields in the Fiber that wrote the chunk, does not block, a.k.a. async.
|
36
|
+
# Only yields for future chunks, so we need to explicitly grab past ones.
|
37
|
+
puts response.body.chunks
|
38
|
+
response.body.closed.on_progress { |chunk| puts chunk }
|
39
|
+
# Yields all past and future chunks here, blocks.
|
40
|
+
response.body.each { |chunk| puts chunk }
|
41
|
+
end
|