浏览代码

Added agi support for http redirect

Toby Chui 2 年之前
父节点
当前提交
9c52a466e5
共有 11 个文件被更改,包括 43 次插入15 次删除
  1. 3 0
      agi-doc.md
  2. 1 1
      main.flags.go
  3. 2 1
      mod/agi/agi.appdata.go
  4. 2 1
      mod/agi/agi.audio.go
  5. 2 1
      mod/agi/agi.file.go
  6. 6 6
      mod/agi/agi.go
  7. 20 1
      mod/agi/agi.http.go
  8. 2 1
      mod/agi/agi.image.go
  9. 2 1
      mod/agi/agi.iot.go
  10. 2 1
      mod/agi/agi.share.go
  11. 1 1
      mod/agi/userFunc.go

+ 3 - 0
agi-doc.md

@@ -678,6 +678,9 @@ http.download("http://example.com/music.mp3", "user:/Desktop", "(Optional) My Mu
 //Since agi v2.0
 http.getb64("http://example.com/photo.png"); //Get target resources as base64 bytes, return null if error
 http.getCode("http://redirect.example.com"); //Get response code for the target endpoint,if the code is redirection related (e.g. 302), a new varaible "_location" will be created to store the redirection address in String.
+
+//Since agi 2.3
+http.redirect("https://example.com", 307); //Redirect to target with status code
 ```
 
 ### websocket

+ 1 - 1
main.flags.go

@@ -29,7 +29,7 @@ var subserviceBasePort = 12810            //Next subservice port
 
 // =========== SYSTEM BUILD INFORMATION ==============
 var build_version = "development"                      //System build flag, this can be either {development / production / stable}
-var internal_version = "0.2.017"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
+var internal_version = "0.2.018"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
 var deviceUUID string                                  //The device uuid of this host
 var deviceVendor = "IMUSLAB.INC"                       //Vendor of the system
 var deviceVendorURL = "http://imuslab.com"             //Vendor contact information

+ 2 - 1
mod/agi/agi.appdata.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"errors"
 	"log"
+	"net/http"
 	"os"
 	"path/filepath"
 
@@ -32,7 +33,7 @@ func (g *Gateway) AppdataLibRegister() {
 	}
 }
 
-func (g *Gateway) injectAppdataLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectAppdataLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 	vm.Set("_appdata_readfile", func(call otto.FunctionCall) otto.Value {
 		relpath, err := call.Argument(0).ToString()
 		if err != nil {

+ 2 - 1
mod/agi/agi.audio.go

@@ -2,6 +2,7 @@ package agi
 
 import (
 	"log"
+	"net/http"
 
 	"github.com/robertkrimen/otto"
 	"imuslab.com/arozos/mod/filesystem"
@@ -25,6 +26,6 @@ func (g *Gateway) AudioLibRegister() {
 	}
 }
 
-func (g *Gateway) injectAudioFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectAudioFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 
 }

+ 2 - 1
mod/agi/agi.file.go

@@ -8,6 +8,7 @@ import (
 	"io"
 	"io/fs"
 	"log"
+	"net/http"
 	"os"
 	"path/filepath"
 
@@ -34,7 +35,7 @@ func (g *Gateway) FileLibRegister() {
 	}
 }
 
-func (g *Gateway) injectFileLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectFileLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 	//writeFile(virtualFilepath, content) => return true/false when succeed / failed
 	vm.Set("_filelib_writeFile", func(call otto.FunctionCall) otto.Value {
 		vpath, err := call.Argument(0).ToString()

+ 6 - 6
mod/agi/agi.go

@@ -33,7 +33,7 @@ import (
 */
 
 var (
-	AgiVersion string = "2.2" //Defination of the agi runtime version. Update this when new function is added
+	AgiVersion string = "2.3" //Defination of the agi runtime version. Update this when new function is added
 
 	//AGI Internal Error Standard
 	errExitcall = errors.New("errExit")
@@ -41,7 +41,7 @@ var (
 )
 
 // Lib interface, require vm, user, target system file handler and the vpath of the running script
-type AgiLibIntergface func(*otto.Otto, *user.User, *filesystem.FileSystemHandler, string) //Define the lib loader interface for AGI Libraries
+type AgiLibIntergface func(*otto.Otto, *user.User, *filesystem.FileSystemHandler, string, http.ResponseWriter, *http.Request) //Define the lib loader interface for AGI Libraries
 type AgiPackage struct {
 	InitRoot string //The initialization of the root for the module that request this package
 }
@@ -338,16 +338,16 @@ func (g *Gateway) ExecuteAGIScript(scriptContent string, fsh *filesystem.FileSys
 }
 
 /*
-	Execute AGI script with given user information
-	scriptFile must be realpath resolved by fsa VirtualPathToRealPath function
-	Pass in http.Request pointer to enable serverless GET / POST request
+Execute AGI script with given user information
+scriptFile must be realpath resolved by fsa VirtualPathToRealPath function
+Pass in http.Request pointer to enable serverless GET / POST request
 */
 func (g *Gateway) ExecuteAGIScriptAsUser(fsh *filesystem.FileSystemHandler, scriptFile string, targetUser *user.User, w http.ResponseWriter, r *http.Request) (string, error) {
 	//Create a new vm for this request
 	vm := otto.New()
 	//Inject standard libs into the vm
 	g.injectStandardLibs(vm, scriptFile, "")
-	g.injectUserFunctions(vm, fsh, scriptFile, "", targetUser, nil, nil)
+	g.injectUserFunctions(vm, fsh, scriptFile, "", targetUser, w, r)
 
 	if r != nil {
 		//Inject serverless script to enable access to GET / POST paramters

+ 20 - 1
mod/agi/agi.http.go

@@ -32,7 +32,7 @@ func (g *Gateway) HTTPLibRegister() {
 	}
 }
 
-func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 	vm.Set("_http_get", func(call otto.FunctionCall) otto.Value {
 		//Get URL from function variable
 		url, err := call.Argument(0).ToString()
@@ -250,6 +250,24 @@ func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User, scriptFsh *fi
 		return r
 	})
 
+	vm.Set("_http_redirect", func(call otto.FunctionCall) otto.Value {
+		//Redirect the current request to another url
+		targetUrl, err := call.Argument(0).ToString()
+		if err != nil {
+			return otto.NullValue()
+		}
+
+		statusCode, err := call.Argument(1).ToInteger()
+		if err != nil {
+			//Default: Temporary redirect
+			statusCode = 307
+		}
+
+		w.Header().Set("Location", targetUrl)
+		w.WriteHeader(int(statusCode))
+		return otto.TrueValue()
+	})
+
 	//Wrap all the native code function into an imagelib class
 	vm.Run(`
 		var http = {};
@@ -259,6 +277,7 @@ func (g *Gateway) injectHTTPFunctions(vm *otto.Otto, u *user.User, scriptFsh *fi
 		http.download = _http_download;
 		http.getb64 = _http_getb64;
 		http.getCode = _http_code;
+		http.redirect = _http_redirect;
 	`)
 
 }

+ 2 - 1
mod/agi/agi.image.go

@@ -10,6 +10,7 @@ import (
 	"image/png"
 	_ "image/png"
 	"log"
+	"net/http"
 	"os"
 	"path/filepath"
 	"strings"
@@ -39,7 +40,7 @@ func (g *Gateway) ImageLibRegister() {
 	}
 }
 
-func (g *Gateway) injectImageLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectImageLibFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 	//Get image dimension, requires filepath (virtual)
 	vm.Set("_imagelib_getImageDimension", func(call otto.FunctionCall) otto.Value {
 		imageFileVpath, err := call.Argument(0).ToString()

+ 2 - 1
mod/agi/agi.iot.go

@@ -3,6 +3,7 @@ package agi
 import (
 	"encoding/json"
 	"log"
+	"net/http"
 
 	"github.com/robertkrimen/otto"
 	"imuslab.com/arozos/mod/filesystem"
@@ -26,7 +27,7 @@ func (g *Gateway) IoTLibRegister() {
 	}
 }
 
-func (g *Gateway) injectIoTFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectIoTFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 	//Scan and return the latest iot device list
 	vm.Set("_iot_scan", func(call otto.FunctionCall) otto.Value {
 		scannedDevices := g.Option.IotManager.ScanDevices()

+ 2 - 1
mod/agi/agi.share.go

@@ -2,6 +2,7 @@ package agi
 
 import (
 	"log"
+	"net/http"
 	"time"
 
 	"github.com/robertkrimen/otto"
@@ -16,7 +17,7 @@ func (g *Gateway) ShareLibRegister() {
 	}
 }
 
-func (g *Gateway) injectShareFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string) {
+func (g *Gateway) injectShareFunctions(vm *otto.Otto, u *user.User, scriptFsh *filesystem.FileSystemHandler, scriptPath string, w http.ResponseWriter, r *http.Request) {
 	vm.Set("_share_file", func(call otto.FunctionCall) otto.Value {
 		//Get the vpath of file to share
 		vpath, err := call.Argument(0).ToString()

+ 1 - 1
mod/agi/userFunc.go

@@ -246,7 +246,7 @@ func (g *Gateway) injectUserFunctions(vm *otto.Otto, fsh *filesystem.FileSystemH
 		} else {
 			//Check if the library name exists. If yes, run the initiation script on the vm
 			if entryPoint, ok := g.LoadedAGILibrary[libname]; ok {
-				entryPoint(vm, u, fsh, scriptPath)
+				entryPoint(vm, u, fsh, scriptPath, w, r)
 				return otto.TrueValue()
 			} else {
 				//Lib not exists