Esempio n. 1
0
        private Uri GetResourceUri(Data.RestRequest requestDetails)
        {
            string queryString = GetHttpRequestQueryString(requestDetails);
            // C# behaves differently from Java when concatenating nulls:
            //  Java: "string" + null = "stringnull" (the string "null" is substituted for null);
            //  C#: "string" + null = "string" (the empty string is substituted for null).
            string uriString = requestDetails.Resource + queryString;
            // .NET System.Uri constructor will always check whether all characters are escaped
            //  and escape those that aren't so no need to specify whether the URI is escaped or
            //  not.
            Uri uri = null;

            try
            {
                // Assume this is a relative URL as host address, passed into the Execute method
                //  separately, is invalid if null or blank.
                uri = new Uri(uriString, UriKind.Relative);
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException("Problem when building URI: " + uriString, ex);
            }

            return(uri);
        }
Esempio n. 2
0
        private void ValidateRequest(RestSharp.IRestClient client,
                                     Data.RestRequest requestDetails)
        {
            // Client cannot be null.
            if (client.BaseUrl == null || string.IsNullOrWhiteSpace(client.BaseUrl.AbsoluteUri))
            {
                throw new ArgumentException("Host address is not set: "
                                            + "Please pass a valid host address.");
            }

            if (requestDetails == null)
            {
                throw new System.ArgumentException("HTTP request details not supplied.");
            }

            if (requestDetails.HttpMethod == Data.RestRequest.Method.NotSet)
            {
                throw new System.ArgumentException(
                          "HTTP request method is not set (eg \"GET\", \"POST\").");
            }

            if (string.IsNullOrWhiteSpace(requestDetails.Resource))
            {
                throw new System.ArgumentException("Relative URL of resource is not set.");
            }
        }
Esempio n. 3
0
        private void AddHttpRequestHeaders(RestSharp.RestRequest requestToBuild,
                                           Data.RestRequest requestDetails)
        {
            // NB: RestSharp will default content type to XML if not set explicitly.

            foreach (Data.RestData.Header header in requestDetails.Headers)
            {
                requestToBuild.AddHeader(header.Name, header.Value);
            }
        }
Esempio n. 4
0
        private void ConfigureRequestMultipartFileUpload(RestSharp.RestRequest request,
                                                         Data.RestRequest requestDetails,
                                                         LinkedHashMap <string, Data.RestMultipart> multipartFiles)
        {
            request.AddHeader("Content-Type", "multipart/form-data");

            foreach (KeyValuePair <string, RestMultipart> multipartFile in multipartFiles)
            {
                ConfigureMultipart(request, multipartFile.Key, multipartFile.Value);
            }
        }
Esempio n. 5
0
        private string GetHttpRequestQueryString(Data.RestRequest requestDetails)
        {
            string queryString = requestDetails.Query;

            if (StringHelper.IsNullOrBlank(queryString))
            {
                return(string.Empty);
            }

            // Ensure query string starts with "?".
            queryString = queryString.TrimStart('?').Trim();
            queryString = "?" + queryString;
            return(queryString);
        }
Esempio n. 6
0
        private RestSharp.Method GetHttpMethod(Data.RestRequest restRequest)
        {
            // No way to tell if restRequest.Method has not been set.  If not set explicitly it
            //  will have value 0 = Get.
            RestSharp.Method httpMethod;
            bool             ignoreCase = true;

            if (Enum.TryParse(restRequest.HttpMethod.ToString(), ignoreCase, out httpMethod))
            {
                return(httpMethod);
            }

            // As at v105.2.3, on 26 Feb 2017, RestSharp is unable to handle TRACE HTTP methods,
            //  although the RestClient in the Java RestFixture can.
            string errorMessage = string.Format("RestRequst.HttpMethod {0} cannot be handled "
                                                + "by RestSharp.",
                                                restRequest.HttpMethod);

            throw new ArgumentException(errorMessage);
        }
Esempio n. 7
0
        /// <summary>
        /// Builds the HTTP request that will be sent.
        /// </summary>
        /// <param name="requestDetails">The RestClient.RestRequest containing details of the request
        /// to send.</param>
        /// <returns>A RestSharp.RestRequest object containing details of the request to send.</returns>
        /// <remarks>Loosely based on RestClient.RestClientImpl.configureHttpMethod, which is
        /// designed around the Apache HttpClient library, written in Java.  This is very different
        /// from the .NET System.Net library so cannot be ported directly; the HttpClient must be
        /// rewritten from scratch.</remarks>
        private RestSharp.RestRequest BuildRequest(Data.RestRequest requestDetails)
        {
            Uri resourceUri = GetResourceUri(requestDetails);

            RestSharp.Method httpMethod = GetHttpMethod(requestDetails);

            RestSharp.RestRequest request = new RestSharp.RestRequest(resourceUri, httpMethod);

            AddHttpRequestHeaders(request, requestDetails);

            // Request type doesn't expect a body (eg GET, DELETE).
            if (!IsEntityEnclosingMethod(httpMethod))
            {
                return(request);
            }

            // Simple file upload.
            string fileName = requestDetails.FileName;

            if (!string.IsNullOrWhiteSpace(fileName))
            {
                if (!File.Exists(fileName))
                {
                    throw new ArgumentException("File not found: " + fileName);
                }
                request.AddFile("file", fileName);
                return(request);
            }

            // Multipart file upload.
            LinkedHashMap <string, Data.RestMultipart>
            multipartFiles = requestDetails.MultipartFileNames;

            if ((multipartFiles != null) && (multipartFiles.Count > 0))
            {
                ConfigureRequestMultipartFileUpload(request, requestDetails, multipartFiles);
                return(request);
            }

            if (string.IsNullOrWhiteSpace(requestDetails.Body))
            {
                return(request);
            }

            // Request includes a body, eg standard POST or PUT.
            string contentType = requestDetails.ContentType;

            if (contentType != null)
            {
                if (contentType.Trim().Length == 0)
                {
                    contentType = null;
                }
                else
                {
                    contentType = contentType.ToLower();
                }
            }

            string body = requestDetails.Body.Trim();

            if (string.IsNullOrWhiteSpace(contentType))
            {
                // RestSharp has only two DataFormats: Json and Xml.

                if (body.StartsWith("{") || body.StartsWith("["))
                {
                    request.RequestFormat = DataFormat.Json;
                    contentType           = "application/json";
                }
                else
                {
                    request.RequestFormat = DataFormat.Xml;
                    contentType           = "application/xml";
                }
            }
            else if (contentType.Contains("json"))
            {
                request.RequestFormat = DataFormat.Json;
                contentType           = requestDetails.ContentType;
            }
            else
            {
                request.RequestFormat = DataFormat.Xml;
                contentType           = requestDetails.ContentType;
            }

            // requestDetails.Body is a string, and RestRequest.AddBody, AddJsonBody
            //  and AddXmlBody take objects as arguments, not strings.  Although they
            //  won't throw exceptions, the result is not as expected if an object is
            //  serialized to JSON or XML before being passed to one of the AddBody
            //  methods.
            //
            //  For example, if a Book object is serialized to JSON and the JSON string
            //  is passed to AddBody or AddJsonBody the body sent across the wire is:
            //
            //  "{\"Id\":10,\"Title\":\"The Meaning of Liff\",\"Year\":1983}"
            //
            //  when it should be:
            //
            //  {Id: 10, Title: "The Meaning of Liff", Year: 1983}

            //  The incorrect format of the JSON in the request body will prevent it
            //  from being desrialized correctly at the server end.

            // Instead of using one of the AddBody methods, use
            //  AddParameter(..., ..., ParameterType.RequestBody)
            //  which can handle objects serialized to JSON or XML strings.
            request.AddParameter(contentType, body, ParameterType.RequestBody);

            return(request);
        }
Esempio n. 8
0
        public Data.RestResponse Execute(string baseAddress, Data.RestRequest requestDetails)
        {
            this.BaseUrlString = baseAddress;
            RestSharp.IRestClient client = this.Client;

            // We're using RestSharp to execute HTTP requests.  RestSharp copes with trailing "/"
            //  on BaseUrl and leading "/" on Resource, whether one or both of the "/" are present
            //  or absent.

            ValidateRequest(client, requestDetails);

            if (requestDetails.TransactionId == null)
            {
                requestDetails.TransactionId = Convert.ToInt64(DateTimeHelper.CurrentUnixTimeMillis());
            }

            client.FollowRedirects = requestDetails.FollowRedirect;

            RestSharp.RestRequest request = BuildRequest(requestDetails);

            if (LOG.IsDebugEnabled)
            {
                try
                {
                    LOG.Info("Http Request : {0} {1}",
                             request.Method, client.BuildUri(request).AbsoluteUri);
                }
                catch (Exception e)
                {
                    LOG.Error(e, "Exception in debug : {0}", e.Message);
                }

                // Request Header
                LogRequestHeaders(request);

                // Request Body
                if (IsEntityEnclosingMethod(request.Method))
                {
                    try
                    {
                        Parameter body = request.Parameters
                                         .Where(p => p.Type == ParameterType.RequestBody).FirstOrDefault();
                        LOG.Debug("Http Request Body : {0}", body.Value);
                    }
                    catch (IOException e)
                    {
                        LOG.Error(e, "Error in reading request body in debug : {0}", e.Message);
                    }
                }
            }

            // Prepare Response
            Data.RestResponse responseDetails = new Data.RestResponse();
            responseDetails.TransactionId = requestDetails.TransactionId;
            responseDetails.Resource      = requestDetails.Resource;
            try
            {
                IRestResponse response = client.Execute(request);

                foreach (RestSharp.Parameter responseHeader in response.Headers)
                {
                    responseDetails.addHeader(responseHeader.Name, responseHeader.Value.ToString());
                }

                responseDetails.StatusCode = (int)response.StatusCode;
                responseDetails.StatusText = response.StatusDescription;
                // The Java byte data type is actually a signed byte, equivalent to sbyte in .NET.
                //  Data.RestResponse is a direct port of the Java class so it uses
                //  the sbyte data type.  The strange conversion from byte[] to sbyte[] was from
                //  the answer to Stackoverflow question http://stackoverflow.com/questions/25759878/convert-byte-to-sbyte
                // TODO: Check RestFixture code to see whether Data.RestResponse.RawBody can be converted to byte[].
                responseDetails.RawBody = response.RawBytes;

                // Debug
                if (LOG.IsDebugEnabled)
                {
                    // Not necessarily the same as the request URI.  The response URI is the URI
                    //  that finally responds to the request, after any redirects.
                    LOG.Debug("Http Request Path : {0}", response.ResponseUri);
                    LogRequestHeaders(request);
                    // Apache HttpClient.HttpMethod.getStatusLine() returns the HTTP response
                    //  status line.  Can't do this with RestSharp as it cannot retrieve the
                    //  protocol version which is at the start of the status line.  So just log
                    //  the status code and description.
                    // Looks like they added ProtocolVersion to RestSharp in issue 795 (commit
                    //  52c18a8) but it's only available in the FRAMEWORK builds.
                    LOG.Debug("Http Response Status : {0} {1}",
                              (int)response.StatusCode, response.StatusDescription);
                    LOG.Debug("Http Response Body : {0}", response.Content);
                }

                if (IsResponseError(response))
                {
                    LOG.Error(response.ErrorException, response.ErrorMessage);
                    string message = "Http call failed";
                    if (!string.IsNullOrWhiteSpace(response.ErrorMessage))
                    {
                        message = response.ErrorMessage.Trim();
                    }
                    throw new System.InvalidOperationException(message, response.ErrorException);
                }
            }
            catch (Exception e)
            {
                string message = "Http call failed";
                throw new System.InvalidOperationException(message, e);
            }

            LOG.Debug("response: {0}", responseDetails);
            return(responseDetails);
        }
Esempio n. 9
0
        // Unfortunately both this RestClient library and RestSharp have classes called
        //  RestRequest and RestResponse.  So we must always specify which RestRequest or
        //  RestResponse class we're using.

        public Data.RestResponse Execute(Data.RestRequest requestDetails)
        {
            return(Execute(this.BaseUrlString, requestDetails));
        }