Home > Software design >  Make request with absolute URL in request line
Make request with absolute URL in request line

Time:02-25

I was wondering if it's possible to make a request as follows using Go's net/http library:

GET http://test2.com/thisisatest HTTP/1.1
Host: test1.com

I can't seem to find any information about it. If it's not possible using net/http is there any other way that this would be doable?

Thank you!

Diego

CodePudding user response:

From https://pkg.go.dev/net/http#Request.Host,

// For client requests, Host optionally overrides the Host
// header to send. If empty, the Request.Write method uses
// the value of URL.Host. Host may contain an international
// domain name.

So you should be able to craft your request, set it's Host field to whatever you desire, and then make the request.

Consider the following code. It doesn't work on the Playground (which won't allow external connections) but should work on your workstation.

package main

import (
    "io"
    "net/http"
    "os"
)

func main() {
    client := &http.Client{}
    req, err := http.NewRequest("GET", "https://httpbin.org/headers", nil)
    if err != nil {
        panic(err)
    }
    req.Host = "myserver.com"
    req.Header.Add("Content-Type", `application/json`)
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    } else if _, err := io.Copy(os.Stdout, resp.Body); err != nil {
        panic(err)
    }
}

https://httpbin.org/headers returns the headers sent with a request, so it is a useful way to verify this works. My results:

{
  "headers": {
    "Accept-Encoding": "gzip",
    "Content-Type": "application/json",
    "Host": "myserver.com",
    "User-Agent": "Go-http-client/2.0",
    "X-Amzn-Trace-Id": "Root=1-6217a78b-27317e7e06a097cb293b5db1"
  }
}

As you can see, since I set the request Host, the http library didn't set it from the URL.

In this case, httpbin request handler doesn't mind that the request header doesn't match the url. Other sites might return a 400 Bad Request if the host header does not match.

Note that you cannot achieve the same by maniuplating a Host header directly. You must use Request.Host.

CodePudding user response:

No, this us undoable with net/http because net/http implements HTTP and what you want to do simply isn't HTTP.

If it's not possible using net/http is there any other way that this would be doable?

Do raw networking, i.e. use package net.

This is wrong. Sorry.

  • Related