Hex Artifact Content
Logged in as anonymous

Artifact fcb6cd99e3e59aa161d3bce4fbd3db80c0ea7b6e6509b82bdd462c7b8304fb60:


0000: 2f 2f 21 20 53 69 6d 70 6c 65 20 53 4d 54 50 2d  //! Simple SMTP-
0010: 74 6f 2d 54 65 6c 65 67 72 61 6d 20 67 61 74 65  to-Telegram gate
0020: 77 61 79 2e 20 43 61 6e 20 70 61 72 73 65 20 65  way. Can parse e
0030: 6d 61 69 6c 20 61 6e 64 20 73 65 6e 64 20 74 68  mail and send th
0040: 65 6d 20 61 73 20 74 65 6c 65 67 72 61 6d 0a 2f  em as telegram./
0050: 2f 21 20 6d 65 73 73 61 67 65 73 20 74 6f 20 73  /! messages to s
0060: 70 65 63 69 66 69 65 64 20 63 68 61 74 73 2c 20  pecified chats, 
0070: 67 65 6e 65 72 61 6c 6c 79 20 79 6f 75 20 73 70  generally you sp
0080: 65 63 69 66 79 20 77 68 69 63 68 20 65 6d 61 69  ecify which emai
0090: 6c 20 61 64 64 72 65 73 73 20 69 73 0a 2f 2f 21  l address is.//!
00a0: 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 63 6f   available in co
00b0: 6e 66 69 67 75 72 61 74 69 6f 6e 2c 20 65 76 65  nfiguration, eve
00c0: 72 79 74 68 69 6e 67 20 65 6c 73 65 20 69 73 20  rything else is 
00d0: 73 65 6e 74 20 74 6f 20 64 65 66 61 75 6c 74 20  sent to default 
00e0: 61 64 64 72 65 73 73 2e 0a 0a 75 73 65 20 73 74  address...use st
00f0: 64 3a 3a 7b 0a 09 6f 73 3a 3a 75 6e 69 78 3a 3a  d::{..os::unix::
0100: 66 73 3a 3a 50 65 72 6d 69 73 73 69 6f 6e 73 45  fs::PermissionsE
0110: 78 74 2c 0a 09 70 61 74 68 3a 3a 50 61 74 68 2c  xt,..path::Path,
0120: 0a 7d 3b 0a 0a 75 73 65 20 63 6c 61 70 3a 3a 50  .};..use clap::P
0130: 61 72 73 65 72 3b 0a 75 73 65 20 73 6d 6f 6c 3a  arser;.use smol:
0140: 3a 66 73 3a 3a 6d 65 74 61 64 61 74 61 3b 0a 75  :fs::metadata;.u
0150: 73 65 20 73 74 61 63 6b 65 64 5f 65 72 72 6f 72  se stacked_error
0160: 73 3a 3a 7b 0a 09 52 65 73 75 6c 74 2c 0a 09 53  s::{..Result,..S
0170: 74 61 63 6b 61 62 6c 65 45 72 72 2c 0a 09 62 61  tackableErr,..ba
0180: 69 6c 2c 0a 7d 3b 0a 0a 75 73 65 20 73 6d 74 70  il,.};..use smtp
0190: 32 74 67 3a 3a 6d 61 69 6c 3a 3a 4d 61 69 6c 53  2tg::mail::MailS
01a0: 65 72 76 65 72 3b 0a 0a 2f 2f 2f 20 53 4d 54 50  erver;../// SMTP
01b0: 2d 74 6f 2d 54 65 6c 65 67 72 61 6d 20 67 61 74  -to-Telegram gat
01c0: 65 77 61 79 0a 23 5b 64 65 72 69 76 65 28 50 61  eway.#[derive(Pa
01d0: 72 73 65 72 2c 20 44 65 62 75 67 29 5d 0a 23 5b  rser, Debug)].#[
01e0: 63 6f 6d 6d 61 6e 64 28 6e 61 6d 65 20 3d 20 22  command(name = "
01f0: 73 6d 74 70 32 74 67 22 29 5d 0a 23 5b 63 6f 6d  smtp2tg")].#[com
0200: 6d 61 6e 64 28 61 62 6f 75 74 20 3d 20 66 6f 72  mand(about = for
0210: 6d 61 74 21 28 22 53 4d 54 50 2d 74 6f 2d 54 65  mat!("SMTP-to-Te
0220: 6c 65 67 72 61 6d 20 67 61 74 65 77 61 79 20 76  legram gateway v
0230: 7b 7d 2c 20 28 43 29 20 32 30 32 34 20 2d 20 32  {}, (C) 2024 - 2
0240: 30 32 36 22 2c 20 65 6e 76 21 28 22 43 41 52 47  026", env!("CARG
0250: 4f 5f 50 4b 47 5f 56 45 52 53 49 4f 4e 22 29 29  O_PKG_VERSION"))
0260: 2c 20 6c 6f 6e 67 5f 61 62 6f 75 74 20 3d 20 4e  , long_about = N
0270: 6f 6e 65 29 5d 0a 73 74 72 75 63 74 20 41 72 67  one)].struct Arg
0280: 73 20 7b 0a 09 2f 2f 2f 20 53 65 74 20 63 6f 6e  s {../// Set con
0290: 66 69 67 75 72 61 74 69 6f 6e 20 66 69 6c 65 20  figuration file 
02a0: 6c 6f 63 61 74 69 6f 6e 0a 09 23 5b 61 72 67 28  location..#[arg(
02b0: 73 68 6f 72 74 2c 20 6c 6f 6e 67 2c 20 64 65 66  short, long, def
02c0: 61 75 6c 74 5f 76 61 6c 75 65 20 3d 20 22 73 6d  ault_value = "sm
02d0: 74 70 32 74 67 2e 74 6f 6d 6c 22 29 5d 0a 09 63  tp2tg.toml")]..c
02e0: 6f 6e 66 69 67 3a 20 53 74 72 69 6e 67 2c 0a 7d  onfig: String,.}
02f0: 0a 0a 2f 2f 2f 20 4d 61 69 6e 20 61 73 79 6e 63  ../// Main async
0300: 68 72 6f 6e 6f 75 73 20 65 6e 74 72 79 20 70 6f  hronous entry po
0310: 69 6e 74 20 66 6f 72 20 74 68 65 20 61 70 70 6c  int for the appl
0320: 69 63 61 74 69 6f 6e 2e 20 52 75 6e 73 20 74 68  ication. Runs th
0330: 65 20 67 61 74 65 77 61 79 20 75 73 69 6e 67 0a  e gateway using.
0340: 2f 2f 2f 20 74 68 65 20 63 6f 6e 66 69 67 75 72  /// the configur
0350: 61 74 69 6f 6e 20 73 65 6c 65 63 74 65 64 20 6f  ation selected o
0360: 6e 20 74 68 65 20 63 6f 6d 6d 61 6e 64 20 6c 69  n the command li
0370: 6e 65 2e 0a 2f 2f 2f 0a 2f 2f 2f 20 54 68 65 20  ne..///./// The 
0380: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 66 69  configuration fi
0390: 6c 65 20 6d 75 73 74 20 75 73 65 20 6f 77 6e 65  le must use owne
03a0: 72 2d 6f 6e 6c 79 20 70 65 72 6d 69 73 73 69 6f  r-only permissio
03b0: 6e 73 2e 20 4f 6e 63 65 20 63 6f 6e 66 69 67 75  ns. Once configu
03c0: 72 65 64 2c 0a 2f 2f 2f 20 74 68 65 20 53 4d 54  red,./// the SMT
03d0: 50 20 73 65 72 76 65 72 20 72 75 6e 73 20 75 6e  P server runs un
03e0: 74 69 6c 20 69 74 20 73 74 6f 70 73 20 6f 72 20  til it stops or 
03f0: 65 6e 63 6f 75 6e 74 65 72 73 20 61 6e 20 65 72  encounters an er
0400: 72 6f 72 2e 0a 2f 2f 2f 0a 2f 2f 2f 20 23 20 45  ror..///./// # E
0410: 72 72 6f 72 73 0a 2f 2f 2f 20 52 65 74 75 72 6e  rrors./// Return
0420: 73 20 61 6e 20 65 72 72 6f 72 20 69 66 20 74 68  s an error if th
0430: 65 20 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20  e configuration 
0440: 66 69 6c 65 20 69 73 20 6d 69 73 73 69 6e 67 2c  file is missing,
0450: 20 69 6e 61 63 63 65 73 73 69 62 6c 65 2c 0a 2f   inaccessible,./
0460: 2f 2f 20 69 6e 73 65 63 75 72 65 2c 20 6d 61 6c  // insecure, mal
0470: 66 6f 72 6d 65 64 2c 20 6f 72 20 63 6f 6e 74 61  formed, or conta
0480: 69 6e 73 20 69 6e 76 61 6c 69 64 20 72 65 71 75  ins invalid requ
0490: 69 72 65 64 20 73 65 74 74 69 6e 67 73 2e 0a 2f  ired settings../
04a0: 2f 2f 20 41 6c 73 6f 20 72 65 74 75 72 6e 73 20  // Also returns 
04b0: 61 6e 20 65 72 72 6f 72 20 69 66 20 74 68 65 20  an error if the 
04c0: 73 79 73 74 65 6d 20 68 6f 73 74 6e 61 6d 65 20  system hostname 
04d0: 63 61 6e 6e 6f 74 20 62 65 20 72 65 61 64 20 6f  cannot be read o
04e0: 72 20 69 73 20 6e 6f 74 0a 2f 2f 2f 20 76 61 6c  r is not./// val
04f0: 69 64 20 55 54 46 2d 38 2c 20 6f 72 20 69 66 20  id UTF-8, or if 
0500: 6d 61 69 6c 20 73 65 72 76 65 72 20 69 6e 69 74  mail server init
0510: 69 61 6c 69 73 61 74 69 6f 6e 20 66 61 69 6c 73  ialisation fails
0520: 2e 0a 2f 2f 2f 0a 2f 2f 2f 20 23 20 50 61 6e 69  ..///./// # Pani
0530: 63 73 0a 2f 2f 2f 20 50 61 6e 69 63 73 20 69 66  cs./// Panics if
0540: 20 63 6f 6e 66 69 67 75 72 69 6e 67 20 6f 72 20   configuring or 
0550: 73 65 72 76 69 6e 67 20 74 68 65 20 53 4d 54 50  serving the SMTP
0560: 20 73 65 72 76 65 72 20 66 61 69 6c 73 2e 0a 66   server fails..f
0570: 6e 20 6d 61 69 6e 20 28 29 20 2d 3e 20 52 65 73  n main () -> Res
0580: 75 6c 74 3c 28 29 3e 20 7b 0a 09 73 6d 6f 6c 3a  ult<()> {..smol:
0590: 3a 62 6c 6f 63 6b 5f 6f 6e 28 61 73 79 6e 63 20  :block_on(async 
05a0: 6d 6f 76 65 7b 0a 09 09 6c 65 74 20 61 72 67 73  move{...let args
05b0: 20 3d 20 41 72 67 73 3a 3a 70 61 72 73 65 28 29   = Args::parse()
05c0: 3b 0a 09 09 6c 65 74 20 73 65 74 74 69 6e 67 73  ;...let settings
05d0: 20 3d 20 7b 0a 09 09 09 2f 2f 20 4c 6f 61 64 20   = {....// Load 
05e0: 63 6f 6e 66 69 67 75 72 61 74 69 6f 6e 20 64 65  configuration de
05f0: 66 61 75 6c 74 73 20 61 6e 64 20 6f 76 65 72 72  faults and overr
0600: 69 64 65 73 20 61 66 74 65 72 20 63 68 65 63 6b  ides after check
0610: 69 6e 67 20 66 69 6c 65 20 70 65 72 6d 69 73 73  ing file permiss
0620: 69 6f 6e 73 2e 0a 09 09 09 6c 65 74 20 63 6f 6e  ions.....let con
0630: 66 69 67 5f 66 69 6c 65 20 3d 20 50 61 74 68 3a  fig_file = Path:
0640: 3a 6e 65 77 28 26 61 72 67 73 2e 63 6f 6e 66 69  :new(&args.confi
0650: 67 29 3b 0a 09 09 09 69 66 20 21 63 6f 6e 66 69  g);....if !confi
0660: 67 5f 66 69 6c 65 2e 74 72 79 5f 65 78 69 73 74  g_file.try_exist
0670: 73 28 29 2e 73 74 61 63 6b 28 29 3f 20 7b 0a 09  s().stack()? {..
0680: 09 09 09 62 61 69 6c 21 28 22 43 6f 6e 66 69 67  ...bail!("Config
0690: 75 72 61 74 69 6f 6e 20 66 69 6c 65 20 6e 6f 74  uration file not
06a0: 20 66 6f 75 6e 64 3a 20 7b 63 6f 6e 66 69 67 5f   found: {config_
06b0: 66 69 6c 65 3a 3f 7d 5c 6e 5c 0a 09 09 09 09 09  file:?}\n\......
06c0: 48 69 6e 74 3a 20 45 6e 73 75 72 65 20 74 68 65  Hint: Ensure the
06d0: 20 66 69 6c 65 20 65 78 69 73 74 73 20 61 6e 64   file exists and
06e0: 20 74 68 65 20 70 61 74 68 20 69 73 20 63 6f 72   the path is cor
06f0: 72 65 63 74 2e 22 29 3b 0a 09 09 09 7d 3b 0a 09  rect.");....};..
0700: 09 09 7b 0a 09 09 09 09 6c 65 74 20 6d 65 74 61  ..{.....let meta
0710: 20 3d 20 6d 65 74 61 64 61 74 61 28 63 6f 6e 66   = metadata(conf
0720: 69 67 5f 66 69 6c 65 29 2e 61 77 61 69 74 2e 73  ig_file).await.s
0730: 74 61 63 6b 28 29 3f 3b 0a 09 09 09 09 69 66 20  tack()?;.....if 
0740: 28 21 30 6f 31 30 30 36 30 30 20 26 20 6d 65 74  (!0o100600 & met
0750: 61 2e 70 65 72 6d 69 73 73 69 6f 6e 73 28 29 2e  a.permissions().
0760: 6d 6f 64 65 28 29 29 20 3e 20 30 20 7b 0a 09 09  mode()) > 0 {...
0770: 09 09 09 62 61 69 6c 21 28 22 43 6f 6e 66 69 67  ...bail!("Config
0780: 75 72 61 74 69 6f 6e 20 66 69 6c 65 20 70 65 72  uration file per
0790: 6d 69 73 73 69 6f 6e 73 20 61 72 65 20 69 6e 73  missions are ins
07a0: 65 63 75 72 65 20 7b 63 6f 6e 66 69 67 5f 66 69  ecure {config_fi
07b0: 6c 65 3a 3f 7d 5c 6e 5c 0a 09 09 09 09 09 09 43  le:?}\n\.......C
07c0: 75 72 72 65 6e 74 20 70 65 72 6d 69 73 73 69 6f  urrent permissio
07d0: 6e 73 3a 20 7b 3a 6f 7d 5c 6e 5c 0a 09 09 09 09  ns: {:o}\n\.....
07e0: 09 09 52 65 71 75 69 72 65 64 3a 20 30 36 30 30  ..Required: 0600
07f0: 20 28 6f 77 6e 65 72 20 72 65 61 64 2f 77 72 69   (owner read/wri
0800: 74 65 20 6f 6e 6c 79 29 2e 5c 6e 5c 0a 09 09 09  te only).\n\....
0810: 09 09 09 46 69 78 20 77 69 74 68 3a 20 63 68 6d  ...Fix with: chm
0820: 6f 64 20 36 30 30 20 7b 63 6f 6e 66 69 67 5f 66  od 600 {config_f
0830: 69 6c 65 3a 3f 7d 22 2c 0a 09 09 09 09 09 09 6d  ile:?}",.......m
0840: 65 74 61 2e 70 65 72 6d 69 73 73 69 6f 6e 73 28  eta.permissions(
0850: 29 2e 6d 6f 64 65 28 29 29 3b 0a 09 09 09 7d 09  ).mode());....}.
0860: 7d 0a 09 09 09 63 6f 6e 66 69 67 3a 3a 43 6f 6e  }....config::Con
0870: 66 69 67 3a 3a 62 75 69 6c 64 65 72 28 29 0a 09  fig::builder()..
0880: 09 09 09 2e 73 65 74 5f 64 65 66 61 75 6c 74 28  ....set_default(
0890: 22 61 70 69 5f 67 61 74 65 77 61 79 22 2c 20 22  "api_gateway", "
08a0: 68 74 74 70 73 3a 2f 2f 61 70 69 2e 74 65 6c 65  https://api.tele
08b0: 67 72 61 6d 2e 6f 72 67 22 29 2e 73 74 61 63 6b  gram.org").stack
08c0: 28 29 3f 0a 09 09 09 09 2e 73 65 74 5f 64 65 66  ()?......set_def
08d0: 61 75 6c 74 28 22 66 69 65 6c 64 73 22 2c 20 76  ault("fields", v
08e0: 65 63 21 5b 22 64 61 74 65 22 2c 20 22 66 72 6f  ec!["date", "fro
08f0: 6d 22 2c 20 22 73 75 62 6a 65 63 74 22 5d 29 2e  m", "subject"]).
0900: 73 74 61 63 6b 28 29 3f 0a 09 09 09 09 2e 73 65  stack()?......se
0910: 74 5f 64 65 66 61 75 6c 74 28 22 68 6f 73 74 6e  t_default("hostn
0920: 61 6d 65 22 2c 20 22 73 6d 74 70 2e 32 2e 74 67  ame", "smtp.2.tg
0930: 22 29 2e 73 74 61 63 6b 28 29 3f 0a 09 09 09 09  ").stack()?.....
0940: 2e 73 65 74 5f 64 65 66 61 75 6c 74 28 22 6c 69  .set_default("li
0950: 73 74 65 6e 5f 6f 6e 22 2c 20 22 30 2e 30 2e 30  sten_on", "0.0.0
0960: 2e 30 3a 31 30 32 35 22 29 2e 73 74 61 63 6b 28  .0:1025").stack(
0970: 29 3f 0a 09 09 09 09 2e 73 65 74 5f 64 65 66 61  )?......set_defa
0980: 75 6c 74 28 22 64 6f 6d 61 69 6e 73 22 2c 20 76  ult("domains", v
0990: 65 63 21 5b 22 6c 6f 63 61 6c 68 6f 73 74 22 2c  ec!["localhost",
09a0: 0a 09 09 09 09 09 68 6f 73 74 6e 61 6d 65 3a 3a  ......hostname::
09b0: 67 65 74 28 29 2e 63 6f 6e 74 65 78 74 28 22 46  get().context("F
09c0: 61 69 6c 65 64 20 74 6f 20 67 65 74 20 63 75 72  ailed to get cur
09d0: 72 65 6e 74 20 68 6f 73 74 6e 61 6d 65 22 29 3f  rent hostname")?
09e0: 0a 09 09 09 09 09 2e 74 6f 5f 73 74 72 28 29 2e  .......to_str().
09f0: 63 6f 6e 74 65 78 74 28 22 43 61 6e 27 74 20 63  context("Can't c
0a00: 6f 6e 76 65 72 74 20 68 6f 73 74 6e 61 6d 65 20  onvert hostname 
0a10: 74 6f 20 73 74 72 69 6e 67 2c 20 62 61 64 20 55  to string, bad U
0a20: 54 46 2d 38 3f 22 29 3f 5d 29 2e 73 74 61 63 6b  TF-8?")?]).stack
0a30: 28 29 3f 0a 09 09 09 09 2e 61 64 64 5f 73 6f 75  ()?......add_sou
0a40: 72 63 65 28 63 6f 6e 66 69 67 3a 3a 46 69 6c 65  rce(config::File
0a50: 3a 3a 66 72 6f 6d 28 63 6f 6e 66 69 67 5f 66 69  ::from(config_fi
0a60: 6c 65 29 29 0a 09 09 09 09 2e 62 75 69 6c 64 28  le))......build(
0a70: 29 0a 09 09 09 09 2e 77 69 74 68 5f 63 6f 6e 74  )......with_cont
0a80: 65 78 74 28 7c 7c 20 66 6f 72 6d 61 74 21 28 0a  ext(|| format!(.
0a90: 09 09 09 09 09 22 46 61 69 6c 65 64 20 74 6f 20  ....."Failed to 
0aa0: 70 61 72 73 65 20 63 6f 6e 66 69 67 75 72 61 74  parse configurat
0ab0: 69 6f 6e 20 66 69 6c 65 3a 20 7b 63 6f 6e 66 69  ion file: {confi
0ac0: 67 5f 66 69 6c 65 3a 3f 7d 5c 6e 5c 0a 09 09 09  g_file:?}\n\....
0ad0: 09 09 43 68 65 63 6b 20 73 79 6e 74 61 78 20 61  ..Check syntax a
0ae0: 67 61 69 6e 73 74 20 73 6d 74 70 32 74 67 2e 74  gainst smtp2tg.t
0af0: 6f 6d 6c 2e 65 78 61 6d 70 6c 65 2e 5c 6e 5c 0a  oml.example.\n\.
0b00: 09 09 09 09 09 43 6f 6d 6d 6f 6e 20 69 73 73 75  .....Common issu
0b10: 65 73 3a 20 6d 69 73 73 69 6e 67 20 71 75 6f 74  es: missing quot
0b20: 65 73 2c 20 74 72 61 69 6c 69 6e 67 20 63 6f 6d  es, trailing com
0b30: 6d 61 73 20 69 6e 20 69 6e 6c 69 6e 65 20 74 61  mas in inline ta
0b40: 62 6c 65 73 2c 20 6f 72 20 69 6e 76 61 6c 69 64  bles, or invalid
0b50: 20 74 79 70 65 73 2e 22 0a 09 09 09 09 29 29 3f   types.".....))?
0b60: 0a 09 09 7d 3b 0a 0a 09 09 6c 65 74 20 6c 69 73  ...};....let lis
0b70: 74 65 6e 5f 6f 6e 20 3d 20 73 65 74 74 69 6e 67  ten_on = setting
0b80: 73 2e 67 65 74 5f 73 74 72 69 6e 67 28 22 6c 69  s.get_string("li
0b90: 73 74 65 6e 5f 6f 6e 22 29 2e 73 74 61 63 6b 28  sten_on").stack(
0ba0: 29 3f 3b 0a 09 09 6c 65 74 20 73 65 72 76 65 72  )?;...let server
0bb0: 5f 6e 61 6d 65 20 3d 20 73 65 74 74 69 6e 67 73  _name = settings
0bc0: 2e 67 65 74 5f 73 74 72 69 6e 67 28 22 68 6f 73  .get_string("hos
0bd0: 74 6e 61 6d 65 22 29 2e 73 74 61 63 6b 28 29 3f  tname").stack()?
0be0: 3b 0a 09 09 6c 65 74 20 63 6f 72 65 20 3d 20 4d  ;...let core = M
0bf0: 61 69 6c 53 65 72 76 65 72 3a 3a 6e 65 77 28 73  ailServer::new(s
0c00: 65 74 74 69 6e 67 73 29 3f 3b 0a 09 09 6c 65 74  ettings)?;...let
0c10: 20 6d 75 74 20 73 65 72 76 65 72 20 3d 20 6d 61   mut server = ma
0c20: 69 6c 69 6e 5f 65 6d 62 65 64 64 65 64 3a 3a 53  ilin_embedded::S
0c30: 65 72 76 65 72 3a 3a 6e 65 77 28 63 6f 72 65 29  erver::new(core)
0c40: 3b 0a 0a 09 09 2f 2f 20 54 4f 44 4f 3a 20 72 65  ;....// TODO: re
0c50: 6d 6f 76 65 20 75 6e 77 72 61 70 73 20 77 68 65  move unwraps whe
0c60: 6e 20 6d 61 69 6c 69 6e 2d 65 6d 62 65 64 64 65  n mailin-embedde
0c70: 64 20 62 75 6d 70 73 20 77 69 74 68 20 62 65 74  d bumps with bet
0c80: 74 65 72 20 65 72 72 6f 72 20 68 61 6e 64 6c 69  ter error handli
0c90: 6e 67 0a 09 09 73 65 72 76 65 72 2e 77 69 74 68  ng...server.with
0ca0: 5f 6e 61 6d 65 28 73 65 72 76 65 72 5f 6e 61 6d  _name(server_nam
0cb0: 65 29 0a 09 09 09 2e 77 69 74 68 5f 73 73 6c 28  e).....with_ssl(
0cc0: 6d 61 69 6c 69 6e 5f 65 6d 62 65 64 64 65 64 3a  mailin_embedded:
0cd0: 3a 53 73 6c 43 6f 6e 66 69 67 3a 3a 4e 6f 6e 65  :SslConfig::None
0ce0: 29 2e 75 6e 77 72 61 70 28 29 0a 09 09 09 2e 77  ).unwrap().....w
0cf0: 69 74 68 5f 61 64 64 72 28 6c 69 73 74 65 6e 5f  ith_addr(listen_
0d00: 6f 6e 29 2e 75 6e 77 72 61 70 28 29 0a 09 09 09  on).unwrap()....
0d10: 2e 77 69 74 68 5f 6e 75 6d 5f 74 68 72 65 61 64  .with_num_thread
0d20: 73 28 31 29 3b 0a 09 09 73 65 72 76 65 72 2e 73  s(1);...server.s
0d30: 65 72 76 65 28 29 2e 75 6e 77 72 61 70 28 29 3b  erve().unwrap();
0d40: 0a 0a 09 09 4f 6b 28 28 29 29 0a 09 7d 29 0a 7d  ....Ok(())..}).}
0d50: 0a                                               .