Esempio n. 1
0
        private RestResponse SendInternal(long contentLength, Stream stream)
        {
            RestResponse resp = SendInternalAsync(contentLength, stream, CancellationToken.None).Result;

            return(resp);
        }
Esempio n. 2
0
        private async Task <RestResponse> SendInternalAsync(long contentLength, Stream stream, CancellationToken token)
        {
            if (String.IsNullOrEmpty(Url))
            {
                throw new ArgumentNullException(nameof(Url));
            }

            Logger?.Invoke(_Header + Method.ToString() + " " + Url);

            try
            {
                #region Setup-Webrequest

                Logger?.Invoke(_Header + "setting up web request");

                if (IgnoreCertificateErrors)
                {
                    ServicePointManager.ServerCertificateValidationCallback = Validator;
                }

                ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

                HttpWebRequest client = (HttpWebRequest)WebRequest.Create(Url);
                client.KeepAlive         = false;
                client.Method            = Method.ToString();
                client.AllowAutoRedirect = true;
                client.Timeout           = _Timeout;
                client.ContentLength     = 0;
                client.ContentType       = ContentType;
                client.UserAgent         = "RestWrapper (https://www.github.com/jchristn/RestWrapper)";

                #endregion

                #region Add-Certificate

                if (!String.IsNullOrEmpty(CertificateFilename))
                {
                    if (!String.IsNullOrEmpty(CertificatePassword))
                    {
                        Logger?.Invoke(_Header + "adding certificate including password");

                        X509Certificate2 cert = new X509Certificate2(CertificateFilename, CertificatePassword);
                        client.ClientCertificates.Add(cert);
                    }
                    else
                    {
                        Logger?.Invoke(_Header + "adding certificate without password");

                        X509Certificate2 cert = new X509Certificate2(CertificateFilename);
                        client.ClientCertificates.Add(cert);
                    }
                }

                #endregion

                #region Add-Headers

                if (Headers != null && Headers.Count > 0)
                {
                    foreach (KeyValuePair <string, string> pair in Headers)
                    {
                        if (String.IsNullOrEmpty(pair.Key))
                        {
                            continue;
                        }
                        if (String.IsNullOrEmpty(pair.Value))
                        {
                            continue;
                        }

                        Logger?.Invoke(_Header + "adding header " + pair.Key + ": " + pair.Value);

                        if (pair.Key.ToLower().Trim().Equals("accept"))
                        {
                            client.Accept = pair.Value;
                        }
                        else if (pair.Key.ToLower().Trim().Equals("close"))
                        {
                            // do nothing
                        }
                        else if (pair.Key.ToLower().Trim().Equals("connection"))
                        {
                            // do nothing
                        }
                        else if (pair.Key.ToLower().Trim().Equals("content-length"))
                        {
                            client.ContentLength = Convert.ToInt64(pair.Value);
                        }
                        else if (pair.Key.ToLower().Trim().Equals("content-type"))
                        {
                            client.ContentType = pair.Value;
                        }
                        else if (pair.Key.ToLower().Trim().Equals("date"))
                        {
                            client.Date = Convert.ToDateTime(pair.Value);
                        }
                        else if (pair.Key.ToLower().Trim().Equals("expect"))
                        {
                            client.Expect = pair.Value;
                        }
                        else if (pair.Key.ToLower().Trim().Equals("host"))
                        {
                            client.Host = pair.Value;
                        }
                        else if (pair.Key.ToLower().Trim().Equals("if-modified-since"))
                        {
                            client.IfModifiedSince = Convert.ToDateTime(pair.Value);
                        }
                        else if (pair.Key.ToLower().Trim().Equals("keep-alive"))
                        {
                            client.KeepAlive = Convert.ToBoolean(pair.Value);
                        }
                        else if (pair.Key.ToLower().Trim().Equals("proxy-connection"))
                        {
                            // do nothing
                        }
                        else if (pair.Key.ToLower().Trim().Equals("referer"))
                        {
                            client.Referer = pair.Value;
                        }
                        else if (pair.Key.ToLower().Trim().Equals("transfer-encoding"))
                        {
                            client.TransferEncoding = pair.Value;
                        }
                        else if (pair.Key.ToLower().Trim().Equals("user-agent"))
                        {
                            client.UserAgent = pair.Value;
                        }
                        else
                        {
                            client.Headers.Add(pair.Key, pair.Value);
                        }
                    }
                }

                #endregion

                #region Add-Auth-Info

                if (!String.IsNullOrEmpty(_Authorization.User))
                {
                    if (_Authorization.EncodeCredentials)
                    {
                        Logger?.Invoke(_Header + "adding encoded credentials for user " + _Authorization.User);

                        string authInfo = _Authorization.User + ":" + _Authorization.Password;
                        authInfo = Convert.ToBase64String(Encoding.Default.GetBytes(authInfo));
                        client.Headers.Add("Authorization", "Basic " + authInfo);
                    }
                    else
                    {
                        Logger?.Invoke(_Header + "adding plaintext credentials for user " + _Authorization.User);
                        client.Headers.Add("Authorization", "Basic " + _Authorization.User + ":" + _Authorization.Password);
                    }
                }
                else if (!String.IsNullOrEmpty(_Authorization.BearerToken))
                {
                    Logger?.Invoke(_Header + "adding authorization bearer token " + _Authorization.BearerToken);
                    client.Headers.Add("Authorization", "Bearer " + _Authorization.BearerToken);
                }

                #endregion

                #region Write-Request-Body-Data

                if (Method == HttpMethod.POST ||
                    Method == HttpMethod.PUT ||
                    Method == HttpMethod.DELETE)
                {
                    if (contentLength > 0 && stream != null)
                    {
                        Logger?.Invoke(_Header + "reading data (" + contentLength + " bytes), writing to request");

                        client.ContentLength = contentLength;
                        client.ContentType   = ContentType;
                        Stream clientStream = client.GetRequestStream();

                        byte[] buffer         = new byte[_StreamReadBufferSize];
                        long   bytesRemaining = contentLength;
                        int    bytesRead      = 0;

                        while (bytesRemaining > 0)
                        {
                            bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length).ConfigureAwait(false);

                            if (bytesRead > 0)
                            {
                                bytesRemaining -= bytesRead;
                                await clientStream.WriteAsync(buffer, 0, bytesRead).ConfigureAwait(false);
                            }
                        }

                        clientStream.Close();

                        Logger?.Invoke(_Header + "added " + contentLength + " bytes to request");
                    }
                }

                #endregion

                #region Submit-Request-and-Build-Response

                Logger?.Invoke(_Header + "submitting");

                HttpWebResponse response = (HttpWebResponse)(await client.GetResponseAsync().ConfigureAwait(false));

                Logger?.Invoke(_Header + "server returned status code " + (int)response.StatusCode);

                RestResponse ret = new RestResponse();
                ret.ProtocolVersion   = "HTTP/" + response.ProtocolVersion.ToString();
                ret.ContentEncoding   = response.ContentEncoding;
                ret.ContentType       = response.ContentType;
                ret.ContentLength     = response.ContentLength;
                ret.ResponseURI       = response.ResponseUri.ToString();
                ret.StatusCode        = (int)response.StatusCode;
                ret.StatusDescription = response.StatusDescription;

                #endregion

                #region Headers

                Logger?.Invoke(_Header + "processing response headers");

                if (response.Headers != null && response.Headers.Count > 0)
                {
                    ret.Headers = new Dictionary <string, string>();

                    for (int i = 0; i < response.Headers.Count; i++)
                    {
                        string key      = response.Headers.GetKey(i);
                        string val      = "";
                        int    valCount = 0;
                        foreach (string value in response.Headers.GetValues(i))
                        {
                            if (valCount == 0)
                            {
                                val += value;
                                valCount++;
                            }
                            else
                            {
                                val += "," + value;
                                valCount++;
                            }
                        }

                        Logger?.Invoke(_Header + "adding response header " + key + ": " + val);
                        ret.Headers.Add(key, val);
                    }
                }

                #endregion

                #region Payload

                bool contentLengthHeaderExists = false;
                if (ret.Headers != null && ret.Headers.Count > 0)
                {
                    foreach (KeyValuePair <string, string> header in ret.Headers)
                    {
                        if (String.IsNullOrEmpty(header.Key))
                        {
                            continue;
                        }
                        if (header.Key.ToLower().Equals("content-length"))
                        {
                            contentLengthHeaderExists = true;
                            break;
                        }
                    }
                }

                if (!contentLengthHeaderExists)
                {
                    Logger?.Invoke(_Header + "content-length header not supplied");

                    long         totalBytesRead = 0;
                    int          bytesRead      = 0;
                    byte[]       buffer         = new byte[_StreamReadBufferSize];
                    MemoryStream ms             = new MemoryStream();

                    while (true)
                    {
                        bytesRead = await response.GetResponseStream().ReadAsync(buffer, 0, buffer.Length, token).ConfigureAwait(false);

                        if (bytesRead > 0)
                        {
                            await ms.WriteAsync(buffer, 0, bytesRead, token).ConfigureAwait(false);

                            totalBytesRead += bytesRead;
                            Logger?.Invoke(_Header + "read " + bytesRead + " bytes, " + totalBytesRead + " total bytes");
                        }
                        else
                        {
                            break;
                        }
                    }

                    ms.Seek(0, SeekOrigin.Begin);
                    ret.ContentLength = totalBytesRead;
                    ret.Data          = ms;
                }
                else if (response.ContentLength > 0)
                {
                    Logger?.Invoke(_Header + "attaching response stream with content length " + response.ContentLength + " bytes");
                    ret.ContentLength = response.ContentLength;
                    ret.Data          = response.GetResponseStream();
                }
                else
                {
                    ret.ContentLength = 0;
                    ret.Data          = null;
                }

                #endregion

                return(ret);
            }
            catch (TaskCanceledException)
            {
                Logger?.Invoke(_Header + "task canceled");
                return(null);
            }
            catch (OperationCanceledException)
            {
                Logger?.Invoke(_Header + "operation canceled");
                return(null);
            }
            catch (WebException we)
            {
                #region WebException

                Logger?.Invoke(_Header + "web exception: " + we.Message);

                RestResponse ret = new RestResponse();
                ret.Headers           = null;
                ret.ContentEncoding   = null;
                ret.ContentType       = null;
                ret.ContentLength     = 0;
                ret.ResponseURI       = null;
                ret.StatusCode        = 0;
                ret.StatusDescription = null;
                ret.Data = null;

                HttpWebResponse exceptionResponse = we.Response as HttpWebResponse;
                if (exceptionResponse != null)
                {
                    ret.ProtocolVersion   = "HTTP/" + exceptionResponse.ProtocolVersion.ToString();
                    ret.ContentEncoding   = exceptionResponse.ContentEncoding;
                    ret.ContentType       = exceptionResponse.ContentType;
                    ret.ContentLength     = exceptionResponse.ContentLength;
                    ret.ResponseURI       = exceptionResponse.ResponseUri.ToString();
                    ret.StatusCode        = (int)exceptionResponse.StatusCode;
                    ret.StatusDescription = exceptionResponse.StatusDescription;

                    Logger?.Invoke(_Header + "server returned status code " + ret.StatusCode);

                    if (exceptionResponse.Headers != null && exceptionResponse.Headers.Count > 0)
                    {
                        ret.Headers = new Dictionary <string, string>();
                        for (int i = 0; i < exceptionResponse.Headers.Count; i++)
                        {
                            string key      = exceptionResponse.Headers.GetKey(i);
                            string val      = "";
                            int    valCount = 0;

                            foreach (string value in exceptionResponse.Headers.GetValues(i))
                            {
                                if (valCount == 0)
                                {
                                    val += value;
                                    valCount++;
                                }
                                else
                                {
                                    val += "," + value;
                                    valCount++;
                                }
                            }

                            Logger?.Invoke(_Header + "adding exception header " + key + ": " + val);
                            ret.Headers.Add(key, val);
                        }
                    }

                    if (exceptionResponse.ContentLength > 0)
                    {
                        Logger?.Invoke(_Header + "attaching exception response stream to response with content length " + exceptionResponse.ContentLength + " bytes");
                        ret.ContentLength = exceptionResponse.ContentLength;
                        ret.Data          = exceptionResponse.GetResponseStream();
                    }
                    else
                    {
                        ret.ContentLength = 0;
                        ret.Data          = null;
                    }
                }

                return(ret);

                #endregion
            }
        }
Esempio n. 3
0
        private RestResponse SendInternal(long contentLength, Stream stream)
        {
            RestResponse resp = SendInternalAsync(contentLength, stream).Result;

            return(resp);
        }