camunda / connectors

Camunda Connectors
https://docs.camunda.io/docs/components/integration-framework/connectors/out-of-the-box-connectors/available-connectors-overview/
Apache License 2.0
40 stars 38 forks source link

[HttpBase] ApacheRequestHeadersBuilder fails when header value is null #2813

Closed sbuettner closed 3 months ago

sbuettner commented 3 months ago

Describe the Bug

A customer that sent an illegal header value ({Accept: null}) ({Content-Type: null}) saw errors when after we upgraded the Cloudproxy function to the latest HTTP client (8.6.0-alpha3).

Reason: The ApacheRequestHeadersBuilder fails if a header entry value is null when calling defaultMultipartContentType() as there is no null check before accessing the header entry value.

Steps to Reproduce

The customer sent the following payload for the headers from a 8.3 Connectors runtime:

{Content-Type: application/json}

and forgot to quote the application/json which is a valid variable name in FEEL leading to the following value for the headers:

{Content-Type: null}

Expected Behavior

The header value should be checked for a null value before accessing the entry value:

e.getValue().contains(MULTIPART_FORM_DATA.getMimeType())

Environment

https://jira.camunda.com/browse/SUPPORT-22639

johnBgood commented 3 months ago

Stack Trace from the logs:


Exception while processing job: 2251799872426124 for tenant: <default>
io.camunda.connector.api.error.ConnectorException: java.lang.NullPointerException: Cannot invoke "String.contains(java.lang.CharSequence)" because the return value of "java.util.Map$Entry.getValue()" is null
    at io.camunda.connector.http.base.services.HttpInteractionService.executeHttpRequest(HttpInteractionService.java:77)
    at io.camunda.connector.http.base.services.HttpService.executeRequestViaProxy(HttpService.java:103)
    at io.camunda.connector.http.base.services.HttpService.executeConnectorRequest(HttpService.java:53)
    at io.camunda.connector.http.rest.HttpJsonFunction.execute(HttpJsonFunction.java:79)
    at io.camunda.connector.runtime.core.outbound.ConnectorJobHandler.handle(ConnectorJobHandler.java:105)
    at io.camunda.connector.runtime.outbound.jobhandling.SpringConnectorJobHandler.lambda$handle$0(SpringConnectorJobHandler.java:75)
    at io.micrometer.core.instrument.AbstractTimer.record(AbstractTimer.java:247)
    at io.camunda.zeebe.spring.client.actuator.MicrometerMetricsRecorder.executeWithTimer(MicrometerMetricsRecorder.java:52)
    at io.camunda.connector.runtime.outbound.jobhandling.SpringConnectorJobHandler.handle(SpringConnectorJobHandler.java:66)
    at io.camunda.zeebe.client.impl.worker.JobRunnableFactoryImpl.executeJob(JobRunnableFactoryImpl.java:45)
    at io.camunda.zeebe.client.impl.worker.JobRunnableFactoryImpl.lambda$create$0(JobRunnableFactoryImpl.java:40)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.base/java.lang.Thread.run(Unknown Source)
Caused by: com.google.api.client.http.HttpResponseException: 500 Internal Server Error
POST https://europe-west1-camunda-saas-prod-connectors.cloudfunctions.net/connector-http-json-proxy
{"error":"java.lang.NullPointerException: Cannot invoke \"String.contains(java.lang.CharSequence)\" because the return value of \"java.util.Map$Entry.getValue()\" is null","errorCode":"Failed to execute request: HttpRequest{url='https://oa-introducer-search.azurewebsites.net/api/ClientCompany/Search', method='POST', authentication=OAuthAuthentication{oauthTokenEndpoint='https://xxxx', clientId='xxxxx', clientSecret=[REDACTED], audience='https://introducerqueryapi.axsesstoday.com.au', clientAuthentication='basicAuthHeader', scopes='null'}, connectionTimeoutInSeconds='20', headers={Content-Type=null}', readTimeoutInSeconds='null, body={filter=clientCompanyId eq 'xxx'}, queryParameters=null}. An error occurred: Cannot invoke \"String.contains(java.lang.CharSequence)\" because the return value of \"java.util.Map$Entry.getValue()\" is null","result":null}
    at com.google.api.client.http.HttpResponseException$Builder.build(HttpResponseException.java:293)
    at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1118)
    at io.camunda.connector.http.base.services.HttpInteractionService.executeHttpRequest(HttpInteractionService.java:63)
    ... 16 common frames omitted