@@ -290,6 +290,56 @@ impl<State: Send + Sync + 'static> Server<State> {
290
290
291
291
server. run ( ) . await
292
292
}
293
+
294
+ /// Respond to a `Request` with a `Response`.
295
+ ///
296
+ /// This method is useful for testing endpoints directly,
297
+ /// or for creating servers over custom transports.
298
+ ///
299
+ /// # Examples
300
+ ///
301
+ /// ```no_run
302
+ /// # #[async_std::main]
303
+ /// # async fn main() -> http_types::Result<()> {
304
+ /// #
305
+ /// use tide::http::{self, Url, Method};
306
+ ///
307
+ /// // Initialize the application with state.
308
+ /// let mut app = tide::new();
309
+ /// app.at("/").get(|_| async move { Ok("hello world") });
310
+ ///
311
+ /// let req = http::Request::new(Method::Get, Url::parse("https://example.com")?);
312
+ /// let res = app.respond(req).await?;
313
+ /// assert_eq!(res.status(), 200);
314
+ /// #
315
+ /// # Ok(()) }
316
+ /// ```
317
+ pub async fn respond (
318
+ & self ,
319
+ req : impl Into < http_types:: Request > ,
320
+ ) -> http_types:: Result < http_types:: Response > {
321
+ let req = Request :: new ( self . state . clone ( ) , req. into ( ) , Vec :: new ( ) ) ;
322
+ match self . call ( req) . await {
323
+ Ok ( value) => {
324
+ let res = value. into ( ) ;
325
+ // We assume that if an error was manually cast to a
326
+ // Response that we actually want to send the body to the
327
+ // client. At this point we don't scrub the message.
328
+ Ok ( res)
329
+ }
330
+ Err ( err) => {
331
+ let mut res = http_types:: Response :: new ( err. status ( ) ) ;
332
+ res. set_content_type ( http_types:: mime:: PLAIN ) ;
333
+ // Only send the message if it is a non-500 range error. All
334
+ // errors default to 500 by default, so sending the error
335
+ // body is opt-in at the call site.
336
+ if !res. status ( ) . is_server_error ( ) {
337
+ res. set_body ( err. to_string ( ) ) ;
338
+ }
339
+ Ok ( res)
340
+ }
341
+ }
342
+ }
293
343
}
294
344
295
345
impl < State > Clone for Server < State > {
0 commit comments