Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split SimplePie\File class into HTTP client and response #774

Merged
merged 27 commits into from
May 21, 2023
Merged
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
24a8c57
Create interfaces for HTTP client and response
Art4 Jan 23, 2023
a5664cf
Add FileClient as new HTTP client implementation
Art4 Jan 23, 2023
221259b
Add Response tests for File class
Art4 Jan 23, 2023
3cda8f2
Use HTTP client inside SimplePie class
Art4 Jan 23, 2023
cd81336
Add support for HTTP client in Sanitize class
Art4 Jan 23, 2023
551ecc7
Use HTTP client in Locator class
Art4 Jan 23, 2023
8fc95ca
use Response methods instead of File attributes
Art4 Jan 23, 2023
c1a6ead
Add method Response::get_permanent_uri()
Art4 Jan 23, 2023
61cd544
Use Response methods instead of File attributes
Art4 Jan 23, 2023
9e3e13f
Improve Sniffer class
Art4 Jan 24, 2023
a6ccbd6
minor improvements
Art4 Jan 24, 2023
48a34d7
Refactore header parsing in File
Art4 Jan 26, 2023
419b8e5
Fix Locator, add integration tests for basic functions
Art4 Jan 26, 2023
9bf0596
Remove unused property
Art4 Jan 27, 2023
5c8a5a3
Fix params, fix url comment
Art4 Jan 30, 2023
32544d5
Deprecate method SimplePie\Sanitize::pass_file_data()
Art4 Jan 30, 2023
f235282
Make sure status_code is always setted
Art4 Jan 30, 2023
854da5d
Mark Response interface as internal
Art4 Jan 30, 2023
f86d4ef
Merge branch 'master' into split-file-into-client-and-response
Art4 Jan 31, 2023
c16ffc1
Remove `@package` and `@subpackage` tags
Art4 Jan 31, 2023
f12dbcc
Merge branch 'master' into split-file-into-client-and-response
Art4 Feb 13, 2023
082e7aa
Mark HttpException as final
Art4 Feb 13, 2023
b04b493
Make sure only throw HttpException in FileClient
Art4 Feb 16, 2023
2c42c1d
Merge branch 'master' into split-file-into-client-and-response
Art4 Mar 20, 2023
a425aee
Replace copyright comments with spdx notes
Art4 Mar 20, 2023
a03affa
Merge branch 'master' into split-file-into-client-and-response
Art4 May 19, 2023
26033c6
Fix code style
Art4 May 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Cache/CallableNameFilter.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php

declare(strict_types=1);
/**
* SimplePie
*
Expand Down
2 changes: 2 additions & 0 deletions src/Cache/NameFilter.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<?php

declare(strict_types=1);
/**
* SimplePie
*
Expand Down
101 changes: 55 additions & 46 deletions src/Content/Type/Sniffer.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@

namespace SimplePie\Content\Type;

use SimplePie\File;

/**
* Content-type sniffing
*
Expand All @@ -71,7 +73,7 @@ class Sniffer
/**
* Create an instance of the class with the input file
*
* @param Sniffer $file Input file
* @param File $file Input file
*/
public function __construct($file)
{
Expand All @@ -85,19 +87,19 @@ public function __construct($file)
*/
public function get_type()
{
if (isset($this->file->headers['content-type'])) {
if (!isset($this->file->headers['content-encoding'])
&& ($this->file->headers['content-type'] === 'text/plain'
|| $this->file->headers['content-type'] === 'text/plain; charset=ISO-8859-1'
|| $this->file->headers['content-type'] === 'text/plain; charset=iso-8859-1'
|| $this->file->headers['content-type'] === 'text/plain; charset=UTF-8')) {
if ($this->file->has_header('content-type')) {
if (!$this->file->has_header('content-encoding')
&& ($this->file->get_header_line('content-type') === 'text/plain'
|| $this->file->get_header_line('content-type') === 'text/plain; charset=ISO-8859-1'
|| $this->file->get_header_line('content-type') === 'text/plain; charset=iso-8859-1'
|| $this->file->get_header_line('content-type') === 'text/plain; charset=UTF-8')) {
return $this->text_or_binary();
}

if (($pos = strpos($this->file->headers['content-type'], ';')) !== false) {
$official = substr($this->file->headers['content-type'], 0, $pos);
if (($pos = strpos($this->file->get_header_line('content-type'), ';')) !== false) {
$official = substr($this->file->get_header_line('content-type'), 0, $pos);
} else {
$official = $this->file->headers['content-type'];
$official = $this->file->get_header_line('content-type');
}
$official = trim(strtolower($official));

Expand Down Expand Up @@ -131,12 +133,14 @@ public function get_type()
*/
public function text_or_binary()
{
if (substr($this->file->body, 0, 2) === "\xFE\xFF"
|| substr($this->file->body, 0, 2) === "\xFF\xFE"
|| substr($this->file->body, 0, 4) === "\x00\x00\xFE\xFF"
|| substr($this->file->body, 0, 3) === "\xEF\xBB\xBF") {
$body = $this->file->get_body_content();

if (substr($body, 0, 2) === "\xFE\xFF"
|| substr($body, 0, 2) === "\xFF\xFE"
|| substr($body, 0, 4) === "\x00\x00\xFE\xFF"
|| substr($body, 0, 3) === "\xEF\xBB\xBF") {
return 'text/plain';
} elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $this->file->body)) {
} elseif (preg_match('/[\x00-\x08\x0E-\x1A\x1C-\x1F]/', $body)) {
return 'application/octet-stream';
}

Expand All @@ -150,25 +154,27 @@ public function text_or_binary()
*/
public function unknown()
{
$ws = strspn($this->file->body, "\x09\x0A\x0B\x0C\x0D\x20");
if (strtolower(substr($this->file->body, $ws, 14)) === '<!doctype html'
|| strtolower(substr($this->file->body, $ws, 5)) === '<html'
|| strtolower(substr($this->file->body, $ws, 7)) === '<script') {
$body = $this->file->get_body_content();
$ws = strspn($body, "\x09\x0A\x0B\x0C\x0D\x20");

if (strtolower(substr($body, $ws, 14)) === '<!doctype html'
|| strtolower(substr($body, $ws, 5)) === '<html'
|| strtolower(substr($body, $ws, 7)) === '<script') {
return 'text/html';
} elseif (substr($this->file->body, 0, 5) === '%PDF-') {
} elseif (substr($body, 0, 5) === '%PDF-') {
return 'application/pdf';
} elseif (substr($this->file->body, 0, 11) === '%!PS-Adobe-') {
} elseif (substr($body, 0, 11) === '%!PS-Adobe-') {
return 'application/postscript';
} elseif (substr($this->file->body, 0, 6) === 'GIF87a'
|| substr($this->file->body, 0, 6) === 'GIF89a') {
} elseif (substr($body, 0, 6) === 'GIF87a'
|| substr($body, 0, 6) === 'GIF89a') {
return 'image/gif';
} elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
} elseif (substr($body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
return 'image/png';
} elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") {
} elseif (substr($body, 0, 3) === "\xFF\xD8\xFF") {
return 'image/jpeg';
} elseif (substr($this->file->body, 0, 2) === "\x42\x4D") {
} elseif (substr($body, 0, 2) === "\x42\x4D") {
return 'image/bmp';
} elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00") {
} elseif (substr($body, 0, 4) === "\x00\x00\x01\x00") {
return 'image/vnd.microsoft.icon';
}

Expand All @@ -182,16 +188,18 @@ public function unknown()
*/
public function image()
{
if (substr($this->file->body, 0, 6) === 'GIF87a'
|| substr($this->file->body, 0, 6) === 'GIF89a') {
$body = $this->file->get_body_content();

if (substr($body, 0, 6) === 'GIF87a'
|| substr($body, 0, 6) === 'GIF89a') {
return 'image/gif';
} elseif (substr($this->file->body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
} elseif (substr($body, 0, 8) === "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A") {
return 'image/png';
} elseif (substr($this->file->body, 0, 3) === "\xFF\xD8\xFF") {
} elseif (substr($body, 0, 3) === "\xFF\xD8\xFF") {
return 'image/jpeg';
} elseif (substr($this->file->body, 0, 2) === "\x42\x4D") {
} elseif (substr($body, 0, 2) === "\x42\x4D") {
return 'image/bmp';
} elseif (substr($this->file->body, 0, 4) === "\x00\x00\x01\x00") {
} elseif (substr($body, 0, 4) === "\x00\x00\x01\x00") {
return 'image/vnd.microsoft.icon';
}

Expand All @@ -205,16 +213,17 @@ public function image()
*/
public function feed_or_html()
{
$len = strlen($this->file->body);
$pos = strspn($this->file->body, "\x09\x0A\x0D\x20\xEF\xBB\xBF");
$body = $this->file->get_body_content();
$len = strlen($body);
$pos = strspn($body, "\x09\x0A\x0D\x20\xEF\xBB\xBF");

while ($pos < $len) {
switch ($this->file->body[$pos]) {
switch ($body[$pos]) {
case "\x09":
case "\x0A":
case "\x0D":
case "\x20":
$pos += strspn($this->file->body, "\x09\x0A\x0D\x20", $pos);
$pos += strspn($body, "\x09\x0A\x0D\x20", $pos);
continue 2;

case '<':
Expand All @@ -225,29 +234,29 @@ public function feed_or_html()
return 'text/html';
}

if (substr($this->file->body, $pos, 3) === '!--') {
if (substr($body, $pos, 3) === '!--') {
$pos += 3;
if ($pos < $len && ($pos = strpos($this->file->body, '-->', $pos)) !== false) {
if ($pos < $len && ($pos = strpos($body, '-->', $pos)) !== false) {
$pos += 3;
} else {
return 'text/html';
}
} elseif (substr($this->file->body, $pos, 1) === '!') {
if ($pos < $len && ($pos = strpos($this->file->body, '>', $pos)) !== false) {
} elseif (substr($body, $pos, 1) === '!') {
if ($pos < $len && ($pos = strpos($body, '>', $pos)) !== false) {
$pos++;
} else {
return 'text/html';
}
} elseif (substr($this->file->body, $pos, 1) === '?') {
if ($pos < $len && ($pos = strpos($this->file->body, '?>', $pos)) !== false) {
} elseif (substr($body, $pos, 1) === '?') {
if ($pos < $len && ($pos = strpos($body, '?>', $pos)) !== false) {
$pos += 2;
} else {
return 'text/html';
}
} elseif (substr($this->file->body, $pos, 3) === 'rss'
|| substr($this->file->body, $pos, 7) === 'rdf:RDF') {
} elseif (substr($body, $pos, 3) === 'rss'
|| substr($body, $pos, 7) === 'rdf:RDF') {
return 'application/rss+xml';
} elseif (substr($this->file->body, $pos, 4) === 'feed') {
} elseif (substr($body, $pos, 4) === 'feed') {
return 'application/atom+xml';
} else {
return 'text/html';
Expand Down
57 changes: 57 additions & 0 deletions src/Exception/HttpException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);
/**
* SimplePie
*
* A PHP-Based RSS and Atom Feed Framework.
* Takes the hard work out of managing a complete RSS/Atom solution.
*
* Copyright (c) 2004-2022, Ryan Parman, Sam Sneddon, Ryan McCue, and contributors
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are
* permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this list of
* conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice, this list
* of conditions and the following disclaimer in the documentation and/or other materials
* provided with the distribution.
*
* * Neither the name of the SimplePie Team nor the names of its contributors may be used
* to endorse or promote products derived from this software without specific prior
* written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS
* AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* @package SimplePie
* @copyright 2004-2022 Ryan Parman, Sam Sneddon, Ryan McCue
* @author Ryan Parman
* @author Sam Sneddon
* @author Ryan McCue
* @link http://simplepie.org/ SimplePie
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
*/

namespace SimplePie\Exception;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any thoughts on having it under SimplePie\HTTP? That way we can remove just a single namespace later.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no strong opinions about the place for exceptions. We will potentially get more Exceptions while fixing #755.


use SimplePie\Exception;

/**
* HTTP exception class
*
* @package SimplePie
*/
class HttpException extends Exception
{
}