diff options
Diffstat (limited to 'libsoup/soup-content-sniffer.c')
| -rw-r--r-- | libsoup/soup-content-sniffer.c | 76 |
1 files changed, 76 insertions, 0 deletions
diff --git a/libsoup/soup-content-sniffer.c b/libsoup/soup-content-sniffer.c index 9e49d225..5fdee5ce 100644 --- a/libsoup/soup-content-sniffer.c +++ b/libsoup/soup-content-sniffer.c @@ -407,6 +407,79 @@ sniff_images (SoupContentSniffer *sniffer, SoupMessage *msg, } static char* +sniff_feed_or_html (SoupContentSniffer *sniffer, SoupMessage *msg, SoupBuffer *buffer) +{ + const char *resource = buffer->data; + int resource_length = MIN (512, buffer->length); + int pos = 0; + + /* Skip a leading UTF-8 BOM */ + if (resource[0] == 0xEF && resource[1] == 0xBB && resource[2] == 0xBF) + pos = 3; + + look_for_tag: + /* Skip insignificant white space */ + while ((resource[pos] == '\x09') || + (resource[pos] == '\x20') || + (resource[pos] == '\x0A') || + (resource[pos] == '\x0D')) + pos++; + + /* != < */ + if (resource[pos] != '\x3C') + return g_strdup ("text/html"); + + pos++; + + /* Skipping comments */ + if ((resource[pos] == '\x2D') || + (resource[pos+1] == '\x2D') || + (resource[pos+2] == '\x3E')) { + pos = pos + 3; + + while ((resource[pos] != '\x2D') && + (resource[pos+1] != '\x2D') && + (resource[pos+2] != '\x3E')) + pos++; + + goto look_for_tag; + } + + /* == ! */ + if (resource[pos] == '\x21') { + do { + pos++; + } while (resource[pos] != '\x3E'); + + pos++; + + goto look_for_tag; + } else if (resource[pos] == '\x3F') { /* ? */ + do { + pos++; + } while ((resource[pos] != '\x3F') && + (resource[pos+1] != '\x3E')); + + pos = pos + 2; + + goto look_for_tag; + } + + if ((resource[pos] == '\x72') && + (resource[pos+1] == '\x73') && + (resource[pos+2] == '\x73')) + return g_strdup ("application/rss+xml"); + + if ((resource[pos] == '\x66') && + (resource[pos+1] == '\x65') && + (resource[pos+2] == '\x65') && + (resource[pos+3] == '\x64')) + return g_strdup ("application/atom+xml"); + + return g_strdup ("text/html"); +} + +static char* sniff (SoupContentSniffer *sniffer, SoupMessage *msg, SoupBuffer *buffer, GHashTable **params) { const char *content_type_with_params; @@ -450,6 +523,9 @@ sniff (SoupContentSniffer *sniffer, SoupMessage *msg, SoupBuffer *buffer, GHashT return sniff_text_or_binary (sniffer, msg, buffer); } + if (!g_ascii_strcasecmp (content_type, "text/html")) + return sniff_feed_or_html (sniffer, msg, buffer); + return g_strdup (content_type); } |
