From 257e098e8f51a394e24b8a53950e31ef17495605 Mon Sep 17 00:00:00 2001 From: Enno Date: Mon, 26 May 2014 15:29:41 +0200 Subject: [PATCH] added resolve api implementation with auto redirect fix for signing the http 302 response to the new location --- SoundCloud.NET/SoundCloudApi.cs | 51 +++++++++++++++------------ SoundCloud.NET/SoundCloudException.cs | 1 + SoundCloud.NET/Track.cs | 10 ++++++ SoundCloud.NET/Utils.cs | 37 +++++++++---------- 4 files changed, 58 insertions(+), 41 deletions(-) diff --git a/SoundCloud.NET/SoundCloudApi.cs b/SoundCloud.NET/SoundCloudApi.cs index 27d8d87..82a5a6a 100644 --- a/SoundCloud.NET/SoundCloudApi.cs +++ b/SoundCloud.NET/SoundCloudApi.cs @@ -20,6 +20,7 @@ You should have received a copy of the GNU General Public License using System.Collections.Generic; using System.IO; using System.IO.Compression; +using System.Linq; using System.Net; namespace SoundCloud.NET @@ -95,7 +96,7 @@ internal class SoundCloudApi : SoundCloudClient { ApiCommand.Playlist, new Uri("https://api.soundcloud.com/playlists/{0}.json") }, //Resolver - { ApiCommand.Resolve, new Uri("https://api.soundcloud.com/resolve.json?url={0}") }, + { ApiCommand.Resolve, new Uri("https://api.soundcloud.com/resolve?url={0}") }, }; #endregion Private Properties @@ -113,10 +114,7 @@ internal class SoundCloudApi : SoundCloudClient /// Parameters format of an api command uri. public static T ApiAction(ApiCommand command, params object[] parameters) { - var uri = - ApiDictionary[command] - .With(parameters); - + var uri = ApiDictionary[command].With(parameters); return ApiAction(uri); } @@ -130,12 +128,8 @@ public static T ApiAction(ApiCommand command, params object[] parameters) /// Parameters format of an api command uri. public static T ApiAction(ApiCommand command, HttpMethod method, params object[] parameters) { - var uri = - ApiDictionary[command] - .With(parameters); - + var uri = ApiDictionary[command].With(parameters); bool requireAuthentication = command != ApiCommand.UserCredentialsFlow; - return ApiAction(uri, method, requireAuthentication); } @@ -147,11 +141,7 @@ public static T ApiAction(ApiCommand command, HttpMethod method, params objec /// Dictionnary of parameters to be passed in the api action uri. public static T ApiAction(ApiCommand command, Dictionary extraParameters) { - var uri = - ApiDictionary[command] - .UriAppendingParameters(extraParameters); - - + var uri = ApiDictionary[command].UriAppendingParameters(extraParameters); return ApiAction(uri); } @@ -166,11 +156,7 @@ public static T ApiAction(ApiCommand command, Dictionary extr /// public static T ApiAction(ApiCommand command, HttpMethod method, Dictionary extraParameters, params object[] parameters) { - var uri = - ApiDictionary[command] - .UriAppendingParameters(extraParameters) - .With(parameters); - + var uri = ApiDictionary[command].UriAppendingParameters(extraParameters).With(parameters); return ApiAction(uri, method); } @@ -199,12 +185,15 @@ public static T ApiAction(Uri uri, HttpMethod method = HttpMethod.Get, bool r api = uri.UriWithAuthorizedUri(SoundCloudAccessToken.AccessToken); } - var request = WebRequest.Create(api); + var request = (HttpWebRequest)WebRequest.Create(api); + + request.AllowAutoRedirect = false; request.Method = method.ToString().ToUpperInvariant(); // Force returned type to JSON request.ContentType = "application/json"; + request.ContentLength = 0; //add gzip enabled header if (EnableGZip) request.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate"); @@ -216,9 +205,25 @@ public static T ApiAction(Uri uri, HttpMethod method = HttpMethod.Get, bool r { //OnApiActionExecuting Event OnApiActionExecuting(EventArgs.Empty); - response = (HttpWebResponse)request.GetResponse(); + //header check for redirects + if (response.Headers != null && response.Headers.AllKeys.Contains("Location")) + { + //got a location url 302 + var loc = response.Headers["Location"]; + if (!string.IsNullOrEmpty(loc)) + { + if (!string.IsNullOrEmpty(loc.Trim())) + { + uri = new Uri(loc); + return ApiAction(uri, method, requireAuthentication); + } + } + } + + + if (response.StatusCode == HttpStatusCode.OK || response.StatusCode == HttpStatusCode.Created) { var stream = response.GetResponseStream(); @@ -269,4 +274,4 @@ public static T ApiAction(Uri uri, HttpMethod method = HttpMethod.Get, bool r #endregion Shared Methods } -} \ No newline at end of file +} diff --git a/SoundCloud.NET/SoundCloudException.cs b/SoundCloud.NET/SoundCloudException.cs index d771e0e..ffbbf3e 100644 --- a/SoundCloud.NET/SoundCloudException.cs +++ b/SoundCloud.NET/SoundCloudException.cs @@ -23,6 +23,7 @@ namespace SoundCloud.NET /// /// Handles SoundCloud api exceptions. /// + [Serializable] public class SoundCloudException : Exception { /// diff --git a/SoundCloud.NET/Track.cs b/SoundCloud.NET/Track.cs index 7145683..b095caf 100644 --- a/SoundCloud.NET/Track.cs +++ b/SoundCloud.NET/Track.cs @@ -202,6 +202,16 @@ public static Track GetTrack(int id) return SoundCloudApi.ApiAction(ApiCommand.Track, id); } + /// + /// Returns a track by track permanent url. + /// + /// Track id. + public static Track GetTrack(string url) + { + return SoundCloudApi.ApiAction(ApiCommand.Resolve, url); + } + + /// /// Returns a collection of tracks after filtering. /// diff --git a/SoundCloud.NET/Utils.cs b/SoundCloud.NET/Utils.cs index ad21a9b..f8c8ee3 100644 --- a/SoundCloud.NET/Utils.cs +++ b/SoundCloud.NET/Utils.cs @@ -1,23 +1,24 @@ -/* - SoundCloud.NET Library For Sound Cloud Api Management. - Copyright (C) 2011 Haythem Tlili - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . +/* + SoundCloud.NET Library For Sound Cloud Api Management. + Copyright (C) 2011 Haythem Tlili + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ using System; using System.Collections.Generic; +using System.Linq; using System.Text; namespace SoundCloud.NET @@ -98,7 +99,7 @@ public static Uri UriAppendingQueryString(this Uri uri, string name, string valu return new UriBuilder(uri) { - Query = (uri.Query + "&" + name + "=" + value).TrimStart('&') + Query = (uri.Query + "&" + name + "=" + value).TrimStart('&').TrimStart('?') } .Uri; } @@ -107,7 +108,7 @@ public static Uri UriAppendingQueryString(this Uri uri, string querystring) return new UriBuilder(uri) { - Query = (uri.Query + "&" + querystring).TrimStart('&') + Query = (uri.Query + "&" + querystring).TrimStart('&').TrimStart('?') } .Uri; }