Why this HTTP GET request to the Ingress (GKE) is always returning 400 (bad request) error?

3/16/2021

I'm trying to make a GET request to an application in Kubernetes (GKE) but is always returning 400 Bad Request.

The POST, PUT and DELETE methods are working perfectly.

And the strangest thing is that when I use the port-forward directly to the pod I haven't problem with the GET request.

I've tried to minimize the code of my application as much as possible and it looks like this:

const express = require('express')
const app = express()
const port = 3000

app.use(express.json())
app.use(express.urlencoded({ extended: true }))

app.get('/', (req, res) => {
  res.send(req.body)
})

app.post('/', function(req, res){
  res.send(req.body);
});

app.put('/', function(req, res){
  res.send(req.body);
});

app.delete('/', function(req, res){
  res.send(req.body);
});

app.listen(port, () => {
  console.log(`Listening to port ${port}`)
})

I think that the problem is in my Ingress configuration because with port-forward it is working well. Here is my Ingress yaml:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: test-ingress
spec:
  tls:
    - hosts:
        - my-test-host
      secretName: tls-secret
  rules:
    - host: my-test-host
      http:
        paths:
        - path: /*
          backend:
            serviceName: my-test-service
            servicePort: 3000

Finally, this is the request that always return 400.

curl --location --request GET 'https://my-test-host/' \
--header 'Content-Type: application/json' \
--data-raw '{
    "test": "123"
}'

The same request with other methods (POST, PUT or DELETE) is working well. Please, what I'm doing wrong?

-- Thiago G. Alves
google-kubernetes-engine
http
kubernetes
kubernetes-ingress
node.js

1 Answer

3/17/2021

I managed to find the solution to the problem.

The problem is that Ingress don't accept HTTP GET requests with body and responds with error 400.

The saddest thing is that I found nothing about this problem in the Kubernetes documentation anywhere.

I searched for good practice information on sending body in GET requests and then found these two links:

https://www.rfc-editor.org/rfc/rfc7231#section-4.3.1

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/GET

As I understand it is not forbidden to send the GET with body, but it is not recommended.

So, to solve my problem I changed my code to get params from "query" instead "body" in the GET request:

app.get('/', (req, res) => {
  res.send(req.query)
})

Consequently, I needed to change the sending parameters in my GET request:

curl --location --request GET 'https://my-test-host?test=123'

Lesson learned: To avoid problems, never accept GET requests with body.

Thanks.

-- Thiago G. Alves
Source: StackOverflow