How do I get the redirect url? - soundcloud

I want to get a redirect url from a url.
Url:
https://api.soundcloud.com/tracks/151935719/stream?client_id=
redirect url looks something like this:
https://ec-media.soundcloud.com/0fdDn45vb5t4.128.mp3?f10880d39085a94a0418a7ef69b03d522cd6dfee9399eeb9a522019d6afabf3e3c10bce51c30cbe03f40dfc788e191ee959a960c826c0a5de46a851702613b05f3906a2971&AWSAccessKeyId=AKIAJNIGGLK7XA7YZSNQ&Expires=1401521245&Signature=B3P8qLw1t%2BQ2oYQUEfpep9%2FULXg%3D
How do I get the redirect url so I can stream from this link?
I am using C# WPF and I am a newbie.
Thanks!!

It should be automatic with HttpWebRequest.AllowAutoRedirect:
HttpWebRequest request = HttpWebRequest.CreateHttp(yourURI);
request.AllowAutoRedirect = true;
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
// Your code
}
However, the default value for AllowAutoRedirect is true, so, in general, you shouldn't even need to set it. Redirection is automatically handled:
HttpWebRequest request = HttpWebRequest.CreateHttp(yourURI);
using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
{
// Your code
}

Related

How to call SSRS Rest-Api V1.0 with custom security implemented (NOT SOAP)

I have implemented the custom security on my reporting services 2016 and it displays the login page once the URL for reporting services is typed on browser URL bar (either reports or reportserver)
I am using the following code to pass the Credentials
when i use the code WITHOUT my security extension it works and looks like this
ICredentials _executionCredentials;
CredentialCache myCache = new CredentialCache();
Uri reportServerUri = new Uri(ReportServerUrl);
myCache.Add(new Uri(reportServerUri.GetLeftPart(UriPartial.Authority)),
"NTLM", new NetworkCredential(MyUserName, MyUserPassword));
_executionCredentials = myCache;
when i use the code WITH the security extension it doesnt work and looks like this
ICredentials _executionCredentials;
CredentialCache myCache = new CredentialCache();
Uri reportServerUri = new Uri(ReportServerUrl);
myCache.Add(new Uri(reportServerUri.GetLeftPart(UriPartial.Authority)),
"Basic", new NetworkCredential(MyUserName, MyUserPassword));
_executionCredentials = myCache;
and i get an Exception saying "The response to this POST request did not contain a 'location' header. That is not supported by this client." when i actually use this credentials
Is "basic" the wrong option ?
Have anyone done this ?
Update 1
Well it turns out that my SSRS is expecting an Authorisation cookie
which i am unable to pass (according to fiddler, there is no cookie)
HttpWebRequest request;
request = (HttpWebRequest)HttpWebRequest.Create("http://mylocalcomputerwithRS/Reports_SQL2016/api/v1.0");
CookieContainer cookieJar = new CookieContainer();
request.CookieContainer = cookieJar;
Cookie authCookie = new Cookie("sqlAuthCookie", "username:password");
authCookie.Domain = ".mydomain.mylocalcomputerwithRS";
if (authCookie != null)
request.CookieContainer.Add(authCookie);
request.Timeout = -1;
HttpWebResponse myHttpWebResponse = (HttpWebResponse)request.GetResponse();
That's how I got it (SSRS 2017; api v2.0). I took the value for the "body" from Fiddler:
var handler = new HttpClientHandler();
var httpClient = new HttpClient(handler);
Assert.AreEqual(0, handler.CookieContainer.Count);
// Create a login form
var body = new Dictionary<string, string>()
{
{"__VIEWSTATE", "9cZYKBmLKR3EbLhJvaf1JI7LZ4cc0244Hpcpzt/2MsDy+ccwNaw9hswvzwepb4InPxvrgR0FJ/TpZWbLZGNEIuD/dmmqy0qXNm5/6VMn9eV+SBbdAhSupsEhmbuTTrg7sjtRig==" },
{"__VIEWSTATEGENERATOR", "480DEEB3"},
{ "__EVENTVALIDATION", "IS0IRlkvSTMCa7SfuB/lrh9f5TpFSB2wpqBZGzpoT/aKGsI5zSjooNO9QvxIh+QIvcbPFDOqTD7R0VDOH8CWkX4T4Fs29e6IL92qPik3euu5QpidxJB14t/WSqBywIMEWXy6lfVTsTWAkkMJRX8DX7OwIhSWZAEbWZUyJRSpXZK5k74jl4x85OZJ19hyfE9qwatskQ=="},
{"txtUserName", "User"},
{"txtPassword", "1"},
{"btnLogin","Войти"}
};
var content = new FormUrlEncodedContent(body);
// POST to login form
var response = await httpClient.PostAsync("http://127.0.0.1:777/ReportServer/Logon.aspx", content);
// Check the cookies created by server
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
var cookies = handler.CookieContainer.GetCookies(new Uri("http://127.0.0.1:777/ReportServer"));
Assert.AreEqual("sqlAuthCookie", cookies[0].Name);
// Make new request to secured resource
var myresponse = await httpClient.GetAsync("http://127.0.0.1:777/Reports/api/v2.0/Folders");
var stringContent = await myresponse.Content.ReadAsStringAsync();
Console.Write(stringContent);
As an alternative you can customize SSRS Custom Security Sample quite a bit.
I forked Microsoft's Custom Security Sample to do just what you are describing (needed the functionality at a client long ago and reimplemented as a shareable project on GitHub).
https://github.com/sonrai-LLC/ExtRSAuth
I created a YouTube walkthrough as well to show how one can extend and debug SSRS security with this ExtRSAuth SSRS security assembly https://www.youtube.com/watch?v=tnsWChwW7lA
TL; DR; just bypass the Microsoft example auth check in Login.aspx.cs and put your auth in Page_Load() or Page_Init() event of Login.aspx.cs- wherever you want to perform some custom logging check- and then immediately redirect auth'd user to their requested URI.

REST Hammock not adding content to post body

I've been fiddling a POST request that isn't working. What I've found is that the content of the request is empty even though I believe I'm adding it correctly (even though there aren't any docs available that I can find).
var json = JsonConvert.SerializeObject(payload);
var client = new RestClient
{
Authority = "",
Credentials = OAuthCredentials.ForProtectedResource(Registration.ClientKey,
Registration.ClientSecret,
AuthorizationToken.Token,
AuthorizationToken.Secret),
Method = WebMethod.Post,
Path = url
};
var request = new RestRequest();
request.AddHeader("Accept", ContentType);
request.AddHeader("Content-Type", ContentType);
request.AddPostContent(Encoding.UTF8.GetBytes(json));
response = client.Request(request);
I'm not having any trouble with authorization. I just kept getting a 400 error. After capturing the request with Fiddler, I noticed that content-length was 0. What am I missing? Do I need to do something in addition to AddPostContent? When I check the request object right before executing, there is content in PostContent, but it's as if Hammock isn't adding it to the request. I am using the latest full nuget (not ClientProfile).

How to post JSON to a URL using the Servoy Framework

The Servoy Framework does not support standard methods of calling a URL (eg: AJAX, JQuery, etc.). How does one go about posting a JSON object to a URL?
The Servoy JavaScript framework relies on the http plugin (included as aprt of Servoy) to make HTTP Posts.
Here is some sample code of how to post JSON to an API using Servoy. I have also included some basic error handling. Refer to the code comments for explanations of what the code is doing:
var sURL = 'http://www.example.com/myapipath/';
var oJSON = {"employees":[
{"firstName":"John", "lastName":"Doe"},
{"firstName":"Anna", "lastName":"Smith"},
{"firstName":"Peter", "lastName":"Jones"}
]};
var sClient = plugins.http.createNewHttpClient(); // HTTP plugin object
var sPoster = sClient.createPostRequest(sURL); // Post request object
sPoster.addHeader('content-type','application/json'); // required for JSON to be parsed as JSON
sPoster.setBodyContent(JSON.stringify(oJSON));
application.output('Executing HTTP POST request and waiting for response from '+sURL, LOGGINGLEVEL.INFO);
var sResponse = null;
var sResponseData = "";
var nHttpStatusCode = 0;
var sCaughtException = '';
try {
nHttpStatusCode = (sResponse = sPoster.executeRequest()).getStatusCode(); // POST JSON request to API
}
catch (e) {
// This handles the case when the domain called does not exist or the server is down, etc.
// in this case there will be no HTTP status code returned so we must handle this differently
// to prevent the Servoy application from crashing
sCaughtException = e['rhinoException'].getMessage();
if (-1 != sCaughtException.indexOf('TypeError: Cannot call method "getStatusCode"')) {
application.output('WARNING: Could not determine HTTP status code. The server might be down or its URL might be invalid.', LOGGINGLEVEL.WARNING);
}
else {
application.output('WARNING: caught unknown HTTP POST exception: '+sCaughtException, LOGGINGLEVEL.WARNING);
}
}
// SUCCESS!:
if (200 == nHttpStatusCode) { // HTTP Ready Status
sResponseData = sResponse.getResponseBody(); // Get the server's response text
application.output('Successful, response received from server:',LOGGINGLEVEL.INFO);
application.output(sResponseData, LOGGINGLEVEL.INFO);
// put your code to handle a successful response from the server here
}
else {
// insert your code to handle various standard HTTP error codes (404 page not found, 403 Forbidden, etc.)
}

Get track.stream_url returning garbage

I am trying to stream SoundCloud songs using JPlayer in a Ruby on Rails application. I try to get the stream url server-side using this:
#stream_url = client.get(#track.stream_url, :allow_redirects => true)
I then try to load this URL using JPlayer like so:
<script type="text/javascript">
$("#jquery_jplayer_1").jPlayer({
ready: function() {
$(this).jPlayer("setMedia", {
mp3: "<%= #stream_url %>"
});
},
swfPath: "/js",
supplied: "mp3"
});
</script>
But when I load the page, the browser chokes on the URL string. The returned markup and script looks like this:
$(this).jPlayer("setMedia", {
mp3: "���DInfo+4F��!$&)+.0368;=#..."
That string goes on for much longer than I'll post here.
My best guess is that this is an encoding issue, but I can't figure it out. I've tried in the rails console to debug, but that got me nowhere.
Any ideas would be appreciated. Thanks!
It seems like there are some encoding issues you are facing with.
When I send the HTTP request manually and get the endpoint URL in C#, I don't face the same problem and the end the endpoint URL of the audio is perfectly fine.
public void Run()
{
if (!string.IsNullOrEmpty(TrackUrl))
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(TrackUrl + ".json?client_id=YOUR_CLIENT_ID");
request.Method = "HEAD";
request.AllowReadStreamBuffering = true;
request.AllowAutoRedirect = true;
request.BeginGetResponse(new AsyncCallback(ReadWebRequestCallback), request);
}
}
private void ReadWebRequestCallback(IAsyncResult callbackResult)
{
HttpWebRequest myRequest = (HttpWebRequest)callbackResult.AsyncState;
HttpWebResponse myResponse = (HttpWebResponse)myRequest.EndGetResponse(callbackResult);
using (StreamReader httpwebStreamReader = new StreamReader(myResponse.GetResponseStream()))
{
this.AudioStreamEndPointUrl = myResponse.ResponseUri.AbsoluteUri;
this.SearchCompleted(this);
}
myResponse.Close();
}
Don't know how that is it applies to Ruby on Rails but you get the idea.
You can try a similar trick to this one instead of using the client.get method.

Using Facebook Requests 2.0 with the C# SDK

I am trying to update the bookmark count field with the SDK but have not had any success yet.
Can somebody tell me what classes I need to instantiate to do something similar to the following link:
http://developers.facebook.com/blog/post/464
Note:
The link demonstrates how to set the bookmark count and delete it. I would like to be able to do the same with the SDK, any help would be appreciated.
To do this, first you need to get you app's access token:
private string GetAppAccessToken() {
var fbSettings = FacebookWebContext.Current.Settings;
var accessTokenUrl = String.Format("{0}oauth/access_token?client_id={1}&client_secret={2}&grant_type=client_credentials",
"https://graph.facebook.com/", fbSettings.AppId, fbSettings.AppSecret);
// the response is in the form: access_token=foo
var accessTokenKeyValue = HttpHelpers.HttpGetRequest(accessTokenUrl);
return accessTokenKeyValue.Split('=')[1];
}
A couple of things to note about the method above:
I'm using the .Net HttpWebRequest instead of the Facebook C# SDK to grab the app access_token because (as of version 5.011 RC1) the SDK throws a SerializationException. It seems that the SDK is expecting a JSON response from Facebook, but Facebook returns the access token in the form: access_token=some_value (which is not valid JSON).
HttpHelpers.HttpGetRequest simply uses .Net's HttpWebRequest. You can just as well use WebClient, but whatever you choose, you ultimately want to make this http request:
GET https://graph.facebook.com/oauth/access_token?client_id=YOUR_APP_ID&client_secret=YOUR_APP_SECRET&grant_type=client_credentials HTTP/1.1
Host: graph.facebook.com
Now that you have a method to retrieve the app access_token, you can generate an app request as follows (here I use the Facebook C# SDK):
public string GenerateAppRequest(string fbUserId) {
var appAccessToken = GetAppAccessToken();
var client = new FacebookClient(appAccessToken);
dynamic parameters = new ExpandoObject();
parameters.message = "Test: Action is required";
parameters.data = "Custom Data Here";
string id = client.Post(String.Format("{0}/apprequests", fbUserId), parameters);
return id;
}
Similarly, you can retrieve all of a user's app requests as follows:
Note: you probably don't want to return "dynamic", but I used it here for simplicity.
public dynamic GetAppRequests(string fbUserId) {
var appAccessToken = GetAppAccessToken();
var client = new FacebookClient(appAccessToken);
dynamic result = client.Get(String.Format("{0}/apprequests", fbUserId));
return result;
}
I hope this helps.