-
-
Save jeromegn/cb76ba14437ab688074c6b2d607d358d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package xhr | |
import ( | |
"bytes" | |
"io" | |
"io/ioutil" | |
"net/http" | |
"net/textproto" | |
"github.com/dop251/goja" | |
"github.com/dop251/goja_nodejs/eventloop" | |
) | |
var program *goja.Program | |
// Enable ... | |
func Enable(r *goja.Runtime, loop *eventloop.EventLoop) { | |
r.Set("__xhr__", xhr(loop)) | |
_, err := r.RunProgram(program) | |
if err != nil { | |
panic(err) | |
} | |
} | |
func xhr(loop *eventloop.EventLoop) func(goja.FunctionCall) goja.Value { | |
return func(call goja.FunctionCall) goja.Value { | |
if fn, ok := goja.AssertFunction(call.Argument(1)); ok { | |
o := call.Argument(0).Export().(map[string]interface{}) | |
go func() { | |
var body io.Reader | |
method := http.MethodGet | |
header := make(http.Header) | |
if headers, ex := o["headers"]; ex { | |
if hmap, okh := headers.(map[string]interface{}); okh { | |
for key, value := range hmap { | |
v := value.([]interface{}) | |
for _, item := range v { | |
var i []string | |
i = append(i, item.(string)) | |
header[textproto.CanonicalMIMEHeaderKey(key)] = i | |
} | |
} | |
} | |
} | |
if b, ex := o["body"]; ex { | |
if bo, ok := b.(string); ok { | |
body = bytes.NewBufferString(bo) | |
} | |
} | |
if m, ex := o["method"]; ex { | |
if me, ok := m.(string); ok { | |
method = me | |
} | |
} | |
var url string | |
if u, ex := o["url"]; ex { | |
if ur, ok := u.(string); ok { | |
url = ur | |
} else { | |
panic("bad url") | |
} | |
} | |
var toRet map[string]interface{} | |
req, err := http.NewRequest(method, url, body) | |
if err != nil { | |
toRet = map[string]interface{}{ | |
"status": 0, | |
} | |
} else { | |
req.Header = header | |
res, err := http.DefaultClient.Do(req) | |
if err != nil { | |
toRet = map[string]interface{}{ | |
"status": 0, | |
} | |
} else { | |
toRet = map[string]interface{}{ | |
"headers": res.Header, | |
"status": res.StatusCode, | |
"statusText": res.Status, | |
"method": method, | |
"url": url, | |
} | |
} | |
} | |
loop.RunOnLoop(func(r *goja.Runtime) { | |
fn(nil, r.ToValue(toRet)) | |
}) | |
}() | |
} | |
return nil | |
} | |
} | |
func init() { | |
b, err := ioutil.ReadFile("xhr.js") | |
if err != nil { | |
panic(err) | |
} | |
program = goja.MustCompile("xhr.js", string(b), false) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var __goxhr__ = global.__xhr__; | |
delete global.__xhr__; | |
function XMLHttpRequest() { | |
// console.log("create a xhr") | |
} | |
XMLHttpRequest.UNSENT = 0 | |
XMLHttpRequest.OPENED = 1 | |
XMLHttpRequest.HEADERS_RECEIVED = 2 | |
XMLHttpRequest.LOADING = 3 | |
XMLHttpRequest.DONE = 4 | |
XMLHttpRequest.prototype = { | |
open: function (method, url, async) { | |
// console.log("opened a xhr", method, url, async); | |
this.__method = method | |
this.__url = url | |
this.__async = !!async | |
this._updateReadyState(XMLHttpRequest.OPENED) | |
}, | |
setRequestHeader: function (name, value) { | |
this.__headers || (this.__headers = {}) | |
this.__headers[name] = value | |
}, | |
send: function (body) { | |
// console.log("xhr send"); | |
var that = this | |
__goxhr__({ | |
url: this.__url, | |
method: this.__method, | |
headers: this.__headers, | |
body: body | |
}, function (res) { | |
// console.log("xhr got response")//, JSON.stringify(res)); | |
that.status = res.status | |
that.statusText = res.statusText | |
that.responseHeaders = res.headers | |
that.responseText = res.body | |
that._updateReadyState(XMLHttpRequest.DONE) | |
}) | |
this._updateReadyState(XMLHttpRequest.LOADING) | |
}, | |
getResponseHeader: function (name) { | |
// console.log("get response header"); | |
this.responseHeaders || (this.responseHeaders = {}) | |
return this.responseHeaders[name] | |
}, | |
getAllResponseHeaders: function () { | |
// console.log("get all response headers") | |
this.responseHeaders || (this.responseHeaders = {}); | |
var keys = Object.keys(this.responseHeaders) | |
var str = "" | |
for (var i = keys.length; i <= 0; i--) { | |
str += keys[i] + ": " + this.responseHeaders[keys[i]] + "\n" | |
} | |
return str | |
}, | |
_updateReadyState: function (state) { | |
// console.log("set ready state:", state) | |
this.readyState = state | |
if (typeof this.onreadystatechange == 'function') { | |
this.onreadystatechange() | |
} | |
} | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment