// HttpHandler provides an http handler for Haxe remoting calls func HttpHandler(rw http.ResponseWriter, req *http.Request) { // TODO add further validaton of the request as from a valid Haxe user here? if req.Header.Get("X-Haxe-Remoting") != "1" { rw.WriteHeader(http.StatusBadRequest) log.Panic("header does not contain X-Haxe-Remoting=1") return } p, e := ioutil.ReadAll(req.Body) //fmt.Printf("DEBUG Request: %#v\nBody: %s, err=%v\n", *req, p, e) if e != nil { rw.WriteHeader(http.StatusBadRequest) log.Panic(e) return } if len(p) < 4 { rw.WriteHeader(http.StatusBadRequest) log.Panic("no body") return } if string(p[:4]) != "__x=" { rw.WriteHeader(http.StatusBadRequest) log.Panic("__x= not found") return } une, err := url.QueryUnescape(string(p[4:])) if err != nil { rw.WriteHeader(http.StatusBadRequest) log.Panic(err) return } buf := []byte(une) //fmt.Printf("DEBUG URL unescaped = %s\n", string(buf)) var targetA interface{} target := "" targetA, buf, err = haxeremote.Unserialize(buf) for i, t := range targetA.([]interface{}) { if i > 0 { target += "." } target += t.(string) } //fmt.Printf("DEBUG Unserialized Target decoded=%s, remaining=%s, error=%v\n", target, buf, err) var args interface{} args, buf, err = haxeremote.Unserialize(buf) //fmt.Printf("DEBUG Unserialized Args decoded=%v, remaining=%s, error=%v\n", args, buf, err) results, err := callHaxeRemoteFunc(target, args) if err != nil { rw.WriteHeader(http.StatusBadRequest) log.Panic(err) return } reply := "hxr" + haxeremote.Serialize(results) fmt.Fprintln(rw, reply) //fmt.Printf("DEBUG haxe http remote results: %v serialized-reply: %s\n", results, reply) }
func TgoCall(serialized string) string { args, _, err := haxeremote.Unserialize([]byte(serialized)) if err != nil { panic(err) } results := tgoremote.CallFunc(args) reply := haxeremote.Serialize(results) //fmt.Printf("DEBUG TgoCall results: %v serialized-reply: %s\n", results, reply) return reply }
// Call as if via Haxe remote to local haxe function func Call(path, args interface{}) interface{} { callMutex.Lock() defer callMutex.Unlock() s := haxeremote.Serialize(path) + haxeremote.Serialize(args) if C.hxrCalling != 0 { panic("C.hxrCalling != 0") } C.hxrIn = C.CString(s) C.hxrCalling = 1 for C.hxrCalling != 0 { // wait for the call to complete runtime.Gosched() } C.free(unsafe.Pointer(C.hxrIn)) rs := C.GoString(C.hxrOut) rs = strings.TrimPrefix(rs, "hxr") rv, _, err := haxeremote.Unserialize([]byte(rs)) if err != nil { return interface{}(err) } return rv }