Добавление zip-файла в качестве содержимого в ответ веб-API, удваивающий размер файла при загрузке - PullRequest
3 голосов
/ 03 августа 2020

Я сохраняю zip-файлы в корзину AWS S3. Сейчас я пытаюсь создать C#. NET API, который позволит мне загрузить указанный ключ из корзины и сохранить его в HttpResponseMessage в ключе содержимого.

Я упомянул следующий вопрос, чтобы настроить мой ответ для zip-файлов: Как отправить zip-файл из веб-API 2 HttpGet

Я изменил код в предыдущем вопросе, чтобы он вместо этого считывался из Поток TransferUtility.

Проблема в том, что я получаю сообщение об ошибке при попытке извлечь или просмотреть файл, который выглядит следующим образом: Error message when attempting to extract zip

The response I am getting back from the API looks like: enter image description here

The relevant code looks like:

[HttpGet, Route("GetFileFromS3Bucket")]
public HttpResponseMessage GetFileFromS3Bucket(string keyName)
{
    HttpResponseMessage response = new HttpResponseMessage();
    string bucketName = "myBucket";
    RegionEndpoint bucketRegion = RegionEndpoint.ARegion;
    IAmazonS3 s3Client;
    s3Client = new AmazonS3Client(bucketRegion);

    try
    {
        var fileTransferUtility = new TransferUtility(s3Client);
        var stream = fileTransferUtility.OpenStream(bucketName, keyName);
        response.Content = new StreamContent(stream);
        response.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
        response.Content.Headers.ContentDisposition.FileName = keyName + ".zip";
        response.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip");
        response.StatusCode = HttpStatusCode.OK;
    }
    catch (Exception e)
    {
        response.Content = new StringContent("Something went wrong, error: " + e.Message);
        response.StatusCode = HttpStatusCode.InternalServerError;
    }

    return response;
}

Results of troubleshooting:

  • The file from the Web API comes out with nearly double the expected size based on what is in S3. This is consistent across different files
  • Changing the bucket to be publicly accessible did not help (setting since reverted to not allowing public access)
  • Changing the file type to XML did not display a nicely formatted error (there was a suggestion that you may receive an XML response if an error was provided from S3)
  • Saving the S3 stream to a file and then saving directly to a file resulted in the correct file size. Seems safe to say the stream from S3 is not the problem

It appears that there ia a problem with the way the HTTPResponseMessage is handling the zip file. I'm unsure of whether it is actually on the server side, or whether it is on the client to parse the data and Swagger is simply incapable of doing that. Any help would be greatly appreciated.

Update 1 I do not believe this string is Base64 encoded as the result I got from converting the stream to a string is the following: enter image description here

I've updated the code sample with the two lines showing the conversion from a stream to string.

Update 2 I've confirmed the issue is with how the response is handling the stream, or something in the response itself. Downloading the file stream from S3 and saving to a new file on the local computer resulted in a valid file that opened as expected.

Update 3 Link to GDrive folder with testing files: https://drive.google.com/drive/folders/1q_N3NTHz5E_nebtBQJHor3HfqUZWhGgd?usp=sharing I к сожалению, не может предоставить доступ к исходному файлу, поскольку он содержит конфиденциальные данные. Однако предоставленные файлы по-прежнему вызывают ту же проблему. Интересно отметить, что тестовый файл выглядел так:

Showing issue with underscores on either side of file name

The underscores on either side of the filename are quite strange.

I am running the following relevant packages:

Update 4 I've found the following UTF8 references in various files:

File: configuration91.svcinfo Проблема с кодировкой Possilbe UTF-8

Я не смог найти ничего, что бы говорило о responseEncoding где-либо в проекте.

1 Ответ

3 голосов
/ 06 августа 2020

Я собираюсь дать ответ, потому что то, что с вами происходит, неортодоксально. Я использую S3 для многих вещей и раньше делал то, что вы делаете, без проблем. Чтобы убедиться, что я имитирую то, что вы делаете, я продублировал ваш код:

[HttpGet, Route("GetFileFromS3Bucket/{keyName}")]
public HttpResponseMessage GetFileFromS3Bucket(string keyName)
{
    string bucketName = "testzipfilesagain";
    string awsAccessKey = "AKIAJ********A3QHOUA";
    string awsSecretKey = "IYUJ9Gy2wFCQ************dCq5suFS";

    IAmazonS3 client = new AmazonS3Client(awsAccessKey, awsSecretKey, RegionEndpoint.USEast1);

    var fileTransferUtility = new TransferUtility(client);
    var stream = fileTransferUtility.OpenStream(bucketName, "md5.zip");

    var resp = new HttpResponseMessage();

    resp.Content = new StreamContent(stream);
    resp.Content.Headers.ContentDisposition = new System.Net.Http.Headers.ContentDispositionHeaderValue("attachment");
    resp.Content.Headers.ContentDisposition.FileName = keyName + ".zip";
    resp.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/zip");
    resp.StatusCode = HttpStatusCode.OK;

    return resp;
}

Это пакеты, которые я установил:

  <ItemGroup>
    <PackageReference Include="AWSSDK.S3" Version="3.3.111.37" />
    <PackageReference Include="Microsoft.AspNetCore.Mvc.WebApiCompatShim" Version="2.2.0" />
    <PackageReference Include="Swashbuckle.AspNetCore" Version="5.5.1" />
  </ItemGroup>

Все работает отлично.

Попытка устранить неполадки в вашем коде будет бесплодной, потому что он работает отлично, но что-то не так с вашей средой.

Так что это не t ответ на ваш вопрос, но ответ на то, как вы можете попытаться решить возникшую проблему и обойти это.

  1. Убедитесь, что ваши пакеты nuget обновлены
  2. Есть ли в вашем конвейере промежуточное ПО? Если да, то что?
  3. Опубликуйте свой startup.cs - возможно, что-то не в порядке в вашей Configure программе.
  4. Не могли бы вы начать новый проект и попробовать свой код в этом ?
  5. Можете ли вы попробовать небольшой zip-файл размером 5 КБ и опубликовать оригинал и поврежденные файлы, чтобы мы могли их посмотреть? для решения подобных проблем.

    РЕДАКТИРОВАТЬ 1

    Итак, я посмотрел на zip-файлы, и они прошли процесс кодирования UTF8. Итак, если вы возьмете исходный zip-файл и запустите на нем этот код:

        var goodBytes = File.ReadAllBytes("Some test to upload to S3.zip");
        var badBytes = File.ReadAllBytes("_Some test to upload to S3.zip.zip_");
    
        File.WriteAllText("Some test to upload to S3.zip.utf8", Encoding.UTF8.GetString(goodBytes));
        var utf8EncodedGoodBytes = File.ReadAllBytes("Some test to upload to S3.zip.utf8");
    
        var identical = badBytes.SequenceEqual(utf8EncodedGoodBytes);
    

    Результат будет следующим:

    bad bytes

    I am going to do some research and figure out what could be causing your stream to become UTF-8 encoded. Is there anything in your config that выглядит так ? Можете ли вы найти в своем решении что-нибудь похожее на «utf», «utf8» или «utf-8»?

...