Files
2025-08-23 02:05:10 +02:00

489 lines
19 KiB
PHP

<?php
// URL reachability check function
function checkUrlReachability($url) {
if (empty($url)) {
return ['reachable' => false, 'status' => 'No URL provided'];
}
if (!filter_var($url, FILTER_VALIDATE_URL)) {
return ['reachable' => false, 'status' => 'Invalid URL format'];
}
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_NOBODY, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$error = curl_error($ch);
curl_close($ch);
if ($httpCode >= 200 && $httpCode < 400) {
return ['reachable' => true, 'status' => "URL is accessible (HTTP $httpCode)"];
} else {
return ['reachable' => false, 'status' => "URL is not accessible: " . ($error ? $error : "HTTP $httpCode")];
}
}
$urlReachability = [];
if (!empty($_GET['url'])) {
$urlReachability = checkUrlReachability($_GET['url']);
}
?>
<?php
if (!empty($urlReachability)) {
$statusClass = $urlReachability['reachable'] ? 'url-accessible' : 'url-inaccessible';
echo "<div class='url-status $statusClass'>" . htmlspecialchars($urlReachability['status']) . "</div>";
}
?>
<script>
// URL reachability check functionality
function checkUrlReachability(url) {
if (!url) {
return Promise.resolve({ reachable: false, status: 'No URL provided' });
}
try {
new URL(url);
} catch (e) {
return Promise.resolve({ reachable: false, status: 'Invalid URL format' });
}
return fetch(url, {
method: 'HEAD',
mode: 'no-cors',
cache: 'no-cache'
})
.then(response => {
return { reachable: true, status: 'URL is accessible' };
})
.catch(error => {
return { reachable: false, status: 'URL is not accessible: ' + error.message };
});
}
function updateUrlStatusIndicator(statusElement, result) {
statusElement.textContent = result.status;
statusElement.className = result.reachable ? 'url-status url-accessible' : 'url-status url-inaccessible';
}
document.addEventListener('DOMContentLoaded', function() {
const urlInput = document.querySelector('input[name="upload_url"]');
const urlUploadDiv = document.getElementById('urlUploadDiv');
if (!urlInput || !urlUploadDiv) return;
const statusElement = document.createElement('div');
statusElement.className = 'url-status';
urlUploadDiv.appendChild(statusElement);
if (urlInput.value) {
statusElement.textContent = 'Checking URL...';
checkUrlReachability(urlInput.value)
.then(result => updateUrlStatusIndicator(statusElement, result));
}
let timeoutId;
urlInput.addEventListener('input', function() {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
if (urlInput.value) {
statusElement.textContent = 'Checking URL...';
checkUrlReachability(urlInput.value)
.then(result => updateUrlStatusIndicator(statusElement, result));
} else {
statusElement.textContent = '';
statusElement.className = 'url-status';
}
}, 800);
});
});
</script>
<style>
.url-status {
margin-top: 5px;
padding: 5px;
border-radius: 3px;
font-size: 12px;
}
.url-accessible {
background-color: #d4edda;
color: #155724;
border: 1px solid #c3e6cb;
}
.url-inaccessible {
background-color: #f8d7da;
color: #721c24;
border: 1px solid #f5c6cb;
}
</style>
<script>
function getQueryParam(name) {
const params = new URLSearchParams(window.location.search);
return params.get(name) || '';
}
window.addEventListener('DOMContentLoaded', () => {
const uploadUrlInput = document.querySelector('input[name="upload_url"]');
const urlParam = getQueryParam('url');
if (uploadUrlInput && urlParam) {
uploadUrlInput.value = urlParam;
}
});
</script>
<script>
function getQueryParam(name) {
const params = new URLSearchParams(window.location.search);
return params.get(name) || '';
}
function saveCredentialsToLocalStorage(username, password) {
if (username) localStorage.setItem('username', username);
if (password) localStorage.setItem('password', password);
}
function loadCredentialsFromLocalStorage() {
return {
username: localStorage.getItem('username') || '',
password: localStorage.getItem('password') || ''
};
}
window.addEventListener('DOMContentLoaded', () => {
const usernameInput = document.querySelector('input[name="username"]');
const passwordInput = document.querySelector('input[name="password"]');
let username = getQueryParam('username');
let password = getQueryParam('password');
if (!username || !password) {
const stored = loadCredentialsFromLocalStorage();
if (!username) username = stored.username;
if (!password) password = stored.password;
}
if (usernameInput && username) usernameInput.value = username;
if (passwordInput && password) passwordInput.value = password;
const form = usernameInput.closest('form');
if (form) {
form.addEventListener('submit', () => {
saveCredentialsToLocalStorage(usernameInput.value, passwordInput.value);
});
}
});
</script>
<?php
ini_set('memory_limit', '256M');
set_time_limit(0);
set_error_handler(function($errno, $errstr, $errfile, $errline) { return true; });
function getQuery($key, $default = '') {
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
}
// ---------------- FTP/SFTP/WebDAV FUNCTIONS ----------------
function ftpUpload($server, $username, $password, $remoteDir, $localFile, $remoteFile, &$debug) {
$conn = @ftp_connect($server);
if (!$conn) { $debug[]="FTP connect failed."; return false; }
if (!@ftp_login($conn, $username, $password)) {
$debug[]="FTP login failed. Check username/password.";
ftp_close($conn); return false;
}
ftp_pasv($conn, true);
if (!@ftp_chdir($conn, $remoteDir)) {
$debug[]="FTP cannot change to directory '$remoteDir'. Check path.";
ftp_close($conn); return false;
}
$list = @ftp_nlist($conn, ".");
if ($list !== false && in_array($remoteFile, $list)) {
$debug[]="FTP upload canceled: '$remoteFile' already exists.";
ftp_close($conn); return false;
}
if (@ftp_put($conn, $remoteFile, $localFile, FTP_BINARY)) {
$debug[]="FTP upload successful: $remoteFile";
ftp_close($conn);
return true;
} else {
$debug[]="FTP upload failed: Unknown error.";
ftp_close($conn);
return false;
}
}
function sftpUpload($server, $username, $password, $remoteDir, $localFile, $remoteFile, &$debug) {
$url = "sftp://$username:$password@$server/" . trim($remoteDir,'/') . '/' . $remoteFile;
// Check if file exists
$chCheck = curl_init();
curl_setopt($chCheck, CURLOPT_URL, $url);
curl_setopt($chCheck, CURLOPT_NOBODY, true);
curl_setopt($chCheck, CURLOPT_RETURNTRANSFER, true);
curl_setopt($chCheck, CURLOPT_PROTOCOLS, CURLPROTO_SFTP);
$resCheck = curl_exec($chCheck);
$codeCheck = curl_getinfo($chCheck, CURLINFO_HTTP_CODE);
curl_close($chCheck);
if($resCheck !== false && $codeCheck === 0) {
$debug[]="SFTP upload canceled: '$remoteFile' already exists.";
return false;
}
$fp = fopen($localFile,'rb');
if(!$fp){ $debug[]="Local file open failed."; return false; }
$ch = curl_init();
curl_setopt($ch,CURLOPT_URL,$url);
curl_setopt($ch,CURLOPT_UPLOAD,true);
curl_setopt($ch,CURLOPT_INFILE,$fp);
curl_setopt($ch,CURLOPT_INFILESIZE,filesize($localFile));
curl_setopt($ch,CURLOPT_PROTOCOLS,CURLPROTO_SFTP);
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
$res = curl_exec($ch);
if($res === false) {
$debug[] = "SFTP upload failed: " . curl_error($ch);
curl_close($ch);
fclose($fp);
return false;
} else {
$debug[] = "SFTP upload successful: $remoteFile";
curl_close($ch);
fclose($fp);
return true;
}
}
function webdavUpload($server, $username, $password, $remoteDir, $localFile, $remoteFile, &$debug) {
$url = rtrim("https://$server/" . trim($remoteDir,'/'), '/') . '/' . $remoteFile;
// 1. Check if file exists via HEAD
$optsCheck = ["http"=>[
"method"=>"HEAD",
"header"=>"Authorization: Basic ".base64_encode("$username:$password"),
"ignore_errors"=>true
]];
$ctxCheck = stream_context_create($optsCheck);
@file_get_contents($url,false,$ctxCheck);
if (isset($http_response_header)) {
foreach($http_response_header as $line){
if (preg_match('#HTTP/\d+\.\d+\s+(\d+)#', $line, $m)){
$code = intval($m[1]);
if($code >= 200 && $code < 300){
$debug[] = "WebDAV upload canceled: '$remoteFile' already exists.";
return false;
}
break;
}
}
}
// 2. Upload
$data = file_get_contents($localFile);
$opts = ["http"=>[
"method"=>"PUT",
"header"=>"Authorization: Basic ".base64_encode("$username:$password")."\r\nContent-Length: ".strlen($data),
"content"=>$data,
"ignore_errors"=>true
]];
$ctx = stream_context_create($opts);
$res = @file_get_contents($url,false,$ctx);
if ($res === false) {
$debug[] = "WebDAV upload failed: Cannot reach server or unauthorized.";
return false;
}
if (isset($http_response_header) && is_array($http_response_header)) {
$statusLine = $http_response_header[0];
preg_match('#HTTP/\d+\.\d+\s+(\d+)#', $statusLine, $matches);
$code = isset($matches[1]) ? intval($matches[1]) : 0;
if ($code >= 200 && $code < 300) {
$debug[] = "WebDAV upload successful: $remoteFile (HTTP $code)";
return true;
} else {
$debug[] = "WebDAV upload failed: HTTP $code - " . $statusLine;
return false;
}
}
$debug[] = "WebDAV upload unknown result.";
return false;
}
function buildUrl($protocol,$server,$path) {
$scheme=($protocol==='webdav')?'https':$protocol;
return "$scheme://$server$path";
}
function listDirectory($protocol, $server, $username, $password, $path, &$debug) {
$files=[];
if ($protocol==='ftp') {
$conn=@ftp_connect($server);
if($conn&&@ftp_login($conn,$username,$password)){
ftp_pasv($conn,true);
if(@ftp_chdir($conn,$path)){
$raw=ftp_rawlist($conn,".");
foreach($raw as $line){
$parts=preg_split("/\s+/",$line,9);
if(count($parts)===9){
$files[]=['name'=>$parts[8],'type'=>$parts[0][0]==='d'?'dir':'file'];
}
}
}
ftp_close($conn);
}
} elseif($protocol==='sftp') {
$conn=@ssh2_connect($server);
if($conn&&@ssh2_auth_password($conn,$username,$password)){
$sftp=ssh2_sftp($conn);
$dh=@opendir("ssh2.sftp://$sftp$path");
if($dh){while(($f=readdir($dh))!==false){if($f==='.'||$f==='..')continue;$fp="ssh2.sftp://$sftp$path$f";$files[]=['name'=>$f,'type'=>is_dir($fp)?'dir':'file'];}closedir($dh);}
}
} elseif($protocol==='webdav') {
$url=buildUrl($protocol,$server,$path);
$opts=["http"=>["method"=>"PROPFIND","header"=>"Authorization: Basic ".base64_encode("$username:$password")."\r\nDepth: 1","content"=>""]];
$ctx=stream_context_create($opts);
$res=@file_get_contents($url,false,$ctx);
if($res!==false){preg_match_all('/<d:href>(.*?)<\/d:href>/i',$res,$m);foreach($m[1] as $href){$nm=basename(parse_url($href,PHP_URL_PATH));if($nm&&$nm!==basename($path)){$files[]=['name'=>$nm,'type'=>(substr($href,-1)==='/')?'dir':'file'];}}}
}
return $files;
}
// ---------------- FORM VALUES -----------------
$username = getQuery('username');
$password = getQuery('password');
$server = getQuery('server');
$path = getQuery('path', '/');
$protocol = getQuery('protocol', 'ftp');
$uploadType = getQuery('upload_type', 'url');
$anonymous = getQuery('anonymous', '') ? true : false;
if ($anonymous) {
$username = 'anonymous';
$password = 'anonymous@domain.com';
}
$isDir = substr($path, -1) === '/';
$files = [];
$debug = [];
// ---------------- HANDLE UPLOAD -----------------
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
if ($uploadType==='file' && !empty($_FILES['upload_file']['tmp_name'])) {
$file = $_FILES['upload_file'];
$remoteFile = basename($file['name']);
$tmpFile = $file['tmp_name'];
if($protocol==='ftp') ftpUpload($server,$username,$password,$path,$tmpFile,$remoteFile,$debug);
elseif($protocol==='sftp') sftpUpload($server,$username,$password,$path,$tmpFile,$remoteFile,$debug);
elseif($protocol==='webdav') webdavUpload($server,$username,$password,$path,$tmpFile,$remoteFile,$debug);
} elseif($uploadType==='url' && !empty($_POST['upload_url'])) {
$urlFile = $_POST['upload_url'];
$remoteFile = basename(parse_url($urlFile, PHP_URL_PATH));
$tmpFile = tempnam(sys_get_temp_dir(), 'up');
if(file_put_contents($tmpFile, file_get_contents($urlFile))===false){
$debug[] = "Download from URL failed: $urlFile";
} else {
if($protocol==='ftp') ftpUpload($server,$username,$password,$path,$tmpFile,$remoteFile,$debug);
elseif($protocol==='sftp') sftpUpload($server,$username,$password,$path,$tmpFile,$remoteFile,$debug);
elseif($protocol==='webdav') webdavUpload($server,$username,$password,$path,$tmpFile,$remoteFile,$debug);
}
unlink($tmpFile);
}
if(!empty($debug)){
echo "<div style='border:1px solid #888;padding:10px;margin:10px 0;background:#f0f0f0;'>";
foreach($debug as $d) echo htmlspecialchars($d) . "<br>";
echo "</div>";
}
}
// ----------------- HTML FORM ------------------
echo '<form method="post" enctype="multipart/form-data" style="margin-bottom:20px;">
Upload type:<br>
<label><input type="radio" name="upload_type" value="file" '.($uploadType==='file'?'checked':'').' onclick="toggleUploadType()"> File</label><br>
<label><input type="radio" name="upload_type" value="url" '.($uploadType==='url'?'checked':'').' onclick="toggleUploadType()"> URL</label><br><br>
<label><input type="checkbox" name="anonymous" value="1" '.($anonymous?'checked':'').' onclick="toggleAnonymous()"> Anonymous Login</label><br><br>
Username: <input type="text" name="username" value="'.htmlspecialchars($username).'"><br>
Password: <input type="password" name="password" value="'.htmlspecialchars($password).'"><br>
Server: <input type="text" name="server" value="'.htmlspecialchars($server).'"><br>
Path: <input type="text" name="path" value="'.htmlspecialchars($path).'"><br>
Protocol:<br>
<label><input type="radio" name="protocol" value="ftp" '.($protocol=='ftp'?'checked':'').'> FTP</label>
<label><input type="radio" name="protocol" value="sftp" '.($protocol=='sftp'?'checked':'').'> SFTP</label>
<label><input type="radio" name="protocol" value="webdav" '.($protocol=='webdav'?'checked':'').'> WebDAV</label>
<br><br>
<div id="fileUploadDiv" style="display: '.($uploadType==='file'?'block':'none').';">
Select file to upload:<br>
<input type="file" name="upload_file"><br>
</div>
<div id="urlUploadDiv" style="display: '.($uploadType==='url'?'block':'none').';">
Enter URL to upload:<br>
<input type="url" name="upload_url" style="width:300px;" value="'.htmlspecialchars(getQuery('upload_url')).'"><br>
</div>
<input type="submit" value="Connect / Upload">
</form>
<script>
function toggleUploadType() {
const fileDiv = document.getElementById("fileUploadDiv");
const urlDiv = document.getElementById("urlUploadDiv");
const fileRadio = document.querySelector(\'input[name="upload_type"][value="file"]\');
if(fileRadio.checked){fileDiv.style.display="block";urlDiv.style.display="none";}else{fileDiv.style.display="none";urlDiv.style.display="block";}
}
</script>
<script>
function toggleAnonymous() {
const anon = document.querySelector(\'input[name="anonymous"]\');
const userField = document.querySelector(\'input[name="username"]\');
const passField = document.querySelector(\'input[name="password"]\');
if(anon.checked){userField.disabled=true;passField.disabled=true;}else{userField.disabled=false;passField.disabled=false;}
}
</script>
';
// ---------------- Directory listing -------------------
if ($server && $isDir) {
$files = listDirectory($protocol, $server, $username, $password, $path, $debug);
if ($path !== '/') {
$parent = rtrim($path, '/');
$parent = substr($parent, 0, strrpos($parent, '/') + 1);
echo '<a href="?username='.urlencode($username).'&password='.urlencode($password).'&server='.urlencode($server).'&protocol='.urlencode($protocol).'&path='.urlencode($parent).'&upload_type='.htmlspecialchars($uploadType).'&anonymous='.($anonymous?1:0).'">.. (Parent directory)</a><br>';
}
echo "<ul>";
foreach ($files as $file) {
$name = $file['name'];
$type = $file['type'];
$urlPath = $path . $name . ($type === 'dir' ? '/' : '');
echo '<li>';
if ($type === 'dir') {
echo "📁 <a href='?username=".urlencode($username)."&password=".urlencode($password)."&server=".urlencode($server)."&protocol=".urlencode($protocol)."&path=".urlencode($urlPath)."&upload_type=".htmlspecialchars($uploadType)."&anonymous=".($anonymous?1:0)."'>" . htmlspecialchars($name) . "</a>";
} else {
$downloadUrl = "download.php?protocol=" . urlencode($protocol) .
"&server=" . urlencode($server) .
"&path=" . urlencode($urlPath) .
"&username=" . urlencode($username) .
"&password=" . urlencode($password) .
"&anonymous=" . ($anonymous?1:0);
$ext = strtolower(pathinfo($name, PATHINFO_EXTENSION));
if (in_array($ext, ['mp3','mp4','png','jpg','jpeg','gif'])) {
echo "📄 <a href='" . htmlspecialchars($downloadUrl) . "' target='_blank'>" . htmlspecialchars($name) . "</a>";
} else {
echo "📄 <a href='" . htmlspecialchars($downloadUrl) . "' download>" . htmlspecialchars($name) . "</a>";
}
}
echo "</li>";
}
echo "</ul>";
}
?>