Overview

Packages

  • None
  • SimplePie

Classes

  • SimplePie
  • SimplePie_Author
  • SimplePie_Autoloader
  • SimplePie_Cache
  • SimplePie_Cache_DB
  • SimplePie_Cache_File
  • SimplePie_Cache_Memcache
  • SimplePie_Cache_MySQL
  • SimplePie_Caption
  • SimplePie_Category
  • SimplePie_Content_Type_Sniffer
  • SimplePie_Copyright
  • SimplePie_Core
  • SimplePie_Credit
  • SimplePie_Decode_HTML_Entities
  • SimplePie_Enclosure
  • SimplePie_File
  • SimplePie_gzdecode
  • SimplePie_HTTP_Parser
  • SimplePie_IRI
  • SimplePie_Item
  • SimplePie_Locator
  • SimplePie_Misc
  • SimplePie_Net_IPv6
  • SimplePie_Parse_Date
  • SimplePie_Parser
  • SimplePie_Rating
  • SimplePie_Registry
  • SimplePie_Restriction
  • SimplePie_Sanitize
  • SimplePie_Source
  • SimplePie_XML_Declaration_Parser

Interfaces

  • SimplePie_Cache_Base
  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Todo
  1: <?php
  2: /**
  3:  * SimplePie
  4:  *
  5:  * A PHP-Based RSS and Atom Feed Framework.
  6:  * Takes the hard work out of managing a complete RSS/Atom solution.
  7:  *
  8:  * Copyright (c) 2004-2012, Ryan Parman, Geoffrey Sneddon, Ryan McCue, and contributors
  9:  * All rights reserved.
 10:  *
 11:  * Redistribution and use in source and binary forms, with or without modification, are
 12:  * permitted provided that the following conditions are met:
 13:  *
 14:  *  * Redistributions of source code must retain the above copyright notice, this list of
 15:  *    conditions and the following disclaimer.
 16:  *
 17:  *  * Redistributions in binary form must reproduce the above copyright notice, this list
 18:  *    of conditions and the following disclaimer in the documentation and/or other materials
 19:  *    provided with the distribution.
 20:  *
 21:  *  * Neither the name of the SimplePie Team nor the names of its contributors may be used
 22:  *    to endorse or promote products derived from this software without specific prior
 23:  *    written permission.
 24:  *
 25:  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
 26:  * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 27:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
 28:  * AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 29:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 30:  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 31:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 32:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 33:  * POSSIBILITY OF SUCH DAMAGE.
 34:  *
 35:  * @package SimplePie
 36:  * @version 1.3-dev
 37:  * @copyright 2004-2012 Ryan Parman, Geoffrey Sneddon, Ryan McCue
 38:  * @author Ryan Parman
 39:  * @author Geoffrey Sneddon
 40:  * @author Ryan McCue
 41:  * @link http://simplepie.org/ SimplePie
 42:  * @license http://www.opensource.org/licenses/bsd-license.php BSD License
 43:  */
 44: 
 45: 
 46: /**
 47:  * Content-type sniffing
 48:  *
 49:  * Based on the rules in http://tools.ietf.org/html/draft-abarth-mime-sniff-06
 50:  *
 51:  * This is used since we can't always trust Content-Type headers, and is based
 52:  * upon the HTML5 parsing rules.
 53:  *
 54:  *
 55:  * This class can be overloaded with {@see SimplePie::set_content_type_sniffer_class()}
 56:  *
 57:  * @package SimplePie
 58:  */
 59: class SimplePie_Content_Type_Sniffer
 60: {
 61:     /**
 62:      * File object
 63:      *
 64:      * @var SimplePie_File
 65:      */
 66:     var $file;
 67: 
 68:     /**
 69:      * Create an instance of the class with the input file
 70:      *
 71:      * @param SimplePie_Content_Type_Sniffer $file Input file
 72:      */
 73:     public function __construct($file)
 74:     {
 75:         $this->file = $file;
 76:     }
 77: 
 78:     /**
 79:      * Get the Content-Type of the specified file
 80:      *
 81:      * @return string Actual Content-Type
 82:      */
 83:     public function get_type()
 84:     {
 85:         if (isset($this->file->headers['content-type']))
 86:         {
 87:             if (!isset($this->file->headers['content-encoding'])
 88:                 && ($this->file->headers['content-type'] === 'text/plain'
 89:                     || $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
 90:                     || $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
 91:                     || $this->file->headers['content-type'] === 'text/plain; charset=UTF-8'))
 92:             {
 93:                 return $this->text_or_binary();
 94:             }
 95: 
 96:             if (($pos = strpos($this->file->headers['content-type'], ';')) !== false)
 97:             {
 98:                 $official = substr($this->file->headers['content-type'], 0, $pos);
 99:             }
100:             else
101:             {
102:                 $official = $this->file->headers['content-type'];
103:             }
104:             $official = trim(strtolower($official));
105: 
106:             if ($official === 'unknown/unknown'
107:                 || $official === 'application/unknown')
108:             {
109:                 return $this->unknown();
110:             }
111:             elseif (substr($official, -4) === '+xml'
112:                 || $official === 'text/xml'
113:                 || $official === 'application/xml')
114:             {
115:                 return $official;
116:             }
117:             elseif (substr($official, 0, 6) === 'image/')
118:             {
119:                 if ($return = $this->image())
120:                 {
121:                     return $return;
122:                 }
123:                 else
124:                 {
125:                     return $official;
126:                 }
127:             }
128:             elseif ($official === 'text/html')
129:             {
130:                 return $this->feed_or_html();
131:             }
132:             else
133:             {
134:                 return $official;
135:             }
136:         }
137:         else
138:         {
139:             return $this->unknown();
140:         }
141:     }
142: 
143:     /**
144:      * Sniff text or binary
145:      *
146:      * @return string Actual Content-Type
147:      */
148:     public function text_or_binary()
149:     {
150:         if (substr($this->file->body, 0, 2) === "\xFE\xFF"
151:             || substr($this->file->body, 0, 2) === "\xFF\xFE"
152:             || substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
153:             || substr($this->file->body, 0, 3) === "\xEF\xBB\xBF")
154:         {
155:             return 'text/plain';
156:         }
157:         elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body))
158:         {
159:             return 'application/octect-stream';
160:         }
161:         else
162:         {
163:             return 'text/plain';
164:         }
165:     }
166: 
167:     /**
168:      * Sniff unknown
169:      *
170:      * @return string Actual Content-Type
171:      */
172:     public function unknown()
173:     {
174:         $ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
175:         if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
176:             || strtolower(substr($this->file->body, $ws, 5)) === '<html'
177:             || strtolower(substr($this->file->body, $ws, 7)) === '<script')
178:         {
179:             return 'text/html';
180:         }
181:         elseif (substr($this->file->body, 0, 5) === '%PDF-')
182:         {
183:             return 'application/pdf';
184:         }
185:         elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-')
186:         {
187:             return 'application/postscript';
188:         }
189:         elseif (substr($this->file->body, 0, 6) === 'GIF87a'
190:             || substr($this->file->body, 0, 6) === 'GIF89a')
191:         {
192:             return 'image/gif';
193:         }
194:         elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
195:         {
196:             return 'image/png';
197:         }
198:         elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
199:         {
200:             return 'image/jpeg';
201:         }
202:         elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
203:         {
204:             return 'image/bmp';
205:         }
206:         elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
207:         {
208:             return 'image/vnd.microsoft.icon';
209:         }
210:         else
211:         {
212:             return $this->text_or_binary();
213:         }
214:     }
215: 
216:     /**
217:      * Sniff images
218:      *
219:      * @return string Actual Content-Type
220:      */
221:     public function image()
222:     {
223:         if (substr($this->file->body, 0, 6) === 'GIF87a'
224:             || substr($this->file->body, 0, 6) === 'GIF89a')
225:         {
226:             return 'image/gif';
227:         }
228:         elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A")
229:         {
230:             return 'image/png';
231:         }
232:         elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF")
233:         {
234:             return 'image/jpeg';
235:         }
236:         elseif (substr($this->file->body, 0, 2) === "\x42\x4D")
237:         {
238:             return 'image/bmp';
239:         }
240:         elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00")
241:         {
242:             return 'image/vnd.microsoft.icon';
243:         }
244:         else
245:         {
246:             return false;
247:         }
248:     }
249: 
250:     /**
251:      * Sniff HTML
252:      *
253:      * @return string Actual Content-Type
254:      */
255:     public function feed_or_html()
256:     {
257:         $len = strlen($this->file->body);
258:         $pos = strspn($this->file->body, "\x09\x0A\x0D\x20");
259: 
260:         while ($pos < $len)
261:         {
262:             switch ($this->file->body[$pos])
263:             {
264:                 case "\x09":
265:                 case "\x0A":
266:                 case "\x0D":
267:                 case "\x20":
268:                     $pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
269:                     continue 2;
270: 
271:                 case '<':
272:                     $pos++;
273:                     break;
274: 
275:                 default:
276:                     return 'text/html';
277:             }
278: 
279:             if (substr($this->file->body, $pos, 3) === '!--')
280:             {
281:                 $pos += 3;
282:                 if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false)
283:                 {
284:                     $pos += 3;
285:                 }
286:                 else
287:                 {
288:                     return 'text/html';
289:                 }
290:             }
291:             elseif (substr($this->file->body, $pos, 1) === '!')
292:             {
293:                 if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false)
294:                 {
295:                     $pos++;
296:                 }
297:                 else
298:                 {
299:                     return 'text/html';
300:                 }
301:             }
302:             elseif (substr($this->file->body, $pos, 1) === '?')
303:             {
304:                 if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false)
305:                 {
306:                     $pos += 2;
307:                 }
308:                 else
309:                 {
310:                     return 'text/html';
311:                 }
312:             }
313:             elseif (substr($this->file->body, $pos, 3) === 'rss'
314:                 || substr($this->file->body, $pos, 7) === 'rdf:RDF')
315:             {
316:                 return 'application/rss+xml';
317:             }
318:             elseif (substr($this->file->body, $pos, 4) === 'feed')
319:             {
320:                 return 'application/atom+xml';
321:             }
322:             else
323:             {
324:                 return 'text/html';
325:             }
326:         }
327: 
328:         return 'text/html';
329:     }
330: }
331: 
332: 
SimplePie Documentation API documentation generated by ApiGen 2.4.0