langgenius / dify

Dify is an open-source LLM app development platform. Dify's intuitive interface combines AI workflow, RAG pipeline, agent capabilities, model management, observability features and more, letting you quickly go from prototype to production.
https://dify.ai
Other
46.73k stars 6.61k forks source link

Content-Type in HTTP request is always overwritten #5611

Closed sepa85 closed 3 months ago

sepa85 commented 3 months ago

Self Checks

Dify version

0.6.11

Cloud or Self Hosted

Cloud

Steps to reproduce

In workflow, I'm using HTTP request. If I set a Content-Type header as "application/vnd.api+json" (that should work with a normal JSON), and set the body in JSON, the software automatically change the Content-Type based on body (in this case json), and the request is made with that content type, giving error.

Screenshot from 2024-06-26 06-32-59

✔️ Expected Behavior

If the Content-Type parameter is explicited in headers, don't automatically change the parameter to the request.

❌ Actual Behavior

Actually the Content-Type is always overwritten, even if set in headers. This sometimes throwing errors.

dosubot[bot] commented 3 months ago

The issue you're encountering is due to Dify's logic for handling the Content-Type header. In Dify, the Content-Type header is set based on the body type of the request, which can lead to the Content-Type being overwritten even if it is explicitly set in the headers.

In the sendRequest method, headers are merged with default headers, and the Content-Type can be overwritten based on the body type. For example, if the body type is JSON, the Content-Type is set to application/json regardless of what is specified in the headers [1][2].

To address this issue, you might need to modify the request handling logic to respect the Content-Type specified in the headers. This could involve checking if the Content-Type is already set in the headers before applying the default based on the body type.

Here is a potential modification to the sendRequest method to respect the Content-Type header if it is explicitly set:

async sendRequest(
  method,
  endpoint,
  data = null,
  params = null,
  stream = false,
  headerParams = {}
) {
  const defaultHeaders = {
    Authorization: `Bearer ${this.apiKey}`,
    "Content-Type": "application/json",
  };

  // Merge headers, but do not overwrite Content-Type if already set
  const headers = {
    ...defaultHeaders,
    ...headerParams,
    ...(headerParams['Content-Type'] && { "Content-Type": headerParams['Content-Type'] })
  };

  const url = `${this.baseUrl}${endpoint}`;
  let response;
  if (stream) {
    response = await axios({
      method,
      url,
      data,
      params,
      headers,
      responseType: "stream",
    });
  } else {
    response = await axios({
      method,
      url,
      ...(method !== "GET" && { data }),
      params,
      headers,
      responseType: "json",
    });
  }

  return response;
}

This modification ensures that if Content-Type is set in headerParams, it will not be overwritten by the default value.

If you are not able to modify the code directly, you might need to handle this at the application level by ensuring the Content-Type is set correctly before making the request.

To continue talking to Dosu, mention @dosu.