Passed
Push — master ( ec0dd3...615970 )
by Pauli
02:15
created

RadioMetadata::findStr()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 7
c 1
b 0
f 0
dl 0
loc 10
rs 10
cc 3
nc 3
nop 2
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
use OCA\Music\Utility\Util;
16
17
/**
18
 * MetaData radio utility functions
19
 */
20
class RadioMetadata {
21
22
	private static function findStr($data, $str) {
23
		$ret = "";
24
		foreach ($data as $value) {
25
			$find = strstr($value, $str);
26
			if ($find !== false) {
27
				$ret = $find;
28
				break;
29
			}
30
		}
31
		return $ret;
32
	}
33
34
	private static function parseStreamUrl($url) {
35
36
		$ret = array();
37
		$parse_url = parse_url($url);
38
39
		$ret['port'] = 80;
40
		if (isset($parse_url['port'])) {
41
			$ret['port'] = $parse_url['port'];
42
		} else if ($parse_url['scheme'] == "https") {
43
			$ret['port'] = 443;
44
		}
45
46
		$ret['scheme'] = $parse_url['scheme'];
47
		$ret['hostname'] = $parse_url['host'];
48
		$ret['pathname'] = $parse_url['path'];
49
50
		if (isset($parse_url['query'])) {
51
			$ret['pathname'] .= "?" . $parse_url['query'];
52
		}
53
54
		if ($parse_url['scheme'] == "https") {
55
			$ret['sockAddress'] = "ssl://" . $ret['hostname'];
56
		} else {
57
			$ret['sockAddress'] = $ret['hostname'];
58
		}
59
60
		return $ret;
61
	}
62
63
64
	public static function fetchUrlData($url) {
65
		$title = "";
66
		$content = \file_get_contents($url);
67
		list($version, $status_code, $msg) = explode(' ', $http_response_header[0], 3);
68
		if ($status_code == 200) {
69
			$data = explode(',', $content);
70
			$title = $data[6];
71
		}
72
		return $title;
73
	}
74
75
	public static function fetchStreamData($url, $maxattempts, $maxredirect) {
76
		$timeout = 10;
77
		$streamTitle = "";
78
		$pUrl = self::parseStreamUrl($url);
79
		if (($pUrl['sockAddress']) && ($pUrl['port'])) {
80
			$fp = fsockopen($pUrl['sockAddress'], $pUrl['port'], $errno, $errstr, $timeout);
81
			if ($fp != false) {
82
				$out = "GET " . $pUrl['pathname'] . " HTTP/1.1\r\n";
83
				$out .= "Host: ". $pUrl['hostname'] . "\r\n";
84
				$out .= "Accept: */*\r\n";
85
				$out .= "User-Agent: OCMusic/1.52\r\n";
86
				$out .= "Icy-MetaData: 1\r\n";
87
				$out .= "Connection: Close\r\n\r\n";
88
				fwrite($fp, $out);
89
				stream_set_timeout($fp, $timeout);
90
91
				$header = fread($fp, 1024);
92
				$headers = explode("\n", $header);
93
94
				if (strpos($headers[0], "200 OK") !== false) {
95
					$interval = 0;
96
					$line = self::findStr($headers, "icy-metaint:");
97
					if ($line) {
98
						$interval = trim(explode(':', $line)[1]);
99
					}
100
101
					if (($interval)&&($interval<64001)) {
102
						$attempts = 0;
103
						while ($attempts < $maxattempts) {
104
							for ($j = 0; $j < $interval; $j++) {
105
								fread($fp, 1);
106
							}
107
108
							$meta_length = ord(fread($fp, 1)) * 16;
109
							if ($meta_length) {
110
								$metadatas = explode(';', fread($fp, $meta_length));
111
								$metadata = self::findStr($metadatas, "StreamTitle");
112
								if ($metadata) {
113
									$streamTitle = Util::truncate(trim(explode('=', $metadata)[1], "'"), 256);
114
									break;
115
								}
116
							}
117
							$attempts++;
118
						}
119
					} else {
120
						$streamTitle = RadioMetadata::fetchUrlData($pUrl['scheme'] . '://' . $pUrl['hostname'] . ':' . $pUrl['port'] . '/7.html');
121
					}
122
				} else if (($maxredirect>0)&&(strpos($headers[0], "302 Found") !== false)) {
123
					$value = self::findStr($headers, "Location:");
124
					if ($value) {
125
						$location = trim(substr($value, 10), "\r");
126
						$streamTitle = RadioMetadata::fetchStreamData($location, $maxattempts, $maxredirect-1);
127
					}
128
				}
129
				fclose($fp);
130
			}
131
		}
132
		return $streamTitle;
133
	}
134
135
}
136