I’m making a tool, that can check a CIDR and see if a domain belongs to one server in the CIDR.
I wanted to do it similar as I do with cUrl, doing the request to the ip address, for example: http://1.2.3.4 and setting the Host Header: example.com
So far the code I have is always returning Status Code 200, but the host exist just in one of the IP I have set. Why is this behavior and how can I get the right behavior from my http request?
Here is the code
package main
import (
"fmt"
"log"
"net"
"net/http"
"time"
)
func main() {
var domain = "anillodegrado.com.ve"
fmt.Println("Analyzing Domain: ", domain)
ipAddresses, err := Hosts("198.50.181.32/27")
if err != nil {
log.Fatal(err)
}
for _, ips := range ipAddresses {
req, err := http.NewRequest("GET", "http://"+ips, nil)
if err != nil {
log.Fatal("Error reading request. ", err)
}
fmt.Println("Using IP: ", ips)
req.Host = domain
req.URL.Host = domain
//req.Header.Set("Host", domain)
client := &http.Client{Timeout: time.Second * 10}
resp, err := client.Do(req)
if err != nil {
log.Fatal("Error reading response. ", err)
}
defer resp.Body.Close()
//body, err := ioutil.ReadAll(resp.Body)
//if err != nil {
// log.Fatal("Error reading body", err)
//}
fmt.Println("HTTP Status: ", resp.StatusCode)
fmt.Println("Content Length: ", resp.ContentLength)
//log.Println(string(body))
}
}
// Hosts function read a CIDR and create a slide with all the IP addresses contained in it
func Hosts(cidr string) ([]string, error) {
ip, ipnet, err := net.ParseCIDR(cidr)
if err != nil {
return nil, err
}
var ips []string
for ip := ip.Mask(ipnet.Mask); ipnet.Contains(ip); inc(ip) {
ips = append(ips, ip.String())
}
// remove network address and broadcast address
lenIPs := len(ips)
switch {
case lenIPs < 2:
return ips, nil
default:
return ips[1 : len(ips)-1], nil
}
}
func inc(ip net.IP) {
for j := len(ip) - 1; j >= 0; j-- {
ip[j]++
if ip[j] > 0 {
break
}
}
}
You set the request.URL.Host to the same hostname every time and not just the request http header. You are basically changing the url on the request made for the IP address.
Also, you should check if resp.Body is nil before calling Close on it
Yes. The requests url is made up of different segments, a schema, possibly username and password, a host, a path, some query string parameters and a url fragment. The Host in the URL object is not the same as the Host on the request object, which is the one you want to change.