private async void sendRequest(HttpClient client, HttpRequestMessage request, dynamic callback)
        {
            HttpResponseMessage response;

            try
            {
                response = await client.SendAsync(request);
            }
            catch (HttpRequestException x)
            {
                dynamic exp = new JsErrorBuilder(x).SetErrorCode((int)ErrorCodes.NetworkOffline).Build();
                dynamic rz  = engine.ManticoreJsObject._.construct();
                callback(exp, rz);
                return;
            }

            dynamic responseInfo = engine.ManticoreJsObject._.construct();
            dynamic headers      = null;

            foreach (var kv in response.Headers)
            {
                if (headers == null)
                {
                    headers = engine.ManticoreJsObject._.construct();
                }

                headers[kv.Key] = engine.Converter.ToJsArray(kv.Value.ToList(), (v) => v.ToString());
            }

            foreach (var kv in response.Content.Headers)
            {
                if (headers == null)
                {
                    headers = engine.ManticoreJsObject._.construct();
                }

                headers[kv.Key] = engine.Converter.ToJsArray(kv.Value.ToList(), (v) => v.ToString());
            }
            responseInfo.headers = headers;
            responseInfo.status  = (int)response.StatusCode;
            // TODO figure out how to sneak this wait into the readers
            var responseBytes = await response.Content.ReadAsByteArrayAsync();

            responseInfo.json = new Func <dynamic>(() =>
            {
                try
                {
                    return(engine.v8.Script.JSON.parse(Encoding.UTF8.GetString(responseBytes)));
                }
                catch (ScriptEngineException se)
                {
                    return(new JsErrorBuilder(se).Build());
                }
            });
            responseInfo.text = new Func <dynamic>(() => Encoding.UTF8.GetString(responseBytes));
            responseInfo.body = new Func <dynamic>(() => Convert.ToBase64String(responseBytes));
            callback(null, responseInfo);
        }
Ejemplo n.º 2
0
        private async void sendRequest(ManticoreEngine engine, int timeout, HttpClient client, HttpRequestMessage request, JsValue callback)
        {
            var responseInfo = engine.CreateJsObject();
            HttpResponseMessage     response = null;
            CancellationTokenSource cts      = new CancellationTokenSource(timeout);

            try
            {
                response = await client.SendRequestAsync(request, HttpCompletionOption.ResponseContentRead).AsTask(cts.Token);
            }
            catch (Exception x)
            {
                var ei = new JsErrorBuilder(engine, x).Build();
                responseInfo.FastAddProperty("error", ei, false, true, false);
            }

            if (response != null && response.Headers.Count > 0)
            {
                var headerCollection = engine.CreateJsObject();
                foreach (var kv in response.Headers)
                {
                    try
                    {
                        headerCollection.FastAddProperty(kv.Key, new JsValue(kv.Value), false, true, false);
                    }
                    catch (ArgumentException)
                    {
                        // Swallow duplicate headers for now.
                    }
                }
                responseInfo.FastAddProperty("headers", headerCollection, false, true, false);
            }

            byte[] binaryResult = null;
            if (response != null)
            {
                responseInfo.FastAddProperty("status", new JsValue((int)response.StatusCode), false, true, false);
                // TODO find a way to sneak this wait into the gap between returning and asking for the results
                // json/body/text signatures probably need to change to take a callback.
                binaryResult = (await response.Content.ReadAsBufferAsync()).ToArray();
            }
            engine.Js(() =>
            {
                responseInfo.FastAddProperty("json", engine.AsJsFunction((thisObject, args) => {
                    return(engine.jsEngine.Json.Parse(JsValue.Null,
                                                      new JsValue[] { Encoding.UTF8.GetString(binaryResult, 0, binaryResult.Length) }));
                }), false, false, false);
                responseInfo.FastAddProperty("body", engine.AsJsFunction((thisObject, args) => {
                    return(engine.jsEngine.Json.Parse(JsValue.Null, new JsValue[] { Convert.ToBase64String(binaryResult) }));
                }), false, false, false);
                responseInfo.FastAddProperty("text", engine.AsJsFunction((thisObject, args) => {
                    return(new JsValue(Encoding.UTF8.GetString(binaryResult, 0, binaryResult.Length)));
                }), false, false, false);
                callback.As <FunctionInstance>().Call(engine.ManticoreJsObject, new JsValue[] { JsValue.Null, responseInfo });
            });
        }
Ejemplo n.º 3
0
        public void Fetch(ManticoreEngine engine, JsValue optionsValue, JsValue callback)
        {
            var     options = optionsValue.As <ObjectInstance>();
            JsValue rawBody = options.Get("nativeBody").As <FunctionInstance>().Call(options, ManticoreEngine.EmptyArgs);
            var     hasBody = rawBody.IsString() && rawBody.AsString().Length > 0;
            var     request = (HttpWebRequest)WebRequest.Create(options.Get("url").AsString());

            request.Method = "GET";
            if (options.HasProperty("method"))
            {
                request.Method = options.Get("method").AsString();
            }

            if (options.HasProperty("headers"))
            {
                var headers = options.Get("headers").AsObject();
                var raw     = headers.Get("raw").As <FunctionInstance>().Call(headers, ManticoreEngine.EmptyArgs);
                if (raw.IsObject())
                {
                    foreach (var p in raw.AsObject().GetOwnProperties())
                    {
                        if (p.Key.Equals("Content-Type", StringComparison.OrdinalIgnoreCase))
                        {
                            if (hasBody)
                            {
                                request.ContentType = p.Value.Value.Value.AsString();
                            }
                        }
                        else if (p.Key.Equals("If-Modified-Since", StringComparison.OrdinalIgnoreCase))
                        {
                            request.IfModifiedSince = DateTime.Parse(p.Value.Value.Value.AsString());
                        }
                        else
                        {
                            request.Headers.Add(p.Key, p.Value.Value.Value.AsString());
                        }
                    }
                }
            }

            if (hasBody)
            {
                var    body = rawBody.AsString();
                byte[] bodyBytes;
                if (options.HasProperty("isBase64") && options.Get("isBase64").AsBoolean())
                {
                    bodyBytes = Convert.FromBase64String(body);
                }
                else
                {
                    bodyBytes = Encoding.UTF8.GetBytes(body);
                }
                request.ContentLength = bodyBytes.Length;

                var errorInstance = JsValue.Null;
                try
                {
                    var rqStream = request.GetRequestStream();
                    rqStream.Write(bodyBytes, 0, bodyBytes.Length);
                    rqStream.Close();
                }
                catch (Exception x)
                {
                    // TODO fire this log into JS? manticore.onError()?
                    Log("error", x.ToString(), JsValue.Null);
                    var errorBuilder = new JsErrorBuilder(engine, x);
                    if (x is WebException)
                    {
                        errorBuilder.SetErrorCode((int)ErrorCodes.NetworkOffline);
                    }
                    errorInstance = errorBuilder.Build();
                }

                if (errorInstance != JsValue.Null)
                {
                    engine.Js(() =>
                    {
                        callback.As <FunctionInstance>().Call(engine.ManticoreJsObject, new[] { errorInstance, JsValue.Null });
                    });
                    return;
                }
            }

            sendRequest(engine, request, callback);
        }
Ejemplo n.º 4
0
        private void sendRequest(ManticoreEngine engine, HttpWebRequest request, JsValue callback)
        {
            request.BeginGetResponse((asyncResult) =>
            {
                HttpWebResponse response = null;
                var errorInstance        = JsValue.Null;
                try
                {
                    response = (HttpWebResponse)request.EndGetResponse(asyncResult);
                }
                catch (WebException e)
                {
                    if (e.Status == WebExceptionStatus.ProtocolError) //Response was received from server but indicated protocol level error
                    {
                        response = (HttpWebResponse)e.Response;
                    }
                    else
                    {
                        errorInstance = new JsErrorBuilder(engine, e).SetErrorCode((int)ErrorCodes.NetworkOffline).Build();
                    }
                }

                if (response == null)
                {
                    engine.Js(() =>
                    {
                        callback.As <FunctionInstance>().Call(engine.ManticoreJsObject, new[] { errorInstance, JsValue.Null });
                    });
                    return;
                }

                var responseInfo = engine.CreateJsObject();
                if (response.Headers.Count > 0)
                {
                    var headerCollection = engine.CreateJsObject();
                    foreach (var kv in response.Headers.AllKeys)
                    {
                        headerCollection.FastAddProperty(kv, new JsValue(response.Headers[kv]), false, true, false);
                    }
                    responseInfo.FastAddProperty("headers", headerCollection, false, true, false);
                }

                responseInfo.FastAddProperty("status", new JsValue((int)response.StatusCode), false, true, false);
                // TODO find a way to sneak this wait into the gap between returning and asking for the results
                // json/body/text signatures probably need to change to take a callback.
                var memStream = new MemoryStream();
                response.GetResponseStream().CopyTo(memStream);
                var binaryResult = memStream.ToArray();
                responseInfo.FastAddProperty("json", engine.AsJsFunction((thisObject, args) => {
                    return(engine.jsEngine.Json.Parse(JsValue.Null, new JsValue[] { Encoding.UTF8.GetString(binaryResult) }));
                }), false, false, false);
                responseInfo.FastAddProperty("body", engine.AsJsFunction((thisObject, args) => {
                    return(engine.jsEngine.Json.Parse(JsValue.Null, new JsValue[] { Convert.ToBase64String(binaryResult) }));
                }), false, false, false);
                responseInfo.FastAddProperty("text", engine.AsJsFunction((thisObject, args) => {
                    return(new JsValue(Encoding.UTF8.GetString(binaryResult)));
                }), false, false, false);
                engine.Js(() =>
                {
                    callback.As <FunctionInstance>().Call(engine.ManticoreJsObject, new[] { errorInstance, responseInfo });
                });
            }, null);
        }