Beispiel #1
0
        static Task <WebResponse> ExecHttpRequestInternalAsync(Context ctx, CURLResource ch, Uri uri)
        {
            var req = WebRequest.CreateHttp(uri);

            // setup request:

            Debug.Assert(ch.Method != null, "Method == null");

            req.Method            = ch.Method;
            req.AllowAutoRedirect = ch.FollowLocation && ch.MaxRedirects != 0;
            req.Timeout           = ch.Timeout <= 0 ? System.Threading.Timeout.Infinite : ch.Timeout;
            req.ContinueTimeout   = ch.ContinueTimeout;
            req.Accept            = "*/*"; // default value
            if (req.AllowAutoRedirect)
            {
                // equal or less than 0 will cause exception
                req.MaximumAutomaticRedirections = ch.MaxRedirects < 0 ? int.MaxValue : ch.MaxRedirects;
            }
            if (ch.CookieContainer != null)
            {
                if (ch.Result != null)
                {
                    // pass cookies from previous response to the request
                    AddCookies(ch.Result.Cookies, ch.CookieContainer);
                }
                req.CookieContainer = ch.CookieContainer;
            }
            //req.AutomaticDecompression = (DecompressionMethods)~0; // NOTICE: this nullify response Content-Length and Content-Encoding
            if (ch.CookieHeader != null)
            {
                TryAddCookieHeader(req, ch.CookieHeader);
            }
            if (ch.Username != null)
            {
                req.Credentials = new NetworkCredential(ch.Username, ch.Password ?? string.Empty);
            }
            // TODO: certificate
            if (!string.IsNullOrEmpty(ch.ProxyType) && !string.IsNullOrEmpty(ch.ProxyHost))
            {
                req.Proxy = new WebProxy($"{ch.ProxyType}://{ch.ProxyHost}:{ch.ProxyPort}")
                {
                    Credentials = string.IsNullOrEmpty(ch.ProxyUsername)
                        ? null
                        : new NetworkCredential(ch.ProxyUsername, ch.ProxyPassword ?? string.Empty)
                };
            }
            else
            {
                // by default, curl does not go through system proxy
                req.Proxy = s_DefaultProxy.Value;
            }

            //
            ch.ApplyOptions(ctx, req);

            // make request:

            // GET, HEAD
            if (string.Equals(ch.Method, WebRequestMethods.Http.Get, StringComparison.OrdinalIgnoreCase) ||
                string.Equals(ch.Method, WebRequestMethods.Http.Head, StringComparison.OrdinalIgnoreCase))
            {
                // nothing to do
            }
            // POST
            else if (string.Equals(ch.Method, WebRequestMethods.Http.Post, StringComparison.OrdinalIgnoreCase))
            {
                ProcessPost(ctx, req, ch);
            }
            // PUT
            else if (string.Equals(ch.Method, WebRequestMethods.Http.Put, StringComparison.OrdinalIgnoreCase))
            {
                ProcessPut(req, ch);
            }
            // DELETE, or custom method
            else
            {
                // custom method, nothing to do
            }

            //
            if (ch.StoreRequestHeaders)
            {
                ch.RequestHeaders = HttpHeaders.HeaderString(req); // and restore it when constructing CURLResponse
            }

            //
            return(req.GetResponseAsync());
        }
Beispiel #2
0
        static PhpValue ProcessResponse(Context ctx, CURLResource ch, HttpWebResponse response)
        {
            // in case we are returning the response value
            var returnstream = ch.ProcessingResponse.Method == ProcessMethodEnum.RETURN
                ? new MemoryStream()
                : null;

            // handle headers
            if (!ch.ProcessingHeaders.IsEmpty)
            {
                switch (ch.ProcessingHeaders.Method)
                {
                case ProcessMethodEnum.RETURN:
                case ProcessMethodEnum.STDOUT:
                    (returnstream ?? ctx.OutputStream).Write(response.Headers.ToByteArray());
                    break;

                case ProcessMethodEnum.FILE:
                    ch.ProcessingHeaders.Stream.RawStream.Write(response.Headers.ToByteArray());
                    break;

                case ProcessMethodEnum.USER:
                    // pass headers one by one,
                    // in original implementation we should pass them as they are read from socket:

                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClr(ch),
                        PhpValue.Create(HttpHeaders.StatusHeader(response) + HttpHeaders.HeaderSeparator)
                    });

                    for (int i = 0; i < response.Headers.Count; i++)
                    {
                        // header
                        ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                            PhpValue.FromClr(ch),
                            PhpValue.Create(response.Headers[i] + HttpHeaders.HeaderSeparator),
                        });
                    }

                    // \r\n
                    ch.ProcessingHeaders.User.Invoke(ctx, new[] {
                        PhpValue.FromClr(ch),
                        PhpValue.Create(HttpHeaders.HeaderSeparator)
                    });

                    break;

                default:
                    Debug.Fail("Unexpected ProcessingHeaders " + ch.ProcessingHeaders.Method);
                    break;
                }
            }

            var stream = response.GetResponseStream();

            // read into output stream:
            switch (ch.ProcessingResponse.Method)
            {
            case ProcessMethodEnum.STDOUT: stream.CopyTo(ctx.OutputStream); break;

            case ProcessMethodEnum.RETURN: stream.CopyTo(returnstream); break;

            case ProcessMethodEnum.FILE: stream.CopyTo(ch.ProcessingResponse.Stream.RawStream); break;

            case ProcessMethodEnum.USER:
                if (response.ContentLength != 0)
                {
                    // preallocate a buffer to read to,
                    // this should be according to PHP's behavior and slightly more effective than memory stream
                    byte[] buffer = new byte[ch.BufferSize > 0 ? ch.BufferSize : 2048];
                    int    bufferread;

                    while ((bufferread = stream.Read(buffer, 0, buffer.Length)) > 0)
                    {
                        ch.ProcessingResponse.User.Invoke(ctx, new[]
                        {
                            PhpValue.FromClr(ch),
                            PhpValue.Create(new PhpString(buffer.AsSpan(0, bufferread).ToArray())),     // clone the array and pass to function
                        });
                    }
                }
                break;

            case ProcessMethodEnum.IGNORE: break;
            }

            //

            return((returnstream != null)
                ? PhpValue.Create(new PhpString(returnstream.ToArray()))
                : PhpValue.True);
        }
Beispiel #3
0
        static Task <WebResponse> ExecHttpRequestInternalAsync(Context ctx, CURLResource ch, Uri uri)
        {
            var req = WebRequest.CreateHttp(uri);

            // setup request:

            Debug.Assert(ch.Method != null, "Method == null");

            req.Method                       = ch.Method;
            req.AllowAutoRedirect            = ch.FollowLocation;
            req.Timeout                      = ch.Timeout;
            req.ContinueTimeout              = ch.ContinueTimeout;
            req.MaximumAutomaticRedirections = ch.MaxRedirects;
            if (ch.UserAgent != null)
            {
                req.UserAgent = ch.UserAgent;
            }
            if (ch.ProtocolVersion != null)
            {
                req.ProtocolVersion = ch.ProtocolVersion;
            }
            if (ch.Referer != null)
            {
                req.Referer = ch.Referer;
            }
            if (ch.Headers != null)
            {
                AddHeaders(req, ch.Headers);
            }
            if (ch.CookieHeader != null)
            {
                TryAddCookieHeader(req, ch.CookieHeader);
            }
            if (ch.CookieFileSet)
            {
                req.CookieContainer = new CookieContainer();
            }
            if (ch.Username != null)
            {
                req.Credentials = new NetworkCredential(ch.Username, ch.Password ?? string.Empty);
            }
            if (ch.AcceptEncoding != null)
            {
                req.Accept = ch.AcceptEncoding;
            }
            // TODO: certificate
            // TODO: proxy

            // make request:

            // GET, HEAD
            if (string.Equals(ch.Method, WebRequestMethods.Http.Get, StringComparison.OrdinalIgnoreCase) ||
                string.Equals(ch.Method, WebRequestMethods.Http.Head, StringComparison.OrdinalIgnoreCase))
            {
                // nothing to do
            }
            // POST
            else if (string.Equals(ch.Method, WebRequestMethods.Http.Post, StringComparison.OrdinalIgnoreCase))
            {
                ProcessPost(ctx, req, ch);
            }
            // PUT
            else if (string.Equals(ch.Method, WebRequestMethods.Http.Put, StringComparison.OrdinalIgnoreCase))
            {
                ProcessPut(req, ch);
            }
            // DELETE, or custom method
            else
            {
                // custom method, nothing to do
            }

            //
            if (ch.StoreRequestHeaders)
            {
                ch.RequestHeaders = HttpHeaders.HeaderString(req); // and restore it when constructing CURLResponse
            }

            //
            return(req.GetResponseAsync());
        }