Reading server error messages for a URLLoader - actionscript-3

I have an URL loader with the following code:
public function getUploadURL():void {
var request:URLRequest = new URLRequest();
var url:String = getPath();
// Adds time to prevent caching
url += "&time=" + new Date().getTime();
request.url = url;
request.method = URLRequestMethod.GET;
_loader = new URLLoader();
_loader.dataFormat = URLLoaderDataFormat.TEXT;
_loader.addEventListener(Event.COMPLETE, getBaseURL);
_loader.addEventListener(IOErrorEvent.IO_ERROR, onGetUploadURLError);
_loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, getHttpStatus);
_loader.load(request);
}
My problem is that this request might be wrong, and so the server will give me a back a 400 Bad Request, with a message to explain the error. If the Event.COMPLETE, I can see some message (a response) back from the server in the "data" field of the Event, but if onGetUploadURLError or getHttpStatus is called, it just says that the error code is 400 but does not show me the message associated with it.
The "data" field is undefined in getHttpStatus and it is "" in onGetUploadURLError.
On the contrary, in getBaseURL, I get: {"ResponseMetadata":{...}}
I checked and I do get a similar response in my browser for a wrong request, but I cannot see it.
Any idea how I can please get the message?
Thank you very much,
Rudy

Flash does not handle HTTP status codes very well. Here is a blog post with comments from an Adobe employee saying the problem is actually the plug-in limitations. The Adobe employee points to a library for doing HTTP requests using AS3 through sockets but I doubt that would be highly efficient (compared to having the plugin-in hand requests off to the browser).
Standard practice on all projects I have ever worked on was to always send a 200 OK and add a error key onto the message.
edit: also see this bug which is exactly your issue.

Related

sending a GET request from a banner

I have to build a banner where people fill a form with their name and email send when they click, we send the data in order to send them back a brochure instantly.
I am not a dev, so it is a little bit confusing for me and I hope my explanations will be clear enough.
Apparently, the website only accept POST request but we cannot send like that from the banner due to crossdomain issue. So the request has to be send as a GET.
We found this website which does the conversion:
http://get-to-post.nickj.org/
for the purpose of the test, everything is hardcoded. When we test, this url:
http://get-to-post.nickj.org/?http://www.vikingrivercruises.co.uk/Forms/SaveRequestBrochures?InquiryReason[0]=2351&InquiryMessage[0]=UK+River+Brochure+Download&InquiryType[0]=Brochure-d&InquiryReason[1]=1450&InquiryMessage[1]=UK+Brochure+Requests+%28from+web%29&InquiryType[1]=Brochure&BrochureCode=UKBR15&SelectedBrochuresDeliverability=UKBR15+mail-yes+ebrochure-yes&selectedBrochures=UKBR15&Title=Mr.&FirstName=Andrew&LastName=Davies&EmailAddress=nicom21a%40gmail.com&PhoneNumberString=098921313132312&Country=United+Kingdom&OtherCountry=&Address1=&Address2=&Address3=&City=&State=&OtherState=&Zip=&EmailMeSpecialOffers=true&FriendTitle=&FriendFirstName=&FriendLastName=&FriendEmailAddress=&RedirectUrl=http%3A%2F%2Fwww.vikingrivercruises.co.uk%2Fbrochures%2Frivers-brochure-thank-you.html
and copy past it in the browser, it works perfectly and we receive a brochure instantly, but when I try to replicate it from the banner it doesn't work.
Here is my code, many thanks
var requestVars:URLVariables = new URLVariables();
requestVars.link = 'InquiryReason[0]=2351&InquiryMessage[0]=UK+River+Brochure+Download&InquiryType[0]=Brochure-d&InquiryReason[1]=1450&InquiryMessage[1]=UK+Brochure+Requests+%28from+web%29&InquiryType[1]=Brochure&BrochureCode=UKBR15&SelectedBrochuresDeliverability=UKBR15+mail-yes+ebrochure-yes&selectedBrochures=UKBR15&Title=Mr.&FirstName=Andrew&LastName=Davies&EmailAddress=nicom21a%40gmail.com&PhoneNumberString=098921313132312&Country=United+Kingdom&OtherCountry=&Address1=&Address2=&Address3=&City=&State=&OtherState=&Zip=&EmailMeSpecialOffers=true&FriendTitle=&FriendFirstName=&FriendLastName=&FriendEmailAddress=&RedirectUrl=http%3A%2F%2Fwww.vikingrivercruises.co.uk%2Fbrochures%2Frivers-brochure-thank-you.html'
var request:URLRequest = new URLRequest();
request.url = 'http://get-to-post.nickj.org/?http://www.vikingrivercruises.co.uk/Forms/SaveRequestBrochures';
request.method = URLRequestMethod.GET;
request.data = requestVars;
for (var prop:String in requestVars) {
trace("Sent " + prop + " as: " + requestVars[prop]);
}
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, loaderCompleteHandler);
loader.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
loader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
loader.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
I also tried like that
request.url = 'http://get-to-post.nickj.org/?http://www.vikingrivercruises.co.uk/Forms/SaveRequestBrochures?';
I think there are many points in your case that should be clarified :
If you want send a URL request to a server, but ignores any response, and I think this is your case because you can't get response, It's better to use sendToURL instead of URLLoader.load().
If you test your swf on line, you will get a security error because the used site(http://get-to-post.nickj.org/) doesn't have a crossdomain.xml file to get authorization to execute the URL : http://get-to-post.nickj.org/?http://www.example.com/?param=value.
Even when you execute your sendToURL successfully, you have another problem because the site that you have mentioned, which convert GET request to a POST one, will not do the job because it's creating a page with a POST form with your data and submitting it when the page is loaded which is never fired with flash.
So, I think it's better to see the crossdomain problem with your target site (vikingrivercruises) to give you authorization to send POST data. And if It's always impossible, try to set another URL (site) that get your GET data and send it via curl, for example, to your destination.

How to get the final URL from a redirect in AS3?

I need to get the final URL from a link that gets redirected. (e.g. if someone is using a URL shortener)
bit.ly/foobar ->redirect-> http://example.com
What the fastest way to do this in AS3?
Thanks you
Since you are using AIR, you can listen for an HTTPStatusEvent.HTTP_RESPONSE_STATUS event:
var urlLoader:URLLoader = new URLLoader(new URLRequest("http://bit.ly/1bdDlXc"));
urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, urlLoader_httpResponseStatus);
function urlLoader_httpResponseStatus(e:HTTPStatusEvent):void
{
trace(e.redirected, e.responseURL);
}
The result of the above trace is true http://www.google.com/
This event gives you information about whether the URL was redirected and what the new URL is.

API Request with adobe AIR

I am trying to consume delicious api in adobe AIR AS3 project described here: https://github.com/avos/delicious-api
particularly the suggest api (/v1/posts/suggest) described at the end of this page: https://github.com/avos/delicious-api/blob/master/api/posts.md
In debug mode the app asks for username and password and keeps asking it even after providing valid username and password and never tracing the response. I have no idea what's going wrong here. Below is my code:
var request:URLRequest = new URLRequest("https://api.del.icio.us/v1/posts/suggest?red=api&url=http%3A%2F%2Fyahoo.com");
request.method = URLRequestMethod.POST;
//encoded string using as3 class at https://github.com/MoritzStefaner/revisit/blob/master/lib/com/hurlant/util/Base64.as
var encoded:String = Base64.encode("validusername:validpassword");
trace(encoded);
var credsHeader:URLRequestHeader = new URLRequestHeader("Authorization", "Basic " + encoded);
request.requestHeaders.push(credsHeader);
var loader:URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.TEXT;
loader.addEventListener(Event.COMPLETE, handleResults);
loader.load(request);
function handleResults(evt:Event):void
{
var response:String = evt.target.data as String;
trace("response:" + response);
}
From taking a brief look at the linked API, none of the methods suggest support for authentication information being sent as part of the POST body (which is what your code is doing). So unless that is documented somewhere else, you are using the API incorrectly. It's also reasonably rare to see an HTTP POST combined with a QueryString (which is again what your code above is doing) so that is a little odd.
I think Delicious just needs HTTP Basic auth, which is covered in an SO question here.

SoundCloud POST Comment Not Authorized

[UPDATE]
Problem fixed. Working code and method updated below!
So, I am trying to post a comment to a SoundCloud track using the SoundCloud api in AS3.
The documentation can be found here:
http://developers.soundcloud.com/docs/#comments
And my code is as follows:
var urlLoader:URLLoader = new URLLoader();
var urlString:String = "https://api.soundcloud.com/tracks/" + soundModel.currentlyPlayingItem.id + "/comments.json" + "?comment[body]=" + commentString + "&comment[timestamp]=" + trackPositionComment;
var urlRequest:URLRequest = new URLRequest(urlString);
urlRequest.method = URLRequestMethod.POST;
var variables:URLVariables = new URLVariables();
variables.oauth_token = soundModel.userToken; //here is the filler variable to make POST, not GET.
urlRequest.data = variables;
urlRequest.contentType = "application/x-www-form-urlencoded";
var header2:URLRequestHeader=new URLRequestHeader("oauth_token",soundModel.userToken);
var header3:URLRequestHeader=new URLRequestHeader("client_id", "sdjhb4jhbkjbe4gkjbh4random");
urlRequest.requestHeaders.push(header2);
urlRequest.requestHeaders.push(header3);
urlLoader.addEventListener(HTTPStatusEvent.HTTP_RESPONSE_STATUS, commentPosted);
urlLoader.load(urlRequest);
Originally I was consistently getting a 401 - unauthorized error.
After playing around with the SoundCloud API console, I saw that there was a 'content-length' of 0, meaning no body. So all the authentication stuff had to be going in headers, not variables. However, with POST method in AS3 UrlLoader, it will automatically send as a GET if there is no body (variables) included. So for that reason I left an arbitrary variable value.
Also the two parameters, 'body' and 'timestamp' indeed have to be sent as 'comment[body]' and 'comment[timestamp]' even though this isn't quite made clear in the documentation. Also both of these parameters have to be included in the URL, and not as variables or headers.
Finally, to get a authorized return, you must provide both your 'client_id' and 'oauth_token' as headers.
It was this magic combination that did it for me. I hope this helps some other people, ready to rip their hair out like I was.
Thx,
Theo M.

Getting Error #2032: Stream Error. in Flash while sending url request to server

I am sending http request to server via URLLoader in Flash. My Code is:
var urlLoader:URLLoader=new URLLoader();
var urlRequest:URLRequest=new URLRequest();
var urlparam:URLVariables= new URLVariables();
urlparam.req=JSON.encode(workout);
urlRequest.method="POST";
urlRequest.data=urlparam;
urlRequest.url="http://mydomain.com/saveworkout.php";
urlLoader.addEventListener(Event.COMPLETE,loadCompleted);
urlLoader.addEventListener(IOErrorEvent.IO_ERROR,loadError);
urlLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR,securityError);
urlLoader.load(urlRequest);
}
private function loadError(event:IOErrorEvent):void{
trace("Stream Error="+event.text);
}
private function securityError(event:SecurityErrorEvent):void{
trace("Security Error="+event.text);
}
private function loadCompleted(event:Event):void{
var urlLoader:URLLoader=event.target as URLLoader;
trace(urlLoader.data);
}
This code works fine when I test it locally and send request to localhost, but giving me Error #2032: Stream Error. At remote server codeigniter framework is being used. I also the crossdomain.xml in the httpdocs directory, and also cross check the request url. Request url opens fine directly in the web browsers. Any idea?
Thanks & Regards,
Check headers in server response.
Maybe it's not of right MIME type or even corrupt.
Browser show it's ok, but in reality its broken. Use Firebug, or Tamperdata plugin for Firefox.