1use std::io::{Read, Write};
2use std::net::TcpStream;
3use std::error::Error;
4
5pub (crate) enum Method {
6 GET,
7 POST,
8 DELETE,
9}
10pub enum LocatorStrategy{
11 CSS(&'static str),
12 LINKTEXT(&'static str),
13 PARTLINKTEXT(&'static str),
14 TAGNAME(&'static str),
15 XPATH(&'static str)
16}
17pub(crate) fn send_request(ip:&str,port:&str,method: Method, path: &str, headers: Vec<String>, body: &str)->Result<String,Box<dyn Error>> {
18 let request = create_req(method, path, headers, body);
19 let address = format!("{}:{}",ip,port);
20 let mut connection = TcpStream::connect(address)?;
21 connection.write(request.as_bytes())?;
22 connection.flush()?;
23 let buf = read_response_to_vec_u8(connection).unwrap();
24 let st = String::from_utf8(buf).unwrap();
25 Ok(st)
26}
27pub(crate) fn send_request_screensh(method: Method, path: &str, headers: Vec<String>, body: &str)->Result<Vec<u8>,Box<dyn Error>> {
41 let request = create_req(method, path, headers, body);
42 let mut connection = TcpStream::connect("127.0.0.1:4444")?;
43 connection.write(request.as_bytes())?;
44 connection.flush()?;
45 Ok(read_response_screensh(connection)?)
46
47}
48
49pub(crate) fn resp_body(response: String)->Result<String,&'static str>{
50 let mut a = response.split("\r\n\r\n");
51 a.next();
52 if let Some(result) = a.next(){
53 return Ok(result.to_string())
54 } else {Err("Can't get the response body")}
55
56}
57pub (crate) fn send_and_read_body(ip:&str,port:&str,method: Method, path: &str, headers: Vec<String>, body: &str)->String{
58 resp_body(send_request(ip,port,method, path, headers, body).unwrap()).unwrap()
59}
60
61fn create_req(method: Method, path: &str, headers: Vec<String>, body: &str) -> String {
62 let mut request = match &method {
63 Method::GET => String::from("GET /"),
64 Method::POST => String::from("POST /"),
65 Method::DELETE => String::from("DELETE /"),
66 };
67 request.push_str(path);
68 request.push_str(" HTTP/1.1\r\n");
69 request.push_str("Host: 127.0.0.1\r\n");
70 if headers.len()>0{
71 for h in headers {
72 request.push_str(&h);
73 request.push_str("\r\n");
74 }
75 }
76 request.push_str("\r\n\r\n");
77 match method {
78 Method::POST => request.push_str(body),
79 _ => (),
80 }
81 request
82}
83fn create_remote_req(ip:&str, method: Method, path: &str, headers: Vec<String>, body: &str)->String {
84 let mut request = match &method {
85 Method::GET => String::from("GET /"),
86 Method::POST => String::from("POST /"),
87 Method::DELETE => String::from("DELETE /"),
88 };
89 request.push_str(path);
90 request.push_str(" HTTP/1.1\r\n");
91 request.push_str("Host: ");
92 request.push_str(ip);
93 request.push_str("\r\n");
94
95 if headers.len()>0{
96 for h in headers {
97 request.push_str(&h);
98 request.push_str("\r\n");
99 }
100 }
101 request.push_str("\r\n\r\n");
102 match method {
103 Method::POST => request.push_str(body),
104 _ => (),
105 }
106 request
107}
108
109fn read_response_to_vec_u8(mut stream: TcpStream)->Result<Vec<u8>,Box<dyn Error>>{
110 use std::thread;
111 use std::sync::mpsc;
112 let mut result_buf = vec![];
113 let mut temp_buf = vec![];
114 let (sender,receiver) = mpsc::channel();
115 std::thread::spawn(move || {
116 loop{
117 let mut b = vec![0;262144];
118 let bytes_num = stream.peek(&mut b).unwrap_or(0);
119 let mut buff = vec![0;bytes_num];
120 let _ = stream.read(&mut buff);
121 let _ = sender.send(buff);
122 }
123 });
124
125 let mut counter = 0;
126 let mut started = false;
127 loop{
128 if counter ==3 {
129 break;
130 }
131 if let Ok(a) = receiver.try_recv(){
132 temp_buf.push(a);
133 started = true;
134 }else if !started {
135 continue;
136 }else {
137 thread::sleep(std::time::Duration::from_millis(10));
138 counter+=1;}
139 }
140
141 for v in temp_buf{
142 for b in v{
143 result_buf.push(b);
144 }
145 }
146 Ok(result_buf)
147}
148fn read_response_screensh(mut stream: TcpStream) -> Result<Vec<u8>,Box<dyn Error>> {
149 use std::thread;
150 use std::sync::mpsc;
151 let mut result_buf = vec![];
152 let mut temp_buf = vec![];
153 let (sender,receiver) = mpsc::channel();
154 std::thread::spawn(move || {
155 loop{
156 let mut b = vec![0;262144];
157 let bytes_num = stream.peek(&mut b).unwrap_or(0);
158 let mut buff = vec![0;bytes_num];
159 let _ = stream.read(&mut buff);
160 let _ = sender.send(buff);
161 }
162 });
163
164 let mut counter = 0;
165 let mut started = false;
166 loop{
167 if counter ==3 {
168 break;
169 }
170 if let Ok(a) = receiver.try_recv(){
171 temp_buf.push(a);
172 started = true;
173 }else if !started {
174 continue;
175 }else {
176 thread::sleep(std::time::Duration::from_millis(10));
177 counter+=1;}
178 }
179
180 for v in temp_buf{
181 for b in v{
182 result_buf.push(b);
183 }
184 }
185 let len = result_buf.len();
186 let mut index = 0;
187 for i in 0..400{
188 if result_buf[i]==b"{"[0]&&
189 result_buf[i+1]==b"\""[0]&&
190 result_buf[i+2]==b"v"[0]&&
191 result_buf[i+3]==b"a"[0]&&
192 result_buf[i+4]==b"l"[0]{
193 index = i+9;
194 break;
195 }
196 }
197 let mut res = vec![];
198 res.extend_from_slice(&result_buf[index+1..len-2]);
199 Ok(res)
200}
201pub (crate) fn cont_length_header(content:&str)->Vec<String>{
202 vec![format!("Content-Length:{}",content.len()+2)]
203}
204pub (crate) fn body_for_find_element(loc_strategy:LocatorStrategy)->String{
205 match loc_strategy{
206 LocatorStrategy::CSS(selector)=>format!(r#"{{"using":"css selector","value":"{}"}}"#,selector),
207 LocatorStrategy::LINKTEXT(selector)=>format!(r#"{{"using":"link text","value":"{}"}}"#,selector),
208 LocatorStrategy::PARTLINKTEXT(selector)=>format!(r#"{{"using":"partial link text","value":"{}"}}"#,selector),
209 LocatorStrategy::TAGNAME(selector)=>format!(r#"{{"using":"tag name","value":"{}"}}"#,selector),
210 LocatorStrategy::XPATH(selector)=>format!(r#"{{"using":"xpath","value":"{}"}}"#,selector)
211 }
212}
213pub (crate) fn parse_value(body: &str)->String{
214 let resp = body.replace("\n","").replace(" ","").replace(r#"{"value":"#,"");
215 let mut resp_vec: Vec<char> = resp.chars().collect();
216 resp_vec.pop();
217 let result: String = resp_vec.iter().collect();
218 result
219}
220pub(crate) fn from_str_vec_to_str(vec: Vec<&str>)->String{
221 if vec.len() == 0 {return String::from("[]");}
222 let mut string_args = String::from("[");
223 for st in vec{
224 string_args.push('"');
225 string_args.push_str(st);
226 string_args.push('"');
227 string_args.push(',');
228 }
229 string_args.pop();
230 string_args.push(']');
231 string_args.push(',');
232 string_args
233}
234
235#[test]
237fn resp_body_extraction() {
238 let response = "I am the metadata\r\n\r\n{\"hi\":\"there\"}".to_string();
239 assert_eq!("{\"hi\":\"there\"}".to_string(),resp_body(response).unwrap());
240}
241#[test]
242fn delete_req_creation() {
243 let del_req = "DELETE /hello/you HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 130\r\n\r\n\r\n".to_string();
244 assert_eq!(
245 del_req,
246 create_req(
247 Method::DELETE,
248 "hello/you",
249 vec!["Content-Length: 130".to_string()],
250 "{dsd}"
251 )
252 );
253}
254#[test]
255fn get_req_creation() {
256 let del_req = "GET /hello/you HTTP/1.1\r\nHost: 127.0.0.1\r\nContent-Length: 130\r\n\r\n\r\n".to_string();
257 assert_eq!(
258 del_req,
259 create_req(
260 Method::GET,
261 "hello/you",
262 vec!["Content-Length: 130".to_string()],
263 "{dsd}"
264 )
265 );
266}
267#[test]
268fn ge_t_status(){
269 let response = send_request("127.0.0.1","4444",Method::GET, "wd/hub/status", vec![], "").unwrap();
270 assert!(response.contains("Server is running"));
271}