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"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"path/filepath"
@ -22,7 +23,7 @@ import (
"forge.cadoles.com/arcad/edge/pkg/module/blob"
"forge.cadoles.com/arcad/edge/pkg/module/cast"
"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/sqlite"
"gitlab.com/wpetit/goweb/logger"
@ -173,7 +174,7 @@ func getServerModules(bus bus.Bus, ds storage.DocumentStore, bs storage.BlobStor
module.ConsoleModuleFactory(),
cast.CastModuleFactory(),
module.LifecycleModuleFactory(),
net.ModuleFactory(bus),
netModule.ModuleFactory(bus),
module.RPCModuleFactory(bus),
module.StoreModuleFactory(ds),
blob.ModuleFactory(bus, bs),
@ -201,11 +202,22 @@ func getServerModules(bus bus.Bus, ds storage.DocumentStore, bs storage.BlobStor
),
appModule.ModuleFactory(appModuleMemory.NewRepository(
func(ctx context.Context, id app.ID, from string) (string, error) {
if strings.HasPrefix(address, ":") {
address = "0.0.0.0" + address
addr := 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,
)),
@ -284,3 +296,52 @@ func loadLocalAccounts(path string) ([]authHTTP.LocalAccount, error) {
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" })
.then(url => {
console.log("getAppUrl result:", 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) {
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) {