fasthttp icon indicating copy to clipboard operation
fasthttp copied to clipboard

[Bug/Question] Hostclient sends content-type header on DELETE request even if it is not set

Open shkreios opened this issue 4 years ago • 3 comments

Hey, I just started to learn golang as well as fashttp. I tried to build a fasthttp reverse proxy using this libary and later using the code from this issue.

All requests work without any problems, only on delete requests the hostclient adds the header content-type with the value application/x-www-form-urlencoded.

The server to which the request is proxyed responds with 406, is there a way to disable this behavior?

Thank you in advance for any help.

Code example: In the code example I don't use a proxy just the fashttp.Client to make a request with the request method set to DELETE. I have tested the behavior with a fashttp and express server, the code is shown below.

sender.go

package main

import (
	"fmt"

	"github.com/valyala/fasthttp"
)

func main() {
	req := fasthttp.AcquireRequest()

	resp := fasthttp.AcquireResponse()
	req.SetRequestURI("http://localhost:3000/")

	req.Header.SetMethod("DELETE")

	req.Header.Del("content-type")

	client := &fasthttp.Client{}
	fmt.Printf("Content-Type: %s\n", string(req.Header.ContentType()))
	client.Do(req, resp)
	fmt.Printf("Content-Type: %s\n", string(req.Header.ContentType()))

	fmt.Println(resp.StatusCode(), string(resp.Body()))
	fmt.Println(string(resp.Body()))

}

Output:

Content-Type: 
Content-Type: 
200 OK
OK

receiver.go

package main

import (
	"fmt"

	"github.com/valyala/fasthttp"
)

func fastHTTPHandler(ctx *fasthttp.RequestCtx) {

	fmt.Println(string(ctx.Request.Header.Header()))

	fmt.Fprintf(ctx, "Hi there! RequestURI is %q", ctx.RequestURI())

}

func main() {
	fmt.Println("server started...")

	server := &fasthttp.Server{
		Handler: fastHTTPHandler,
	}

	err := server.ListenAndServe(":3000")
	if err != nil {
		panic(err)
	}

}

Output:

DELETE / HTTP/1.1
User-Agent: fasthttp
Host: localhost:3000
Content-Type: application/x-www-form-urlencoded
Content-Length: 0

Express JS Server example server.js

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

app.use((req, res, next) => {
  console.log(req.headers);
  res.sendStatus(200);
});

app.listen(port, () => {
  console.log(`Example app listening at http://localhost:${port}`);
});

Output:

{
  'user-agent': 'fasthttp',
  host: 'localhost:3000',
  'content-type': 'application/x-www-form-urlencoded',
  'content-length': '0'
}

shkreios avatar Sep 05 '20 13:09 shkreios

This is because fasthttp always wants to set a Content-Type header for non GET/HEAD requests: https://github.com/valyala/fasthttp/blob/aa3f96c883322033099b4466c151893a3f9c2172/header.go#L1593-L1595

It is currently not possible to disable this.

Maybe it would work for you to set the Content-Type to text/plain?

erikdubbelboer avatar Sep 06 '20 11:09 erikdubbelboer

@erikdubbelboer Thank you for your answer. text/plain does not work but the app strangely accepts application/json even if the body is empty. Do you think it will be possible to disable this in the future? Because I want to use fashttp as reverse proxy and it is not possible for me to create a "failover" for all potentially wrong set Content-Type headers. Thanks again for your time.

shkreios avatar Sep 06 '20 12:09 shkreios

For ResponseHeader we have ResponseHeader.SetNoDefaultContentType(). I think we should add something similar for RequestHeader.

erikdubbelboer avatar Sep 08 '20 15:09 erikdubbelboer