wip - add JSON response for web-ip

This commit is contained in:
DataHearth 2022-09-02 21:40:23 +02:00
parent c5c69099dd
commit 8415836cb0
No known key found for this signature in database
GPG Key ID: E88FD356ACC5F3C4
3 changed files with 64 additions and 11 deletions

View File

@ -15,6 +15,7 @@ type Provider interface {
UpdateSubdomains(ip string) error UpdateSubdomains(ip string) error
updateSubdomain(subdomain, ip string) error updateSubdomain(subdomain, ip string) error
retrieveSubdomainIP(addr string) (string, error) retrieveSubdomainIP(addr string) (string, error)
checkResponse(body []byte, tokenBased bool, ip string) error
} }
type provider struct { type provider struct {
@ -96,7 +97,7 @@ func (p *provider) updateSubdomain(subdomain, ip string) error {
req, err := http.NewRequest("GET", newURL, nil) req, err := http.NewRequest("GET", newURL, nil)
if err != nil { if err != nil {
return utils.ErrCreateNewRequest return fmt.Errorf("%v: %v", utils.ErrCreateNewRequest, err)
} }
if !tokenBased { if !tokenBased {
req.SetBasicAuth(p.config.Username, p.config.Password) req.SetBasicAuth(p.config.Username, p.config.Password)
@ -134,14 +135,14 @@ func (p *provider) retrieveSubdomainIP(addr string) (string, error) {
} }
if len(ips) != 1 { if len(ips) != 1 {
return "", utils.ErrIpLenght return "", fmt.Errorf("%v: %v", utils.ErrIpLenght, ips)
} }
ip := ips[0].String() ip := ips[0].String()
if strings.Contains(ip, ":") { if strings.Contains(ip, ":") {
ip, _, err = net.SplitHostPort(ip) ip, _, err = net.SplitHostPort(ip)
if err != nil { if err != nil {
return "", utils.ErrSplitAddr return "", fmt.Errorf("%v: %v", utils.ErrSplitAddr, ip)
} }
} }

View File

@ -13,7 +13,7 @@ var (
// ErrGetServerIP is thrown when HTTP can't contact the web-ip service // ErrGetServerIP is thrown when HTTP can't contact the web-ip service
ErrGetServerIP = errors.New("HTTP error") ErrGetServerIP = errors.New("HTTP error")
// ErrParseHTTPBody is thrown when the HTTP service can't parse the body response // ErrParseHTTPBody is thrown when the HTTP service can't parse the body response
ErrParseHTTPBody = errors.New("can't parse response body") ErrParseHTTPBody = errors.New("can't read response body")
// ErrSplitAddr is thrown when the remote address can't be splitted // ErrSplitAddr is thrown when the remote address can't be splitted
ErrSplitAddr = errors.New("can't split subdomain remote IP address") ErrSplitAddr = errors.New("can't split subdomain remote IP address")
// ErrCreateNewRequest is thrown when http request creation failed // ErrCreateNewRequest is thrown when http request creation failed

View File

@ -1,8 +1,12 @@
package watcher package watcher
import ( import (
"encoding/json"
"fmt"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"strings"
"time" "time"
"github.com/datahearth/ddnsclient/pkg/provider" "github.com/datahearth/ddnsclient/pkg/provider"
@ -102,18 +106,66 @@ func (w *watcher) runDDNSCheck() error {
} }
func (w *watcher) retrieveServerIP() (string, error) { func (w *watcher) retrieveServerIP() (string, error) {
resp, err := http.Get(w.webIP) rsp, err := http.Get(w.webIP)
if err != nil { if err != nil {
return "", utils.ErrGetServerIP return "", fmt.Errorf("%v: %v", utils.ErrGetServerIP, err)
} }
if resp.StatusCode != 200 { if rsp.StatusCode != 200 {
return "", utils.ErrWrongStatusCode return "", fmt.Errorf("%v: %v", utils.ErrWrongStatusCode, rsp.Status)
} }
d, err := ioutil.ReadAll(resp.Body) b, err := ioutil.ReadAll(rsp.Body)
if err != nil { if err != nil {
return "", utils.ErrParseHTTPBody return "", fmt.Errorf("%v: %v", utils.ErrParseHTTPBody, err)
} }
return string(d), nil var ip string
if rsp.Header.Get("content-type") == "application/json" {
body := make(map[string]interface{})
if err := json.Unmarshal(b, &body); err != nil {
return "", fmt.Errorf("failed to unmarshal JSON body: %v", err)
}
if v, ok := body["ip"]; ok {
if v, ok := v.(string); ok {
ip = v
} else {
return "", fmt.Errorf("\"ip\" field found in JSON response but is not a string value")
}
} else {
for _, v := range body {
if v, ok := v.(string); ok {
if parsedIP := net.ParseIP(v); parsedIP != nil {
ip = parsedIP.String()
}
}
}
if ip == "" {
return "", fmt.Errorf("no field found with a valid IPv4 address in JSON response")
}
}
} else {
body := string(b)
if strings.Count(body, "\n") > 0 {
for _, l := range strings.Split(body, "\n") {
if parsedIP := net.ParseIP(l); parsedIP != nil {
ip = parsedIP.String()
break
}
}
if ip == "" {
return "", fmt.Errorf("no field found with a valid IPv4 address in body response")
}
} else {
if body == "" {
return "", fmt.Errorf("body is empty")
}
ip = body
}
}
return ip, nil
} }