Beispiel #1
0
func (c *Context) makeHttpRequest(method string, call otto.FunctionCall) otto.Value {
	val := c.sendHttpRequest(method, call)
	callback := call.Argument(len(call.ArgumentList) - 1)
	if callback.IsFunction() {
		callback.Call(otto.Value{}, val)
	}
	return val
}
Beispiel #2
0
func (c *Context) htmlParse(call otto.FunctionCall) otto.Value {
	doc, err := html.Parse(strings.NewReader(call.Argument(0).String()))
	if err != nil {
		c.Errorf("error parsing HTML: %s\n", err)
		return otto.Value{}
	}
	val, err := c.vm.ToValue(asNode(doc, c.vm))
	if err != nil {
		panic(err)
	}
	return val
}
Beispiel #3
0
func (c *Context) htmlParseFragment(call otto.FunctionCall) otto.Value {
	fragment := call.Argument(0).String()
	var ctx *html.Node
	arg1, _ := call.Argument(1).Export()
	if c, ok := arg1.(*node); ok {
		ctx = c.node
	}
	nodes, err := html.ParseFragment(strings.NewReader(fragment), ctx)
	if err != nil {
		c.Errorf("error parsing HTML fragment: %s\n", err)
		return otto.Value{}
	}
	values := make([]*node, len(nodes))
	for ii, v := range nodes {
		values[ii] = asNode(v, c.vm)
	}
	val, err := c.vm.ToValue(values)
	if err != nil {
		panic(err)
	}
	return val
}
Beispiel #4
0
func (n *node) Visit(call otto.FunctionCall) otto.Value {
	fn := call.Argument(0)
	if fn.IsFunction() {
		thisVal, err := n.vm.ToValue(nil)
		if err != nil {
			panic(err)
		}
		n.visit(n.node, func(node *html.Node) bool {
			nodeVal, err := n.vm.ToValue(asNode(node, n.vm))
			if err != nil {
				panic(err)
			}
			res, err := fn.Call(thisVal, nodeVal)
			if err != nil {
				panic(err)
			}
			if b, _ := res.ToBoolean(); b {
				return true
			}
			return false
		})
	}
	return otto.Value{}
}
Beispiel #5
0
func (c *Context) sendHttpRequest(method string, call otto.FunctionCall) otto.Value {
	idx := 0
	if method == "" {
		method = call.Argument(0).String()
		idx = 1
	}
	method = strings.ToUpper(method)
	u := call.Argument(idx).String()
	idx++
	var qs string
	data := call.Argument(idx)
	idx++
	if data.IsObject() {
		values := make(url.Values)
		obj := data.Object()
		for _, k := range obj.Keys() {
			val, err := obj.Get(k)
			if err != nil {
				c.Errorf("error getting object key %q: %s", k, err)
				return otto.Value{}
			}
			values.Add(k, val.String())
			qs = values.Encode()
		}
	} else if !data.IsUndefined() && !data.IsNull() {
		qs = data.String()
	}
	if len(qs) > 0 && !methodHasBody(method) {
		sep := "?"
		if strings.IndexByte(u, '?') >= 0 {
			sep = "&"
		}
		u += sep + qs
	}
	c.Debugf("%s - %s\n", method, u)
	req, err := http.NewRequest(method, u, nil)
	if err != nil {
		return c.responseError(err)
	}
	opts := call.Argument(idx)
	idx++
	var cache bool
	if opts.IsObject() {
		obj := opts.Object()
		for _, k := range obj.Keys() {
			val, err := obj.Get(k)
			if err != nil {
				c.Errorf("error getting object key %q: %s", k, err)
				return otto.Value{}
			}
			switch strings.ToLower(k) {
			case "headers":
				if !val.IsObject() {
					c.Errorf("headers must be an object")
					return otto.Value{}
				}
				hobj := val.Object()
				for _, hk := range hobj.Keys() {
					hval, err := hobj.Get(hk)
					if err != nil {
						c.Errorf("error getting object key %q: %s", k, err)
						return otto.Value{}
					}
					req.Header.Add(hk, hval.String())
				}
			case "cache":
				cache, _ = val.ToBoolean()
			}
		}
	}
	if len(qs) > 0 && methodHasBody(method) {
		req.Body = &readerCloser{strings.NewReader(qs)}
		if method == "POST" && len(req.Header["Content-Type"]) == 0 {
			req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
		}
	}
	if cache && !methodHasBody(method) {
		// Try cache
		if entry, err := c.cache.cachedEntry(u); err == nil {
			c.Debugf("cached response from %s\n", u)
			return c.newHTTPResponse(u, entry.URL, entry.Data, entry.StatusCode, entry.Header)
		}
	}
	resp, err := c.httpClient().Do(req)
	if err != nil {
		return c.responseError(err)
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return c.responseError(err)
	}
	if cache && !methodHasBody(method) {
		// Save into cache
		if err := c.cache.cacheData(u, body, resp); err != nil {
			c.Debugf("error caching response from %s: %s\n", u, err)
		}
	}
	return c.newHTTPResponse(u, resp.Request.URL.String(), body, resp.StatusCode, resp.Header)
}
Beispiel #6
0
func imageReader(call otto.FunctionCall) (io.Reader, error) {
	return strings.NewReader(call.Argument(0).String()), nil
}