1use std::net::TcpStream;
2
3use crate::handler::Handler;
4use crate::headers::Headers;
5use crate::http_message;
6use crate::http_message::{HttpMessage, read_message_from_wire, Request, RequestOptions, Response, with_content_length, write_message_to_wire};
7use crate::http_message::Body::{BodyString};
8
9impl Client {
10 pub fn new(base_uri: &str, port: u16, options: Option<ClientOptions>) -> Client {
11 Client {
12 base_uri: base_uri.to_string(),
13 port,
14 options: options.unwrap_or(ClientOptions {
15 headers_size: 16384,
16 trailers_size: 16384,
17 }),
18 err: "".to_string()
19 }
20 }
21}
22
23impl Handler for Client {
24 fn handle<F>(self: &mut Client, req: Request, fun: F) -> ()
25 where F: FnOnce(Response) -> () + Sized {
26 let uri = format!("{}:{}", self.base_uri, self.port);
27 let mut stream = TcpStream::connect(uri.clone()).unwrap();
28
29 let with_host_header = req.with_header(("Host", uri.as_str()));
30 write_message_to_wire(&mut stream, HttpMessage::Request(with_host_header), RequestOptions::default());
31
32 let mut reader: &mut [u8] = &mut [0; 4096];
33 let mut chunks_writer = Vec::with_capacity(1048576);
34 let mut compress_writer = Vec::with_capacity(1048576);
35 let mut start_line_writer = Vec::with_capacity(16384);
36 let mut headers_writer = Vec::with_capacity(16384);
37 let mut trailers_writer = Vec::with_capacity(16384);
38
39 let result = read_message_from_wire(
40 stream.try_clone().unwrap(),
41 &mut reader,
42 &mut start_line_writer,
43 &mut headers_writer,
44 &mut chunks_writer,
45 &mut compress_writer,
46 &mut trailers_writer
47 );
48
49 let response = match result {
50 Ok(http_message::HttpMessage::Response(res)) => res,
51 Err(e) => {
52 self.err = e.to_string();
53 Response::bad_request(Headers::empty(), BodyString(self.err.as_str()))
54 },
55 _ => Response::bad_request(Headers::empty(), BodyString("will happen if server replies with invalid response"))
56 };
57
58 fun(response)
59 }
60}
61
62pub struct Client {
63 pub base_uri: String,
64 pub port: u16,
65 options: ClientOptions,
66 pub err: String,
67}
68
69pub struct ClientOptions {
70 headers_size: usize,
71 trailers_size: usize,
72}
73
74pub struct WithContentLength<H> where H: Handler {
75 next_handler: H,
76}
77
78impl<H> WithContentLength<H> where H: Handler {
79 pub fn new(next_handler: H) -> WithContentLength<H> {
80 WithContentLength {
81 next_handler
82 }
83 }
84}
85
86impl<H> Handler for WithContentLength<H> where H: Handler {
87 fn handle<F>(self: &mut WithContentLength<H>, req: Request, fun: F) -> ()
88 where F: FnOnce(Response) -> () + Sized {
89 let request = with_content_length(HttpMessage::Request(req)).to_req();
90 self.next_handler.handle(request, |res| {
91 fun(res)
92 })
93 }
94}