1use crate::header::{Entry, HeaderMap, HeaderValue, OccupiedEntry};
2
3pub fn basic_auth<U, P>(username: U, password: Option<P>) -> HeaderValue
4where
5 U: std::fmt::Display,
6 P: std::fmt::Display,
7{
8 use base64::prelude::BASE64_STANDARD;
9 use base64::write::EncoderWriter;
10 use std::io::Write;
11
12 let mut buf: Vec = b"Basic ".to_vec();
13 {
14 let mut encoder: EncoderWriter<'_, GeneralPurpose, …> = EncoderWriter::new(&mut buf, &BASE64_STANDARD);
15 let _ = write!(encoder, "{username}:");
16 if let Some(password: P) = password {
17 let _ = write!(encoder, "{password}");
18 }
19 }
20 let mut header: HeaderValue = HeaderValue::from_bytes(&buf).expect(msg:"base64 is always valid HeaderValue");
21 header.set_sensitive(val:true);
22 header
23}
24
25// xor-shift
26#[cfg(not(target_arch = "wasm32"))]
27pub(crate) fn fast_random() -> u64 {
28 use std::cell::Cell;
29 use std::collections::hash_map::RandomState;
30 use std::hash::{BuildHasher, Hasher};
31 use std::num::Wrapping;
32
33 thread_local! {
34 static RNG: Cell<Wrapping<u64>> = Cell::new(Wrapping(seed()));
35 }
36
37 fn seed() -> u64 {
38 let seed = RandomState::new();
39
40 let mut out = 0;
41 let mut cnt = 0;
42 while out == 0 {
43 cnt += 1;
44 let mut hasher = seed.build_hasher();
45 hasher.write_usize(cnt);
46 out = hasher.finish();
47 }
48 out
49 }
50
51 RNG.with(|rng| {
52 let mut n = rng.get();
53 debug_assert_ne!(n.0, 0);
54 n ^= n >> 12;
55 n ^= n << 25;
56 n ^= n >> 27;
57 rng.set(n);
58 n.0.wrapping_mul(0x2545_f491_4f6c_dd1d)
59 })
60}
61
62pub(crate) fn replace_headers(dst: &mut HeaderMap, src: HeaderMap) {
63 // IntoIter of HeaderMap yields (Option<HeaderName>, HeaderValue).
64 // The first time a name is yielded, it will be Some(name), and if
65 // there are more values with the same name, the next yield will be
66 // None.
67
68 let mut prev_entry: Option<OccupiedEntry<_>> = None;
69 for (key, value) in src {
70 match key {
71 Some(key) => match dst.entry(key) {
72 Entry::Occupied(mut e) => {
73 e.insert(value);
74 prev_entry = Some(e);
75 }
76 Entry::Vacant(e) => {
77 let e = e.insert_entry(value);
78 prev_entry = Some(e);
79 }
80 },
81 None => match prev_entry {
82 Some(ref mut entry) => {
83 entry.append(value);
84 }
85 None => unreachable!("HeaderMap::into_iter yielded None first"),
86 },
87 }
88 }
89}
90