func DefineWithHandler(vm *otto.Otto, l *loop.Loop, h http.Handler) error { if err := promise.Define(vm, l); err != nil { return err } jsData := rice.MustFindBox("dist-fetch").MustString("bundle.js") smData := rice.MustFindBox("dist-fetch").MustString("bundle.js.map") s, err := vm.CompileWithSourceMap("fetch-bundle.js", jsData, smData) if err != nil { return err } if _, err := vm.Run(s); err != nil { return err } vm.Set("__private__fetch_execute", func(c otto.FunctionCall) otto.Value { jsReq := c.Argument(0).Object() jsRes := c.Argument(1).Object() cb := c.Argument(2) method := mustValue(jsReq.Get("method")).String() urlStr := mustValue(jsReq.Get("url")).String() jsBody := mustValue(jsReq.Get("body")) var body io.Reader if jsBody.IsString() { body = strings.NewReader(jsBody.String()) } t := &fetchTask{ jsReq: jsReq, jsRes: jsRes, cb: cb, } l.Add(t) go func() { defer l.Ready(t) req, err := http.NewRequest(method, urlStr, body) if err != nil { t.err = err return } if h != nil && urlStr[0] == '/' { res := httptest.NewRecorder() h.ServeHTTP(res, req) t.status = res.Code t.statusText = http.StatusText(res.Code) t.headers = res.Header() t.body = res.Body.Bytes() } else { res, err := http.DefaultClient.Do(req) if err != nil { t.err = err return } d, err := ioutil.ReadAll(res.Body) if err != nil { t.err = err return } t.status = res.StatusCode t.statusText = res.Status t.headers = res.Header t.body = d } }() return otto.UndefinedValue() }) return nil }
func DefineWithHandler(vm *otto.Otto, l *loop.Loop, h http.Handler) error { if err := promise.Define(vm, l); err != nil { return err } s, err := vm.Compile("fetch.js", rice.MustFindBox("dist-fetch").MustString("bundle.js")) if err != nil { return err } if _, err := vm.Run(s); err != nil { return err } vm.Set("__private__fetch_execute", func(c otto.FunctionCall) otto.Value { jsReq := c.Argument(0).Object() jsRes := c.Argument(1).Object() cb := c.Argument(2) method := mustValue(jsReq.Get("method")).String() urlStr := mustValue(jsReq.Get("url")).String() jsBody := mustValue(jsReq.Get("body")) var body io.Reader if jsBody.IsString() { body = strings.NewReader(jsBody.String()) } t := &fetchTask{ jsReq: jsReq, jsRes: jsRes, cb: cb, } l.Add(t) go func() { defer l.Ready(t) req, err := http.NewRequest(method, urlStr, body) if err != nil { t.err = err return } if h != nil && urlStr[0] == '/' { res := httptest.NewRecorder() h.ServeHTTP(res, req) jsRes.Set("status", res.Code) jsRes.Set("statusText", http.StatusText(res.Code)) h := mustValue(jsRes.Get("headers")).Object() for k, vs := range res.Header() { for _, v := range vs { if _, err := h.Call("append", k, v); err != nil { t.err = err return } } } jsRes.Set("_body", string(res.Body.Bytes())) } else { res, err := http.DefaultClient.Do(req) if err != nil { t.err = err return } jsRes.Set("status", res.StatusCode) jsRes.Set("statusText", res.Status) h := mustValue(jsRes.Get("headers")).Object() for k, vs := range res.Header { for _, v := range vs { if _, err := h.Call("append", k, v); err != nil { t.err = err return } } } d, err := ioutil.ReadAll(res.Body) if err != nil { t.err = err return } jsRes.Set("_body", string(d)) } }() return otto.UndefinedValue() }) return nil }
func main() { flag.Parse() vm := otto.New() if *debugger { vm.SetDebuggerHandler(repl.DebuggerHandler) } l := loop.New(vm) if err := timers.Define(vm, l); err != nil { panic(err) } if err := promise.Define(vm, l); err != nil { panic(err) } if err := fetch.Define(vm, l); err != nil { panic(err) } if err := process.Define(vm, flag.Args()); err != nil { panic(err) } blockingTask := looptask.NewEvalTask("") if len(flag.Args()) == 0 || *openRepl { l.Add(blockingTask) } if len(flag.Args()) > 0 { d, err := ioutil.ReadFile(flag.Arg(0)) if err != nil { panic(err) } // this is a very cheap way of "supporting" shebang lines if d[0] == '#' { d = []byte("// " + string(d)) } s, err := vm.Compile(flag.Arg(0), string(d)) if err != nil { panic(err) } if err := l.Eval(s); err != nil { panic(err) } } if len(flag.Args()) == 0 || *openRepl { go func() { if err := erepl.Run(l); err != nil && err != io.EOF { panic(err) } l.Ready(blockingTask) }() } if err := l.Run(); err != nil { panic(err) } }