Skip to content

Commit 8000336

Browse files
Add protocol HTTP application boundary. (#57)
1 parent 2914915 commit 8000336

115 files changed

Lines changed: 2889 additions & 1162 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.body -text

bake/utopia/site.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def initialize(...)
1818
SETUP_ROOT = File.expand_path("../../setup", __dir__)
1919

2020
# Configuration files which should be installed/updated:
21-
CONFIGURATION_FILES = [".gitignore", "config.ru", "config/environment.rb", "falcon.rb", "gems.rb", "bake.rb", "test/website.rb", "fixtures/website.rb"]
21+
CONFIGURATION_FILES = [".gitignore", "config/application.rb", "config/environment.rb", "config/serve.rb", "falcon.rb", "gems.rb", "bake.rb", "test/website.rb", "fixtures/website.rb"]
2222

2323
# Directories that should exist:
2424
DIRECTORIES = ["config", "lib", "pages", "public", "bake", "fixtures", "test"]

bake/utopia/static.rb

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,29 @@
33
# Released under the MIT License.
44
# Copyright, 2017-2025, by Samuel Williams.
55

6-
def generate(output_path: "static")
6+
# Generate a static copy of the application.
7+
# @parameter output_path [String] The output path for the generated site.
8+
# @parameter application_path [String] The application configuration path.
9+
# @parameter public_path [String] The public assets path.
10+
# @parameter force [Boolean] Remove the output directory before generating the site.
11+
def generate(output_path: "static", application_path: "config/application.rb", public_path: "public", force: true)
712
require "falcon/server"
8-
require "async/io"
913
require "async/http/endpoint"
1014
require "async/container"
15+
require "fileutils"
16+
require "utopia/application"
1117

12-
config_path = File.join(Dir.pwd, "config.ru")
18+
application_path = File.expand_path(application_path, Dir.pwd)
19+
public_path = File.expand_path(public_path, Dir.pwd)
1320
container_class = Async::Container::Threaded
1421
server_port = 9090
1522

16-
app, options = Rack::Builder.parse_file(config_path)
23+
app = Utopia::Application.load(application_path)
1724

18-
container = container_class.run(count: 2) do
25+
container = container_class.run(count: 1) do
1926
Async do
2027
server = Falcon::Server.new(
21-
Falcon::Server.middleware(app),
28+
Falcon::Server.protocol_middleware(app),
2229
Async::HTTP::Endpoint.parse("http://localhost:#{server_port}")
2330
)
2431

@@ -28,17 +35,23 @@ def generate(output_path: "static")
2835

2936
output_path = File.expand_path(output_path, Dir.pwd)
3037

31-
# Delete any existing stuff:
32-
FileUtils.rm_rf(output_path)
38+
# Delete existing output when explicitly requested:
39+
if force
40+
FileUtils.rm_rf(output_path)
41+
end
3342

3443
# Copy all public assets:
3544
FileUtils::Verbose.mkpath(output_path)
36-
Dir.glob(File.join(Dir.pwd, "public/*")) do |path|
45+
Dir.glob(File.join(public_path, "*")) do |path|
3746
FileUtils::Verbose.cp_r(path, output_path)
3847
end
3948

40-
# Generate HTML pages:
41-
system("wget", "--mirror", "--recursive", "--continue", "--convert-links", "--adjust-extension", "--no-host-directories", "--directory-prefix", output_path.to_s, "http://localhost:#{server_port}")
42-
43-
container.stop
49+
begin
50+
# Generate HTML pages:
51+
unless system("wget", "--mirror", "--recursive", "--continue", "--convert-links", "--adjust-extension", "--no-host-directories", "--directory-prefix", output_path.to_s, "http://localhost:#{server_port}")
52+
raise "Static site generation failed!"
53+
end
54+
ensure
55+
container.stop
56+
end
4457
end

config/external.yaml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
utopia-project:
22
url: https://github.com/socketry/utopia-project.git
3-
command: bundle exec bake test
4-
www.codeotaku.com:
5-
url: https://github.com/ioquatix/www.codeotaku.com.git
3+
branch: v3-protocol-application
64
command: bundle exec bake test

context/getting-started.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This guide explains how to set up a `utopia` website for local development and d
44

55
## Installation
66

7-
Utopia is built on Ruby and Rack. Therefore, Ruby (suggested 2.0+) should be installed and working. Then, to install `utopia` and all required dependencies, run:
7+
Utopia is built on Ruby. Therefore, Ruby should be installed and working. Then, to install `utopia` and all required dependencies, run:
88

99
~~~ bash
1010
$ gem install utopia
@@ -32,10 +32,12 @@ You will now have a basic template site running on `https://localhost:9292`.
3232
Utopia includes a redirection middleware to redirect all root-level requests to a given URI. The default being `/welcome/index`:
3333

3434
```ruby
35-
# in config.ru
35+
# in config/application.rb
3636

37-
use Utopia::Redirection::Rewrite,
38-
"/" => "/welcome/index"
37+
Application = Utopia::Application.build do
38+
use Utopia::Redirection::Rewrite,
39+
"/" => "/welcome/index"
40+
end
3941
```
4042

4143
The content for this page is stored in `pages/welcome/index.xnode`. The format of this page is a subset of HTML5 - open and close tags are strictly enforced.
@@ -84,7 +86,7 @@ website
8486

8587
Least Coverage:
8688
pages/_page.xnode: 6 lines not executed!
87-
config.ru: 4 lines not executed!
89+
config/application.rb: 4 lines not executed!
8890
pages/welcome/index.xnode: 2 lines not executed!
8991
pages/_heading.xnode: 1 lines not executed!
9092

context/index.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ files:
1313
and deployment.
1414
- path: middleware.md
1515
title: Middleware
16-
description: This guide gives an overview of the different Rack middleware used
16+
description: This guide gives an overview of the different middleware used
1717
by Utopia.
1818
- path: server-setup.md
1919
title: Server Setup

context/middleware.md

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# Middleware
22

3-
This guide gives an overview of the different Rack middleware used by Utopia.
3+
This guide gives an overview of the different middleware used by Utopia.
44

55
## Static
66

7-
The {ruby Utopia::Static} middleware services static files efficiently. By default, it works with `Rack::Sendfile` and supports `ETag` based caching. Normally, you'd prefer to put static files into `public/_static` but it's also acceptable to put static content into `pages/` if it makes sense.
7+
The {ruby Utopia::Static} middleware services static files efficiently and supports `ETag` based caching. Normally, you'd prefer to put static files into `public/_static` but it's also acceptable to put static content into `pages/` if it makes sense.
88

99
~~~ ruby
1010
use Utopia::Static,
@@ -36,7 +36,7 @@ use Utopia::Redirection::Errors,
3636

3737
## Localization
3838

39-
The {ruby Utopia::Localization} middleware provides non-intrusive localization on top of the controller and view layers. The middleware uses the `accept-language` header to guess the preferred locale out of the given options. If a request path maps to a resource, that resource is returned. Otherwise, a non-localized request is made.
39+
The {ruby Utopia::Localization} middleware computes immutable localization preferences from the request path, host, and `accept-language` header. Localization-aware resource middleware, including {ruby Utopia::Static} and {ruby Utopia::Content}, resolves those preferences without invoking controllers more than once. Place the localization middleware before those resources in the middleware stack.
4040

4141
~~~ ruby
4242
use Utopia::Localization,
@@ -53,7 +53,7 @@ pages/index.ja.xnode
5353
pages/index.zh.xnode
5454
~~~
5555

56-
You can also access the current locale in the view via {ruby Utopia::Content::Node::Context#localization}.
56+
You can access the selected locale in a view using `localization.locale`. Controllers can inspect the request preferences using `request.localization`.
5757

5858
## Controller
5959

@@ -90,7 +90,7 @@ def passthrough(request, path)
9090

9191
# Succeed the request and immediately respond.
9292
# def succeed!(status: 200, headers: {}, **options)
93-
# options may include content: string or body: Enumerable (as per Rack specifications
93+
# options may include content: String or body: Enumerable.
9494

9595
suceed!
9696
end
@@ -108,7 +108,7 @@ end
108108

109109
on "edit" do |request, path|
110110
if request.post?
111-
@user.update_attributes(request[:user])
111+
@user.update_attributes(parse_body(request)["user"])
112112
end
113113
end
114114

@@ -155,3 +155,9 @@ use Utopia::Session,
155155
```
156156

157157
All session data is stored on the client, but it's encrypted with a salt and the secret key. It is impossible for the client to decrypt the data without the secret stored on the server.
158+
159+
When the middleware is installed, the session is available on the request:
160+
161+
```ruby
162+
request.session[:user_id] = user.id
163+
```

fixtures/a_rack_application.rb

Lines changed: 0 additions & 14 deletions
This file was deleted.

gems.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
group :development do
2323
gem "json"
24-
gem "rackula"
2524
end
2625

2726
group :test do
@@ -32,14 +31,13 @@
3231
gem "rubocop-md"
3332
gem "rubocop-socketry"
3433

35-
gem "falcon"
34+
gem "falcon", "~> 0.57"
3635
gem "async-websocket"
3736
gem "sus-fixtures-async-http"
37+
gem "sus-fixtures-protocol-http", "~> 0.1"
3838

3939
gem "bake-test"
4040
gem "bake-test-external"
4141

4242
gem "benchmark-ips"
43-
44-
gem "rack-test"
4543
end

guides/getting-started/readme.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ This guide explains how to set up a `utopia` website for local development and d
44

55
## Installation
66

7-
Utopia is built on Ruby and Rack. Therefore, Ruby (suggested 2.0+) should be installed and working. Then, to install `utopia` and all required dependencies, run:
7+
Utopia is built on Ruby. Therefore, Ruby should be installed and working. Then, to install `utopia` and all required dependencies, run:
88

99
~~~ bash
1010
$ gem install utopia
@@ -32,10 +32,12 @@ You will now have a basic template site running on `https://localhost:9292`.
3232
Utopia includes a redirection middleware to redirect all root-level requests to a given URI. The default being `/welcome/index`:
3333

3434
```ruby
35-
# in config.ru
35+
# in config/application.rb
3636

37-
use Utopia::Redirection::Rewrite,
38-
"/" => "/welcome/index"
37+
Application = Utopia::Application.build do
38+
use Utopia::Redirection::Rewrite,
39+
"/" => "/welcome/index"
40+
end
3941
```
4042

4143
The content for this page is stored in `pages/welcome/index.xnode`. The format of this page is a subset of HTML5 - open and close tags are strictly enforced.
@@ -84,7 +86,7 @@ website
8486

8587
Least Coverage:
8688
pages/_page.xnode: 6 lines not executed!
87-
config.ru: 4 lines not executed!
89+
config/application.rb: 4 lines not executed!
8890
pages/welcome/index.xnode: 2 lines not executed!
8991
pages/_heading.xnode: 1 lines not executed!
9092

0 commit comments

Comments
 (0)