Passed
Pull Request — master (#992)
by
unknown
02:09
created

RadioMetadata   A

Complexity

Total Complexity 25

Size/Duplication

Total Lines 107
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
wmc 25
eloc 69
c 3
b 0
f 0
dl 0
loc 107
rs 10

4 Methods

Rating   Name   Duplication   Size   Complexity  
A parseStreamUrl() 0 25 5
C fetchStreamData() 0 59 16
A fetchUrlData() 0 4 1
A findStr() 0 10 3
1
<?php declare(strict_types=1);
2
3
/**
4
 * ownCloud - Music app
5
 *
6
 * This file is licensed under the Affero General Public License version 3 or
7
 * later. See the COPYING file.
8
 *
9
 * @author Moahmed-Ismail MEJRI <[email protected]>
10
 * @copyright Moahmed-Ismail MEJRI 2022
11
 */
12
13
namespace OCA\Music\Utility;
14
15
/**
16
 * MetaData radio utility functions
17
 */
18
class RadioMetadata {
19
20
	private static function findStr($data, $str) {
21
		$ret = "";
22
		foreach ($data as $value) {
23
			$find = strstr($value, $str);
24
			if ($find !== false) {
25
				$ret = $find;
26
				break;
27
			}
28
		}
29
		return $ret;
30
	}
31
32
	private static function parseStreamUrl($url) {
33
34
		$parse_url = parse_url($url);
35
36
		$ret['port'] = 80;
0 ignored issues
show
Comprehensibility Best Practice introduced by
$ret was never initialized. Although not strictly required by PHP, it is generally a good practice to add $ret = array(); before regardless.
Loading history...
37
		if (isset($parse_url['port'])) {
38
			$ret['port'] = $parse_url['port'];
39
		} else if ($parse_url['scheme'] == "https") {
40
			$ret['port'] = 443;
41
		}
42
43
		$ret['hostname'] = $parse_url['host'];
44
		$ret['pathname'] = $parse_url['path'];
45
46
		if (isset($parse_url['query'])) {
47
			$ret['pathname'] .= "?" . $parse_url['query'];
48
		}
49
50
		if ($parse_url['scheme'] == "https") {
51
			$ret['sockadd'] = "ssl://" . $ret['hostname'];
52
		} else {
53
			$ret['sockadd'] = $ret['hostname'];
54
		}
55
56
		return $ret;
57
	}
58
59
60
	public static function fetchUrlData($url) : array {
61
		$content = \file_get_contents($url);
62
		list($version, $status_code, $msg) = explode(' ', $http_response_header[0], 3);
63
		return [$content, $status_code, $msg];
64
	}
65
66
	public static function fetchStreamData($url, $maxattempts, $maxredirect) {
67
		$timeout = 10;
68
		$streamTitle = "";
69
		$pUrl = self::parseStreamUrl($url);
70
		if (($pUrl['sockadd']) && ($pUrl['port'])) {
71
			$fp = fsockopen($pUrl['sockadd'], $pUrl['port'], $errno, $errstr, $timeout);
72
			if ($fp != false) {
73
				$out = "GET " . $pUrl['pathname'] . " HTTP/1.1\r\n";
74
				$out .= "Host: ". $pUrl['hostname'] . "\r\n";
75
				$out .= "Accept: */*\r\n"; /* test */
76
				$out .= "User-Agent: OCMusic/1.52\r\n";
77
				$out .= "Icy-MetaData: 1\r\n";
78
				$out .= "Connection: Close\r\n\r\n";
79
				fwrite($fp, $out);
80
				stream_set_timeout($fp, $timeout);
81
82
				$header = fread($fp, 1024);
83
				$headers = explode("\n", $header);
84
85
				if (strstr($headers[0], "200 OK") !== false) {
86
					$interval = 0;
87
					$line = self::findStr($headers, "icy-metaint:");
88
					if ($line) {
89
						$interval = trim(explode(':', $line)[1]);
90
					}
91
92
					if (($interval)&&($interval<64001)) {
93
						$attempts = 0;
94
						while ($attempts < $maxattempts) {
95
							for ($j = 0; $j < $interval; $j++) {
96
								fread($fp, 1);
97
							}
98
99
							$meta_length = ord(fread($fp, 1)) * 16;
100
							if ($meta_length) {
101
								$metadatas = explode(';', fread($fp, $meta_length));
102
								$metadata = self::findStr($metadatas, "StreamTitle");
103
								if ($metadata) {
104
									$streamTitle = trim(explode('=', $metadata)[1], "'");
105
									if (strlen($streamTitle) > 256) {
106
										$streamTitle = "";
107
									}
108
									break;
109
								}
110
							}
111
							$attempts++;
112
						}
113
					}
114
				} else if (($maxredirect>0)&&(strstr($headers[0], "302 Found") !== false)) {
115
					$value = self::findStr($headers, "Location:");
116
					if ($value) {
117
						$location = trim(substr($value, 10), "\r");
118
						$streamTitle = RadioMetadata::fetchStreamData($location, $maxattempts, $maxredirect-1);
119
					}
120
				}
121
				fclose($fp);
122
			}
123
		}
124
		return $streamTitle;
125
	}
126
127
}
128