我试图在Rust上实现简单的tcp/http服务器。主要特点是可以通过url从服务器下载文件。exapmple: localhost:端口/root_storage someFile.fileExt
主要功能:
fn main() {
let tcp_listener = TcpListener::bind("127.0.0.1:7000").unwrap();
println!("Server starded!");
for stream in tcp_listener.incoming()
{
let stream = stream.unwrap();
handle_connection(stream);
}
}
我正在接收tcpStream请求,解析以获取传入url等。然后我试着发送一些文件回浏览器并在客户端下载他。
if http_request[0].contains("storage/10mb.pdf") {
status_line = "HTTP/1.1 200 OK";
let buf_content = fs::read("storage/10mb.pdf").unwrap();
let contents = unsafe {String::from_utf8_unchecked(buf_content)};
length = contents.len();
response = format!("{status_line}rn
Content-Disposition: attachment; filename="10mb.pdf"rn
Content-Type: application/pdfrn
Content-Length: {length}rnrn
{contents}");
}
可以,但只能是pdf格式
这段代码不会下载文件,只是在浏览器中显示文件的内容:
else if http_request[0].contains("storage/10mb.txt") {
status_line = "HTTP/1.1 200 OK";
let buf_content = fs::read("storage/10mb.txt").unwrap();
let contents = unsafe {String::from_utf8_unchecked(buf_content)};
length = contents.len();
response = format!("{status_line}rn
Content-Disposition: attachment; filename="10mb.txt"rn
Content-Type: application/octet-streamrn
Content-Length: {length}rnrn
{contents}");
stream.write_all(response.as_bytes()).unwrap();
stream.flush().unwrap();
我的假设是在内容编码。我不知道为什么- Content-Disposition和其他标头根本不起作用。如果我从pdf案例中删除Content-Disposition。无论如何,它都会下载文件。
我的实现出了什么问题?可能是我编码内容的方式不对或其他什么?
乌利希期刊指南:有这个,但也没有效果
if http_request[0].contains("storage/10mb.pdf") {
status_line = "HTTP/1.1 200 OK";
let buf_content = fs::read("storage/10mb.pdf").unwrap();
length = buf_content.len();
response = format!("{status_line}rn
Content-Disposition: attachment; filename="10mb.pdf"rn
Content-Type: application/pdfrn
Content-Length: {length}rnrn");
stream.write_all(response.as_bytes()).unwrap();
stream.write_all(&buf_content).unwrap();
stream.flush().unwrap();
}
else if http_request[0].contains("storage/10mb.txt") {
status_line = "HTTP/1.1 200 OK";
let buf_content = fs::read("storage/10mb.txt").unwrap();
length = buf_content.len();
response = format!("{status_line}rn
Content-Disposition: attachment; filename="10mb.txt"rn
Content-Type: text/plainrn
Content-Length: {length}rnrn");
stream.write_all(response.as_bytes()).unwrap();
stream.write_all(&buf_content).unwrap();
stream.flush().unwrap();
}
我认为多行文本文本有问题。
每一行包含一个隐式n
后显式rn
和下一行开始之前的许多空间选项名称。
当浏览器收到这个回复头时,它不理解它,可能会试图显示所有内容…
如果您以结束行(后面没有任何内容,甚至没有空格),那么只有您的显式
rn
将结束行,并且前导空格将被丢弃。
response = format!("{status_line}rn
Content-Disposition: attachment; filename="10mb.txt"rn
Content-Type: text/plainrn
Content-Length: {length}rnrn");