alex-therapeutics / diga-api-client

Production-ready java library for DiGA (Digital Health Application) manufacturers to integrate with DiGA API endpoints for code validation and billing.
https://github.com/alex-therapeutics/diga-api-client
Apache License 2.0
32 stars 13 forks source link

ProtocolException: expected the Content-Type to have a boundary parameter #62

Closed gtuk closed 2 years ago

gtuk commented 2 years ago

Problem

Currently we have some problem with the following insurance endpoints while validating a code:

The error only appears with real codes and not with test codes

If a request is parsed the library currently tries to read the response.body with a MultiPartReader regardless from the http status code

var responseBuilder = DigaApiHttpResponse.builder().statusCode(okHttpResponse.code());
var multiPartReader = new MultipartReader(okHttpResponse.body());

What we get back

Based on the document https://www.gkv-datenaustausch.de/media/dokumente/leistungserbringer_1/digitale_gesundheitsanwendungen/technische_anlagen_aktuell_7/digaSP_1_0_05.yaml the response does not need to have a content and when we try now to read the body with new MultipartReader an java.net.ProtocolException: expected the Content-Type to have a boundary parameter error is thrown

responses:
        200:
          description: OK
          content: 
            multipart/form-data:
              schema:
                $ref: '#/components/schemas/DigaResponse'
              encoding:
                ikempfaenger:
                  contentType: text/plain
                iksender:
                  contentType: text/plain
                verfahren:
                  contentType: text/plain
                nutzdaten:
                  contentType: application/octet-stream
        400:
          description: Bad Request
        401:
          description: Unauthorized
        403:
          description: Forbidden
        500:
          description: |
            Internal Server Error - Während der Verarbeitung in der
            DIGAPI ist ein technischer Fehler aufgetreten.

Solution

Not sure if we should check the status code before we read the content or not

fongie commented 2 years ago

Hi @gtuk ! I see, it makes sense and does look like a bug. It should be able to be solved by simply checking at https://github.com/alex-therapeutics/diga-api-client/blob/3d6991b7a5b29d9d7d68559bc823dda4fcec01de/src/main/java/com/alextherapeutics/diga/implementation/DigaOkHttpClient.java#L79 something like if okHttpResponse.code() != 200: return responseBuilder.build()

You will also need to return in the diga clients main class before it attempts to access the body of the request, which doesnt exist when this happens. We need to return before https://github.com/alex-therapeutics/diga-api-client/blob/3d6991b7a5b29d9d7d68559bc823dda4fcec01de/src/main/java/com/alextherapeutics/diga/DigaApiClient.java#L291 and https://github.com/alex-therapeutics/diga-api-client/blob/3d6991b7a5b29d9d7d68559bc823dda4fcec01de/src/main/java/com/alextherapeutics/diga/DigaApiClient.java#L226 if the body doesnt exist. We need to make sure the diga client response says there's an error as well.

I may be able to work on this later this week since it looks like a small fix, but if you're in a hurry perhaps you'd like to do it?

gtuk commented 2 years ago

Wouldn't it make more sense to just throw an io exception in case the response code is not 200

if (okHttpResponse.code() != 200) {
  throw new IOException(String.format("Request returned with status code %d", okHttpResponse.code()));
}

Then the post method would catch it, log it and transform it into a DigaHttpClientException and the the rest of the code stays as it is.

public DigaApiHttpResponse post(DigaApiHttpRequest request) throws DigaHttpClientException {
  ...
  } catch (IOException e) {
    log.error("Http request failed", e);
    throw new DigaHttpClientException(e);
  }
}

Additionally if would propose to still check okHttpResponse.body(), because this could still null even if the status code is 200. Something like this

    if (okHttpResponse.body() == null) {
      throw new IOException(String.format("Request returned with an empty body and status code %d", okHttpResponse.code()));
    }
fongie commented 2 years ago

Sure that makes sense too!

fongie commented 2 years ago

released in 1.2.2 @gtuk

gtuk commented 2 years ago

Thanks a lot. Just a heads up, the actual root cause was a problem on the insurance side. On the 25.12.2021 a new key file got uploaded because at the end of the year only keys with a key length of 4096 bit are allowed. The problem now was that the key file included already the new keys for some insurances but the backend systems of the insurance was still handling only the old key with 2048 bit