PayaraMicro doesn't support http range header? - html5-audio

My webapp running on Payara-Micro is a tool to listen to audio files and navigate freely through them using the javascript currentTime property.
So the browser has <audio src="..."> tags and to get the audio file, it sends http GET request to the server with the header Range: bytes=0-
Unfortunately Payara in response doesn't returns 206 code and Content-range: bytes 0-881403 but it returns 200 and this has the effect that when I use currentTime=10 for exemple, the currentTime becomes equal to 0!
Previously this app was running in PHP with an apache server and apache was supporting the range header.
Is it possible to configure PayaraMicro or Grizzly to support range request ? Or If I put an Apache server in front of PayaraMicro it will work ?
Thank you for your help!

Payara supports RFC-7233. I did a mistake: there was a filter in my code that removed the default response header for media files.
Here is the devil filter:
public void doFilter(...
(...)
httpServletResponse.setHeader("Content-Type", "text/html; charset=UTF-8");
filterChain.doFilter(servletRequest,servletResponse);
}
Subject closed!

Related

Cannot play wav file on safari

I'm trying to play a wav file on safari. Pretty much the same question as this: playing a WAV file on iOS Safari
But the accepted answers aren't working. I'm using a rails server with apache and phusion passenger. The audio file plays fine on chrome but not on any safari (desktop, mobile, and through uiwebview).
I'm sending the file in rails with
send_file filename, :type => "audio/x-wav", :disposition => "inline"
From the other stack overflow q&a, I tried adding Content-Range and Content-Length headers to the response
size = File.size(filename)
response.header["Content-Range"] = "bytes 0-#{size-1}/#{size}"
response.header["Content-Length"] = "#{size}"
The error i'm receiving is pretty nondescript "Failed to load resource: Plug-in handled load"
Here are the headers of the response
x-runtime 0.589797
Date Wed, 17 Aug 2016 16:38:49 GMT
X-Content-Type-Options nosniff
Server Apache/2.2.15 (CentOS)
X-Powered-By Phusion Passenger 5.0.7
Status 200 OK
Content-Type audio/x-wav
content-range bytes 0-3243/3244
Cache-Control private
Content-Transfer-Encoding binary
Content-Disposition inline; filename="eng-182-msg0026.wav"
Connection close
Content-Length 3244
X-XSS-Protection 1; mode=block
x-runtime 0.589797
When requesting a direct link to a media file this would work. But I was requesting this through a controller. Safari was making multiple http requests each for a certain range. The server was responding with the entire file every time which is why it fails.
The annoying thing is that the Safari web inspector decides not to show the "Range" header in the network request. It'll show other http headers but not the most important one in this case...
Anyways, short answer, respond back with the the correct byte range that each request wants.
I had the same problem, playing audio files on the Safari didn't work, but on the Chrome and every other browser everything worked as expected.
Set proper Content-Range in response header solve my problem. I used forked gem send_file_with_range, which contain fix for the Rails 5.1.
I recommend this gem because code in this gem is pretty simple and short, and this solution seems like the simplest and quickest.
Note: this solution is specific for the Ruby on Rails developers, but general solution is to set proper Content-Range in the response header, for every request.
I hope that this will be helpful for somebody.

apache httpclient and etag cache

I'm using Apache HttpClient 4.3.1 and I'm trying to integrate etag validation cache.
I've tried to "drop in" httpclient-cache CachingHttpClientBuilder instead of my usual HttpClientBuilder using instructions in here, but that didn't seem to do any good. While tracing the execution, it seems like a response that has "etag" header (weak etag) isn't considered cache-able - and so isn't retained for the next cycle.
Has anyone managed to use etag validation based cache with Apache HttpClient? I'm also open for alternative implementations.
Notes:
The server returns the first request with a weak etag header (W/"1234"). If the second request to the same URL has "If-None-Match=1234", the server returns 304. This is checked and working.
The server does not send any other cache header (expires, etc).
The whole setup works wonderfully when using a modern browser.
Whether a response is considered as cacheable or not is decided in
ResponseCachingPolicy#isResponseCacheable(org.apache.http.HttpRequest, org.apache.http.HttpResponse)
which checks for some headers using
ResponseCachingPolicy#isExplicitlyCacheable
when
header 'Expires' is set or the header 'Cache-Control:' has one of the values "max-age" "s-maxage" "must-revalidate" "proxy-revalidate" or "public" the response is considered cacheable.
For us, it worked to add "Cache-Control: 'must-revalidate' to the response on the server, along with the 'Etag' header.
With this settings the apache http client
stores the response of the first request in the cache
on the second request, sends a request to the server and if this responds with a HttpStatus 304 (Not Modified) returns a HttpStatus 200 (ok) and the original content to the caller
That is how it should be.
We are using release 4.5.2 of apache http client cache.

How to set response Content-Length to infinite

I try to create an application in web2py framework. By default web2py server has Transfer-Encoding: Chunked header for response, but in that case when target remote web application sends GET request to my app it could get only first string of text from requested page (from file's content that displayed on page). If to use Content-Length instead, for example, with value of 1000 it will get 1000 bytes of data from page... But if I expect to response with huge range of data, how to set Content-Length parameter to infinity or by file (like here but with web2py syntax instead of php )?
If you are serving web2py via the built-in development server and serving files via the Expose functionality, then the files will be served via chunked transfer encoding.
However, if you instead use response.stream to serve files, the Content-Length header will be set automatically.

How to get browsers to cache video response from Azure CDN?

I have uploaded an mp4 video animation to Azure Blob Storage. The headers are are all default apart from setting the Content-Type to video/mp4. The video can be accessed at http://paddingtondev.blob.core.windows.net/media/1001/animation_default_headers.mp4
I have an Azure CDN sitting over that blob storage account. The URL for the same video through the CDN is http://az593791.vo.msecnd.net/media/1001/animation_default_headers.mp4
When I access the blob-stored video through an HTML5 video element on a web page, the browser (have tested in FF and Chrome) receives the entire video in a 200 HTTP response. Further requests for that video then receive a 304 response from blob storage.
However, when you request the video through the Azure CDN, it helpfully returns it to you as a series of HTTP 206 partial responses. This is in response to the browsers specifying a Range header with the request.
However, further requests for the video through the CDN are NOT cached, and the whole video is re-downloaded by the browser (through a series of further 206 requests).
How do I ensure the video is cached? I understand the usefulness of partial responses, but in our case the video won't be seekable and we only play it when the whole file is downloaded. I can see a few approaches here, but none have helped so far:
Forbid Azure CDN from returning partial responses
Remove range header from original browser request somehow
Persuade browsers to cache 206 partial responses
I have tried adding a max-age Cache-Control header to the file but this had no impact. Ideally we wouldn't even hit Azure at all when re-loading the video (as it will never change), but I'm happy to accept the cost of the HTTP request to Azure if it subsequently returns a 304 .
Caching 206 responses is tricky. The RFC for the client requires that in order to cache the content the ETAG and the range requested must match exactly.
There are a couple of things you can check -
1) Verify that the ETAGS did not change on the request. From the description of your environment (and setting the content expiration date), this sounds unlikely, but it may be an avenue to pursue.
2) More likely is that the range requests are not lining up. A request for byte range 1000-->2000 and a second request of 1500-->2000 would not (per RFC) be served from the client cache. So you may be in a situation of seeing exactly what is supposed to happen with that particular format/client.
I'm pretty sure HTML5 only supports progressive download, so unless you wanted to reconsider the delivery this may be expected behavior.

How to determine version of http in get html?

I want to request a server by 'get' and I use this method:
http://smarttracking.ir/gprmc_receiver.php?strVar=27,0,146,1,$GPRMC,213659.000,A,3238.0007,N,05118.5837,E,36.74,274.01,170114,,,N*6A5,username1,64,5}
If you copy this in the address bar on your browser, you will get a response. But there is a problem for me. I send this by sim900 module and it doesn't support http 1.0 or 1.1 and it is less than 1 so I need to send http version by address bar if it is possible. Something like this:
http://smarttracking.ir/gprmc_receiver.php?id=1 http/1.1 strVar=27,0,146,1,$GPRMC,213659.000,A,3238.0007,N,05118.5837,E,36.74,274.01,170114,,,N*6A5,username1,64,5}
Open a socket from the sim900 module to http://smarttraking.it and send a http request in according to the standard. The format of http request offers the possibility to specify the http version.
Look this image:
format http request