Playing Windows Media Video Served By .ashx - asp.net

I have embedded a windows media player in a web page, using the usual <object> and <embed> tags. The video is served by an ashx (http handler). When I try to play the video, I usually (but not always) get an error message telling me that the file extension (ashx) does not match the file format.
This happens in IE (9 & 10) and also in Firefox (latest) with the WMP plugin.
I know that the tags (with classid, etc) are correct because the media player displays and allows me to click the 'play' button.
The ashx returns the correct mime type (video/x-ms-wmv) and a valid file name (somevideo.wmv) in the response headers. I have tried content-disposition attachment and inline.
I have tried urls using 'http://', 'https://', and '//' (which I prefer)
If I put the url (including the .ashx) of the video file in the browser address bar directly, the video downloads and plays.
If I modify the object tag to use a direct path to the video file (/somewhere/somevideo.wmv), it works - but I can't use this as a solution.
The same ashx serves up video and audio in various other formats with out any fuss - it just seems that the embedded windows media player doesn't like it.
This has been working for several years - I think this is some new behavior, though I can't identify what has changed, other than browser updates.
EDIT: a more careful study in Fiddler showed something I missed before. If I access the video directly (by entering my ashx url in the browser address bar), the video plays in the standalone media player. The content type and disposition headers are correct.
However, when using the embedded player, I usually (not always) get OPTIONS and PROPFIND requests from user agent "Microsoft-WebDAV-MiniRedir/6.1.7601". I do not have WebDAV enabled, and I do not respond to options and propfind requests. The embedded player does not request the actual video file.
Correction - I do actually respond to the options request - here is the request and response info from fiddler :
OPTIONS http://mydomain.com/myhandler.ashx HTTP/1.1
User-Agent: Microsoft-WebDAV-MiniRedir/6.1.7601
translate: f
Connection: Keep-Alive
Host: mydomain.com
HTTP/1.1 200 OK
Allow: OPTIONS, TRACE, GET, HEAD, POST
Server: Microsoft-IIS/7.5
Public: OPTIONS, TRACE, GET, HEAD, POST
X-Powered-By: ASP.NET
Date: Tue, 24 Dec 2013 16:03:49 GMT
Content-Length: 0
This is followed by four identical requests, using PROPFIND instead of OPTIONS. the response is 404.

To successfully play the file you need to specify Content-Disposition and Content-Type headers correctly.
In your ashx, make sure you add following lines,
Response.AddHeader("Content-Disposition","attachment;filename='a.wmv'");
Response.AddHeader("Content-Type","video/wmv");
Please identify correct name and content-type based on type of file you have, and substitute them in above code.
Looks like it has Cross Origin Resource Sharing Issue,
make sure you are returning correct headers for different domain as suggested by following response.
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: X-Requested-With, Accept, Content-Type, Origin
Access-Control-Max-Age: 1728000
Replace * with domain where your page is hosted which embeds your media player.

Have you tried appending the file type to the end of the URL? for example:
http://www.mywebsite.com/MyVideoHandler.ashx?videofile=123245&.wmv
This example assumes that the file is of wmv type.

Related

Which HTTP headers are set by the web browser and sent automatically

I am assuming that all web browsers send User-Agent, DNT, Accept, Accept-Language, Accept-Encoding etc automatically. The web developer do not have to do anything to set these headers. I am saying this because previously www.whatismybrowser.com used to show these header values.
If so then which headers are set by the web browser and sent automatically?
OP here. I got the answer from reddit.
One thing you could easily do is create a page like test.php and set it to just:
<?php
print_r($_SERVER);
Then visit that in the different browser and OS combos that you care about and take any of the notes that you're looking for.

Flask send_file: how do I know if I need "as_attachment"?

Flask has a method to return a file: http://flask.pocoo.org/docs/1.0/api/#flask.send_file
There is a parameter called as_attachment with a default of False, and there is a handwaavy statement about it: "For extra security you probably want to send certain files as attachment (HTML for instance)"
How do I know if my use case is "those certain files"? Or alternatively stated, what does this do as opposed to leaving this as False?
You'll find a clue in the same documentation, further down in the parameter list:
as_attachment – set to True if you want to send this file with a Content-Disposition: attachment header.
So when the flag is set, an extra header is added to the response, which controls how the browser will handle the response. From the MDN documenation on Content-Disposition:
In a regular HTTP response, the Content-Disposition response header is a header indicating if the content is expected to be displayed inline in the browser, that is, as a Web page or as part of a Web page, or as an attachment, that is downloaded and saved locally.
Without an explicit Content-Disposition header, a text/html response from your Flask server will be shown as a web page in the browser. If you needed the file to be saved to disk instead (the browser prompting you what to do with the file), then you need to have a Content-Disposition: attachment set.
So when your response content type is likely to be shown in the browser as a web page but you want the user to download it instead, use as_attachment=True. These days, in addition to HTML, you probably want to set that flag for images, PDF files, and XML as well.

FormsAuthentication cookie not sent by browser when clicking external links

We've noticed that for some users of our website, they have a problem that if they following links to the website from external source (specifically Outlook and MS Word) that they arrive at the website in such a way that User.IsAuthenticated is false, even though they are still logged in in other tabs.
After hours of diagnosis, it appears to be because the FormsAuthentication cookie is not sent sometimes when the external link is clicked. If we examine in Fiddler, we see different headers for links clicked within the website, versus the headers which are as a result of clicking a link in a Word document or Email. There doesn't appear to be anything wrong with the cookie (has "/" as path, no domain, and a future expiration date).
Here is the cookie being set:
Set-Cookie: DRYXADMINAUTH2014=<hexdata>; expires=Wed, 01-Jul-2015 23:30:37 GMT; path=/
Here is a request sent from an internal link:
GET http://domain.com/searchresults/media/?sk=creative HTTP/1.1
Host: domain.com
Cookie: Diary_SessionID=r4krwqqhaoqvt1q0vcdzj5md; DRYXADMINAUTH2014=<hexdata>;
Here is a request sent from an external (Word) link:
GET http://domain.com/searchresults/media/?sk=creative HTTP/1.1
Host: domain.com
Cookie: Diary_SessionID=cpnriieepi4rzdbjtenfpvdb
Note that the .NET FormsAuthentication token is missing from the second request. The problem doesn't seem to be affected by which browser is set as default and happens in both Chrome and Firefox.
Is this normal/expected behaviour, or there a way we can fix this?
Turns out this a known issue with Microsoft Word, Outlook and other MS Office products: <sigh>
See: Why are cookies unrecognized when a link is clicked from an external source (i.e. Excel, Word, etc...)
Summary: Word tries to open the URL itself (in case it's an Office document) but gets redirected as it doesn't have the authentication cookie. Due to a bug in Word, it then incorrectly tries to open the redirected URL in the OS's default browser instead of the original URL. If you monitor the the "process" column in Fiddler it's easy to see the exact behaviour from the linked article occurring:

How to fetch every possible media types

Having a resource identified by the URL https://example.com/resource, accepting image/svg+xml and text/html media types (using HTTP's Accept header).
How can a client be aware of those possible media types?
We frequently refer to Accept header as a negotiation between the client and the server. But I don't really understand how the client can give to the server its wanted type, and how the server is supposed to answer.
I think the server may be able to teach to the client its allowed types.
I think this needs to be split up:
If you are a server and wish to inform clients about alternative representations of the requested resource, you can do so via the Link header as described in RFC 5988. A possible response could look like this:
HTTP/1.1 200 Ok
Content-Type: image/svg+xml
Link: <https://example.com/resource>; rel="alternate"; type="image/png"
Link: <https://example.com/resource>; rel="alternate"; type="image/jpeg"
If a client fetches a resource and wants to know which alternative representations are available, this were the way to go if no Link headers can be found:
Fetch the resource and send an Accept header containing */*, implying every imaginable media type were understood by the client.
Extract the media type from the response and add it to your Accept header with a weight q=0, letting the server know the served media type were not acceptable. Example:
Accept: image/svg+xml;q=0, */*
Send out a new request for the same resource with the new accept header created in step 2
If you receive a 406/Not acceptable response, you're done. If not: Go back to step 2.
You should now know all media types for the given resource on the server.

How do I use Fiddler to modify the status code in an HTTP response?

I need to test some client application code I've written to test its' handling of various status codes returned in an HTTP response from a web server.
I have Fiddler 2 (Web Debugging Proxy) installed and I believe there's a way to modify responses using this application, but I'm struggling to find out how. This would be the most convenient way, as it would allow me to leave both client and server code unmodified.
Can anyone assist as I'd like to intercept the HTTP response being sent from server to client and modify the status code before it reaches the client?
Any advice would be much appreciated.
Ok, so I assume that you're already able to monitor your client/server traffic. What you want to do is set a breakpoint on the response then fiddle with it before sending it on to the client.
Here are a couple of different ways to do that:
Rules > Automatic Breakpoints > After Responses
In the quickexec box (the black box at the bottom) type "bpafter yourpage.svc". Now Fiddler will stop at a breakpoint before all requests to any URL that contains "yourpage.svc". Type "bpafter" with no parameters to clear the breakpoint.
Programmatically tamper with the response using FiddlerScript. The best documentation for FiddlerScript is on the official site: http://www.fiddler2.com/Fiddler/dev/
Once you've got a response stopped at the breakpoint, just double click it to open it in the inspectors. You've got a couple of options now:
Right next to the green Run to Completion button (which you click to send the response) there's a dropdown that lets you choose some default response types.
Or, on the Headers inspector, change the response code & message in the textbox at the top.
Or, click the "Raw" inspector and mess with the raw response to do arbitrary things to it. Also a good way to see what your client does when it gets a malformed response, which you'll probably test accidentally :)
Another alternative is to use Fiddler's AutoResponder tab (on the right-hand panel). This allows you to catch a request to any URI that matches a string and serve a "canned" response from a file. The file can contain both headers and payload. The advantage of this approach is that you don't have to write FiddlerScript and you don't have to handle each request manually via a breakpoint.
You would set the rule up in Fiddler like shown below (ensure you enable unmatched requests passthrough otherwise all other http requests will fail).
In this example, any request whose URI includes "fooBar" will get the canned response. The format of the file will vary depending on your APIs (you can use your browser to intercept a "real" response and base it on that) but mine looked like the following:
HTTP/1.1 409 Conflict
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, DELETE, PUT, PATCH, OPTIONS
Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization
Access-Control-Max-Age: 86400
Content-Type: application/vnd.api+json
Content-Length: 149
Date: Tue, 28 Mar 2017 10:03:29 GMT
{"errors":[{"code":"OutOfStock","detail":"Item not in stock","source":{"lineId":{"type":"Order line Number","id":"1"}},"meta":{"availableStock":0}}]}
I found that it needed a carriage return at the end of the last line (i.e. after the json), and that the Content-Length header had to match the number of characters in the json, otherwise the webapp would hang. Your mileage may vary.
Create a FiddlerScript rule. Here's what I used in order to generate a local copy of a website that was intentionally using 403 on every page to thwart HTTrack/WGET.
https://gist.github.com/JamoCA/22db8d68a9a2fb20cb04a85360185333
/* 20180615 Fiddler rule to ignore all 403 HTTP Status errors so WGET or HTTrack can generate local copy of remote website */
SCENARIO: Changing the user agent or setting a delay isn't enough and the entire remote server is configured to respond w/403.
CONFIGURE: Add below rule to FiddlerScript OnBeforeReponse() section. Configure HTTrack/WGET/CRON to use proxy 127.0.0.01:8888 */
static function OnBeforeResponse(oSession: Session) {
if (oSession.HostnameIs("TARGETHOSTNAME_FILTER.com") && oSession.responseCode == 403) {
oSession.responseCode = 200;
oSession.oResponse.headers.HTTPResponseCode = 200;
oSession.oResponse.headers.HTTPResponseStatus = "200 OK";
}
}

Resources