-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathusage.html.hbs
More file actions
159 lines (154 loc) · 6.94 KB
/
Copy pathusage.html.hbs
File metadata and controls
159 lines (154 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
{{#> _page.html.hbs}}
{{get "/_header"}}
<article>
<p>The CLI has three subcommands:</p>
<ol>
<li><code>eval</code> evaluates a handlebars template from STDIN.</li>
<li><code>get</code> renders content from a content directory.</li>
<li><code>serve</code> starts an HTTP server.</li>
</ol>
<p><code>serve</code> is where the real action is, but the other two come in handy at times.</p>
<p>
These commands all require a <em>content directory</em>, which is just the folder where your website lives. There
are a bunch of sample content directories
<a href="https://github.com/mkantor/operator/blob/master/samples">in the repository</a>.
</p>
<div class="group">
<p>
To learn more, use the <code>--help</code> option (alone or with a subcommand):
</p>
<details name="help">
<summary><code>operator --help</code></summary>
{{get "/_operator-help"}}
</details>
<details name="help">
<summary><code>operator eval --help</code></summary>
{{get "/_operator-help" subcommand="eval"}}
</details>
<details name="help">
<summary><code>operator get --help</code></summary>
{{get "/_operator-help" subcommand="get"}}
</details>
<details name="help">
<summary><code>operator serve --help</code></summary>
{{get "/_operator-help" subcommand="serve"}}
</details>
</div>
</article>
<article>
<h2>Quick Start</h2>
<div class="group">
<p>Let's run this website:</p>
<ul class="commands">
<li>git clone https://github.com/mkantor/operator-website.git</li>
<li>operator -vv serve \
--content-directory=operator-website/content \
--index-route=/home \
--error-handler-route=/error-handler \
--bind-to=127.0.0.1:8080</li>
</ul>
<p>Then open <a href="http://localhost:8080">http://localhost:8080</a> in your browser of choice.</p>
</div>
<p>
Try making a change to the site (in <code>operator-website/content</code>) and restart the server to see the
update.
</p>
</article>
<article>
<h2>Content</h2>
<p>
When Operator starts up it crawls through your content directory to build a representation of your website. The
site's routes and configuration are derived from this directory.
</p>
<p>
Operator needs to know what
<a href="https://tools.ietf.org/html/rfc6838">media type</a> will be emitted by each content file. This is
specified via file extensions (<code>.html</code> is <code>text/html</code>, <code>.js</code> is
<code>text/javascript</code>, <code>.png</code> is <code>image/png</code>, and
<a href="https://crates.io/crates/mime_guess">so on</a>).
</p>
<p>There are three different kinds of content files:</p>
<ol>
<li>
<p>
<strong>Static files</strong> are served directly. For example, you can drop an image or html file into your
content directory and it'll be served as is.
</p>
<p>
Static files only have one extension (<code>about.html</code>,
<code>kittens.mp4</code>, etc).
</p>
</li>
<li>
<p>
<strong>Executables</strong> are run at request time, with standard output piped out as the response body. Any
program that you can run from the command line will work (scripts, compiled programs, etc). The executable is
invoked with no CLI arguments and with its working directory set to its own parent folder.
</p>
<p>
An environment variable named <code>OPERATOR_RENDER_DATA</code> is provided to executables. Its value is
<a
href="https://docs.rs/operator/{{get "/_current-operator-release/version"}}/operator/content/struct.RenderData.html"
>render data</a
>
encoded as JSON. This is the same data provided to handlebars templates.
</p>
<p>
Executables have two extensions, with the first one indicating the media type of the executable's output
(<code>contact.html.py</code>, <code>styles.css.sh</code>, <code>dankmeme.jpg.exe</code>, etc). Operator
requires execute permissions on these files, and scripts will typically need a
<a href="https://en.wikipedia.org/wiki/Shebang_(Unix)">shebang</a>
so your OS knows how to interpret them.
</p>
<p class="small">
Operator doesn't care what the second extension is for executables, but you can use it to indicate the file
type—for example, <code>contact.html.py</code> would be a Python script which outputs HTML. In
executables the <em>file type</em> is usually not the same as its <em>output type</em>, although if you're
feeling feisty then things like
<a href="https://github.com/mkantor/operator-website/blob/master/content/examples/wat.js.js">wat.js.js</a>
are certainly <a href="/examples/wat" target="_blank">possible</a>.
</p>
</li>
<li>
<p>
<strong>Handlebars templates</strong> are compiled during server startup and rendered at request time. The
heavy lifting is done by
<a href="https://crates.io/crates/handlebars">the <code>handlebars</code> Rust library</a>
which is largely compatible with
<a href="https://handlebarsjs.com">the original JavaScript handlebars implementation</a>. Operator provides
some
<a
href="https://docs.rs/operator/{{get "/_current-operator-release/version"}}/operator/content/struct.RenderData.html"
>render data</a
>
and a custom <code>get</code> helper to make your content composable.
</p>
<p>
Like executables, handlebars templates also have two extensions. The first one indicates the media type, and
the second one must be <code>.hbs</code> to tell Operator that it's a template (<code>faq.html.hbs</code>,
<code>metadata.json.hbs</code>, etc).
</p>
</li>
</ol>
</article>
<article>
<h2>Security</h2>
<p>Operator is only as secure as your content directory, so be careful! Here are some best practices:</p>
<ul>
<li>
Always create a dedicated user with limited privileges to run the server and/or run it inside a locked-down
container or chroot jail.
</li>
<li>
Make sure that nobody except you has write permissions on the content directory and everything in it (and,
again, don't run Operator as yourself in production).
</li>
<li>
Any executables you put in the content directory must be trusted. You should think carefully about what effects
they can have and how they handle request data. An executable that could <code>rm -rf /</code>, leak sensitive
information, or fork bomb your system would be a bad idea.
</li>
</ul>
</article>
{{get "/_footer"}}
{{/_page.html.hbs}}