Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Storage erroneously looks for Content-Disposition as a request header #102

Open
5 tasks
SandGrainOne opened this issue Dec 5, 2022 · 1 comment
Open
5 tasks
Labels
kind/bug Something isn't working tm/no Threat modelling considered unnecessary for issue

Comments

@SandGrainOne
Copy link
Member

Description

Storage has the same issue as the app lib logic described in issue Altinn/app-lib-dotnet#96. Content-Disposition should not appear as a request header. This should to be fixed.

Initial analysis indicate that a valid multipart request will work. Storage should be able to handle valid requests without any additional changes. This issue is primarily for cleaning up what would otherwise be dead code.

The bug is found in the DataController class in method ReadRequestAndCreateDataElementAsync.

Additional Information

No response

Tasks

  • Identify all cases where Storage expect to find Content-Disposition in a request header.
  • Rewrite the incorrect logic.
  • Write unit tests.

Acceptance Criterias

  • DataController doesn't accept requests where Content-Disposition as a request header.
  • DataController is able to identify the filename and file size from Content-Disposition as a section header.
@SandGrainOne SandGrainOne added kind/bug Something isn't working tm/no Threat modelling considered unnecessary for issue labels Dec 5, 2022
@tjololo
Copy link
Member

tjololo commented Dec 8, 2022

After further investigation it seems like Content-Disposition will be present in the Requests headers when the HttpClient uploads a binary attachment through ByteArrayContent or StreamContent.
Logged all headers in the apps controller and wrote a client for uploading a xml and pdf.
Client code:

public async Task<string> ProcessUploadXml(string instanceId, byte[] attachment, string filename, CancellationToken ct)
{
    var uri = $"{_baseUri}/{_appUri}/instances/501337/{instanceId}/data?dataType=attachment";
    using (var content = new StreamContent(new MemoryStream(attachment)))
    {
        content.Headers.ContentType = new MediaTypeHeaderValue("application/xml");
        content.Headers.ContentDisposition = ContentDispositionHeaderValue.Parse($"attachment; filename=\"{filename}\"");
        var httppRequest = new HttpRequestMessage(HttpMethod.Post, uri);
        httppRequest.Content = content;
        var res = await _client.SendAsync(httppRequest);
        if (!res.IsSuccessStatusCode)
        {
            _logger.LogError("Upload to {URI} failed with statuscode: {StatusCode} content: {Response}", uri,res.StatusCode, await res.Content.ReadAsStringAsync());
            throw new Exception("upload failed");
        }

        var responseConrtent = await res.Content.ReadAsStringAsync();
        return responseConrtent;
    }
}

Headers logged on the server side was:

      Connection: close
      Host: local.altinn.cloud
      Authorization: Bearer ##omitted##
      Content-Type: application/xml
      Content-Length: 33
      X-Real-IP: 172.18.0.1
      X-Forwarded-For: 172.18.0.1
      Content-Disposition: attachment; filename="demo.xml"

As this is how HttpClient sets header when setting content.Headers.ContentDisposition on StreamContent and other I think we should keep the logic as it is today in storage

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Something isn't working tm/no Threat modelling considered unnecessary for issue
Projects
None yet
Development

No branches or pull requests

2 participants