feat(cli,run): resolve app url based on available network interfaces

This commit is contained in:
wpetit 2023-04-06 11:52:04 +02:00
parent 050e529f0a
commit 32c6f0a77e
3 changed files with 80 additions and 7 deletions

View File

@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"net"
"net/http" "net/http"
"os" "os"
"path/filepath" "path/filepath"
@ -22,7 +23,7 @@ import (
"forge.cadoles.com/arcad/edge/pkg/module/blob" "forge.cadoles.com/arcad/edge/pkg/module/blob"
"forge.cadoles.com/arcad/edge/pkg/module/cast" "forge.cadoles.com/arcad/edge/pkg/module/cast"
"forge.cadoles.com/arcad/edge/pkg/module/fetch" "forge.cadoles.com/arcad/edge/pkg/module/fetch"
"forge.cadoles.com/arcad/edge/pkg/module/net" netModule "forge.cadoles.com/arcad/edge/pkg/module/net"
"forge.cadoles.com/arcad/edge/pkg/storage" "forge.cadoles.com/arcad/edge/pkg/storage"
"forge.cadoles.com/arcad/edge/pkg/storage/sqlite" "forge.cadoles.com/arcad/edge/pkg/storage/sqlite"
"gitlab.com/wpetit/goweb/logger" "gitlab.com/wpetit/goweb/logger"
@ -173,7 +174,7 @@ func getServerModules(bus bus.Bus, ds storage.DocumentStore, bs storage.BlobStor
module.ConsoleModuleFactory(), module.ConsoleModuleFactory(),
cast.CastModuleFactory(), cast.CastModuleFactory(),
module.LifecycleModuleFactory(), module.LifecycleModuleFactory(),
net.ModuleFactory(bus), netModule.ModuleFactory(bus),
module.RPCModuleFactory(bus), module.RPCModuleFactory(bus),
module.StoreModuleFactory(ds), module.StoreModuleFactory(ds),
blob.ModuleFactory(bus, bs), blob.ModuleFactory(bus, bs),
@ -201,11 +202,22 @@ func getServerModules(bus bus.Bus, ds storage.DocumentStore, bs storage.BlobStor
), ),
appModule.ModuleFactory(appModuleMemory.NewRepository( appModule.ModuleFactory(appModuleMemory.NewRepository(
func(ctx context.Context, id app.ID, from string) (string, error) { func(ctx context.Context, id app.ID, from string) (string, error) {
if strings.HasPrefix(address, ":") { addr := address
address = "0.0.0.0" + address if strings.HasPrefix(addr, ":") {
addr = "0.0.0.0" + addr
} }
return fmt.Sprintf("http://%s", address), nil host, port, err := net.SplitHostPort(addr)
if err != nil {
return "", errors.WithStack(err)
}
addr, err = findMatchingDeviceAddress(ctx, from, host)
if err != nil {
return "", errors.WithStack(err)
}
return fmt.Sprintf("http://%s:%s", addr, port), nil
}, },
manifest, manifest,
)), )),
@ -284,3 +296,52 @@ func loadLocalAccounts(path string) ([]authHTTP.LocalAccount, error) {
return accounts, nil return accounts, nil
} }
func findMatchingDeviceAddress(ctx context.Context, from string, defaultAddr string) (string, error) {
if from == "" {
return defaultAddr, nil
}
fromIP := net.ParseIP(from)
if fromIP == nil {
return defaultAddr, nil
}
ifaces, err := net.Interfaces()
if err != nil {
return "", errors.WithStack(err)
}
for _, ifa := range ifaces {
addrs, err := ifa.Addrs()
if err != nil {
logger.Error(
ctx, "could not retrieve iface adresses",
logger.E(errors.WithStack(err)), logger.F("iface", ifa.Name),
)
continue
}
for _, addr := range addrs {
ip, network, err := net.ParseCIDR(addr.String())
if err != nil {
logger.Error(
ctx, "could not parse address",
logger.E(errors.WithStack(err)), logger.F("address", addr.String()),
)
continue
}
if !network.Contains(fromIP) {
continue
}
return ip.String(), nil
}
}
return defaultAddr, nil
}

View File

@ -26,11 +26,21 @@ describe('App Module', function() {
}) })
}); });
it('should retrieve requested app url', function() { it('should retrieve requested app url without from address', function() {
return Edge.rpc("getAppUrl", { appId: "edge.sdk.client.test" }) return Edge.rpc("getAppUrl", { appId: "edge.sdk.client.test" })
.then(url => { .then(url => {
console.log("getAppUrl result:", url); console.log("getAppUrl result:", url);
chai.assert.isNotEmpty(url); chai.assert.isNotEmpty(url);
chai.assert.match(url, /^http:\/\/0\.0\.0\.0/)
})
});
it('should retrieve requested app url with from address', function() {
return Edge.rpc("getAppUrl", { appId: "edge.sdk.client.test", from: "127.0.0.2" })
.then(url => {
console.log("getAppUrl result:", url);
chai.assert.isNotEmpty(url);
chai.assert.match(url, /^http:\/\/127\.0\.0\.1/)
}) })
}); });

View File

@ -96,7 +96,9 @@ function getApp(ctx, params) {
function getAppUrl(ctx, params) { function getAppUrl(ctx, params) {
var appId = params.appId; var appId = params.appId;
return app.getUrl(ctx, appId); var from = params.from;
return app.getUrl(ctx, appId, from ? from : '');
} }
function onClientFetch(ctx, url, remoteAddr) { function onClientFetch(ctx, url, remoteAddr) {