AS3 ioError on some browsers only, why is that? - actionscript-3

I am making a flash that calls google translate Text-to-speech service through the url:
translate.google.com/translate_tts?tl=en&q=example
I got it to work in firefox, but for some reason it does NOT work in chrome and safari. Where could be the problem?
the error I get is:
[IOErrorEvent type="ioError" bubbles=false cancelable=false eventPhase=2 text="Error #2032: Stream Error. URL: http://translate.google.com/translate_tts?tl=en&q=example"]
but when i copy/paste the URL in the browser, it returns a fil just like it should.
Flash players:
firefox: 10,0,42,34 installed - WORKS
chrome: 11,1,102,55 installed - DOES NOT WORK
safari: 10,0,42,34 installed - DOES NOT WORK
I am completely stunned. Don't know how to debug further.
Please help
UPDATE 1: FLASH CODE
public function say(text:String, language:String):void {
var urlString:String = createGoogleTTSUrl(text, language);
var url:URLRequest = new URLRequest(urlString);
//var context:SoundLoaderContext = new SoundLoaderContext(1000, true);
_sound = new Sound();
_sound.addEventListener(Event.COMPLETE, loadComplete);
_sound.addEventListener(ErrorEvent.ERROR, err);
_sound.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler2);
_soundChannel = new SoundChannel();
_sound.load(url); //, context);
}
private function ioErrorHandler2(event:IOErrorEvent):void {
trace(event);
}
I only later removed the SoundLoaderContext, but that didn't change anything.
UPDATE 2: Other people with same problem:
This tutorial has the same issue. Works in FF, but not in Chrome or Safari. People in comments reporting similar errors
(click the demo button:)
http://active.tutsplus.com/freebies/exclusive/exclusive-freebie-text-to-speech-utility/

The obvious reason for the #2032 error, when sniffing the actual request and response, is that Google is responding with a 404 when called from Flash in Chrome or IE (haven't tested Safari or Opera). But why does it return a 404?
Not a solution, but some troubleshooting - what does Firefox do differently from the others in terms of the request? In the following, ChD = "Chrome directly calling the API with no Flash (which works)"
Accept
FF: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Ch: Accept: */*
IE: Accept: */*
ChD: Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
This might be it, but it seems unlikely. The two that work send more than just a wildcard Accept header.
User-Agent
Obviously each browser sends along different User-Agents. Except ChD sends the same as Ch - and the former works, so that isn't it.
Referer
Firefox sends no Referer along. The others send:
Referer: http://activetuts.s3.amazonaws.com/freebies/006_textToSpeech/tutorial/text2speech.swf
ChD obviously sends no Referer either, since I typed in the address manually. So the Referer header might be the problem.
Considering that TTS isn't a public API, but a private endpoint (for Google's own translate service), i.e. an endpoint which you're really not allowed to use, that wouldn't be surprising.
Other
Other than that, and some language acceptance details (+ cookie contents - the same set of cookies are sent - and on my machine, it's actually their own cookies for once - Flash used to have a problem where it sent cookies from IE in the Firefox plugin)... Other than that, the requests are identical, but only Firefox's doesn't result in a 404 on my machine.
FlashPlayer versions
FF: 11.0.1.152 Debug
Ch: 11.1.102.55
IE: 11.0.1.152 Debug
Update: IE also sends the Flash version along: x-flash-version: 11,0,1,152 - but none of the other browsers do, so that's not why they don't work.

Related

Access-Control-Request-Private-Network header issues

Today we updated the last version of google chrome browser (Version 102.0.5005.61). We have an aplication that runs into a vpn. And since then we start getting this errors on the console:
As you can see we get a timed out error on the preflight and then the xhr request fails.
We noticed that on this version of chorme they add the new header: Access-Control-Request-Private-Network. An that is what I see on the preflight headers:
Serching on what could be wrong, since this is happening only when we update the chrome version and in other browsers the site works perfectly; Ive found this:
https://developer.chrome.com/blog/private-network-access-preflight/
On the article is explained what to do and how to handle this.
And show kind of what is happening to me:
If your request would have triggered a regular CORS preflight without
Private Network Access rules, then two preflights may appear in the
network panel, with the first one always appearing to have failed.
This is a known bug, and you can safely ignore it.
Based on that I added the new header support on my API that is made on JAVA with spring boot.
response.setHeader("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
response.setHeader("Access-Control-Allow-Headers", "content-type");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("Access-Control-Max-Age", "180");
response.setHeader("Access-Control-Allow-Private-Network", "true");
response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
As you can see just added the header and return 200 for the option request
if ("OPTIONS".equals(request.getMethod())) {
response.setStatus(HttpServletResponse.SC_OK);
return;
}
The site is running, meaning it get served and is loaded on chrome browser but all the API calls from the site get that error. (See screen shoots avobe).
But still after that have the same issues. Any one had the same issue and was able to solve?
Any help will be appreciated!
Thanks!
EDIT:
We just add the headers on the preflight response:
Access-Control-Request-Private-Network: true
Access-Control-Allow-Private-Network: true
Then we go to the google flags configuration and disable this:
Now Im not sure why google thinks that my requests are insecure.
This issue is coming for Private and Public combination, like our web is deployed as CloudFront Public URL and backend is Private api hosting, so we are also facing this issue, currently only disabling "Send Private Network Access preflights" property of chrome is working (its only enough).
We have tried setting "preflight request will carry a new header, Access-Control-Request-Private-Network: true, and the response to it must carry a corresponding header, Access-Control-Allow-Private-Network: true" but no luck till now.
Our another web application on which FE/BE both are private hosting is working fine.

Storing cookie with SameSite option as `Any kind of connection`

Im working on a .NetCore MVC project.
As the title suggests my goal is to store a cookie that will eventually be accessible through an iframe.
In order to achieve that this is what I did -
Startup.cs -
app.UseCookiePolicy(new CookiePolicyOptions
{
MinimumSameSitePolicy = SameSiteMode.None
});
Using the actual CookieOption class -
public void SetCookie(string key, string value, int? expireTime, HttpResponse Response)
{
CookieOptions option = new CookieOptions();
//allow cross-site cookies for iframes
option.SameSite = SameSiteMode.None;
if (expireTime.HasValue)
option.Expires = DateTime.Now.AddMinutes(expireTime.Value);
else
option.Expires = DateTime.Now.AddMilliseconds(10);
Response.Cookies.Append(key, value, option);
}
Doing the above It seems like it doesn't always work as intended.
Iv'e tested lots of browsers both desktop and mobile.
Just found out that sometimes the cookie is stored successfully like so -
Send for:
Any kind of connection
Accessible to script:
Yes
And sometimes on the same exact chrome version just a different computer its stored like so -
Send for:
Same-site connections only
Accessible to script:
Yes
Which basically means it won't be accessible using iframes.
The problem isn't a specific computer issue as I was managed to duplicate the problem on 3 different computers running the same chrome version which works fine on other computers.
The example above was produced using this chrome version (last version):
Version 80.0.3987.149 (Official Build) (64-bit)
Anyone have an idea how can I overcome that ? gotta make sure cookies will always be accessible using an iframe.
Thanks!
Edit - Attempt with Secure and HttpOnly flag
So iv'e adjusted my code to set the HttpOnly and the Secure flags to true.
The computers that usually worked fine had this cookie settings -
Send for
Secure connections only
Accessible to script
No (HttpOnly)
And it works fine with iframe.
The computer which didn't work before had this cookie settings -
Send for
Secure same-site connections only
Accessible to script
No (HttpOnly)
Which obviously didn't work with an iframe...
Just updating of another approach that didn't work.
Edit 2 - Using fiddler to intercept the cookies response:
So using fiddler to read the cookie this is what it looks like -
Set-Cookie: __cfduid={randomvaluehere}; expires=Fri, 24-Apr-20 17:37:48 GMT; path=/; domain=.domain.com; HttpOnly; SameSite=Lax
Set-Cookie: mycookie=mycookievalue; expires=Fri, 24 Apr 2020 17:37:49 GMT; path=/; secure; httponly
So seems like the response is storing a cookie with is SameSite=Lax on the apex of the domain, which I don't care about.
I work on a sub-domain which is the second set-cookie that is shown above.
Looks like SameSite=None isn't explicitly presented, should it? if so why wouldn't it seeing the code above?
Also reminding you that exactly that works fine for other browsers or other computers with the same chrome version.
The sample above is exactly the same on computer where it worked and in one that it wasn't.

<video> plays in other browsers, but not Safari

We have an MP4 video on our site; it plays fine in IE9+, Firefox, Chrome, and Chrome on mac. However, on Safari, the video doesn't play at all - it does trigger a "stalled" event and then nothing loads. I would post our HTML, but I traced the problem further by finding that Safari wouldn't play it even when navigating to the original MP4's URL. When downloaded and played locally, the video works fine in Quicktime.
The weirdest part of this is that of all our developers, I can get the video to work on Safari when I run the related server from my development computer. What's more, other MP4 files in the same directory have a similar problem. This has been the key to me, and I've been searching for any little difference in the way the videos transfer from the server - request/response headers, exact filesize, etc.
Headers copied from Chrome (only since Safari is harder to copy/paste from)
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Cache-Control:max-age=0
Connection:keep-alive
DNT:1
Host:*************:8443
User-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36
Response Headers
Accept-Ranges:bytes
Content-Length:44875102
Content-Type:video/mp4;charset=UTF-8
Date:Tue, 30 Dec 2014 21:11:51 GMT
ETag:W/"44875102-1419959755000"
Last-Modified:Tue, 30 Dec 2014 17:15:55 GMT
Server:Apache-Coyote/1.1
(Also, just in case this reminds you of an older issue; I'm aware Safari on Windows has been dead for ages. This issue is occurring on OS X)
EDIT: New info that might help a bit. I took a personal video from my own webserver, which was able to work from there on the problematic Safari browsers in question, and downloaded it to our server's local video directory. From there, it encounters the same issue as our other videos. This suggests to me that the MP4 itself may not matter - this is probably a server issue of some sort with our Tomcat 7 webserver. We do have the Content-Types registered correctly, which at least covers the basics, but I am curious if there are other necessary parts.
MORE INFO: I didn't think to mention this initially, but we are loading our webpages and videos over an HTTPS connection. Most of our test servers do not have valid certificates, and so we need to click through the standard browser warning that "This server might not be who it says". We are now looking into what it would take to have correct certificates on all our servers.
Safari requires webserver to support "Range" request header in order to play your media content.
https://developer.apple.com/library/safari/documentation/AppleApplications/Reference/SafariWebContent/CreatingVideoforSafarioniPhone/CreatingVideoforSafarioniPhone.html#//apple_ref/doc/uid/TP40006514-SW6
For a legit "Range" request response, your webserve need to return status code "206".
I had a similar problem with audio. The solution was to add the source tag, to the audio tag. Can you try in your case the following:
<video loop controls='true' width='100%' height='100%'>
<source src='//some_video.mp4' type='video/mp4'>
</video>
I uploaded a new MP4 file, but it played in SAFARI only (on both my MAC and my iPhone), not Chrome, Oasis, Firefox, or Brave. HTML code was identical to previous successes. File size and Dimensions were fine. But the Codecs on the old, working files were "H.264, AAC". The Codecs on the new, not working files were "MPEG-4, AAC". I edit my video files on VideoPad. So I looked at the specification selections on the "Export file as" options, and, sure enough, the Codecs was defaulted to MPEG-4. I selected H.264 and exported the file. Uploaded to AWS and made public. Retried my new files in the four failure browsers and BINGO!, they all worked. There is a God!
Make sure controls='true' type='video/mp4' is given in your html code.
<video loop controls='true' width='100%' height='100%' src='//some_video.mp4' type='video/mp4'></video>
This could indeed be an issue of missing byte-range support, depending on the version you are using. It was added to the DMSDownloadServlet in MAGNOLIA-3855 (Magnolia fix version 4.4.6).
Just ran into the same issue. All headers, range, etc. were correct. However, I had a poorly constructed service worker. All other browsers handled the failure, Safari did not. Temporarily removed the service worker, and things are back to normal.
...
On a side note, does charset make any sense on the video/mp4 type at all? Try removing the charset on it.
EDIT: Yes, charset might be the problem, see: Specify content-type for documents uploaded in Magnolia
EDIT2: Not charset, woops, reading comprehension fail. Might be byte range?
To quote: "[...] we found out that Safari/iOS "uses HTTP byte-ranges for requesting audio and video files." Now we guess that the Magnolia DMS file serving doesn't support this feature, and hence the streaming fails."
What happens if you add these to your .htaccess?
AddType video/ogg .ogv
AddType video/mp4 .mp4
AddType video/webm .webm
Recently, my team ran into a particular issue that resulted in the same behavior. We were using Apache 2.4 and noticed that if we had an authentication layer such as .htpasswd enabled, Safari would not display videos at all even after authenticating. It's almost as if it does not continue to honor the initial authentication clearance for certain types of subsequent HTTP requests.
Sorry I don't have anything more technical to provide, but it's something to check for anyone experiencing video issues only in Safari.
I ran into the same problem and solved it but no other answer here is not involved to mine, so I'll remain the solution here for someone following.
I've been making my own video streaming server, which, in the questioned case, simply returns a "Ranged" mp4 file, and I found Safari does not play video carried in HTTP response lacking of "Connection" response header for some reason.
Please, forgive me if you already solve this issue!
I've had the same problem with my server videos in Safari. I was abled to solve this using POSTMAN/INSOMNIA for check the headers that my server is sending. Chrome may can trick your, once that in this browser the video works fine!
If the video is not ranged(full video request) your server must return status(200) and check it out if the 'Accept-Ranges:bytes' is sent from your server.
Header sample status 200:
Server: nginx
Date: Wed, 25 Jul 2018 17:34:18 GMT
Content-Type: video/mp4
Content-Length: 22995782
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Headers: X-Requested-With,content-type
Access-Control-Allow-Credentials: true
Accept-Ranges: bytes
if the video is ranged your server must return status(206) with range headers correctly.
Header sample status 206:
Server: nginx
Date: Wed, 25 Jul 2018 18:13:07 GMT
Content-Type: video/mp4
Content-Length: 1023
Connection: keep-alive
X-Powered-By: Express
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS, PUT, PATCH, DELETE
Access-Control-Allow-Headers: X-Requested-With,content-type
Access-Control-Allow-Credentials: true
Accept-Ranges: bytes
Content-Range: bytes 1-1023/22995782
I hope this help you! my best regards,
Paulo Durço
Safari and iPhone require the "Range" request header to play your media content.
you have to handle Range on the server-side.
if (request.getHeader("Range") != null) {
System.out.println("Inside range ");
System.out.println("range value "+request.getHeader("range"));
// String fileLocation = melpUploadFiles.getFilethumbPath();
resfilename=melpUploadFiles.getFilename();
response.setStatus(206);
String rangeValue = request.getHeader("range").trim().substring("bytes=".length());
File fileloc= new File(melpUploadFiles.getFilePath());
long fileLength = fileloc.length();
long start, end;
if (rangeValue.startsWith("-")) {
end = fileLength - 1;
start = fileLength - 1 - Long.parseLong(rangeValue.substring("-".length()));
} else {
String[] range = rangeValue.split("-");
start = Long.parseLong(range[0]);
end = range.length > 1 ? Long.parseLong(range[1]) : fileLength - 1;
}
if (end > fileLength - 1) {
end = fileLength - 1;
}
if (start <= end) {
System.out.println("inside response block");
long contentLength = end - start + 1;
response.setHeader("Content-Length", contentLength + "");
response.setHeader("Content-Range", "bytes " + start + "-" + end + "/" + fileLength);
response.setHeader("Content-Type", "video/mp4");
response.setHeader("Accept-Ranges","bytes");
response.setHeader("ETag","\"a226e70476837efa4df4b4bfd75366c4\"");
response.setHeader("Server", "Apache");
response.setHeader("Last-Modified",System.currentTimeMillis()+"");
response.setDateHeader("Expires", System.currentTimeMillis() + 604800000L);
// response.setHeader("Content-Disposition", "inline; filename="+resfilename+"");
RandomAccessFile raf = new RandomAccessFile(fileloc, "r");
raf.seek(start);
output = response.getOutputStream();
byte[] buffer = new byte[2096];
int bytesRead = 0;
long totalRead = 0;
System.out.println("content length "+contentLength);
while(totalRead<contentLength) {
bytesRead = raf.read(buffer);
totalRead += bytesRead;
output.write(buffer, 0, bytesRead);
}
}
}
else
{
for other browser
}
In my case, I needed to remove default attribute from track tag:
<track default kind='captions' />
In case someone else have this problem.

Cannot run xmlhttprequest in Chrome App : provisional headers & No 'Access-Control-Allow-Origin'

I am building a chrome app sending a Get HTTPRequest to an external API:
I get the answer:
XMLHttpRequest cannot load
http://developer.echonest.com/api/v4/artist/profile?api_key=FILDTEOIK2HBORODV&name=weezer.
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'chrome-extension://ihdfphmemcdeadpnjkhpihmcoeiklphe'
is therefore not allowed access.
I did allow the external domain in permissions in my manifest (to prevent blocking in cross domain requests)
When I type the URL in the Address Bar it works perfectly
It seems Chrome is blocking my request, I even tried to load directly the script in an HTML page and it does not work (same message but with origin "null") (oh and it did not allow me to cheat by changing the Origin in the Header).
I also get the famous "Caution : Provisional Headers are shown" in the console, which makes me think Chrome is blocking my request, I looked up on other Stack Overflow Questions but apart running chrome://net-internals and looking for stuff I haven't the first clue about I cannot find any good answers (I did run chrome://net-internals but really can't make any sense out of it).
Here is the request :
function update_stations() {
var xhr = new XMLHttpRequest();
xhr.open("Get","http://developer.echonest.com/api/v4/artist/profile?api_key=FILDTEOIK2HBORODV&name=weezer", true);
xhr.responseType = "json";
xhr.onreadystatechange = function() {
console.log("Essai");
console.log(xhr.readyState);
console.log(xhr);
document.getElementById("resp").innerText = xhr;
}
xhr.send()
}
Any thoughts (would be highly appreciated)?
Cross-Origin XMLHttpRequest chrome developer documentation explains that the host must be listed in the permissions of the manifest file.
I've taken the XHR code from above and included it in the hello world sample. It works after adding the following to the manifest.json.
"permissions": [
"http://*.echonest.com/"
]

SignalR client function not called when transport=serverSentEvents

On my machines I find that SignalR client functions are not called in Chrome.
My SignalR test app works fine with with IE9, Firefox and even Safari on my iphone. Looking at Fiddler, these browsers all seem to negotiate transport=longPolling. But Chrome negotiates a connection with transport=serverSentEvents, and I'm assuming this is why client functions are not called in Chrome.
More detail:
I'm using full IIS (not IIS express) on Windows 7. I'm using SignalR version 1.0.0-rc2. I've disabled my AVG firewall and the Windows firewall is not running. Chrome is version 24.0.1312.56, and was up-to-date at the time of writing. The app is invoked on localhost.
On Chrome, the signalR connection seems to take place OK - the $.connection.hub.start().done callback function is invoked. But after that, the client function is never called, even while the other browsers work just fine.
In the client-side code, I've turned on logging with
$.connection.hub.logging = true;
I can see log messages in Chrome's javascript console that correspond to a successful connection.
For reference, those log messages are
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: Negotiating with '/SignalRChat-RC/signalr/negotiate'. jquery.signalR-1.0.0-rc2.js:54
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: Attempting to connect to SSE endpoint 'http://localhost/SignalRChat-RC/signalr/connect?transport=serverSentEvents&…7-22c5dbf27e0d&connectionData=%5B%7B%22name%22%3A%22chathub%22%7D%5D&tid=3' jquery.signalR-1.0.0-rc2.js:54
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: EventSource connected jquery.signalR-1.0.0-rc2.js:54
[20:22:16 GMT+0800 (W. Australia Standard Time)] SignalR: Now monitoring keep alive with a warning timeout of 40000 and a connection lost timeout of 60000 jquery.signalR-1.0.0-rc2.js:54
But there are no messages logged in Chrome's javascript console when a client-side method is invoked.
Interestingly, the send method works OK on Chrome. The other clients display a message sent from Chrome even through Chrome itself can't see it.
The application is pretty much the chat application from the signalR tutorial at http://www.asp.net/signalr/overview/getting-started/tutorial-getting-started-with-signalr
If I explicitly specify longPolling in the start method, i.e.
$.connection.hub.start({ transport: 'longPolling' })
then Chrome works OK. But my expectation was that I should be able to allow the browsers to negotiate their connection, and things would Just Work.
For reference, the relevant part of my client-side code looks like this:
$(function () {
// Turn on logging to the javascript console
$.connection.hub.logging = true;
// set up an error-handling function
$.connection.hub.error(function (err) {
alert("Error signalR:" + JSON.stringify(err));
});
// Declare a proxy to reference the hub.
var chat = $.connection.chatHub;
// Create a function that the hub can call to broadcast messages.
// This function is never called when running in Chrome with the default signalR connection
chat.client.broadcastMessage = function (name, message) {
// Html encode display name and message.
var encodedName = $('<div />').text(name).html();
var encodedMsg = $('<div />').text(message).html();
// Add the message to the page.
$('#discussion').append('<li><strong>' + encodedName
+ '</strong>: ' + encodedMsg + '</li>');
};
// Get the user name and store it to prepend to messages.
$('#displayname').val(prompt('Enter your name:', ''));
// Set initial focus to message input box.
$('#message').focus();
// Start the connection.
// Use $.connection.hub.start({ transport: 'longPolling' }) for reliability
// Use $.connection.hub.start() to demonstrate that Chrome doesn't receive messages
$.connection.hub.start().done(function () {
// Enable the "Send" button
$('#sendmessage').removeAttr('disabled');
$('#sendmessage').click(function () {
// Call the Send method on the hub.
chat.server.send($('#displayname').val(), $('#message').val());
// Clear text box and reset focus for next comment.
$('#message').val('').focus();
});
});
});
Can anybody see what I'm doing wrong?
I tried the sample in Win7 Google Chrome 24 and it works fine.
You can troubleshoot installing Fiddler and setting breakpoints in the javascript
POST /signalr/send?transport=serverSentEvents&connectionId=6ff0bffa-c31e-4d85-9aff-24f4528555ee HTTP/1.1
Host: localhost:43637
Connection: keep-alive
Content-Length: 113
Accept: application/json, text/javascript, */*; q=0.01
Origin:
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.17 (KHTML, like Gecko) Chrome/24.0.1312.57 Safari/537.17
Content-Type: application/x-www-form-urlencoded
Referer: /index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3
data=%7B%22H%22%3A%22chathub%22%2C%22M%22%3A%22Send%22%2C%22A%22%3A%5B%22gus%22%2C%22hello%22%5D%2C%22I%22%3A0%7D
May be it is related with buffering the responses.
https://github.com/SignalR/SignalR/issues/1944
Try setting EnableJSONP = False on the server hub. This fixed a similar issue I was having.