rust_rcs_core/http/
request.rs

1// Copyright 2023 宋昊文
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15extern crate url;
16
17use std::io::Read;
18use std::str;
19
20use crate::internet::Body;
21use crate::io::{BytesReader, Serializable};
22
23use crate::internet::header::{headers_get_readers, Header};
24
25pub const GET: &[u8] = b"GET";
26pub const POST: &[u8] = b"POST";
27pub const PUT: &[u8] = b"PUT";
28pub const DELETE: &[u8] = b"DELETE";
29pub const HEAD: &[u8] = b"HEAD";
30pub const CONNECT: &[u8] = b"CONNECT";
31
32pub struct Request {
33    pub method: &'static [u8],
34    pub reference: String,
35    pub headers: Vec<Header>,
36    pub body: Option<Body>,
37}
38
39impl Request {
40    pub fn new_with_default_headers(
41        method: &'static [u8],
42        host: &str,
43        path: &str,
44        query: Option<&str>,
45    ) -> Request {
46        let mut headers = Vec::new();
47
48        headers.push(Header::new(b"Host", String::from(host)));
49
50        headers.push(Header::new(b"Accept", "*/*"));
51
52        headers.push(Header::new(b"Cache-Control", "no-cache"));
53
54        headers.push(Header::new(b"User-Agent", "CPM-client/OMA2.2 RCS-client/UP_2.4 term-Hisense/HNR550T-9 client-Rusty/1.0.0 OS-Android/9 Channel-terminal-000000 Channel-client-000000 3gpp-gba"));
55
56        if let Some(query) = query {
57            Request {
58                method,
59                reference: format!("{}?{}", path, query),
60                headers,
61                body: None,
62            }
63        } else {
64            Request {
65                method,
66                reference: String::from(path),
67                headers,
68                body: None,
69            }
70        }
71    }
72
73    pub fn get_readers<'a>(&'a self, readers: &mut Vec<Box<dyn Read + Send + 'a>>) {
74        readers.push(Box::new(BytesReader::new(self.method)));
75        readers.push(Box::new(BytesReader::new(b" ")));
76        readers.push(Box::new(self.reference.as_bytes()));
77        readers.push(Box::new(&b" HTTP/1.1\r\n"[..]));
78
79        headers_get_readers(&self.headers, readers);
80
81        readers.push(Box::new(&b"\r\n"[..]));
82    }
83}
84
85impl Serializable for Request {
86    fn estimated_size(&self) -> usize {
87        let mut size = 0;
88
89        size += self.method.len();
90        size += 1;
91        size += self.reference.as_bytes().len();
92        size += 11;
93
94        size += self.headers.estimated_size();
95
96        size += 2;
97
98        size
99    }
100}