function parse_link($link, $level=0) { global $name, $the_file_name, $the_link, $locationheader, $parsed_link, $link_update; if ($level > 3) return FALSE; if ($link == "***" && $link_update) $link = getLinkPath($link_update); $url_parts = @parse_url( $link ); //filter out localhost and reserved or private IPs if (stripos($url_parts["host"], 'localhost') !== false || stripos($url_parts["host"], 'loopback') !== false || (filter_var($url_parts["host"], FILTER_VALIDATE_IP) !== false && (strpos($url_parts["host"],'127') === 0 || filter_var($url_parts["host"], FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE) === false) ) ) { return array('response' => 'HTTP/1.0 400 Bad Request', 'response_code' => 400); } if (substr($link,0,6) == "ftp://") { // Parsing an FTF-Adress $documentpath = $url_parts["path"]; if (strpos($url_parts["host"],"@")) { $url_parts["pass"] .= "@".substr($url_parts["host"],0,strpos($url_parts["host"],"@")); $url_parts["host"] = substr(strrchr($url_parts["host"],"@"),1); } if (preg_match('/[^a-z0-9_.-]/i',$url_parts['host'])){ // exists umlauts ? $IDN = new idna_convert(); $out = $IDN->encode(utf8_encode($url_parts['host'])); // false by error $url_parts['host'] = ($out)? $out : $url_parts['host']; } $ftp = ftp_connect($url_parts["host"]); if (!$url_parts["user"]) $url_parts["user"] = "******"; if (!$url_parts["pass"]) { $mailclass = new StudipMail(); $url_parts["pass"] = $mailclass->getSenderEmail(); } if (!@ftp_login($ftp,$url_parts["user"],$url_parts["pass"])) { ftp_quit($ftp); return FALSE; } $parsed_link["Content-Length"] = ftp_size($ftp, $documentpath); ftp_quit($ftp); if ($parsed_link["Content-Length"] != "-1") { $parsed_link["HTTP/1.0 200 OK"] = "HTTP/1.0 200 OK"; $parsed_link["response_code"] = 200; } else { $parsed_link = FALSE; } $url_parts["pass"] = preg_replace("!@!","%40",$url_parts["pass"]); $the_link = "ftp://".$url_parts["user"].":".$url_parts["pass"]."@".$url_parts["host"].$documentpath; return $parsed_link; } else { if (!empty( $url_parts["path"])){ $documentpath = $url_parts["path"]; } else { $documentpath = "/"; } if ( !empty( $url_parts["query"] ) ) { $documentpath .= "?" . $url_parts["query"]; } $host = $url_parts["host"]; $port = $url_parts["port"]; $scheme = strtolower($url_parts['scheme']); if (!in_array($scheme , words('http https'))) { return array('response' => 'HTTP/1.0 400 Bad Request', 'response_code' => 400); } if ($scheme == "https") { $ssl = TRUE; if (empty($port)) $port = 443; } else { $ssl = FALSE; } if (empty( $port ) ) $port = "80"; if (preg_match('/[^a-z0-9_.-]/i',$host)){ // exists umlauts ? $IDN = new idna_convert(); $out = $IDN->encode(utf8_encode($host)); // false by error $host = ($out)? $out : $host; $pwtxt = ($url_parts['user'] && $url_parts['pass'])? $url_parts['user'].':'. $url_parts['pass'].'@':''; $the_link = $url_parts['scheme'].'://'.$pwtxt.$host.':'.$port.$documentpath; } $socket = @fsockopen( ($ssl? 'ssl://':'').$host, $port, $errno, $errstr, 10 ); if (!$socket) { return array('response' => 'HTTP/1.0 400 Bad Request', 'response_code' => 400); } else { $urlString = "GET ".$documentpath." HTTP/1.0\r\nHost: $host\r\n"; if ($url_parts["user"] && $url_parts["pass"]) { $pass = $url_parts["pass"]; $user = $url_parts["user"]; $urlString .= "Authorization: Basic ".base64_encode("$user:$pass")."\r\n"; } $urlString .= sprintf("User-Agent: Stud.IP v%s File Crawler\r\n", $GLOBALS['SOFTWARE_VERSION']); $urlString .= "Connection: close\r\n\r\n"; fputs($socket, $urlString); stream_set_timeout($socket, 5); $response = ''; do { $response .= fgets($socket, 128); $info = stream_get_meta_data($socket); } while (!feof($socket) && !$info['timed_out'] && strlen($response) < 1024); fclose($socket); } $parsed_link = parse_header($response); // Anderer Dateiname? $disposition_header = $parsed_link['Content-Disposition'] ?: $parsed_link['content-disposition']; if ($disposition_header) { $header_parts = explode(';', $disposition_header); foreach ($header_parts as $part) { $part = trim($part); list($key, $value) = explode('=', $part, 2); if (strtolower($key) === 'filename') { $the_file_name = trim($value, '"'); } } } else { $the_file_name = basename($url_parts['path']) ?: $the_file_name; } // Weg über einen Locationheader: $location_header = $parsed_link["Location"] ?: $parsed_link["location"]; if (in_array($parsed_link["response_code"], array(300,301,302,303,305,307)) && $location_header) { if (strpos($location_header, 'http') !== 0) { $location_header = $url_parts['scheme'] . '://' . $url_parts['host'] . '/' . $location_header; } $parsed_link = parse_link($location_header, $level + 1); } return $parsed_link; } }