2
votes

Is anyone from soundcloud looking at this? Why am I getting a 403 for a valid request?

I am building an iOS app at the moment using Titanium.

I am including a new feature that allows users to download Soundcloud .mp3 files and play them from the app (Saving to the application directory)

The code I have written is working fine for some of the tracks, but not for others. The client has unlimited downloads for all tracks, and I have increased the max timeout quite a lot, and it still just downloads around 170 bytes then fails on some of the tracks. On others it downloads the whole track with no issues. Really stumped with this one, anyone got any ideas?

Below is the code and also an example of a track working, and one not working if anyone can see a difference?

Thanks

Justin

//Download code


var newDir = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'scDownloads');

    newDir.createDirectory();

    var id = fStripped;

    var dlXhr = Titanium.Network.createHTTPClient({
        timeout : 500000});

    dlXhr.onload = function(){
        var file = Ti.Filesystem.getFile(newDir.resolve(),id +'.mp3');

        Ti.API.warn('file is: ' + file);

        file.createFile();

        file.write(this.responseData);

    }

    dlXhr.open('GET',dlURL + '?client_id=' + soundcloudClientID);

    dlXhr.send();

And here are a couple of tracks (With client ID)

This one works: https://api.soundcloud.com/tracks/60943956/download?client_id=7a0984726d0eefbb310771c4c02116a8

This one doesn't: https://api.soundcloud.com/tracks/63980557/download?client_id=7a0984726d0eefbb310771c4c02116a8

I have tested this on Soundcloud's API console (http://developers.soundcloud.com/console) and got the following:

HTTP/1.1 302 Moved Temporarily Access-Control-Expose-Headers: Date X-Runtime: 20 Age: 0 Content-Length: 28 X-Cacheable: NO:Cache-Control=no-cache Location: gda=1351783496_b465064be1b41027a7a0bf6067d83169">http://ak-media.soundcloud.com/kw7JNYi7HtCq?AWSAccessKeyId=AKIAJ4IAZE5EOI7PA7VQ&Expires=1351783496&Signature=UNtBsSfBh1XNvXPLSLNVzTQEclY%3D&gda=1351783496_b465064be1b41027a7a0bf6067d83169 Access-Control-Allow-Methods: GET, PUT, POST, DELETE Connection: close Server: nginx X-Cache: MISS Cache-Control: no-cache X-Varnish: 1398398080 Access-Control-Allow-Headers: Accept, Authorization, Content-Type, Origin Date: Thu, 01 Nov 2012 15:24:36 GMT Access-Control-Allow-Origin: * Via: 1.1 varnish Content-Type: application/xml; charset=utf-8

302 - Found

I also added a Ti.API.debug(e.error); to the dlXhr.onerror function I have created, and this simply returned

1

1 Answers

1
votes

I'm getting a 403 for the one that "doesn't". You should listen for the onerror event, and handle it appropriately. Also, you should stream the file rather than keeping it in memory than writing out out all at once. Take advantage of the "file" property available on Ti.Network.HTTPClient on iOS to do this simply. Plus, show progress, because that's a huge file you're downloading. The below sample demonstrates all of this:

var win = Ti.UI.createWindow({
    backgroundColor: 'white'
});
var progressBar = Ti.UI.createProgressBar({
    max: 1, min: 0, value: 0,
    left: 20, right: 20,
    height: 20,
    visible: true
});
win.add(progressBar);
win.open();

var fileName = 'file.mp3';
var link = 'https://api.soundcloud.com/tracks/63980557/download?client_id=7a0984726d0eefbb310771c4c02116a8';
var file = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory, fileName);

var client = Ti.Network.createHTTPClient({
    ondatastream: function (e) {
        progressBar.value = e.progress;
    },
    onload: function () {
        alert('Download Complete: ' + file.size);
    },
    onerror: function (e) {
        alert(client.status);
    }
});
client.open('GET', link);
client.file = file;
client.send();