Пример #1
0
		/// <summary>
		/// Executes the provided request asynchronously, returning the response object.
		/// </summary>
		/// <param name="request"><see cref="ISteamRequest"/> object for execution.</param>
		/// <returns><see cref="ISteamResponse"/> object containing the result of the request.</returns>
		public async Task<ISteamResponse> ExecuteAsync( ISteamRequest request ) {

			AuthenticateClient( this, request );

			HttpRequestMessage httpRequest = BuildHttpRequest( request );

			CookieContainer cookieContainer = new CookieContainer();

			if( request.Cookies == null || request.Cookies.Count > 0 ) {
				foreach( Cookie cookie in request.Cookies )
					cookieContainer.Add( httpRequest.RequestUri, cookie );
			}

			HttpClientHandler httpHandler = new HttpClientHandler();
			httpHandler.CookieContainer = cookieContainer;

			using( var httpClient = new HttpClient( httpHandler ) ){

				httpClient.Timeout = TimeSpan.FromMilliseconds( ( ( request.Timeout > 0 ) ? request.Timeout : this.Timeout ) );

				try {
					request.IncreaseNumAttempts();
					return ConvertToResponse( request, await httpClient.SendAsync( httpRequest ), cookieContainer );
				}catch( Exception ex ) {
					if( ex.InnerException != null && ex.InnerException is WebException )
						return CreateErrorResponse( request, ex.InnerException );
					return CreateErrorResponse( request, ex );
				}

			}

		}
Пример #2
0
 /// <summary>
 /// Method invoked by the library in order to authenticate for a resource.
 /// Should not be called directly by consumer code.
 /// </summary>
 /// <param name="client">SteamClient instance to authenticate.</param>
 /// <param name="request">Request requiring authentication.</param>
 public void Authenticate( SteamClient client, ISteamRequest request )
 {
     if( AccessToken != null )
         request.AddParameter( "access_token", AccessToken, ParameterType.GetOrPost );
 }
Пример #3
0
 /// <summary>
 /// Method invoked by the library in order to authenticate for a resource.
 /// Should not be called directly by consumer code.
 /// </summary>
 /// <param name="client">SteamClient instance to authenticate.</param>
 /// <param name="request">Request requiring authentication.</param>
 public void Authenticate( SteamClient client, ISteamRequest request )
 {
     request.AddParameter( "key", ApiKey, ParameterType.QueryString );
 }
 /// <summary>
 /// Method invoked by the library in order to authenticate for a resource.
 /// Should not be called directly by consumer code.
 /// </summary>
 /// <param name="client">SteamClient instance to authenticate.</param>
 /// <param name="request">Request requiring authentication.</param>
 public void Authenticate( SteamClient client, ISteamRequest request )
 {
     if( AuthCookie != null )
         request.AddCookie( AuthCookie );
 }
Пример #5
0
 /// <summary>
 /// Authenticates the client with the Steam API.
 /// </summary>
 /// <param name="client">SteamClient instance to be authenticated.</param>
 /// <param name="request">Request requiring authentication.</param>
 private void AuthenticateClient( SteamClient client, ISteamRequest request )
 {
     if( Authenticator != null ) {
         Authenticator.Authenticate( client, request );
     }
 }
Пример #6
0
        /// <summary>
        /// Utility method for POST requests. We must produce an object array such that it can be serialized (non-Raw POST style requests).
        /// </summary>
        /// <param name="request">Request to be evaluated.</param>
        /// <param name="body">Current parameter intended for addition to the body of the request.</param>
        /// <returns>Content which can be sent over the HTTP Request, including all parameters (both body and GetOrPost).</returns>
        private string SerializeBodyWithParameters( ISteamRequest request, SteamRequestParameter body, PostDataFormat format )
        {
            Dictionary<string, object> output = new Dictionary<string, object>();

            IEnumerable<SteamRequestParameter> parameters = request.Parameters.Where( p => p.Type == ParameterType.GetOrPost );
            foreach( var p in parameters ) {
                output.Add( p.Name, p.Value );
            }

            if( format == PostDataFormat.Json ) {

                if( body != null && output.Count < 1 )
                    return JsonConvert.SerializeObject( body.Value );
                else if( body != null ) {
                    output.Add( body.Name, body.Value );
                    return JsonConvert.SerializeObject( output );
                } else {
                    return JsonConvert.SerializeObject( output );
                }

            } else {

                var payload = new StringBuilder();
                foreach( SteamRequestParameter p in parameters ) {
                    if( payload.Length > 1 )
                        payload.Append( "&" );
                    string appendValue = ( p.IsUrlEncoded ) ? p.Value.ToString() : Uri.EscapeDataString( p.Value.ToString() );
                    payload.AppendFormat( "{0}={1}", Uri.EscapeDataString( p.Name ), appendValue );
                }

                if( body != null && body.Value != null )
                    payload.AppendFormat( "{0}={1}", body.Name, body.Value.ToString() );

                return payload.ToString();

            }
        }
Пример #7
0
        protected SteamResponse CreateErrorResponse( ISteamRequest request, Exception ex )
        {
            SteamResponse response = new SteamResponse();
            response.Request = request;
            response.IsSuccessful = false;
            response.ErrorMessage = ex.Message;

            if( ex is WebException ) {

                var webException = ex as WebException;
                if( webException != null ) {

                    if( webException.Status == WebExceptionStatus.RequestCanceled )
                        response.ResponseStatus = ResponseStatus.Aborted;
                    else
                        response.ResponseStatus = ResponseStatus.Error;

                    response.ErrorException = ex;

                    return response;
                }

            } else if( ex is TaskCanceledException ) {

                response.ErrorMessage = "The request timed out.";
                response.ResponseStatus = ResponseStatus.TimedOut;
                return response;

            }

            response.ErrorException = ex;
            response.ResponseStatus = ResponseStatus.Error;

            return response;
        }
Пример #8
0
        protected SteamResponse ConvertToResponse( ISteamRequest request, HttpResponseMessage response, CookieContainer cookies )
        {
            var cookieJar = new Dictionary<string,Cookie>();

            if( cookies != null ) {
                foreach( Cookie cookie in cookies.GetCookies( response.RequestMessage.RequestUri ).Cast<Cookie>() ) {
                    cookieJar.Add( cookie.Name, cookie );
                }
            }

            SteamResponse steamResponse = new SteamResponse {
                HttpResponse = response,
                Request = request,
                RequestUri = response.RequestMessage.RequestUri,
                Cookies = cookieJar,
                ResponseStatus = SteamSharp.ResponseStatus.Completed,
                StatusCode = response.StatusCode,
                StatusDescription = response.StatusCode.ToString(),
                IsSuccessful = response.IsSuccessStatusCode
            };

            if( !steamResponse.IsSuccessful && response.ReasonPhrase != null )
                steamResponse.ErrorMessage = response.ReasonPhrase;

            StreamReader stream = new StreamReader( response.Content.ReadAsStreamAsync().Result, System.Text.Encoding.UTF8 );
            steamResponse.Content = stream.ReadToEnd();

            return steamResponse;
        }
Пример #9
0
        /// <summary>
        /// Constructs the <see cref="HttpWebRequest" /> object which will be used to execute the web request. 
        /// </summary>
        /// <param name="request">Request for execution.</param>
        protected HttpRequestMessage BuildHttpRequest( ISteamRequest request )
        {
            // Add any Default client parameters (if it exists in the request, the request wins)
            foreach( var param in DefaultParameters ) {
                if( !request.Parameters.Any( p => p.Name == param.Name && p.Type == param.Type ) )
                    request.AddParameter( param );
            }

            HttpRequestMessage httpRequest = new HttpRequestMessage( request.Method, BuildUri( request ) );

            // HEADERS
            // -- Add UserAgent header, if it does not already exist in both the request and the standard request message (shouldn't overwrite valuable system/platform data)
            if( !request.Parameters.Any( p => p.Name == "User-Agent" && p.Type == ParameterType.HttpHeader ) && !httpRequest.Headers.Any( h => h.Key == "User-Agent" ) )
                request.Parameters.Add( new SteamRequestParameter { Name = "User-Agent", Value = ( ( DefaultUserAgent == null ) ? "SteamSharp/" + AssemblyVersion : DefaultUserAgent ), Type = ParameterType.HttpHeader } );

            // -- Currently we only accept and deserialize JSON responses
            request.Parameters.Add( new SteamRequestParameter { Name = "Accept", Value = "application/json", Type = ParameterType.HttpHeader } );

            IEnumerable<SteamRequestParameter> headers = request.Parameters.Where( p => p.Type == ParameterType.HttpHeader );
            foreach( var header in headers ) {
                if( httpRequest.Headers.Contains( header.Name ) )
                    httpRequest.Headers.Remove( header.Name );
                httpRequest.Headers.Add( header.Name, header.Value.ToString() );
            }

            // BODY -- Only evaluate if post
            if( request.Method == HttpMethod.Post ) {
                var body = request.Parameters.FirstOrDefault( p => p.Type == ParameterType.RequestBody );

                HttpContent content;

                switch( request.DataFormat ) {
                    case PostDataFormat.Json:
                        content = new StringContent( SerializeBodyWithParameters( request, body, PostDataFormat.Json ) );
                        content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse( "application/json" );
                        break;
                    case PostDataFormat.FormUrlEncoded:
                        content = new StringContent( SerializeBodyWithParameters( request, body, PostDataFormat.FormUrlEncoded ) );
                        content.Headers.ContentType = System.Net.Http.Headers.MediaTypeHeaderValue.Parse( "application/x-www-form-urlencoded" );
                        break;
                    default:
                        content = new StringContent( ( ( body != null ) ? body.Value.ToString() : String.Empty ) );
                        break;
                }

                httpRequest.Content = content;
            }

            return httpRequest;
        }
Пример #10
0
        /// <summary>
        /// Helper method which creates the final Uri used in the HTTP request.
        /// </summary>
        /// <param name="request">Request for execution.</param>
        /// <returns>Well formed Uri for use in an <see cref="System.Net.Http.HttpRequestMessage"/>.</returns>
        public Uri BuildUri( ISteamRequest request )
        {
            string destination = request.Resource;

            // Add trailing slash if none exists
            if( !BaseAPIEndpoint.EndsWith( "/" ) )
                BaseAPIEndpoint = BaseAPIEndpoint + "/";

            if( !Uri.IsWellFormedUriString( BaseAPIEndpoint, UriKind.RelativeOrAbsolute ) )
                throw new FormatException( "BaseAPIEndpoint specified does not conform to a valid Uri format. BaseAPIEndpoint specified: " + BaseAPIEndpoint );

            // URL Segement replacement is only valid if the Resource URI is non-empty
            if( !String.IsNullOrEmpty( destination ) ) {

                // To prefix or not to prefix - that is the question! (The answer is don't. Obviously.)
                if( destination.StartsWith( "/" ) )
                    destination = destination.Substring( 1 );

                var urlParams = request.Parameters.Where( p => p.Type == ParameterType.UrlSegment );
                foreach( SteamRequestParameter p in urlParams )
                    destination = destination.Replace( "{" + p.Name + "}", p.Value.ToString() );

                destination = BaseAPIEndpoint + destination;

            } else
                destination = BaseAPIEndpoint;

            IEnumerable<SteamRequestParameter> parameters = null;
            if( request.DataFormat != PostDataFormat.Raw && ( request.Method == HttpMethod.Post || request.Method == HttpMethod.Put ) ) {
                // This conforms to a POST-style request and the output will be serialized (i.e. not Raw)
                parameters = request.Parameters.Where( p => p.Type == ParameterType.QueryString );
            } else {
                // This conforms to a GET-style request
                parameters = request.Parameters.Where( p => p.Type == ParameterType.GetOrPost || p.Type == ParameterType.QueryString );
            }

            var queryString = new StringBuilder();
            if( parameters != null && parameters.Any() ) {
                foreach( SteamRequestParameter p in parameters ) {
                    if( queryString.Length > 1 )
                        queryString.Append( "&" );
                    string appendValue = ( p.IsUrlEncoded ) ? p.Value.ToString() : Uri.EscapeDataString( p.Value.ToString() );
                    queryString.AppendFormat( "{0}={1}", Uri.EscapeDataString( p.Name ), appendValue );
                }

                destination = destination + "?" + queryString;
            }

            return new Uri( destination );
        }
Пример #11
0
 /// <summary>
 /// Executes the provided request synchronously, returning the response object.
 /// </summary>
 /// <param name="request"><see cref="ISteamRequest"/> object for execution.</param>
 /// <returns><see cref="ISteamResponse"/> object containing the result of the request.</returns>
 public ISteamResponse Execute( ISteamRequest request )
 {
     return ExecuteAsync( request ).Result;
 }