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

Garbled request body #1439

Open
qwertycho opened this issue Oct 24, 2024 · 10 comments
Open

Garbled request body #1439

qwertycho opened this issue Oct 24, 2024 · 10 comments
Assignees
Milestone

Comments

@qwertycho
Copy link

When sending a post request the json body becomes an arbitrary data.
Example

Image

Sample

vite react + typescript project

import './App.css'

import { AnonymousAuthenticationProvider } from '@microsoft/kiota-abstractions';
import { FetchRequestAdapter, HttpClient } from '@microsoft/kiota-http-fetchlibrary';
import {createWebClient} from '../WebClient/webClient'

function App() {
  return (
    <>
        <button onClick={async () => {
            const authProvider = new AnonymousAuthenticationProvider();
            const adapter = new FetchRequestAdapter(authProvider);
            adapter.baseUrl = "https://localhost:7139";

            const client = createWebClient(adapter);
            await client.api.values.post({
              name: "test",
              value: "test",
            });
        }}>
          test
        </button>
    </>
  )
}

export default App

api

dotnet 8 webapplication

{
  "openapi": "3.0.1",
  "info": {
    "title": "WebApplication2",
    "version": "1.0"
  },
  "paths": {
    "/api/Values": {
      "post": {
        "tags": [
          "Values"
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadModel"
              }
            },
            "text/json": {
              "schema": {
                "$ref": "#/components/schemas/UploadModel"
              }
            },
            "application/*+json": {
              "schema": {
                "$ref": "#/components/schemas/UploadModel"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      },
      "get": {
        "tags": [
          "Values"
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/WeatherForecast": {
      "get": {
        "tags": [
          "WeatherForecast"
        ],
        "operationId": "GetWeatherForecast",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "text/plain": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              },
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              },
              "text/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/WeatherForecast"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "UploadModel": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "nullable": true
          },
          "value": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      },
      "WeatherForecast": {
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "format": "date"
          },
          "temperatureC": {
            "type": "integer",
            "format": "int32"
          },
          "temperatureF": {
            "type": "integer",
            "format": "int32",
            "readOnly": true
          },
          "summary": {
            "type": "string",
            "nullable": true
          }
        },
        "additionalProperties": false
      }
    }
  }
}
@github-project-automation github-project-automation bot moved this to Needs Triage 🔍 in Kiota Oct 24, 2024
@rkodev rkodev self-assigned this Oct 24, 2024
@rkodev
Copy link
Contributor

rkodev commented Oct 24, 2024

Hi @qwertycho, Thanks for trying out the SDK.
This issue is caused by the compression middleware, which is enabled by default. If you would like to view the request body, you can disable the compression middleware or de-compress the request

@rkodev rkodev moved this from Needs Triage 🔍 to Waits for author 🔁 in Kiota Oct 24, 2024
@baywet baywet added the status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close label Oct 24, 2024
@andrueastman andrueastman added this to the Kiota-TS-GA milestone Oct 30, 2024
@qwertycho
Copy link
Author

Thank you @rkodev ! I have disabled the compression with this snipped:

    const http = KiotaClientFactory.create(undefined, [
      new RetryHandler(), new RedirectHandler(), new ParametersNameDecodingHandler(), new UserAgentHandler(),  new HeadersInspectionHandler()
    ])
  
    const adapter = new FetchRequestAdapter(new BearerAuthenticationProvider(), undefined, undefined, http);
    const client = createApiClient(adapter);

    client.api.endpoint.post({
      field: "testdata",
    })

The compression is a bit annoying when the api does not support it.

I did notice that the CompressionHandler is not in exported in the http fetch library, so that limits discoverability. Although it seems there isn't much to configure anyway.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 and removed status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close Status: No Recent Activity labels Oct 31, 2024
@baywet
Copy link
Member

baywet commented Nov 9, 2024

@qwertycho
Thank you for the additional information.

When the API you're targeting replies to the compressed request, does it send back a 415 status code? Or something else?
The handler should retry with an uncompressed request body making failures "transparent" (although haven't a negative impact on bandwidth usage and latency).

We didn't get any feedback about APIs not supporting request body compression in other languages where it's been implemented to date as far as I know.

The addition of this handler by default is guided by our design guidelines

Can you expand on the export comment you were making please?

@brad-technologik
Copy link

I find it bizarre that requests are compressed by default. In my decade+ of web development, I've never heard of compressing json payloads sent to a server (only responses). Furthermore, given that Kiota is closely related to ASP.NET core and ASP.NET core fails to recognized compressed data by default, Kiota basically is broken out of the box for ASP.NET backends.

Disabling compression as per the comment above worked for me.

@qwertycho
Copy link
Author

qwertycho commented Nov 12, 2024

@baywet
The api does not send a 415 statuscode but a 400. When i tested it with a api that send a 415 it works perfectly fine.
As @brad-technologik said ASP.NET does not support compressed content by default.

The kiota-http-fetchlibrary exports all the middlewares (RedirectHandler, RetryHandler, etc) except for the CompressionHandler. So if somebody wanted to build a HttpClient with a custom set of middleware, they won't be able to use the CompressionHandler.

As far as i can see the only thing that is configurable in the CompressionHandler is the 'enableCompression' flag, so that's why i said that there isn't much to configure.

@microsoft-github-policy-service microsoft-github-policy-service bot added Needs: Attention 👋 and removed status:waiting-for-author-feedback Issue that we've responded but needs author feedback to close labels Nov 12, 2024
@andreaTP
Copy link
Contributor

Hitting this same issue here: Apicurio/apicurio-registry#5498

So, I can confirm that Java server are being affected by this issue too.

@baywet
Copy link
Member

baywet commented Nov 14, 2024

Thank you for the additional information.

@qwertycho are you referring to the missing entries here and there ?? This is most likely an oversight.
Is this something you'd like to submit a pull request for provided some guidance?

As for request compression being enabled by default, extrapolating from Microsoft Graph we might have made two assumptions that are not holding:

  • Broad support for request body compression in APIs. (seems the support is lower than we expected)
  • Broad support for replying with 415 from APIs that do not support request body compression. (it seems that the ones that don't support it are oblivious to it, and just send a 400 back).

What's strange is that go has been our canary and has supported request body compression for over 2 years now. While we received feedback about content range and other aspects where compression should NOT be applied, we have not received feedback asking to disable request body compression all together.

We could consider disabling request compression by default (and only enabling it in Microsoft Graph core), but before we go there, I'd love to brainstorm potential solutions to:

  • Make the issue easier to find for the developer, and disable when API does not "do the right thing".
  • (assuming disabled by default) make it easier for people to discover this feature/performance improvement for there clients.

@andreaTP
Copy link
Contributor

For reference, in the Java world, either in Spring Boot and Quarkus enabling compression is still opt in(i.e. disabled by default).

@qwertycho
Copy link
Author

@baywet
Yes, That are the points where the CompressionHandler is missing.

As for for compression being enabled by default: I think it's fine, as long as it's properly documented. When looking at the documentation there is no mention of compression being enabled. Currently the only mention of default middleware is Create a middleware handlers array and use the existing middleware already implemented within Microsoft.Kiota.HttpClientLibrary that includes existing handlers like retry, redirect, and more.

I think that it would be good to mention the different middleware handlers that are enabled by default in the quickstart guides and then link to the middleware page.

@baywet
Copy link
Member

baywet commented Nov 19, 2024

Thank you for the additional information.

Can you please create an issue here for the gap in public documentation?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Waits for author 🔁
Development

No branches or pull requests

6 participants