···
6
6
use dropshot::ConfigLogging;
7
7
use dropshot::ConfigLoggingLevel;
8
8
use dropshot::HttpError;
9
9
+
use dropshot::HttpResponseHeaders;
9
10
use dropshot::HttpResponseOk;
10
11
use dropshot::Query;
11
12
use dropshot::RequestContext;
···
26
27
method = GET,
27
28
path = "/openapi",
28
29
}]
29
29
-
async fn get_openapi(
30
30
-
ctx: RequestContext<Context>,
31
31
-
) -> Result<HttpResponseOk<serde_json::Value>, HttpError> {
30
30
+
async fn get_openapi(ctx: RequestContext<Context>) -> OkCorsResponse<serde_json::Value> {
32
31
let spec = (*ctx.context().spec).clone();
33
33
-
Ok(HttpResponseOk(spec))
32
32
+
ok_cors(spec)
34
33
}
35
34
36
35
#[derive(Debug, Serialize, JsonSchema)]
···
45
44
method = GET,
46
45
path = "/meta"
47
46
}]
48
48
-
async fn get_meta_info(
49
49
-
ctx: RequestContext<Context>,
50
50
-
) -> Result<HttpResponseOk<MetaInfo>, HttpError> {
47
47
+
async fn get_meta_info(ctx: RequestContext<Context>) -> OkCorsResponse<MetaInfo> {
51
48
let Context { storage, .. } = ctx.context();
52
49
53
50
let failed_to_get =
···
76
73
.map_err(failed_to_get("jetstream cursor"))?
77
74
.map(|c| c.to_raw_u64());
78
75
79
79
-
Ok(HttpResponseOk(MetaInfo {
76
76
+
ok_cors(MetaInfo {
80
77
storage_info,
81
78
jetstream_endpoint,
82
79
jetstream_cursor,
83
80
mod_cursor,
84
84
-
}))
81
81
+
})
85
82
}
86
83
87
84
#[derive(Debug, Deserialize, JsonSchema)]
···
121
118
async fn get_records_by_collection(
122
119
ctx: RequestContext<Context>,
123
120
collection_query: Query<CollectionQuery>,
124
124
-
) -> Result<HttpResponseOk<Vec<ApiRecord>>, HttpError> {
121
121
+
) -> OkCorsResponse<Vec<ApiRecord>> {
125
122
let Ok(collection) = Nsid::new(collection_query.into_inner().collection) else {
126
123
return Err(HttpError::for_bad_request(
127
124
None,
···
146
143
.map(|r| ApiRecord::from_create_record(r, &collection))
147
144
.collect();
148
145
149
149
-
Ok(HttpResponseOk(api_records))
146
146
+
ok_cors(api_records)
150
147
}
151
148
152
149
/// Get total records seen by collection
···
157
154
async fn get_records_total_seen(
158
155
ctx: RequestContext<Context>,
159
156
collection_query: Query<CollectionQuery>,
160
160
-
) -> Result<HttpResponseOk<u64>, HttpError> {
157
157
+
) -> OkCorsResponse<u64> {
161
158
let Ok(collection) = Nsid::new(collection_query.into_inner().collection) else {
162
159
return Err(HttpError::for_bad_request(
163
160
None,
···
170
167
.await
171
168
.map_err(|e| HttpError::for_internal_error(format!("boooo: {e:?}")))?;
172
169
173
173
-
Ok(HttpResponseOk(total))
170
170
+
ok_cors(total)
174
171
}
175
172
176
173
/// Get top collections
···
178
175
method = GET,
179
176
path = "/collections"
180
177
}]
181
181
-
async fn get_top_collections(
182
182
-
ctx: RequestContext<Context>,
183
183
-
) -> Result<HttpResponseOk<HashMap<String, u64>>, HttpError> {
178
178
+
async fn get_top_collections(ctx: RequestContext<Context>) -> OkCorsResponse<HashMap<String, u64>> {
184
179
let Context { storage, .. } = ctx.context();
185
180
let collections = storage
186
181
.get_top_collections()
187
182
.await
188
183
.map_err(|e| HttpError::for_internal_error(format!("boooo: {e:?}")))?;
189
184
190
190
-
Ok(HttpResponseOk(collections))
185
185
+
ok_cors(collections)
191
186
}
192
187
193
188
pub async fn serve(storage: Storage) -> Result<(), String> {
···
223
218
.map_err(|error| format!("failed to start server: {}", error))?
224
219
.await
225
220
}
221
221
+
222
222
+
/// awkward helpers
223
223
+
type OkCorsResponse<T> = Result<HttpResponseHeaders<HttpResponseOk<T>>, HttpError>;
224
224
+
fn ok_cors<T: Send + Sync + Serialize + JsonSchema>(t: T) -> OkCorsResponse<T> {
225
225
+
let mut res = HttpResponseHeaders::new_unnamed(HttpResponseOk(t));
226
226
+
res.headers_mut()
227
227
+
.insert("access-control-allow-origin", "*".parse().unwrap());
228
228
+
Ok(res)
229
229
+
}