Передача двоичных файлов через http выходит из строя

Я делаю ниже, чтобы загрузить файл.pptx и сохранить его на диске сервера.

Когда я пытаюсь открыть файл, он говорит, что он поврежден и не может быть открыт.

Это из-за моего типа кодировки или из-за чего-то другого?

Можно ли отправить любой произвольный файл в двоичном виде в POST и получить его на сервере в один кусок?

    public static void ListenerCallback(IAsyncResult result)
    {
        HttpListener listener = (HttpListener)result.AsyncState;
        HttpListenerContext context = listener.EndGetContext(result);
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;
        StreamReader reader = new StreamReader(request.InputStream);
        var res = reader.ReadToEnd();
        reader.Close();
        toLog.Add(res);
        NameValueCollection coll = HttpUtility.ParseQueryString(res);
        byte[] bytes = System.Text.Encoding.UTF8.GetBytes(res);
        File.WriteAllBytes("output.pptx", bytes);
        response.StatusCode = 200;
        response.ContentType = "text/html";
        using (StreamWriter writer = new StreamWriter(context.Response.OutputStream, Encoding.UTF8))
            writer.WriteLine("File Uploaded");
        response.Close();
    }

Это почтальон-превью того, что я отправляю:

POST  HTTP/1.1
Host: localhost:80
Content-Type: application/vnd.openxmlformats-officedocument.presentationml.presentation
Cache-Control: no-cache
Postman-Token: 9a04aa33-cd44-d238-6873-b330524f4ae5

undefined

Если я открываю исходный (не поврежденный) файл в np++, я вижу, что редактор выбирает кодировать его в ANSI.

В настоящее время я кодирую его в UTF8, и у меня нет возможности кодировать в ANSI.

Также при сравнении размера файла я теряю килобайт данных.

РЕДАКТИРОВАТЬ: мой текущий код теперь это

Это записывает пустой файл на диск.

    public static void ListenerCallback(IAsyncResult result)
    {
        HttpListener listener = (HttpListener)result.AsyncState;
        HttpListenerContext context = listener.EndGetContext(result);
        HttpListenerRequest request = context.Request;
        HttpListenerResponse response = context.Response;

        StreamReader reader = new StreamReader(request.InputStream);
        var res = reader.ReadToEnd();
        reader.Close();
        Console.WriteLine(res);
        NameValueCollection coll = HttpUtility.ParseQueryString(res);

        using (var outp = File.OpenWrite("output.pptx"))
        {
            request.InputStream.CopyTo(outp);
        }

        response.StatusCode = 200;
        response.ContentType = "text/html";
        using (StreamWriter writer = new StreamWriter(context.Response.OutputStream, Encoding.UTF7))
            writer.WriteLine("File Uploaded");
        response.Close();
    }

2 ответа

Решение

У меня нет времени, чтобы проверить это прямо сейчас, но попробуйте это:

public static void ListenerCallback(IAsyncResult result)
{
    HttpListener listener = (HttpListener)result.AsyncState;
    HttpListenerContext context = listener.EndGetContext(result);
    HttpListenerRequest request = context.Request;
    HttpListenerResponse response = context.Response;

    using (var out = File.OpenWrite("output.pptx"))
    {
        request.InputStream.CopyTo(out);
    }

    response.StatusCode = 200;
    response.ContentType = "text/html";
    using (StreamWriter writer = new StreamWriter(context.Response.OutputStream, Encoding.UTF8))
        writer.WriteLine("File Uploaded");
    response.Close();
}

Я думаю, это потому, что вы отправляете его как MIME-тип "text/html", а не как правильный тип "application/vnd.openxmlformats-officedocument.presentationml.presentation".

Другие вопросы по тегам