1use anyhow::Result;
2use tokio::io::{AsyncReadExt, AsyncWriteExt};
3
4pub async fn write_http_resp<T>(
5 stream: &mut T,
6 status: u16,
7 status_str: &str,
8 content: &str,
9 content_type: &str,
10) -> Result<()>
11where
12 T: AsyncReadExt + AsyncWriteExt + Unpin,
13{
14 let resp = construct_http_resp(status, status_str, content, content_type);
15 stream.write_all(resp.as_bytes()).await?;
16 Ok(())
17}
18
19pub fn construct_http_resp(
20 status: u16,
21 status_str: &str,
22 content: &str,
23 content_type: &str,
24) -> String {
25 format!(
26 "HTTP/1.1 {status} {status_str}\r\n\
27 Content-Length: {content_len}\r\n\
28 Content-Type: {content_type}\r\n\
29 Connection: close\r\n\
30 \r\n\
31 {content}",
32 content_len = content.len(),
33 )
34}
35
36pub fn construct_raw_http_resp(
37 status: u16,
38 status_str: &str,
39 content: &[u8],
40 content_type: &str,
41) -> Vec<u8> {
42 let response = format!(
43 "HTTP/1.1 {status} {status_str}\r\n\
44 Content-Length: {content_len}\r\n\
45 Content-Type: {content_type}\r\n\
46 Connection: close\r\n\
47 \r\n",
48 content_len = content.len(),
49 );
50
51 let mut result = response.into_bytes();
52 result.extend_from_slice(content);
53 result
54}
55
56pub fn construct_http_redirect(url: &str) -> String {
57 format!(
58 "HTTP/1.1 301 Moved Permanently\r\nLocation: {}\r\nContent-Length: 0\r\n\r\n",
59 url
60 )
61}