1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use crate::{
request::{Get, Post},
Request,
};
use cookie::Cookie;
use cookie_store::CookieStore;
use parking_lot::Mutex;
use std::{fmt::Write, slice, str, sync::Arc};
use url::Url;
use worker::Method;
#[derive(Clone, Default)]
pub struct Agent(Arc<AgentInner>);
impl Agent {
pub fn new() -> Self {
Default::default()
}
pub fn get(&self, url: Url) -> Request<Get> {
self.init_request(url, Method::Get, Get)
}
pub fn post(&self, url: Url) -> Request<Post> {
self.init_request(url, Method::Post, Post)
}
fn init_request<M>(&self, url: Url, method: Method, _marker: M) -> Request<M> {
Request::new(self.clone(), url, method, _marker)
}
pub(crate) fn get_request_cookies(&self, url: &Url) -> String {
let mut cookies = String::new();
for (name, value) in self.0.cookie_store.lock().get_request_values(url) {
write!(&mut cookies, "{name}={value}; ").unwrap();
}
cookies
}
pub(crate) fn store_response_cookies(&self, url: &Url, cookies: &str) {
let mut cookies = cookies.split_inclusive(',').peekable();
let mut pending = None;
let mut curr_part = cookies.next();
let mut next_part = cookies.peek();
while let Some(next_cookie) = next_part {
if let Ok(next_cookie) = Cookie::parse(*next_cookie) {
let new = pending
.or_else(|| curr_part.and_then(|curr_part| Cookie::parse(curr_part).ok()));
let _ = self.0.cookie_store.lock().insert_raw(&new.unwrap(), url);
pending = Some(next_cookie);
} else {
let ptr = curr_part.unwrap().as_ptr();
let len = curr_part.unwrap().len() + next_part.unwrap().len();
let curr_cookie =
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(ptr, len)) };
if let Ok(new) = Cookie::parse(curr_cookie) {
let _ = self.0.cookie_store.lock().insert_raw(&new, url);
}
cookies.next();
}
curr_part = cookies.next();
next_part = cookies.peek();
}
if let Some(new) = curr_part.and_then(|cookie| Cookie::parse(cookie).ok()) {
let _ = self.0.cookie_store.lock().insert_raw(&new, url);
}
}
}
#[derive(Default)]
struct AgentInner {
cookie_store: Mutex<CookieStore>,
}