Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 09e24ef

Browse files
author
Parth Shandilya
committedFeb 15, 2023
feat: Allow global level Response headers
1 parent 1f4078a commit 09e24ef

File tree

6 files changed

+49
-4
lines changed

6 files changed

+49
-4
lines changed
 

‎docs/features.md

+9-1
Original file line numberDiff line numberDiff line change
@@ -171,14 +171,22 @@ async def hello(request):
171171
return "Hello World"
172172
```
173173

174-
## Global Headers
174+
## Global Request Headers
175175

176176
You can also add global headers for every request.
177177

178178
```python
179179
app.add_request_header("server", "robyn")
180180
```
181181

182+
## Global Response Headers
183+
184+
You can also add global response headers for every request.
185+
186+
```python
187+
app.add_response_header("content-type", "application/json")
188+
```
189+
182190
## Per route headers
183191

184192
You can also add headers for every route.

‎integration_tests/test_app.py

+6
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,12 @@ def test_add_request_header():
99
assert app.request_headers == [Header(key="server", val="robyn")]
1010

1111

12+
def test_add_response_header():
13+
app = Robyn(__file__)
14+
app.add_response_header("content-type", "application/json")
15+
assert app.response_headers == [Header(key="content-type", val="application/json")]
16+
17+
1218
def test_lifecycle_handlers():
1319
def mock_startup_handler():
1420
pass

‎robyn/__init__.py

+4
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(self, file_object: str) -> None:
3232
self.middleware_router = MiddlewareRouter()
3333
self.web_socket_router = WebSocketRouter()
3434
self.request_headers: List[Header] = [] # This needs a better type
35+
self.response_headers: List[Header] = [] # This needs a better type
3536
self.directories: List[Directory] = []
3637
self.event_handlers = {}
3738
load_vars(project_root=directory_path)
@@ -82,6 +83,9 @@ def add_directory(
8283
def add_request_header(self, key: str, value: str) -> None:
8384
self.request_headers.append(Header(key, value))
8485

86+
def add_response_header(self, key: str, value: str) -> None:
87+
self.response_headers.append(Header(key, value))
88+
8589
def add_web_socket(self, endpoint: str, ws: WS) -> None:
8690
self.web_socket_router.add_route(endpoint, ws)
8791

‎robyn/processpool.py

+4
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ def initialize_event_loop():
122122
def spawn_process(
123123
directories: List[Directory],
124124
request_headers: List[Header],
125+
response_headers: List[Header],
125126
routes: List[Route],
126127
middlewares: List[MiddlewareRoute],
127128
web_sockets: Dict[str, WS],
@@ -156,6 +157,9 @@ def spawn_process(
156157
for header in request_headers:
157158
server.add_request_header(*header.as_list())
158159

160+
for header in response_headers:
161+
server.add_response_header(*header.as_list())
162+
159163
for route in routes:
160164
route_type, endpoint, function, is_const = route
161165
server.add_route(route_type, endpoint, function, is_const)

‎robyn/robyn.pyi

+2
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ class Server:
3737
pass
3838
def add_request_header(self, key: str, value: str) -> None:
3939
pass
40+
def add_response_header(self, key: str, value: str) -> None:
41+
pass
4042
def add_route(
4143
self,
4244
route_type: str,

‎src/server.rs

+24-3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ pub struct Server {
4848
websocket_router: Arc<WebSocketRouter>,
4949
middleware_router: Arc<MiddlewareRouter>,
5050
global_request_headers: Arc<DashMap<String, String>>,
51+
global_response_headers: Arc<DashMap<String, String>>,
5152
directories: Arc<RwLock<Vec<Directory>>>,
5253
startup_handler: Option<Arc<FunctionInfo>>,
5354
shutdown_handler: Option<Arc<FunctionInfo>>,
@@ -63,6 +64,7 @@ impl Server {
6364
websocket_router: Arc::new(WebSocketRouter::new()),
6465
middleware_router: Arc::new(MiddlewareRouter::new()),
6566
global_request_headers: Arc::new(DashMap::new()),
67+
global_response_headers: Arc::new(DashMap::new()),
6668
directories: Arc::new(RwLock::new(Vec::new())),
6769
startup_handler: None,
6870
shutdown_handler: None,
@@ -92,6 +94,7 @@ impl Server {
9294
let middleware_router = self.middleware_router.clone();
9395
let web_socket_router = self.websocket_router.clone();
9496
let global_request_headers = self.global_request_headers.clone();
97+
let global_response_headers = self.global_response_headers.clone();
9598
let directories = self.directories.clone();
9699
let workers = Arc::new(workers);
97100

@@ -145,7 +148,8 @@ impl Server {
145148
.app_data(web::Data::new(router.clone()))
146149
.app_data(web::Data::new(const_router.clone()))
147150
.app_data(web::Data::new(middleware_router.clone()))
148-
.app_data(web::Data::new(global_request_headers.clone()));
151+
.app_data(web::Data::new(global_request_headers.clone()))
152+
.app_data(web::Data::new(global_response_headers.clone()));
149153

150154
let web_socket_map = web_socket_router.get_web_socket_map();
151155
for (elem, value) in (web_socket_map.read().unwrap()).iter() {
@@ -165,6 +169,7 @@ impl Server {
165169
const_router: web::Data<Arc<ConstRouter>>,
166170
middleware_router: web::Data<Arc<MiddlewareRouter>>,
167171
global_request_headers,
172+
global_response_headers,
168173
body,
169174
req| {
170175
pyo3_asyncio::tokio::scope_local(task_locals.clone(), async move {
@@ -173,6 +178,7 @@ impl Server {
173178
const_router,
174179
middleware_router,
175180
global_request_headers,
181+
global_response_headers,
176182
body,
177183
req,
178184
)
@@ -223,19 +229,32 @@ impl Server {
223229
});
224230
}
225231

226-
/// Adds a new header to our concurrent hashmap
232+
/// Adds a new request header to our concurrent hashmap
227233
/// this can be called after the server has started.
228234
pub fn add_request_header(&self, key: &str, value: &str) {
229235
self.global_request_headers
230236
.insert(key.to_string(), value.to_string());
231237
}
232238

233-
/// Removes a new header to our concurrent hashmap
239+
/// Adds a new response header to our concurrent hashmap
240+
/// this can be called after the server has started.
241+
pub fn add_response_header(&self, key: &str, value: &str) {
242+
self.global_response_headers
243+
.insert(key.to_string(), value.to_string());
244+
}
245+
246+
/// Removes a new request header to our concurrent hashmap
234247
/// this can be called after the server has started.
235248
pub fn remove_header(&self, key: &str) {
236249
self.global_request_headers.remove(key);
237250
}
238251

252+
/// Removes a new response header to our concurrent hashmap
253+
/// this can be called after the server has started.
254+
pub fn remove_response_header(&self, key: &str) {
255+
self.global_response_headers.remove(key);
256+
}
257+
239258
/// Add a new route to the routing tables
240259
/// can be called after the server has been started
241260
pub fn add_route(
@@ -345,6 +364,7 @@ async fn index(
345364
const_router: web::Data<Arc<ConstRouter>>,
346365
middleware_router: web::Data<Arc<MiddlewareRouter>>,
347366
global_request_headers: web::Data<Arc<Headers>>,
367+
global_response_headers: web::Data<Arc<Headers>>,
348368
body: Bytes,
349369
req: HttpRequest,
350370
) -> impl Responder {
@@ -360,6 +380,7 @@ async fn index(
360380

361381
let mut response_builder = HttpResponse::Ok();
362382
apply_dashmap_headers(&mut response_builder, &global_request_headers);
383+
apply_dashmap_headers(&mut response_builder, &global_response_headers);
363384
apply_hashmap_headers(&mut response_builder, &request.headers);
364385

365386
let response = if let Some(r) = const_router.get_route(req.method(), req.uri().path()) {

0 commit comments

Comments
 (0)
Please sign in to comment.