I am using AWS MediaLive and MediaPackage to deliver a HLS Livestream.
However if the stream ends there is always one Minute available in the .m3u8 playlist.
The settings "Startover window (sec.): 0" does not seem to solve this.
Deleting and creating new .m3u8 playlist would be very inconviniert because all players would have to be updatet.
Do anyone have an advice?
Cheers, Richy
Thanks for your post. If i understand correctly, you are referring to the MediaPackage endpoint which serves up a manifest with the last known segments, (60 seconds worth of segments by default).
There are several ways to alter or stop this behavior. I suggest testing some of these methods to see which you prefer:
[a] Delete the public-facing MediaPackage endpoint shortly (perhaps 10s) after your event ends. All subsequent requests to that endpoint will return an error. Segments already retrieved and cached by the player will not be affected, but no new data will be served. Note: you may also maintain a private endpoint on the same Channel to allow for viewing + harvesting of the streamed content if you wish.
[b] Use an AWS CloudFront CDN Distribution with a short Time to Live (TTL) in front of your MediaPackage Channel (which acts as the origin) to deliver content segments to your viewers. When the event ends, you can immediately disable or delete this CDN Distribution, and all requests for content segments will return an error. Segments already retrieved and cached by the player will not be affected, but no new data will be served from this distribution.
[c] Encrypt the content using MediaPackage encryption, then disable the keys at the end of the event. This Same approach applies to CDN Authorization headers, which you can mandate for the event playback and then delete after event completes.
[e] Use DNS redirection to your MediaPackage endpoint. When the event ends, remove the DNS redirector so that any calls to the old domain will fail.
I think one or a combination of these methods will work for you. Good Luck!
Related
Does Cloudfront require special settings to trigger a log?
I have the following flow:
Devices -> Cloudfront -> API Gateway -> Lambda Function
which works, but Cloudwatch doesn't seem to create logs for the lambda function (or API Gateway).
However, the following flow creates logs:
Web/Curl -> API Gateway -> Lambda Function
In comments, above, we seem to have arrived at a conclusion that unanticipated client-side caching (or caching somewhere between the client and the AWS infrastructure) may be a more appropriate explanation for the observed behavior, since there is no known mechanism by which an independent CloudFront distribution could access a Lambda function via API Gateway and cause those requests not to be logged by Lambda.
So, I'll answer this with a way to confirm or reject this hypothesis.
CloudFront injects a header into both requests and responses, X-Amz-Cf-Id, containing opaque tokens that uniquely identify the request and the response. Documentation refers to these as "encrypted," but for our purposes, they're simply opaque values with a very high probability of uniqueness.
In spite of having the same name, the request header and the response header are actually two uncorrelated values (they don't match each other on the same request/response).
The origin-side X-Amz-Cf-Id is sent to the origin server in the request is only really useful to AWS engineers, for troubleshooting.
But the viewer-side X-Amz-Cf-Id returned by CloudFront in the response is useful to us, because not only is it unique to each response (even responses from the CloudFront cache have different values each time you fetch the same object) but it also appears in the CloudFront access logs as x-edge-request-id (although the documentation does not appear to unambiguously state this).
Thus, if the client side sees duplicate X-Amz-Cf-Id values across multiple responses, there is something either internal to the client or between the client and CloudFront (in the client's network or ISP) that is causing cached responses to be seen by the client.
Correlating the X-Amz-Cf-Id from the client across multiple responses may be useful (since they should never be the same) and with the CloudFront logs may also be useful, since this confirms the timestamp of the request where CloudFront actually generated this particular response.
tl;dr: observing the same X-Amz-Cf-Id in more than one response means caching is occurring outside the boundaries of AWS.
Note that even though CloudFront allows min/max/default TTLs to impact how long CloudFront will cache the object, these settings don't impact any downstream or client caching behavior. The origin should return correct Cache-Control response headers (e.g. private, no-cache, no-store) to ensure correct caching behavior throughout the chain. If the origin behavior can't be changed, then Lambda#Edge origin response or viewer response triggers can be used to inject appropriate response headers -- see this example on Server Fault.
Note also that CloudFront caches 4xx/5xx error responses for 5 minutes by default. See Amazon CloudFront Latency for an explanation and steps to disable this behavior, if desired. This feature is designed to give the origin server a break, and not bombard it with requests that are presumed to continue to fail, anyway. This behavior may cause various problems in testing as well as production, so there are cases where it should be disabled.
I have an application deployed on AWS Elastic Beanstalk, I added some simple licensing to stop abuse of the api, the user has to pass a licensekey as a field
i.e
search.myapi.com/?license=4ca53b04&query=fred
If this is not valid then the request is rejected.
However until the monthly updates the above query will always return the same data, therefore I now point search.myapi.com to an AWS CloudFront distribution, then only if query is not cached does it go to actual server as
direct.myapi.com/?license=4ca53b04&query=fred
However the problem is that if two users make the same query they wont be deemed the same by Cloudfront because the license parameter is different. So the Cloudfront caching is only working at a per user level which is of no use.
What I want to do is have CloudFront ignore the license parameters for caching but not the other parameters. I dont mind too much if that means user could access CloudFront with invalid license as long as they cant make successful query to server (since CloudFront calls are cheap but server calls are expensive, both in terms of cpu and monetary cost)
Perhaps what I need is something in front of CloudFront that does the license check and then strips out the license parameter but I don't know what that would be ?
Two possible come to mind.
The first solution feels like a hack, but would prevent unlicensed users from successfully fetching uncached query responses. If the response is cached, it would leak out, but at no cost in terms of origin server resources.
If the content is not sensitive, and you're only trying to avoid petty theft/annoyance, this might be viable.
For query parameters, CloudFront allows you to forward all, cache on whitelist.
So, whitelist query (and any other necessary fields) but not license.
Results for a given query:
valid license, cache miss: request goes to origin, origin returns response, response stored in cache
valid license, cache hit: response served from cache
invalid license, cache hit: response served from cache
invalid license, cache miss: response goes to origin, origin returns error, error stored in cache.
Oops. The last condition is problematic, because authorized users will receive the cached error if the make the same query.
But we can fix this, as long as the origin returns an HTTP error for an invalid request, such as 403 Forbidden.
As I explained in Amazon CloudFront Latency, CloudFront caches responses with HTTP errors using different timers (not min/default/max-ttl), with a default of t minutes. This value can be set to 0 (or other values) for each of several individual HTTP status codes, like 403. So, for the error code your origin returns, set the Error Caching Minimum TTL to 0 seconds.
At this point, the problematic condition of caching error responses and playing them back to authorized clients has been solved.
The second option seems like a better idea, overall, but would require more sophistication and probably cost slightly more.
CloudFront has a feature that connects it with AWS Lambda, called Lambda#Edge. This allows you to analyze and manipulate requests and responses using simple Javascript scripts that are run at specific trigger points in the CloudFront signal flow.
Viewer Request runs for each request, before the cache is checked. It can allow the request to continue into CloudFront, or it can stop processing and generate a reaponse directly back to the viewer. Generated responses here are not stored in the cache.
Origin Request runs after the cache is checked, only for cache misses, before the request goes to the origin. If this trigger generates a response, the response is stored in the cache and the origin is not contacted.
Origin Response runs after the origin response arrives, only for cache misses, and before the response goes onto the cache. If this trigger modifies the response, the modified response stored in the cache.
Viewer Response runs immediately before the response is returned to the viewer, for both cache misses and cache hits. If this trigger modifies the response, the modified response is not cached.
From this, you can see how this might be useful.
A Viewer Request trigger could check each request for a valid license key, and reject those without. For this, it would need access to a way to validate the license keys.
If your client base is very small or rarely changes, the list of keys could be embedded in the trigger code itself.
Otherwise, it needs to validate the key, which could be done by sending a request to the origin server from within the trigger code (the runtime environment allows your code to make outbound requests and receive responses via the Internet) or by doing a lookup in a hosted database such as DynamoDB.
Lambda#Edge triggers run in Lambda containers, and depending on traffic load, observations suggest that it is very likely that subsequent requests reaching the same edge location will be handled by the same container. Each container only handles one request at a time, but the container becomes available for the next request as soon as control is returned to CloudFront. As a consequence of this, you can cache the results in memory in a global data structure inside each container, significantly reducing the number of times you need to ascertain whether a license key is valid. The function either allows CloudFront to continue processing as normal, or actively rejects the invalid key by generating its own response. A single trigger will cost you a little under $1 per million requests that it handles.
This solution prevents missing or unauthorized license keys from actually checking the cache or making query requests to the origin. As before, you would want to customize the query string whitelist in the CloudFront cache behavior settings to eliminate license from the whitelist, and change the error caching minimum TTL to ensure that errors are not cached, even though these errors should never occur.
We are working on setting up an API Management portal for one of our Web API. We are using eventhubs for logging the events and we are transferring the event messages to Azure Blob storage using Azure functions.
We would like to know how can we find the Time taken by API Management portal for providing the response for a message (we are capturing the time taken at the back end api layer but not from the API Management layer).
Regards,
John
The simpler solution is to enable Azure Monitor Diagnostic Logs for the Apimanagement service. You will get raw logs for each request including
durationMs - interval between receiving request line and headers from a client and writing last chunk of response body to a client. All writes and reads include network latency.
BackendTime - time spent waiting on backend response
ClientTime - time spent with client for request and response
CacheTime - time spent on fetching from cache
You can also refer this video.
Not the correct way of doing this, but still get an idea of how much time each request is taking. We can actually use the context variable to set the start time in the inbound policy node and then calculate the end time in the outbound node.
We recently switched to Amazon's new ALBs (Application Load Balancer) and were excited to get the benefits of http2 multiplexing. But it appears that there is still a HOL (Head of line) blocking issues going on.
The client is able to request the images in parallel but still has to wait for a period of time before it can begin downloading the image. My guess it that because AWS's Application Load Balancer terminates http2 and then talks to the ec2 instances via http/1 creating the HOL delay.
I may be reading this chart wrong, and if so could someone please explain to me why content isn't being downloaded faster, in other words I would expect the green portion to be smaller and the blue bar to appear sooner. Does networking between the load balacner and ec2 instance not suffer from HOL? Is there some magic stuff happening?
I believe that what you see might be related to how current Chrome (around v54) prioritizes requests.
Exclusive dependencies
Chrome uses HTTP/2's exclusive dependencies (that can be dynamically re-arranged as the page is parsed and new resources are discovered) in order to have all streams depend strictly on one another. That means that all resources are effectively sent one after the other. I wrote a small utility that parses the output of chrome://net-internals/#http2 in order to show the tree for a given page: https://github.com/deweerdt/h2priograph.
A dependency from stream to another can either be exclusive or not. Section 5.3.1 of RFC 7540 covers that part: https://www.rfc-editor.org/rfc/rfc7540#section-5.3.1, here's the example they give when adding a new stream D to A:
Not exclusive:
A A
/ \ ==> /|\
B C B D C
Exclusive:
A
A |
/ \ ==> D
B C / \
B C
Example
Let's take this page for example
Chrome only uses the exclusive dependencies, so the dependency tree might at first look like:
HTML
|
PNG
|
PNG
When the javascript is discovered, Chrome reprioritizes it above the images (because the javascript is more likely to affect how the page is rendered), so Chrome puts the JS right below the HTML:
HTML
|
JS
|
PNG
|
PNG
Because all the requests are daisy chained, it might look, as in the waterfall you posted that requests are executed one after another like in HTTP/1, but they're not, because they can be re-ordered on the fly and all the requests are sent to the browser ASAP.
Firefox on the other hand will have resources of the same type share the same priority so you should be able to see some interlacing there.
Please note that what Chrome does isn't equivalent to what used to happen with HTTP/1 since all the requests have been sent to the server, so the server always has something to be sent on the wire. In addition to that, ordering is dynamic, so if a higher priority resource is discovered in the page, Chrome will re-order the priority tree so that this new resource takes precedence over existing lower priority resources.
Might be super late for an answer, but still.
AWS ELB documentation clearly states that:
The backend connection (between ALB and target) supports HTTP 1.1 only
The backend connection does not support HTTP 1.1 pipelining (which might have somewhat replicated HTTP 2 multiplexing).
So essentially what you observe are multiplexed requests on the frontend connection that are processed one by one by ALB and waiting for backend reply until next frontend request is processed and routed to target.
You can refer to "HTTP connections" section from documentation.
How are cookies matched between DSPs like DoubleClick and DMPs like BlueKai for the purpose of ad serving if browser security prevents 1 party from reading the cookie of another party?
From what I've read, the DSP ad pixel would piggyback on the DMPs container tag so that each time the DMP's pixel is called the DSP's pixel is called. At this point, what information can be passed from the DMP to the DSP that allows the DSP to equate its ViewerId to the DMPs ViewerId?
Perhaps, I'm misunderstanding how piggybacking works. Any help is greatly appreciated
Thanks!
Usually u will place a DMP container tag on the page (well, there are other ways as well, I only list one of the standard approaches), where the first request sent is to hit the DMP and the response is DMP id plus a bunch of redirects from the partners (DSP's pixel link could be one of them. Actually if u are using Bluekai,these seats are biddable through their data marketplace). Then the browser will hit all these redirects with the DMP id. So DSP knows the DMP id to its own id mapping. The responses of these redirects return each unique id of these partners, so DMP can store the mappings as well. A simplified explanination could be found at http://www.adopsinsider.com/online-ad-measurement-tracking/data-management-platforms/syncing-online-data-to-a-data-management-platform/
The param passed by http GET or POST is usually cookie ids, where the actual data syn is usually carried out through real time or more often batch download server to server communication.