Skip to content

Commit 19a838f

Browse files
Improve documentation for sessions and serving files (#24)
1 parent ee47476 commit 19a838f

File tree

2 files changed

+83
-6
lines changed

2 files changed

+83
-6
lines changed

blacksheep/docs/sessions.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ sequenceDiagram
6767
Client->>Server: HTTP Request (Cookie: session ID)
6868
Server->>Store: Retrieve session data using session ID
6969
Store-->>Server: Session data
70-
Server-->>Client: HTTP Response (may update Set-Cookie)
70+
Server-->>Client: HTTP Response
7171
```
7272

7373
In this scenario, Session ID is exchanged between client and server via
@@ -137,6 +137,36 @@ Before version `2.4.0`, BlackSheep offered built-in support only for sessions
137137
stored entirely on the client side, in cookies. Using sessions with a different
138138
store required custom code.
139139

140+
/// admonition | Cookies and cross-site request forgery.
141+
type: danger
142+
143+
When you store sessions in cookies on the client side, web applications must
144+
implement [Anti-Forgery validation](anti-request-forgery.md) to prevent
145+
Cross-Site Request Forgery (XSRF/CSRF).
146+
147+
**Why?**
148+
149+
Cookies are sent automatically by browsers with every request to your
150+
domain, making your app vulnerable to Cross-Site Request Forgery (CSRF)
151+
attacks, if information in cookies is used to authenticate requests and your
152+
application does not implement [Anti-Forgery
153+
validation](anti-request-forgery.md).
154+
155+
**How?**
156+
157+
Common anti-forgery mechanisms include:
158+
159+
- CSRF tokens: Generate a unique token per session/request and require it in
160+
forms or headers.
161+
- SameSite cookies: Set your session cookie with `SameSite=Strict` or
162+
`SameSite=Lax` to limit cross-site requests.
163+
- Custom headers: For APIs, use and require a custom header (e.g.,
164+
`X-Session-ID`) that browsers do not send cross-origin. In a user-defined
165+
`SessionStore` type, you can rely on a custom request and response header to
166+
exchange information with clients —updating your client code accordingly.
167+
168+
///
169+
140170
## Enabling sessions, with custom store
141171

142172
Starting from `2.4.0`, the built-in classes for sessions include support for

blacksheep/docs/static-files.md

Lines changed: 52 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Serving static files
1+
F# Serving static files
22

33
This page covers:
44

@@ -28,21 +28,22 @@ When serving files this way, a match-all route ("*") is configured in the
2828
application router for `GET` and `HEAD`, and files are read from the configured
2929
folder upon web requests.
3030

31+
3132
It is also possible to serve static files from sub-folders:
3233

3334
```python
3435
app.serve_files("app/static")
3536
```
3637

37-
Enable file discovery (in such case, requests for directories will generate an
38-
HTML response with a list of files):
38+
To enable file discovery, add the `discovery=True` parameter. In such case,
39+
requests for directories will generate an HTML response with a list of files:
3940

4041
```python
4142
app.serve_files("app/static", discovery=True)
4243
```
4344

44-
BlackSheep also supports serving static files from multiple folders, and
45-
specifying a prefix for the route path:
45+
Serving static files from multiple folders is supported, using a different path
46+
for each folder:
4647

4748
```python
4849
app = Application()
@@ -52,6 +53,52 @@ app.serve_files("app/images", root_path="images")
5253
app.serve_files("app/videos", root_path="videos")
5354
```
5455

56+
### Route paths and folder names
57+
58+
By default, when you serve files from a folder, the folder name is **not**
59+
included in the route at which files are served. For example, if you have a
60+
file `test.txt` in your `static` directory and you use:
61+
62+
```python
63+
app.serve_files("static")
64+
```
65+
66+
the file will be accessible at `http://localhost/test.txt` (not
67+
`http://localhost/static/test.txt`).
68+
69+
If you want the files to be accessible under a specific route path (such as
70+
`/static/`), use the `root_path` parameter:
71+
72+
```python
73+
app.serve_files("static", root_path="static")
74+
```
75+
76+
With this configuration, `test.txt` will be accessible at `http://localhost/static/test.txt`.
77+
78+
### Serving single files
79+
80+
If you need to serve single files, it is possible to use the `file` function
81+
like in the following example.
82+
83+
```python
84+
from blacksheep import Application, get
85+
from blacksheep.server.responses import file, ContentDispositionType
86+
87+
88+
app = Application()
89+
90+
91+
@get("/favicon.ico")
92+
def favicon_icon():
93+
# Note: the file is read asynchronously and served in chunks,
94+
# even though this function itself is synchronous
95+
return file(
96+
"path-to-your/favicon.ico", # ← local path
97+
"image/vnd.microsoft.icon",
98+
content_disposition=ContentDispositionType.INLINE,
99+
)
100+
```
101+
55102
## File extensions
56103

57104
Only files with a configured extension are served to the client. By default,

0 commit comments

Comments
 (0)