crowdin / crowdin-api-client-dotnet

.NET client library for Crowdin API
https://www.nuget.org/packages/Crowdin.Api/
MIT License
53 stars 26 forks source link

BundleApiExector.ExportBundle responds 500 because it's not sending an expected Content-Type header. #166

Closed PatrickMNL closed 1 year ago

PatrickMNL commented 1 year ago

Current:

The call BundleApiExector.ExportBundle() aka POST api/v2/projects/{projectId}/bundles/{bundleId}/exports doesn't require any content, the package doesn't send any as expected, however when using it, the API now returns the following;

Crowdin.Api.CrowdinApiException: Unsupported Content-Type Header
   at Crowdin.Api.CrowdinApiClient.CheckDefaultPreconditionsAndErrors(HttpResponseMessage response) in C:\Projects\crowdin-api-client-dotnet\src\Crowdin.Api\CrowdinApiClient.cs:line 416
   at Crowdin.Api.CrowdinApiClient.SendRequest(Func`1 createRequestMessage) in C:\Projects\crowdin-api-client-dotnet\src\Crowdin.Api\CrowdinApiClient.cs:line 354
   at Crowdin.Api.Bundles.BundlesApiExecutor.ExportBundle(Int32 projectId, Int32 bundleId) in C:\Projects\crowdin-api-client-dotnet\src\Crowdin.Api\Bundles\BundlesApiExecutor.cs:line 119
   at OSM.Translations.Api.Services.CrowdinService.ExportBundle(Bundle bundleDefinition) in C:\Projects\OSM.Translations\OSM.Translations.Api\Services\CrowdinService.cs:line 50
   at OSM.Translations.Api.Services.CrowdinService.GetBundleDownloadUrl(String bundleName) in C:\Projects\OSM.Translations\OSM.Translations.Api\Services\CrowdinService.cs:line 32
   at OSM.Translations.Api.V1.TranslationController.GetCrowdinTranslationBundleAsDownloadableUrl(String bundleName) in C:\Projects\OSM.Translations\OSM.Translations.Api\V1\TranslationController.cs:line 31
   at Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor.TaskOfIActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask`1 actionResultValueTask)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeInnerFilterAsync>g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|20_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Logged|17_1(ResourceInvoker invoker)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)
   at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

HEADERS
=======
Accept: application/json
Host: localhost:59954
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36
:method: GET
Accept-Encoding: gzip, deflate, br
Accept-Language: en,nl;q=0.9,nl-NL;q=0.8
Referer: https://localhost:59954/swagger/index.html
sec-ch-ua: "Not.A/Brand";v="8", "Chromium";v="114", "Google Chrome";v="114"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty

Expected: Either the API shouldn't expect the Content-Type field on this call, or it should be set through the package (which would require creating JsonContent even though none is included).

PatrickMNL commented 1 year ago

@andrii-bodnar I don't mind picking this up myself, if I can get permissions to open pull requests.

PatrickMNL commented 1 year ago

I am wondering though, whether this one should be fixed in this client package, or that it would be better to fix this on the API server side. Considering we're not sending a body (read as no content) and the server still demanding a specific content header.

andrii-bodnar commented 1 year ago

I am wondering though, whether this one should be fixed in this client package, or that it would be better to fix this on the API server side. Considering we're not sending a body (read as no content) and the server still demanding a specific content header.

It looks like this is a pretty unique case since it's the only (probably) API method that doesn't require a request body schema. It would be great to fix this on the client side, and I'll also pass this on to the development team for further investigation on the server side.