client.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package gluetun
  2. import (
  3. "encoding/json"
  4. "fmt"
  5. "io"
  6. "net/http"
  7. "os"
  8. "strings"
  9. )
  10. /*
  11. will need to parse a configuration like this:
  12. [[roles]]
  13. name = "qbittorrent"
  14. # Define a list of routes with the syntax "Http-Method /path"
  15. routes = ["GET /v1/portforward"]
  16. # Define an authentication method with its parameters
  17. auth = "basic"
  18. username = "myusername"
  19. password = "mypassword"
  20. Or if using the API key authentication method:
  21. auth = "apikey"
  22. apikey = "myapikey"
  23. the 'apikey' is then sent in the X-API-Key header
  24. we will need to extract the username and password for authentication to gluetun. This will be done by mounting the same
  25. config file that gluetun has to a static location, like /gluetun-qbitt-sidecar/config.toml
  26. will need to just retrieve the exposed port via the route:
  27. GET /v1/portforward ----> {"port":5914}
  28. */
  29. const (
  30. PORT_FORWARD_PATH = "v1/portforward"
  31. API_KEY_HEADER = "X-API-Key"
  32. )
  33. type Port struct {
  34. Port int `json:"port"`
  35. }
  36. type Authentication struct {
  37. ApiKey string `toml:"apikey"`
  38. Username string `toml:"username"`
  39. Password string `toml:"password"`
  40. }
  41. /*
  42. Read in the config.toml file that gluetun uses to set the api key / username and password
  43. :param path: the path to the config file. Use the path for where this is running, since this
  44. can be either ran as a container next to your deployment, or on the host itself
  45. */
  46. func GetAuthentication(path string) (Authentication, error) {
  47. var auth Authentication
  48. _, err := os.ReadFile(path)
  49. if err != nil {
  50. return auth, err
  51. }
  52. return auth, nil
  53. }
  54. // strips everything but the port number and hostname from a string
  55. func sanitizeUrl(s string) string {
  56. protoStripped := strings.ReplaceAll(
  57. strings.ReplaceAll(
  58. strings.ReplaceAll(
  59. s, "https", "",
  60. ), "http", "",
  61. ), "://", "",
  62. )
  63. splitHost := strings.Split(protoStripped, "/")
  64. return splitHost[0]
  65. }
  66. /*
  67. Gets the forwarded port from the server
  68. */
  69. func GetForwardedPort(address string, apiKey string) (Port, error) {
  70. formattedUrl := fmt.Sprintf("http://%s/%s", sanitizeUrl(address), PORT_FORWARD_PATH)
  71. req, err := http.NewRequest(http.MethodGet, formattedUrl, nil)
  72. if err != nil {
  73. return Port{}, err
  74. }
  75. req.Header.Add(API_KEY_HEADER, apiKey)
  76. client := http.Client{}
  77. resp, err := client.Do(req)
  78. if err != nil {
  79. return Port{}, err
  80. }
  81. var b []byte
  82. defer resp.Body.Close()
  83. b, err = io.ReadAll(resp.Body)
  84. if err != nil {
  85. return Port{}, err
  86. }
  87. var port Port
  88. err = json.Unmarshal(b, &port)
  89. if err != nil {
  90. return port, err
  91. }
  92. return port, nil
  93. }