Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot REST app returns 400 when requested from other docker-compose service by service name

I'm trying to introduce a Spring Boot REST service in our development setup. The development setup is using docker-compose and an API gateway to expose the individual services on the same domain (ie. localhost).

When I try to make a HTTP request to my service from inside another container via the service name in the shared docker-compose file, the service returns a 400.

The setup

I've edited our docker-compose file, so it looks like the below to introduce the Spring Boot Java service. The service is based on spring-boot-starter-parent (2.0.3.RELEASE) and spring-boot-starter-web. I haven't configured anything related to the web server (except adding the server.server-header property to ensure myself that the request is hitting my service).

version: '3'
services:
  ...

  hello_java:
    build:
      context: ../hello-java/
      dockerfile: Dockerfile
    depends_on:
      - postgres
      - castle_black
    ports:
      - "8301:8080"

  castle_black:
    build: ../castle-black/tyk-gateway
    ports:
      - "8191:8080"
    depends_on:
      - redis

The behaviour

If I request the hello service from outside the containers (e.g. in my browser on localhost:8301) it replies back correctly. If I'm inside a container, but obtain the IP that the container with my new service gets in the docker network and use that the new service also responds correctly back.

Below I have shown a request from inside the API gateway container to the Java service, first by using the service name and then afterwards with the IP that was resolved. It only replies with a correct response in the IP case.

# curl -v http://hello_java:8080/hello-java/greet?username=Java
* Hostname was NOT found in DNS cache
*   Trying 172.19.0.6...
* Connected to hello_java (172.19.0.6) port 8080 (#0)
> GET /hello-java/greet?username=Java HTTP/1.1
> User-Agent: curl/7.35.0
> Host: hello_java:8080
> Accept: */*
> 
< HTTP/1.1 400 
< Transfer-Encoding: chunked
< Date: Wed, 01 Aug 2018 11:34:34 GMT
< Connection: close
* Server MySpringBootApp is not blacklisted
< Server: MySpringBootApp
< 
* Closing connection 0

# curl -v http://172.19.0.6:8080/hello-java/greet?username=Java
* Hostname was NOT found in DNS cache
*   Trying 172.19.0.6...
* Connected to 172.19.0.6 (172.19.0.6) port 8080 (#0)
> GET /hello-java/greet?username=Java HTTP/1.1
> User-Agent: curl/7.35.0
> Host: 172.19.0.6:8080
> Accept: */*
> 
< HTTP/1.1 200 
< Content-Type: text/plain;charset=UTF-8
< Content-Length: 10
< Date: Wed, 01 Aug 2018 11:34:55 GMT
* Server MySpringBootApp is not blacklisted
< Server: MySpringBootApp
< 
* Connection #0 to host 172.19.0.6 left intact
Hello Java

The questions

Is there something in the standard spring-boot-starter-web setup that prevents the web server from servicing the request, when the client adds the "Host: hello_java:8080" header? Or why is the web server behaving differently in the two scenarios? And what can I do about it?

like image 619
Morten Olsen Avatar asked Jan 03 '23 01:01

Morten Olsen


2 Answers

After some experimentation it turned out that the it was the underscore in the service name that caused the issue. Changing the service name to not have an underscore solved the problem.

like image 131
Morten Olsen Avatar answered Jan 04 '23 15:01

Morten Olsen


RFC 952 stipulates that "name" (Net, Host, Gateway, or Domain name) is a text string up to 24 characters drawn from the alphabet (A-Z), digits (0-9), minus sign (-), and period (.)

It seems that the _ is not a valid component for host names. It's a bit confusing because I had the same problem and when I ping app_server it's fine but when I wget from app_server I got bad request.

Changing the underscore to minus fixed it for me.

like image 39
Nikolay Mihaylov Avatar answered Jan 04 '23 15:01

Nikolay Mihaylov