tipi 0.30

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/test.yml +27 -0
  3. data/.gitignore +56 -0
  4. data/CHANGELOG.md +33 -0
  5. data/Gemfile +3 -0
  6. data/Gemfile.lock +50 -0
  7. data/LICENSE +21 -0
  8. data/README.md +23 -0
  9. data/Rakefile +12 -0
  10. data/TODO.md +66 -0
  11. data/bin/tipi +12 -0
  12. data/docs/README.md +62 -0
  13. data/docs/summary.md +60 -0
  14. data/examples/cuba.ru +23 -0
  15. data/examples/hanami-api.ru +23 -0
  16. data/examples/http_server.js +24 -0
  17. data/examples/http_server.rb +21 -0
  18. data/examples/http_server_forked.rb +29 -0
  19. data/examples/http_server_graceful.rb +27 -0
  20. data/examples/http_server_simple.rb +11 -0
  21. data/examples/http_server_throttled.rb +15 -0
  22. data/examples/http_server_timeout.rb +35 -0
  23. data/examples/http_ws_server.rb +37 -0
  24. data/examples/https_server.rb +24 -0
  25. data/examples/https_server_forked.rb +32 -0
  26. data/examples/https_wss_server.rb +39 -0
  27. data/examples/rack_server.rb +12 -0
  28. data/examples/rack_server_https.rb +19 -0
  29. data/examples/rack_server_https_forked.rb +27 -0
  30. data/examples/websocket_secure_server.rb +27 -0
  31. data/examples/websocket_server.rb +24 -0
  32. data/examples/ws_page.html +34 -0
  33. data/examples/wss_page.html +34 -0
  34. data/lib/tipi.rb +54 -0
  35. data/lib/tipi/http1_adapter.rb +268 -0
  36. data/lib/tipi/http2_adapter.rb +74 -0
  37. data/lib/tipi/http2_stream.rb +134 -0
  38. data/lib/tipi/rack_adapter.rb +67 -0
  39. data/lib/tipi/request.rb +118 -0
  40. data/lib/tipi/version.rb +5 -0
  41. data/lib/tipi/websocket.rb +61 -0
  42. data/test/coverage.rb +45 -0
  43. data/test/eg.rb +27 -0
  44. data/test/helper.rb +51 -0
  45. data/test/run.rb +5 -0
  46. data/test/test_http_server.rb +321 -0
  47. data/tipi.gemspec +34 -0
  48. metadata +241 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 92c33ccc40f7b8f4f53fded65ab5902c81bcf0a92598fa5b2be3ada409a78721
4
+ data.tar.gz: b4f80d28c10539b44d1554fbd8e640c253919070cc576efbf62249eee8efeeb7
5
+ SHA512:
6
+ metadata.gz: 6a5712289bb6adc18e4c6fa24495157c19c41831036adc2e5ef082a640b09df426d015de5f00cb48d1d78d0855ce078c1cc7f2c15a1cec24a68cf022d45f9eea
7
+ data.tar.gz: 55e627cb9a6e91a846460ee30f3480ad77e4cb9124a40cd2fc68bf9abba7d6ecdbc52530ac92271d78c4a75fc9654be706efb59dba491ebbc6bc70532bc42aaa
@@ -0,0 +1,27 @@
1
+ name: Tests
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ strategy:
8
+ fail-fast: false
9
+ matrix:
10
+ os: [ubuntu-latest]
11
+ ruby: [2.6, 2.7]
12
+
13
+ name: >-
14
+ ${{matrix.os}}, ${{matrix.ruby}}
15
+
16
+ runs-on: ${{matrix.os}}
17
+ steps:
18
+ - uses: actions/checkout@v1
19
+ - uses: actions/setup-ruby@v1
20
+ with:
21
+ ruby-version: ${{matrix.ruby}}
22
+ - name: Install dependencies
23
+ run: |
24
+ gem install bundler
25
+ bundle install
26
+ - name: Run tests
27
+ run: bundle exec rake test
@@ -0,0 +1,56 @@
1
+ *.gem
2
+ *.rbc
3
+ /.config
4
+ /coverage/
5
+ /InstalledFiles
6
+ /pkg/
7
+ /spec/reports/
8
+ /spec/examples.txt
9
+ /test/tmp/
10
+ /test/version_tmp/
11
+ /tmp/
12
+
13
+ # Used by dotenv library to load environment variables.
14
+ # .env
15
+
16
+ # Ignore Byebug command history file.
17
+ .byebug_history
18
+
19
+ ## Specific to RubyMotion:
20
+ .dat*
21
+ .repl_history
22
+ build/
23
+ *.bridgesupport
24
+ build-iPhoneOS/
25
+ build-iPhoneSimulator/
26
+
27
+ ## Specific to RubyMotion (use of CocoaPods):
28
+ #
29
+ # We recommend against adding the Pods directory to your .gitignore. However
30
+ # you should judge for yourself, the pros and cons are mentioned at:
31
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
32
+ #
33
+ # vendor/Pods/
34
+
35
+ ## Documentation cache and generated files:
36
+ /.yardoc/
37
+ /_yardoc/
38
+ /doc/
39
+ /rdoc/
40
+
41
+ ## Environment normalization:
42
+ /.bundle/
43
+ /vendor/bundle
44
+ /lib/bundler/man/
45
+
46
+ # for a library or gem, you might want to ignore these files since the code is
47
+ # intended to run in multiple environments; otherwise, check them in:
48
+ # Gemfile.lock
49
+ # .ruby-version
50
+ # .ruby-gemset
51
+
52
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
53
+ .rvmrc
54
+
55
+ # Used by RuboCop. Remote config files pulled in from inherit_from directive.
56
+ # .rubocop-https?--*
@@ -0,0 +1,33 @@
1
+ ## 0.30 2020-07-15
2
+
3
+ * Rename project to Tipi
4
+ * Rearrange source code
5
+ * Remove HTTP client code (to be developed eventually into a separate gem)
6
+ * Fix header rendering in rack adapter (#2)
7
+
8
+ ## 0.29 2020-07-06
9
+
10
+ * Use IO#read_loop
11
+
12
+ ## 0.28 2020-07-03
13
+
14
+ * Update with API changes from Polyphony >= 0.41
15
+
16
+ ## 0.27 2020-04-14
17
+
18
+ * Remove modulation dependency
19
+
20
+ ## 0.26 2020-03-03
21
+
22
+ * Fix `Server#listen`
23
+
24
+ ## 0.25 2020-02-19
25
+
26
+ * Ensure server socket is closed upon stopping loop
27
+ * Fix `Request#format_header_lines`
28
+
29
+ ## 0.24 2020-01-08
30
+
31
+ * Move HTTP to separate polyphony-http gem
32
+
33
+ For earlier changes look at the Polyphony changelog.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,50 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ tipi (0.30)
5
+ http-2 (~> 0.10.0)
6
+ http_parser.rb (~> 0.6.0)
7
+ polyphony (~> 0.43.5)
8
+ rack (>= 2.0.8, < 2.3.0)
9
+ websocket (~> 1.2.8)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ ansi (1.5.0)
15
+ builder (3.2.4)
16
+ docile (1.3.2)
17
+ http-2 (0.10.2)
18
+ http_parser.rb (0.6.0)
19
+ json (2.1.0)
20
+ localhost (1.1.4)
21
+ minitest (5.11.3)
22
+ minitest-reporters (1.4.2)
23
+ ansi
24
+ builder
25
+ minitest (>= 5.0)
26
+ ruby-progressbar
27
+ polyphony (0.43.5)
28
+ rack (2.2.3)
29
+ rake (12.3.3)
30
+ ruby-progressbar (1.10.1)
31
+ simplecov (0.17.1)
32
+ docile (~> 1.1)
33
+ json (>= 1.8, < 3)
34
+ simplecov-html (~> 0.10.0)
35
+ simplecov-html (0.10.2)
36
+ websocket (1.2.8)
37
+
38
+ PLATFORMS
39
+ ruby
40
+
41
+ DEPENDENCIES
42
+ localhost (~> 1.1.4)
43
+ minitest (~> 5.11.3)
44
+ minitest-reporters (~> 1.4.2)
45
+ rake (~> 12.3.3)
46
+ simplecov (~> 0.17.1)
47
+ tipi!
48
+
49
+ BUNDLED WITH
50
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Sharon Rosner
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,23 @@
1
+ # Tipi - the All-in-one Web Server for Ruby Apps
2
+
3
+ [![Gem Version](https://badge.fury.io/rb/tipi.svg)](http://rubygems.org/gems/tipi)
4
+ [![Modulation Test](https://github.com/digital-fabric/tipi/workflows/Tests/badge.svg)](https://github.com/digital-fabric/tipi/actions?query=workflow%3ATests)
5
+ [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/digital-fabric/tipi/blob/master/LICENSE)
6
+
7
+ ## What is Tipi?
8
+
9
+ Tipi is an integrated, feature-complete HTTP/S server for Ruby applications.
10
+ Tipi is built on Polyphony, a robust, high-performance library for building
11
+ highly-concurrent applications in Ruby. Tipi can be used to serve any Rack
12
+ application or set of static files directly without having to employ a
13
+ reverse-proxy such as Nginx.
14
+
15
+ ## Features
16
+
17
+ * **Full-blown, integrated, high-performance HTTP 1 / HTTP 2 / WebSocket server
18
+ with TLS/SSL termination, automatic ALPN protocol selection, and body
19
+ streaming**.
20
+
21
+ ## Documentation
22
+
23
+ Documentation for Tipi is coming soon...
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rake/clean"
5
+
6
+ # frozen_string_literal: true
7
+
8
+ task :default => [:test]
9
+ task :test do
10
+ exec 'ruby test/run.rb'
11
+ end
12
+
data/TODO.md ADDED
@@ -0,0 +1,66 @@
1
+ # Roadmap
2
+
3
+ - Update README (get rid of non-http stuff)
4
+ - Improve Rack spec compliance, add tests
5
+ - Homogenize HTTP 1 and HTTP 2 headers - upcase ? downcase ?
6
+
7
+ ## 0.30
8
+
9
+ - Add more poly CLI commands and options:
10
+
11
+ - serve static files from given directory
12
+ - serve from rack up file
13
+ - serve both http and https
14
+ - use custom certificate files for SSL
15
+ - set host address to bind to
16
+ - set port to bind to
17
+ - set forking process count
18
+
19
+ ## 0.31 Working Sinatra application
20
+
21
+ - app with database access (postgresql)
22
+ - benchmarks!
23
+
24
+ # HTTP Client Agent
25
+
26
+ The concurrency model and the fact that we want to serve the response object on
27
+ receiving headers and let the user lazily read the response body, means we'll
28
+ need to change the API to accept a block:
29
+
30
+ ```ruby
31
+ # current API
32
+ resp = Agent.get('http://acme.org')
33
+ puts resp.body
34
+
35
+ # proposed API
36
+ Agent.get('http://acme.org') do |resp|
37
+ puts resp.body
38
+ end
39
+ ```
40
+
41
+ While the block is running, the connection adapter is acquired. Once the block
42
+ is done running, the request (and response) can be discarded. The problem with
43
+ that if we spin up a coprocess from that block we risk all kinds of race
44
+ conditions and weird behaviours.
45
+
46
+ A compromise might be to allow the two: doing a `get` without providing a block
47
+ will return a response object that already has the body (i.e. the entire
48
+ response has already been received). Doing a `get` with a block will invoke the
49
+ block once headers are received, letting the user's code stream the body:
50
+
51
+ ```ruby
52
+ def request(ctx, &block)
53
+ ...
54
+ connection_manager.acquire do |adapter|
55
+ response = adapter.request(ctx)
56
+ if block
57
+ block.(response)
58
+ else
59
+ # wait for body
60
+ response.body
61
+ end
62
+ response
63
+ end
64
+ end
65
+ ```
66
+
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require File.expand_path('../lib/tipi', __dir__)
4
+ require File.expand_path('../lib/tipi/rack_adapter', __dir__)
5
+
6
+ app_path = ARGV.first || './config.ru'
7
+ app = Tipi::RackAdapter.load(app_path)
8
+ opts = { reuse_addr: true, dont_linger: true }
9
+
10
+ puts "listening on port 1234"
11
+ puts "pid: #{Process.pid}"
12
+ Tipi.serve('0.0.0.0', 1234, opts, &app)
@@ -0,0 +1,62 @@
1
+ # Polyphony - Easy Concurrency for Ruby
2
+
3
+ > Polyphony \| pəˈlɪf\(ə\)ni \|
4
+ > 1. _Music_ the style of simultaneously combining a number of parts, each
5
+ > forming an individual melody and harmonizing with each other.
6
+ > 2. _Programming_ a Ruby gem for concurrent programming focusing on performance
7
+ > and developer happiness.
8
+
9
+ Polyphony is a library for building concurrent applications in Ruby. Polyphony
10
+ harnesses the power of [Ruby fibers](https://ruby-doc.org/core-2.5.1/Fiber.html)
11
+ to provide a cooperative, sequential coprocess-based concurrency model. Under
12
+ the hood, Polyphony uses [libev](https://github.com/enki/libev) as a
13
+ high-performance event reactor that provides timers, I/O watchers and other
14
+ asynchronous event primitives.
15
+
16
+ Polyphony makes it possible to use normal Ruby built-in classes like `IO`, and
17
+ `Socket` in a concurrent fashion without having to resort to threads. Polyphony
18
+ takes care of context-switching automatically whenever a blocking call like
19
+ `Socket#accept` or `IO#read` is issued.
20
+
21
+ ## Features
22
+
23
+ * **Full-blown, integrated, high-performance HTTP 1 / HTTP 2 / WebSocket server
24
+ with TLS/SSL termination, automatic ALPN protocol selection, and body
25
+ streaming**.
26
+ * Co-operative scheduling of concurrent tasks using Ruby fibers.
27
+ * High-performance event reactor for handling I/O events and timers.
28
+ * Natural, sequential programming style that makes it easy to reason about concurrent code.
29
+ * Abstractions and constructs for controlling the execution of concurrent code:
30
+ coprocesses, supervisors, throttling, resource pools etc.
31
+ * Code can use native networking classes and libraries, growing support for
32
+ third-party gems such as `pg` and `redis`.
33
+ * Use stdlib classes such as `TCPServer` and `TCPSocket` and `Net::HTTP`.
34
+ * HTTP 1 / HTTP 2 client agent with persistent connections.
35
+ * Competitive performance and scalability characteristics, in terms of both
36
+ throughput and memory consumption.
37
+
38
+ ## Prior Art
39
+
40
+ Polyphony draws inspiration from the following, in no particular order:
41
+
42
+ * [nio4r](https://github.com/socketry/nio4r/) and
43
+ [async](https://github.com/socketry/async) (Polyphony's C-extension code is
44
+ largely a spinoff of
45
+ [nio4r's](https://github.com/socketry/nio4r/tree/master/ext))
46
+ * [EventMachine](https://github.com/eventmachine/eventmachine)
47
+ * [Trio](https://trio.readthedocs.io/)
48
+ * [Erlang supervisors](http://erlang.org/doc/man/supervisor.html) (and actually,
49
+ Erlang in general)
50
+
51
+ ## Going further
52
+
53
+ To learn more about using Polyphony to build concurrent applications, read the
54
+ technical overview below, or look at the [included
55
+ examples](https://github.com/digital-fabric/polyphony/tree/9e0f3b09213156bdf376ef33684ef267517f06e8/examples/README.md).
56
+ A thorough reference is forthcoming.
57
+
58
+ ## Contributing to Polyphony
59
+
60
+ Issues and pull requests will be gladly accepted. Please use the git repository
61
+ at https://github.com/digital-fabric/polyphony as your primary point of
62
+ departure for contributing.
@@ -0,0 +1,60 @@
1
+ # Table of contents
2
+
3
+ * [Polyphony - Easy Concurrency for Ruby](../README.md)
4
+
5
+ ## Getting Started
6
+
7
+ * [Installing](getting-started/installing.md)
8
+ * [Tutorial](getting-started/tutorial.md)
9
+
10
+ ## Technical overview
11
+
12
+ * [Design Principles](technical-overview/design-principles.md)
13
+ * [Concurrency the Easy Way](technical-overview/concurrency.md)
14
+ * [How Fibers are Scheduled](technical-overview/fiber-scheduling.md)
15
+ * [Exception Handling](technical-overview/exception-handling.md)
16
+ * [Frequently Asked Questions](technical-overview/faq.md)
17
+
18
+ ## How To
19
+
20
+ * [Make an echo server](howto/echo-server.md)
21
+ * [Make an HTTP server](howto/http-server.md)
22
+ * [Make a Websocket server](howto/websocket-server.md)
23
+ * [Use timers](howto/timers.md)
24
+ * [Throttle recurrent operations](howto/throttle.md)
25
+ * [Cancel ongoing operations](howto/cancel.md)
26
+ * [Control coprocesses](howto/coprocesses.md)
27
+ * [Synchronize concurrent operations](howto/synchronize.md)
28
+ * [Perform CPU-bound operations](howto/cpu-bound.md)
29
+ * [Control backpressure](howto/backpressure.md)
30
+ * [Fork worker processes](howto/worker-processes.md)
31
+
32
+ ## Polyphony extensions
33
+
34
+ * [Postgresql](extensions/pg)
35
+ * [Redis](extensions/redis)
36
+ * [IRB](extensions/irb)
37
+ * [Throttlers](#)
38
+ * [Resource Pools](#)
39
+ * [Synchronisation](#)
40
+ * [Web Server](user-guide/web-server.md)
41
+ * [Websocket Server](#)
42
+ * [Reactor API](#)
43
+
44
+ ## API Reference
45
+
46
+ * [Polyphony::CancelScope](#)
47
+ * [Polyphony::Coprocess](#)
48
+ * [Gyro](#)
49
+ * [Gyro::Async](#)
50
+ * [Gyro::Child](#)
51
+ * [Gyro::IO](#)
52
+ * [Gyro::Timer](#)
53
+ * [Kernel](#)
54
+ * [Polyphony](#)
55
+ * [Polyphony::Mutex](#)
56
+ * [Polyphony::Pulser](#)
57
+ * [Polyphony::ResourcePool](#)
58
+ * [Polyphony::Throttler](#)
59
+
60
+ ## [Contributing to Polyphony](contributing.md)