httpkit 0.6.0.pre.5 → 0.6.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 (52) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +0 -2
  3. data/.travis.yml +1 -1
  4. data/Gemfile +2 -0
  5. data/README.md +32 -25
  6. data/Rakefile +5 -0
  7. data/config/flay.yml +1 -1
  8. data/doc/api/httpkit.html +50 -0
  9. data/doc/api/httpkit/body.html +149 -0
  10. data/doc/api/httpkit/client.html +50 -0
  11. data/doc/api/httpkit/client/body_handler.html +50 -0
  12. data/doc/api/httpkit/client/keep_alive_handler.html +79 -0
  13. data/doc/api/httpkit/client/mandatory_handler.html +50 -0
  14. data/doc/api/httpkit/client/timeouts_handler.html +82 -0
  15. data/doc/api/httpkit/connection/eventmachine.html +157 -0
  16. data/doc/api/httpkit/connection/status.html +50 -0
  17. data/doc/api/httpkit/promise.html +50 -0
  18. data/doc/api/httpkit/request.html +123 -0
  19. data/doc/api/httpkit/response.html +209 -0
  20. data/doc/api/httpkit/serializer.html +150 -0
  21. data/doc/api/httpkit/server.html +50 -0
  22. data/doc/api/httpkit/server/block_handler.html +50 -0
  23. data/doc/api/httpkit/server/body_handler.html +50 -0
  24. data/doc/api/httpkit/server/keep_alive_handler.html +145 -0
  25. data/doc/api/httpkit/server/mandatory_handler.html +50 -0
  26. data/doc/api/httpkit/server/timeouts_handler.html +81 -0
  27. data/doc/api/httpkit/support/handler_manager.html +95 -0
  28. data/doc/api/httpkit/support/message.html +50 -0
  29. data/doc/api/httpkit/version.html +50 -0
  30. data/doc/examples/echo_server.html +101 -0
  31. data/doc/examples/error_handling.html +176 -0
  32. data/doc/examples/getting_started.html +161 -0
  33. data/doc/examples/streaming.html +108 -0
  34. data/doc/index.html +165 -0
  35. data/examples/echo_server.rb +14 -6
  36. data/examples/error_handling.rb +56 -0
  37. data/examples/getting_started.rb +10 -18
  38. data/examples/streaming.rb +41 -0
  39. data/lib/httpkit.rb +22 -0
  40. data/lib/httpkit/body.rb +4 -0
  41. data/lib/httpkit/client.rb +1 -9
  42. data/lib/httpkit/client/keep_alive_handler.rb +1 -0
  43. data/lib/httpkit/connection/eventmachine.rb +2 -1
  44. data/lib/httpkit/server/block_handler.rb +13 -0
  45. data/lib/httpkit/server/keep_alive_handler.rb +1 -0
  46. data/lib/httpkit/version.rb +1 -1
  47. data/spec/integration/timeouts_spec.rb +3 -2
  48. data/spec/support/helper.rb +1 -8
  49. data/spec/unit/client_spec.rb +2 -21
  50. data/spec/unit/server_spec.rb +11 -1
  51. metadata +34 -5
  52. 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 &hellip;
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">&#182;</a>
34
+ </div>
35
+
36
+ </td>
37
+ <td class=code>
38
+ <div class='highlight'><pre><span class="nb">require</span> <span class="s1">&#39;httpkit&#39;</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">&#39;Doing stuff...&#39;</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">&#39;More stuff...&#39;</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">&#39;Done!&#39;</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">&#182;</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">&#39;Content-Type&#39;</span> <span class="o">=&gt;</span> <span class="s1">&#39;application/octet-stream&#39;</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">&#39;127.0.0.1&#39;</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">&quot;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">&quot;</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">&#182;</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">&#182;</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>
@@ -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">&#182;</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">&#39;</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">&#39;</span><span class="n">httpkit</span><span class="err">&#39;</span><span class="p">,</span> <span class="err">&#39;</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">&#39;</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">&#39;</span><span class="n">Add</span> <span class="n">some</span> <span class="n">feature</span><span class="err">&#39;`</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">&#182;</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">&#182;</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">&#182;</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">&#182;</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">&#182;</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>
@@ -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, { 'Content-Type' => 'text/plain' },
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.start do
29
- HTTPkit::Server.start(address: ENV.fetch('ADDRESS', '127.0.0.1'),
30
- port: ENV.fetch('PORT', 3000).to_i,
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
- Signal.trap(:INT) { HTTPkit.stop }
35
- Signal.trap(:TERM) { HTTPkit.stop }
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
@@ -2,39 +2,31 @@
2
2
 
3
3
  require 'httpkit'
4
4
 
5
- class HelloServer
6
- def serve(request, served)
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
- # => {"Host"=>"127.0.0.1:3000", "Content-Length"=>"0"}
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(response)
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
- response = client.request(:get, '/')
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
- # => {"Content-Type"=>"text/plain", "Content-Length"=>"5"}
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