如何通过TcpStream发送.jpg作为HTTP?

Fro*_*age 0 tcp http rust

我试着写一个静态的HTTP文件服务器,但是当我尝试发送.jpg文件时我就陷入了困境TcpStream.

即使我read将文件作为二进制文件,浏览器似乎也无法解码图像:

extern crate chunked_transfer;
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::thread;
use std::fs::File;
use chunked_transfer::Encoder;

fn main() {
    let listener = TcpListener::bind("127.0.0.1:9527").unwrap();
    println!("Listening for connections on port {}", 9527);
    for stream in listener.incoming() {
        match stream {
            Ok(stream) => {
                thread::spawn(|| handle_client(stream));
            }
            Err(e) => println!("Unable to connect: {}", e),
        }
    }
}

fn get_path(mut stream: &TcpStream) -> String {
    let mut buf = [0u8; 4096];
    match stream.read(&mut buf) {
        Ok(_) => {
            let req_str = String::from_utf8_lossy(&buf);
            let path: Vec<&str> = req_str.lines().next().unwrap().split(" ").collect();
            println!("GET {}", path[1]);
            // println!("{}", req_str);
            path[1].to_string()
        }
        Err(e) => {
            println!("Unable to read stream: {}", e);
            "/".to_string()
        }
    }
}

fn response(path: &str, mut stream: TcpStream) {
    let file_path: &str = &("/home/xinbg/Downloads/wallpaper".to_string() + path);
    println!("{}", file_path);
    let mut buf = vec![0u8];
    let file = File::open(file_path);
    file.unwrap().read_to_end(&mut buf);

    let mut encoded: Vec<u8> = vec![];
    {
        let mut encoder = Encoder::with_chunks_size(&mut encoded, 8);
        encoder.write_all(&buf);
    }

    let headers =
        ["HTTP/1.1 200 OK", "Content-type: image/jpeg", "Transfer-Encoding: chunked", "\r\n"];
    let mut response: Vec<u8> = headers.join("\r\n")
        .to_string()
        .into_bytes();
    response.extend(encoded);

    match stream.write(&response) {
        Ok(_) => println!("Response sent"),
        Err(e) => println!("Failed sending response: {}", e),
    }
}

fn handle_client(stream: TcpStream) {
    response(&get_path(&stream), stream);
}
Run Code Online (Sandbox Code Playgroud)

我听说有一些"HTTP服务器标准指南"的东西,任何想法在哪里找到它?

She*_*ter 6

始终修复编译器警告,特别是有关您未使用的结果的警告.返回并重新阅读有关错误处理的"Rust编程语言"一章,以便对该主题进行更新.

但是,这不是你的问题.我不知道你的想法let mut buf = vec![0u8];,但你不想要它.它分配一个矢量,其中只有一个值,一个8位零.然后,在JPEG之前发送该流氓字节,这使其不再是有效的JPEG.删除它允许您的程序工作:

fn response(path: &str, mut stream: TcpStream) {
    let file_path = format!("/tmp/images/{}", path);

    let mut buf = Vec::new();
    let mut file = File::open(&file_path).unwrap();
    file.read_to_end(&mut buf).unwrap();

    let mut encoded = Vec::new();
    {
        let mut encoder = Encoder::with_chunks_size(&mut encoded, 8);
        encoder.write_all(&buf).unwrap();
    }

    let headers = [
        "HTTP/1.1 200 OK",
        "Content-type: image/jpeg",
        "Transfer-Encoding: chunked",
        "\r\n"
    ];
    let mut response = headers.join("\r\n")
        .to_string()
        .into_bytes();
    response.extend(encoded);

    match stream.write(&response) {
        Ok(_) => println!("Response sent"),
        Err(e) => println!("Failed sending response: {}", e),
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,您的程序有一个巨大的安全漏洞,称为路径遍历.你应该不会公开此任何地方,有什么有价值的信息.