46 #include "nsStringStream.h"
50 #include "nsICategoryManager.h"
51 #include "nsIServiceManager.h"
52 #include "nsComponentManagerUtils.h"
53 #include "nsServiceManagerUtils.h"
55 #include "nsIStreamConverterService.h"
56 #include "nsIStreamConverter.h"
58 #include "nsIStreamListener.h"
60 #include "nsIHttpChannel.h"
61 #include "nsIMIMEHeaderParam.h"
63 #include "nsMimeTypes.h"
65 #define TYPE_ATOM "application/atom+xml"
66 #define TYPE_RSS "application/rss+xml"
67 #define TYPE_MAYBE_FEED "application/vnd.mozilla.maybe.feed"
69 #define NS_RDF "http://www.w3.org/1999/02/22-rdf-syntax-ns#"
70 #define NS_RSS "http://purl.org/rss/1.0/"
87 nsCOMPtr<nsIHttpChannel> httpChannel(do_QueryInterface(request));
89 return NS_ERROR_NO_INTERFACE;
91 nsCAutoString contentEncoding;
92 httpChannel->GetResponseHeader(NS_LITERAL_CSTRING(
"Content-Encoding"),
94 if (!contentEncoding.IsEmpty()) {
95 nsCOMPtr<nsIStreamConverterService> converterService(do_GetService(NS_STREAMCONVERTERSERVICE_CONTRACTID));
96 if (converterService) {
97 ToLowerCase(contentEncoding);
100 rv = converterService->AsyncConvertData(contentEncoding.get(),
101 "uncompressed",
this, nsnull,
102 getter_AddRefs(converter));
103 NS_ENSURE_SUCCESS(rv, rv);
105 converter->OnStartRequest(request, nsnull);
107 nsCOMPtr<nsIStringInputStream> rawStream =
108 do_CreateInstance(NS_STRINGINPUTSTREAM_CONTRACTID);
110 return NS_ERROR_FAILURE;
112 rv = rawStream->SetData((
const char*)data, length);
113 NS_ENSURE_SUCCESS(rv, rv);
115 rv = converter->OnDataAvailable(request, nsnull, rawStream, 0, length);
116 NS_ENSURE_SUCCESS(rv, rv);
118 converter->OnStopRequest(request, nsnull,
NS_OK);
129 return StringHead(aString, N).LowerCaseEqualsLiteral(
aSubstring);
140 nsCAutoString contentDisposition;
142 httpChannel->GetResponseHeader(NS_LITERAL_CSTRING(
"content-disposition"),
145 if (NS_SUCCEEDED(rv) && !contentDisposition.IsEmpty()) {
146 nsCOMPtr<nsIURI>
uri;
147 httpChannel->GetURI(getter_AddRefs(uri));
148 nsCOMPtr<nsIMIMEHeaderParam> mimehdrpar =
149 do_GetService(NS_MIMEHEADERPARAM_CONTRACTID, &rv);
150 if (NS_SUCCEEDED(rv))
152 nsCAutoString fallbackCharset;
154 uri->GetOriginCharset(fallbackCharset);
155 nsAutoString dispToken;
157 rv = mimehdrpar->GetParameter(contentDisposition,
"", fallbackCharset,
158 PR_TRUE, nsnull, dispToken);
164 (!dispToken.IsEmpty() &&
185 FindChar(
char c,
const char *begin,
const char *end)
187 for (; begin < end; ++begin) {
217 while ( (start =
FindChar(
'<', start, end)) ) {
225 if (*start !=
'?' && *start !=
'!')
253 PRInt32
offset = dataString.Find(substring);
257 const char *begin = dataString.BeginReading();
264 nsFeedSniffer::GetMIMETypeFromContent(nsIRequest* request,
267 nsACString& sniffedType)
269 nsCOMPtr<nsIHttpChannel> channel(do_QueryInterface(request));
271 return NS_ERROR_NO_INTERFACE;
274 nsCAutoString method;
275 channel->GetRequestMethod(method);
276 if (!method.Equals(
"GET")) {
277 sniffedType.Truncate();
288 nsCOMPtr<nsIURI> originalURI;
289 channel->GetOriginalURI(getter_AddRefs(originalURI));
291 nsCAutoString scheme;
292 originalURI->GetScheme(scheme);
293 if (scheme.EqualsLiteral(
"view-source")) {
294 sniffedType.Truncate();
302 nsCAutoString contentType;
303 channel->GetContentType(contentType);
304 PRBool noSniff = contentType.EqualsLiteral(
TYPE_RSS) ||
311 nsCAutoString sniffHeader;
312 nsresult foundHeader =
313 channel->GetRequestHeader(NS_LITERAL_CSTRING(
"X-Moz-Is-Feed"),
315 noSniff = NS_SUCCEEDED(foundHeader);
321 sniffedType.Truncate();
327 channel->SetResponseHeader(NS_LITERAL_CSTRING(
"X-Moz-Is-Feed"),
328 NS_LITERAL_CSTRING(
"1"), PR_FALSE);
335 if (!contentType.EqualsLiteral(TEXT_HTML) &&
336 !contentType.EqualsLiteral(APPLICATION_OCTET_STREAM) &&
339 contentType.Find(
"xml") == -1) {
340 sniffedType.Truncate();
351 mDecodedData.IsEmpty() ? (
const char*)data : mDecodedData.get();
364 nsDependentCSubstring dataString((
const char*)testData, length);
366 PRBool isFeed = PR_FALSE;
378 dataString.Find(
NS_RDF) != -1 &&
379 dataString.Find(
NS_RSS) != -1;
386 sniffedType.Truncate();
391 nsFeedSniffer::OnStartRequest(nsIRequest* request,
nsISupports* context)
399 const char* rawSegment,
402 PRUint32* writeCount)
404 nsCString* decodedData =
static_cast<nsCString*
>(closure);
405 decodedData->Append(rawSegment, count);
411 nsFeedSniffer::OnDataAvailable(nsIRequest* request,
nsISupports* context,
412 nsIInputStream* stream, PRUint32
offset,
421 nsFeedSniffer::OnStopRequest(nsIRequest* request,
nsISupports* context,
429 const char *registryLocation,
430 const char *componentType,
431 const nsModuleComponentInfo *info)
434 nsCOMPtr<nsICategoryManager> catman = do_GetService(NS_CATEGORYMANAGER_CONTRACTID, &rv);
438 return catman->AddCategoryEntry(NS_CONTENT_SNIFFER_CATEGORY,
"Feed Sniffer",
static PRBool StringBeginsWithLowercaseLiteral(nsAString &aString, const char(&aSubstring)[N])
NS_DECL_ISUPPORTS NS_DECL_NSICONTENTSNIFFER NS_DECL_NSIREQUESTOBSERVER static NS_DECL_NSISTREAMLISTENER NS_METHOD AppendSegmentToString(nsIInputStream *inputStream, void *closure, const char *rawSegment, PRUint32 toOffset, PRUint32 count, PRUint32 *writeCount)
static NS_METHOD Register(nsIComponentManager *compMgr, nsIFile *path, const char *registryLocation, const char *componentType, const nsModuleComponentInfo *info)
PRBool HasAttachmentDisposition(nsIHttpChannel *httpChannel)
PRUint32 const nsAString & aSubstring
static const char * FindChar(char c, const char *begin, const char *end)
static PRBool ContainsTopLevelSubstring(nsACString &dataString, const char *substring)
NS_IMPL_ISUPPORTS3(nsFeedSniffer, nsIContentSniffer, nsIStreamListener, nsIRequestObserver) nsresult nsFeedSniffer
static PRBool IsDocumentElement(const char *start, const char *end)
nsresult ConvertEncodedData(nsIRequest *request, const PRUint8 *data, PRUint32 length)
#define NS_FEEDSNIFFER_CONTRACTID