diff --git a/conststr.php b/conststr.php index 920aa3c..b0954f9 100644 --- a/conststr.php +++ b/conststr.php @@ -16,92 +16,64 @@ $constStr = [ 'ja' => '日本語', ], 'Week' => [ - 0 => [ - 'en-us' => 'Sunday', - 'zh-cn' => '星期日', - 'ja' => '日曜日', + 'en-us' => [ + 0 => 'Sunday', + 1 => 'Monday', + 2 => 'Tuesday', + 3 => 'Wednesday', + 4 => 'Thursday', + 5 => 'Friday', + 6 => 'Saturday', ], - 1 => [ - 'en-us' => 'Monday', - 'zh-cn' => '星期一', - 'ja' => '月曜日', + 'zh-cn' => [ + 0 => '星期日', + 1 => '星期一', + 2 => '星期二', + 3 => '星期三', + 4 => '星期四', + 5 => '星期五', + 6 => '星期六', ], - 2 => [ - 'en-us' => 'Tuesday', - 'zh-cn' => '星期二', - 'ja' => '火曜日', - ], - 3 => [ - 'en-us' => 'Wednesday', - 'zh-cn' => '星期三', - 'ja' => '水曜日', - ], - 4 => [ - 'en-us' => 'Thursday', - 'zh-cn' => '星期四', - 'ja' => '木曜日', - ], - 5 => [ - 'en-us' => 'Friday', - 'zh-cn' => '星期五', - 'ja' => '金曜日', - ], - 6 => [ - 'en-us' => 'Saturday', - 'zh-cn' => '星期六', - 'ja' => '土曜日', + 'ja' => [ + 0 => '日曜日', + 1 => '月曜日', + 2 => '火曜日', + 3 => '水曜日', + 4 => '木曜日', + 5 => '金曜日', + 6 => '土曜日', ], ], 'EnvironmentsDescription' => [ - 'admin' => [ - 'en-us' => 'The admin password, Login button will not show when empty', - 'zh-cn' => '管理密码,不添加时不显示登录页面且无法登录。', - 'ja' => 'パスワードを管理する、追加しない場合、ログインページは表示されず、ログインできません。', + 'en-us' => [ + 'admin' => 'The admin password, Login button will not show when empty', + 'adminloginpage' => 'if set, the Login button will not display, and the login page no longer \'?admin\', it is \'?{this value}\'.', + 'domain_path' => 'more custom domain, format is a1.com:/dirto/path1|b2.com:/path2', + 'guestup_path' => 'Set guest upload dir, before set this, the files in this dir will show as normal.', + 'passfile' => 'The password of dir will save in this file.', + 'public_path' => 'Show this Onedrive dir when through the long url of API Gateway; public show files less than private.', + 'sitename' => 'sitename', + 'Onedrive_ver' => 'Onedrive version', ], - 'adminloginpage' => [ - 'en-us' => 'if set, the Login button will not display, and the login page no longer \'?admin\', it is \'?{this value}\'.', - 'zh-cn' => '如果设置,登录按钮及页面隐藏。管理登录的页面不再是\'?admin\',而是\'?此设置的值\'。', - 'ja' => '設定すると、ログインボタンとページが非表示になります。ログインを管理するためのページは\'?admin \'ではなく、\'?この設定の値\'。', + 'zh-cn' => [ + 'admin' => '管理密码,不添加时不显示登录页面且无法登录。', + 'adminloginpage' => '如果设置,登录按钮及页面隐藏。管理登录的页面不再是\'?admin\',而是\'?此设置的值\'。', + 'domain_path' => '使用多个自定义域名时,指定每个域名看到的目录。格式为a1.com:/dirto/path1|b1.com:/path2,比private_path优先。', + 'guestup_path' => '设置游客上传路径(图床路径),不设置这个值时该目录内容会正常列文件出来,设置后只有上传界面,不显示其中文件(登录后显示)。', + 'passfile' => '自定义密码文件的名字,可以是\'pppppp\',也可以是\'aaaa.txt\'等等;列目录时不会显示,只有知道密码才能查看或下载此文件。密码是这个文件的内容,可以空格、可以中文;', + 'public_path' => '使用API长链接访问时,显示网盘文件的路径,不设置时默认为根目录;不能是private_path的上级(public看到的不能比private多,要么看到的就不一样)。', + 'sitename' => '网站的名称', + 'Onedrive_ver' => 'Onedrive版本', ], - 'domain_path' => [ - 'en-us' => 'more custom domain, format is a1.com:/dirto/path1|b2.com:/path2', - 'zh-cn' => '使用多个自定义域名时,指定每个域名看到的目录。格式为a1.com:/dirto/path1|b1.com:/path2,比private_path优先。', - 'ja' => '複数のカスタムドメイン名を使用する場合、各ドメイン名に表示されるディレクトリを指定します。形式はa1.com:/dirto/path1|b1.com:/path2で、private_pathよりも優先されます。', - ], - 'guestup_path' => [ - 'en-us' => 'Set guest upload dir, before set this, the files in this dir will show as normal.', - 'zh-cn' => '设置游客上传路径(图床路径),不设置这个值时该目录内容会正常列文件出来,设置后只有上传界面,不显示其中文件(登录后显示)。', - 'ja' => 'マップベッドのパスを設定します。この値が設定されていない場合、ディレクトリの内容は通常ファイルにリストされ、設定後はアップロードインターフェイスのみが表示されます。', - ], - 'passfile' => [ - 'en-us' => 'The password of dir will save in this file.', - 'zh-cn' => '自定义密码文件的名字,可以是\'pppppp\',也可以是\'aaaa.txt\'等等;列目录时不会显示,只有知道密码才能查看或下载此文件。密码是这个文件的内容,可以空格、可以中文;', - 'ja' => 'カスタムパスワードファイルの名前は、\'pppppp \'、\'aaaa.txt \'などの場合があります。ディレクトリをリストするときには表示されません。パスワードを知っている場合にのみ、このファイルを表示またはダウンロードできます。 パスワードはこのファイルの内容であり、スペースまたは漢字を使用できます。', - ], - 'private_path' => [ - 'en-us' => 'Show this Onedrive dir when through custom domain, default is \'/\'.', - 'zh-cn' => '使用自定义域名访问时,显示网盘文件的路径,不设置时默认为根目录。', - 'ja' => 'カスタムドメイン名を使用してアクセスする場合、ネットワークディスクファイルのパスが表示されます設定されていない場合は、デフォルトでルートディレクトリになります。', - ], - 'public_path' => [ - 'en-us' => 'Show this Onedrive dir when through the long url of API Gateway; public show files less than private.', - 'zh-cn' => '使用API长链接访问时,显示网盘文件的路径,不设置时默认为根目录;不能是private_path的上级(public看到的不能比private多,要么看到的就不一样)。', - 'ja' => 'APIのロングリンクアクセスを使用する場合、ネットワークディスクファイルのパスが表示されますが、設定されていない場合はデフォルトでルートディレクトリになり、private_pathの上位にはなりません(publicはprivate以上のものを見ることができません。それ以外は異なります。)。', - ], - 'sitename' => [ - 'en-us' => 'sitename', - 'zh-cn' => '网站的名称', - 'ja' => 'ウェブサイト名', - ], - 'language' => [ - 'en-us' => 'en-us', - 'zh-cn' => '中文', - 'ja' => '日本語', - ], - 'Onedrive_ver' => [ - 'en-us' => 'Onedrive version', - 'zh-cn' => 'Onedrive版本', - 'ja' => 'Onedriveバージョン', + 'ja' => [ + 'admin' => 'パスワードを管理する、追加しない場合、ログインページは表示されず、ログインできません。', + 'adminloginpage' => '設定すると、ログインボタンとページが非表示になります。ログインを管理するためのページは\'?admin \'ではなく、\'?この設定の値\'。', + 'domain_path' => '複数のカスタムドメイン名を使用する場合、各ドメイン名に表示されるディレクトリを指定します。形式はa1.com:/dirto/path1|b1.com:/path2で、private_pathよりも優先されます。', + 'guestup_path' => 'マップベッドのパスを設定します。この値が設定されていない場合、ディレクトリの内容は通常ファイルにリストされ、設定後はアップロードインターフェイスのみが表示されます。', + 'passfile' => 'カスタムパスワードファイルの名前は、\'pppppp \'、\'aaaa.txt \'などの場合があります。ディレクトリをリストするときには表示されません。パスワードを知っている場合にのみ、このファイルを表示またはダウンロードできます。 パスワードはこのファイルの内容であり、スペースまたは漢字を使用できます。', + 'public_path' => 'APIのロングリンクアクセスを使用する場合、ネットワークディスクファイルのパスが表示されますが、設定されていない場合はデフォルトでルートディレクトリになり、private_pathの上位にはなりません(publicはprivate以上のものを見ることができません。それ以外は異なります。)。', + 'sitename' => 'ウェブサイト名', + 'Onedrive_ver' => 'Onedriveバージョン', ], ], 'SetSecretsFirst' => [ diff --git a/function/common.php b/function/common.php index fe036ae..70f55f7 100644 --- a/function/common.php +++ b/function/common.php @@ -14,14 +14,21 @@ function savecache($key, $value, $exp = 3300) $cache->save($key, $value, $exp); } -function config_oauth() +function getconstStr($str) { global $constStr; $constStr['language'] = $_COOKIE['language']; if ($constStr['language']=='') $constStr['language'] = getConfig('language'); if ($constStr['language']=='') $constStr['language'] = 'en-us'; + if ($constStr[$str][$constStr['language']]!='') return $constStr[$str][$constStr['language']]; + return $constStr[$str]['en-us']; +} + +function config_oauth() +{ + global $constStr; $_SERVER['sitename'] = getConfig('sitename'); - if (empty($_SERVER['sitename'])) $_SERVER['sitename'] = $constStr['defaultSitename'][$constStr['language']]; + if (empty($_SERVER['sitename'])) $_SERVER['sitename'] = getconstStr('defaultSitename'); $_SERVER['redirect_uri'] = 'https://scfonedrive.github.io'; if (getConfig('Onedrive_ver')=='MS') { @@ -311,3 +318,546 @@ function get_thumbnails_url($path = '/') if (isset($files['url'])) return output($files['url']); return output('', 404); } + +function bigfileupload($path) +{ + $path1 = path_format($_SERVER['list_path'] . path_format($path)); + if (substr($path1,-1)=='/') $path1=substr($path1,0,-1); + if ($_GET['upbigfilename']!=''&&$_GET['filesize']>0) { + $fileinfo['name'] = $_GET['upbigfilename']; + $fileinfo['size'] = $_GET['filesize']; + $fileinfo['lastModified'] = $_GET['lastModified']; + $filename = spurlencode( $fileinfo['name'] ); + $cachefilename = '.' . $fileinfo['lastModified'] . '_' . $fileinfo['size'] . '_' . $filename . '.tmp'; + $getoldupinfo=fetch_files(path_format($path . '/' . $cachefilename)); + //echo json_encode($getoldupinfo, JSON_PRETTY_PRINT); + if (isset($getoldupinfo['file'])&&$getoldupinfo['size']<5120) { + $getoldupinfo_j = curl_request($getoldupinfo['@microsoft.graph.downloadUrl']); + $getoldupinfo = json_decode($getoldupinfo_j , true); + if ( json_decode( curl_request($getoldupinfo['uploadUrl']), true)['@odata.context']!='' ) return output($getoldupinfo_j); + } + if (!$_SERVER['admin']) $filename = spurlencode( $fileinfo['name'] ) . '.scfupload'; + $response=MSAPI('createUploadSession',path_format($path1 . '/' . $filename),'{"item": { "@microsoft.graph.conflictBehavior": "fail" }}',$_SERVER['access_token']); + $responsearry = json_decode($response['body'],true); + if (isset($responsearry['error'])) return output($response['body'], $response['stat']); + $fileinfo['uploadUrl'] = $responsearry['uploadUrl']; + MSAPI('PUT', path_format($path1 . '/' . $cachefilename), json_encode($fileinfo, JSON_PRETTY_PRINT), $_SERVER['access_token'])['body']; + return output($response['body'], $response['stat']); + } + return output('error', 400); +} + +function main($path) +{ + global $exts; + global $constStr; + config_oauth(); + $_SERVER['list_path'] = getListpath($_SERVER['HTTP_HOST']); + if ($_SERVER['list_path']=='') $_SERVER['list_path'] = '/'; + $_SERVER['is_guestup_path'] = is_guestup_path($path); + $_SERVER['PHP_SELF'] = path_format($_SERVER['base_path'] . $path); + $_SERVER['ajax']=0; + if (isset($_SERVER['HTTP_X_REQUESTED_WITH'])) if ($_SERVER['HTTP_X_REQUESTED_WITH']=='XMLHttpRequest') $_SERVER['ajax']=1; + + $refresh_token = getConfig('refresh_token'); + if (!$refresh_token) return get_refresh_token(); + + if (getConfig('adminloginpage')=='') { + $adminloginpage = 'admin'; + } else { + $adminloginpage = getConfig('adminloginpage'); + } + if ($_GET[$adminloginpage]) { + if ($_GET['preview']) { + $url = $_SERVER['PHP_SELF'] . '?preview'; + } else { + $url = path_format($_SERVER['PHP_SELF'] . '/'); + } + if (getConfig('admin')!='') { + if ($_POST['password1']==getConfig('admin')) { + return adminform($_SERVER['function_name'].'admin',md5($_POST['password1']),$url); + } else return adminform(); + } else { + return output('', 302, [ 'Location' => $url ]); + } + } + if (getConfig('admin')!='') + if ( $_COOKIE['admin']==md5(getConfig('admin')) || $_POST['password1']==getConfig('admin') ) { + $_SERVER['admin']=1; + $_SERVER['needUpdate'] = needUpdate(); + } else { + $_SERVER['admin']=0; + } + if ($_GET['setup']) + if ($_SERVER['admin']) { + // setup Environments. 设置,对环境变量操作 + return EnvOpt($_SERVER['function_name'], $_SERVER['needUpdate']); + } else { + $url = path_format($_SERVER['PHP_SELF'] . '/'); + return output('', 302, [ 'Location' => $url ]); + } + $_SERVER['retry'] = 0; + + if (!($_SERVER['access_token'] = getcache('access_token'))) { + $ret = json_decode(curl_request( + $_SERVER['oauth_url'] . 'token', + 'client_id='. $_SERVER['client_id'] .'&client_secret='. $_SERVER['client_secret'] .'&grant_type=refresh_token&requested_token_use=on_behalf_of&refresh_token=' . $refresh_token + )['body'], true); + if (!isset($ret['access_token'])) { + error_log('failed to get access_token. response' . json_encode($ret)); + throw new Exception('failed to get access_token.'); + } + $_SERVER['access_token'] = $ret['access_token']; + savecache('access_token', $_SERVER['access_token']); + } + + if ($_SERVER['ajax']) { + if ($_GET['action']=='del_upload_cache'&&substr($_GET['filename'],-4)=='.tmp') { + // del '.tmp' without login. 无需登录即可删除.tmp后缀文件 + $tmp = MSAPI('DELETE',path_format(path_format($_SERVER['list_path'] . path_format($path)) . '/' . spurlencode($_GET['filename']) ),'',$_SERVER['access_token']); + $path1 = path_format($_SERVER['list_path'] . path_format($path)); + savecache('path_' . $path1, json_decode('{}',true), 1); + return output($tmp['body'],$tmp['stat']); + } + if ($_GET['action']=='uploaded_rename') { + // rename .scfupload file without login. + // 无需登录即可重命名.scfupload后缀文件,filemd5为用户提交,可被构造,问题不大,以后处理 + $oldname = spurlencode($_GET['filename']); + $pos = strrpos($oldname, '.'); + if ($pos>0) $ext = strtolower(substr($oldname, $pos)); + $oldname = path_format(path_format($_SERVER['list_path'] . path_format($path)) . '/' . $oldname . '.scfupload' ); + $data = '{"name":"' . $_GET['filemd5'] . $ext . '"}'; + //echo $oldname .'
'. $data; + $tmp = MSAPI('PATCH',$oldname,$data,$_SERVER['access_token']); + if ($tmp['stat']==409) MSAPI('DELETE',$oldname,'',$_SERVER['access_token'])['body']; + $path1 = path_format($_SERVER['list_path'] . path_format($path)); + savecache('path_' . $path1, json_decode('{}',true), 1); + return output($tmp['body'],$tmp['stat']); + } + if ($_GET['action']=='upbigfile') return bigfileupload($path); + } + if ($_SERVER['admin']) { + $tmp = adminoperate($path); + if ($tmp['statusCode'] > 0) { + $path1 = path_format($_SERVER['list_path'] . path_format($path)); + savecache('path_' . $path1, json_decode('{}',true), 1); + return $tmp; + } + } else { + if ($_SERVER['ajax']) return output(getconstStr('RefleshtoLogin'),401); + } + $_SERVER['ishidden'] = passhidden($path); + if ($_GET['thumbnails']) { + if ($_SERVER['ishidden']<4) { + if (in_array(strtolower(substr($path, strrpos($path, '.') + 1)), $exts['img'])) { + return get_thumbnails_url($path); + } else return output(json_encode($exts['img']),400); + } else return output('',401); + } + $files = list_files($path); + if (isset($files['file']) && !$_GET['preview']) { + // is file && not preview mode + if ($_SERVER['ishidden']<4) return output('', 302, [ 'Location' => $files['@microsoft.graph.downloadUrl'] ]); + } + if ( isset($files['folder']) || isset($files['file']) ) { + return render_list($path, $files); + } else { + return message('
' . $files['error']['message'] . '
'.getconstStr('Back').'', $files['error']['code'], $files['error']['stat']); + } +} + +function list_files($path) +{ + $path = path_format($path); + if ($_SERVER['is_guestup_path']&&!$_SERVER['admin']) { + $files = json_decode('{"folder":{}}', true); + } elseif ($_SERVER['ishidden']==4) { + $files = json_decode('{"folder":{}}', true); + } else { + $files = fetch_files($path); + } + if ( isset($files['folder']) || isset($files['file']) || isset($files['error']) ) { + return $files; + } else { + error_log( json_encode($files) . ' Network Error
' ); + $_SERVER['retry']++; + if ($_SERVER['retry'] < 3) { + return list_files($path); + } else return $files; + } +} + +function adminform($name = '', $pass = '', $path = '') +{ + global $constStr; + $statusCode = 401; + $html = ''.getconstStr('AdminLogin').''; + if ($name!=''&&$pass!='') { + $html .= ''.getconstStr('LoginSuccess').''; + $statusCode = 302; + date_default_timezone_set('UTC'); + $header = [ + 'Set-Cookie' => $name.'='.$pass.'; path=/; expires='.date(DATE_COOKIE,strtotime('+1hour')), + 'Location' => $path, + 'Content-Type' => 'text/html' + ]; + return output($html,$statusCode,$header); + } + $html .= ' + +
+

'.getconstStr('InputPassword').'

+
+
+ + +
+
+
+
+'; + $html .= ''; + return output($html,$statusCode); +} + +function adminoperate($path) +{ + global $constStr; + $path1 = path_format($_SERVER['list_path'] . path_format($path)); + if (substr($path1,-1)=='/') $path1=substr($path1,0,-1); + $tmparr['statusCode'] = 0; + if ($_GET['rename_newname']!=$_GET['rename_oldname'] && $_GET['rename_newname']!='') { + // rename 重命名 + $oldname = spurlencode($_GET['rename_oldname']); + $oldname = path_format($path1 . '/' . $oldname); + $data = '{"name":"' . $_GET['rename_newname'] . '"}'; + //echo $oldname; + $result = MSAPI('PATCH',$oldname,$data,$_SERVER['access_token']); + //savecache('path_' . $path1, json_decode('{}',true), 1); + return output($result['body'], $result['stat']); + } + if ($_GET['delete_name']!='') { + // delete 删除 + $filename = spurlencode($_GET['delete_name']); + $filename = path_format($path1 . '/' . $filename); + //echo $filename; + $result = MSAPI('DELETE', $filename, '', $_SERVER['access_token']); + //savecache('path_' . $path1, json_decode('{}',true), 1); + return output($result['body'], $result['stat']); + } + if ($_GET['operate_action']==getconstStr('encrypt')) { + // encrypt 加密 + if (getConfig('passfile')=='') return message(getconstStr('SetpassfileBfEncrypt'),'',403); + if ($_GET['encrypt_folder']=='/') $_GET['encrypt_folder']==''; + $foldername = spurlencode($_GET['encrypt_folder']); + $filename = path_format($path1 . '/' . $foldername . '/' . getConfig('passfile')); + //echo $foldername; + $result = MSAPI('PUT', $filename, $_GET['encrypt_newpass'], $_SERVER['access_token']); + //savecache('path_' . $path1, json_decode('{}',true), 1); + return output($result['body'], $result['stat']); + } + if ($_GET['move_folder']!='') { + // move 移动 + $moveable = 1; + if ($path == '/' && $_GET['move_folder'] == '/../') $moveable=0; + if ($_GET['move_folder'] == $_GET['move_name']) $moveable=0; + if ($moveable) { + $filename = spurlencode($_GET['move_name']); + $filename = path_format($path1 . '/' . $filename); + $foldername = path_format('/'.urldecode($path1).'/'.$_GET['move_folder']); + $data = '{"parentReference":{"path": "/drive/root:'.$foldername.'"}}'; + $result = MSAPI('PATCH', $filename, $data, $_SERVER['access_token']); + //savecache('path_' . $path1, json_decode('{}',true), 1); + if ($_GET['move_folder'] == '/../') $path2 = path_format( substr($path1, 0, strrpos($path1, '/')) . '/' ); + else $path2 = path_format( $path1 . '/' . $_GET['move_folder'] . '/' ); + savecache('path_' . $path2, json_decode('{}',true), 1); + return output($result['body'], $result['stat']); + } else { + return output('{"error":"Can not Move!"}', 403); + } + } + if ($_POST['editfile']!='') { + // edit 编辑 + $data = $_POST['editfile']; + /*TXT一般不会超过4M,不用二段上传 + $filename = $path1 . ':/createUploadSession'; + $response=MSAPI('POST',$filename,'{"item": { "@microsoft.graph.conflictBehavior": "replace" }}',$_SERVER['access_token']); + $uploadurl=json_decode($response,true)['uploadUrl']; + echo MSAPI('PUT',$uploadurl,$data,$_SERVER['access_token']);*/ + $result = MSAPI('PUT', $path1, $data, $_SERVER['access_token'])['body']; + //echo $result; + $resultarry = json_decode($result,true); + if (isset($resultarry['error'])) return message($resultarry['error']['message']. '
上一页','Error',403); + } + if ($_GET['create_name']!='') { + // create 新建 + if ($_GET['create_type']=='file') { + $filename = spurlencode($_GET['create_name']); + $filename = path_format($path1 . '/' . $filename); + $result = MSAPI('PUT', $filename, $_GET['create_text'], $_SERVER['access_token']); + } + if ($_GET['create_type']=='folder') { + $data = '{ "name": "' . $_GET['create_name'] . '", "folder": { }, "@microsoft.graph.conflictBehavior": "rename" }'; + $result = MSAPI('children', $path1, $data, $_SERVER['access_token']); + } + //savecache('path_' . $path1, json_decode('{}',true), 1); + return output($result['body'], $result['stat']); + } + if ($_GET['RefreshCache']) { + //savecache('path_' . $path1, json_decode('{}',true), 1); + return output(''.getconstStr('RefreshCache'), 302); + } + return $tmparr; +} + +function MSAPI($method, $path, $data = '', $access_token) +{ + if (substr($path,0,7) == 'http://' or substr($path,0,8) == 'https://') { + $url=$path; + $lenth=strlen($data); + $headers['Content-Length'] = $lenth; + $lenth--; + $headers['Content-Range'] = 'bytes 0-' . $lenth . '/' . $headers['Content-Length']; + } else { + $url = $_SERVER['api_url']; + if ($path=='' or $path=='/') { + $url .= '/'; + } else { + $url .= ':' . $path; + if (substr($url,-1)=='/') $url=substr($url,0,-1); + } + if ($method=='PUT') { + if ($path=='' or $path=='/') { + $url .= 'content'; + } else { + $url .= ':/content'; + } + $headers['Content-Type'] = 'text/plain'; + } elseif ($method=='PATCH') { + $headers['Content-Type'] = 'application/json'; + } elseif ($method=='POST') { + $headers['Content-Type'] = 'application/json'; + } elseif ($method=='DELETE') { + $headers['Content-Type'] = 'application/json'; + } else { + if ($path=='' or $path=='/') { + $url .= $method; + } else { + $url .= ':/' . $method; + } + $method='POST'; + $headers['Content-Type'] = 'application/json'; + } + } + $headers['Authorization'] = 'Bearer ' . $access_token; + if (!isset($headers['Accept'])) $headers['Accept'] = '*/*'; + if (!isset($headers['Referer'])) $headers['Referer'] = $url; + $sendHeaders = array(); + foreach ($headers as $headerName => $headerVal) { + $sendHeaders[] = $headerName . ': ' . $headerVal; + } + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_CUSTOMREQUEST,$method); + curl_setopt($ch, CURLOPT_POSTFIELDS,$data); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); + curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_HEADER, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + curl_setopt($ch, CURLOPT_HTTPHEADER, $sendHeaders); + $response['body'] = curl_exec($ch); + $response['stat'] = curl_getinfo($ch,CURLINFO_HTTP_CODE); + curl_close($ch); + error_log($response['stat'].' +'.$response['body'].' +'); + return $response; +} + +function fetch_files($path = '/') +{ + $path1 = path_format($path); + $path = path_format($_SERVER['list_path'] . path_format($path)); + if (!($files = getcache('path_' . $path))) { + // https://docs.microsoft.com/en-us/graph/api/driveitem-get?view=graph-rest-1.0 + // https://docs.microsoft.com/zh-cn/graph/api/driveitem-put-content?view=graph-rest-1.0&tabs=http + // https://developer.microsoft.com/zh-cn/graph/graph-explorer + $url = $_SERVER['api_url']; + if ($path !== '/') { + $url .= ':' . $path; + if (substr($url,-1)=='/') $url=substr($url,0,-1); + } + $url .= '?expand=children(select=name,size,file,folder,parentReference,lastModifiedDateTime)'; + $arr = curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']]); + if ($arr['stat']<500) { + $files = json_decode($arr['body'], true); + // echo $path . '
' . json_encode($files, JSON_PRETTY_PRINT) . '
'; + if (isset($files['folder'])) { + if ($files['folder']['childCount']>200) { + // files num > 200 , then get nextlink + $page = $_POST['pagenum']==''?1:$_POST['pagenum']; + $files=fetch_files_children($files, $path, $page); + } else { + // files num < 200 , then cache + savecache('path_' . $path, $files); + } + } + if (isset($files['error'])) { + $files['error']['stat'] = $arr['stat']; + } + } else { + error_log($arr['body']); + $files = json_decode( '{"unknownError":{ "stat":'.$arr['stat'].',"message":"'.$arr['body'].'"}}', true); + } + } + return $files; +} + +function fetch_files_children($files, $path, $page) +{ + $cachefilename = '.SCFcache_'.$_SERVER['function_name']; + $maxpage = ceil($files['folder']['childCount']/200); + if (!($files['children'] = getcache('files_' . $path . '_page_' . $page))) { + // down cache file get jump info. 下载cache文件获取跳页链接 + $cachefile = fetch_files(path_format($path1 . '/' .$cachefilename)); + if ($cachefile['size']>0) { + $pageinfo = curl_request($cachefile['@microsoft.graph.downloadUrl'])['body']; + $pageinfo = json_decode($pageinfo,true); + for ($page4=1;$page4<$maxpage;$page4++) { + savecache('nextlink_' . $path . '_page_' . $page4, $pageinfo['nextlink_' . $path . '_page_' . $page4]); + $pageinfocache['nextlink_' . $path . '_page_' . $page4] = $pageinfo['nextlink_' . $path . '_page_' . $page4]; + } + } + $pageinfochange=0; + for ($page1=$page;$page1>=1;$page1--) { + $page3=$page1-1; + $url = getcache('nextlink_' . $path . '_page_' . $page3); + if ($url == '') { + if ($page1==1) { + $url = $_SERVER['api_url']; + if ($path !== '/') { + $url .= ':' . $path; + if (substr($url,-1)=='/') $url=substr($url,0,-1); + $url .= ':/children?$select=name,size,file,folder,parentReference,lastModifiedDateTime'; + } else { + $url .= '/children?$select=name,size,file,folder,parentReference,lastModifiedDateTime'; + } + $children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true); + // echo $url . '
' . json_encode($children, JSON_PRETTY_PRINT) . '
'; + savecache('files_' . $path . '_page_' . $page1, $children['value']); + $nextlink=getcache('nextlink_' . $path . '_page_' . $page1); + if ($nextlink!=$children['@odata.nextLink']) { + savecache('nextlink_' . $path . '_page_' . $page1, $children['@odata.nextLink']); + $pageinfocache['nextlink_' . $path . '_page_' . $page1] = $children['@odata.nextLink']; + $pageinfocache = clearbehindvalue($path,$page1,$maxpage,$pageinfocache); + $pageinfochange = 1; + } + $url = $children['@odata.nextLink']; + for ($page2=$page1+1;$page2<=$page;$page2++) { + sleep(1); + $children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true); + savecache('files_' . $path . '_page_' . $page2, $children['value']); + $nextlink=getcache('nextlink_' . $path . '_page_' . $page2); + if ($nextlink!=$children['@odata.nextLink']) { + savecache('nextlink_' . $path . '_page_' . $page2, $children['@odata.nextLink']); + $pageinfocache['nextlink_' . $path . '_page_' . $page2] = $children['@odata.nextLink']; + $pageinfocache = clearbehindvalue($path,$page2,$maxpage,$pageinfocache); + $pageinfochange = 1; + } + $url = $children['@odata.nextLink']; + } + //echo $url . '
' . json_encode($children, JSON_PRETTY_PRINT) . '
'; + $files['children'] = $children['value']; + $files['folder']['page']=$page; + $pageinfocache['filenum'] = $files['folder']['childCount']; + $pageinfocache['dirsize'] = $files['size']; + $pageinfocache['cachesize'] = $cachefile['size']; + $pageinfocache['size'] = $files['size']-$cachefile['size']; + if ($pageinfochange == 1) MSAPI('PUT', path_format($path.'/'.$cachefilename), json_encode($pageinfocache, JSON_PRETTY_PRINT), $_SERVER['access_token'])['body']; + return $files; + } + } else { + for ($page2=$page3+1;$page2<=$page;$page2++) { + sleep(1); + $children = json_decode(curl_request($url, false, ['Authorization' => 'Bearer ' . $_SERVER['access_token']])['body'], true); + savecache('files_' . $path . '_page_' . $page2, $children['value'], 3300); + $nextlink=getcache('nextlink_' . $path . '_page_' . $page2); + if ($nextlink!=$children['@odata.nextLink']) { + savecache('nextlink_' . $path . '_page_' . $page2, $children['@odata.nextLink'], 3300); + $pageinfocache['nextlink_' . $path . '_page_' . $page2] = $children['@odata.nextLink']; + $pageinfocache = clearbehindvalue($path,$page2,$maxpage,$pageinfocache); + $pageinfochange = 1; + } + $url = $children['@odata.nextLink']; + } + //echo $url . '
' . json_encode($children, JSON_PRETTY_PRINT) . '
'; + $files['children'] = $children['value']; + $files['folder']['page']=$page; + $pageinfocache['filenum'] = $files['folder']['childCount']; + $pageinfocache['dirsize'] = $files['size']; + $pageinfocache['cachesize'] = $cachefile['size']; + $pageinfocache['size'] = $files['size']-$cachefile['size']; + if ($pageinfochange == 1) MSAPI('PUT', path_format($path.'/'.$cachefilename), json_encode($pageinfocache, JSON_PRETTY_PRINT), $_SERVER['access_token'])['body']; + return $files; + } + } + } else { + $files['folder']['page']=$page; + for ($page4=1;$page4<=$maxpage;$page4++) { + if (!($url = getcache('nextlink_' . $path . '_page_' . $page4))) { + if ($files['folder'][$path.'_'.$page4]!='') savecache('nextlink_' . $path . '_page_' . $page4, $files['folder'][$path.'_'.$page4]); + } else { + $files['folder'][$path.'_'.$page4] = $url; + } + } + } + return $files; +} + +function render_list($path, $files) +{ + global $exts; + global $constStr; + + $path = str_replace('%20','%2520',$path); + $path = str_replace('+','%2B',$path); + $path = str_replace('&','&',path_format(urldecode($path))) ; + $path = str_replace('%20',' ',$path); + $path = str_replace('#','%23',$path); + $p_path=''; + if ($path !== '/') { + if (isset($files['file'])) { + $pretitle = str_replace('&','&', $files['name']); + $n_path=$pretitle; + } else { + $pretitle = substr($path,-1)=='/'?substr($path,0,-1):$path; + $n_path=substr($pretitle,strrpos($pretitle,'/')+1); + $pretitle = substr($pretitle,1); + } + if (strrpos($path,'/')!=0) { + $p_path=substr($path,0,strrpos($path,'/')); + $p_path=substr($p_path,strrpos($p_path,'/')+1); + } + } else { + $pretitle = getconstStr('Home'); + $n_path=$pretitle; + } + $n_path=str_replace('&','&',$n_path); + $p_path=str_replace('&','&',$p_path); + $pretitle = str_replace('%23','#',$pretitle); + $statusCode=200; + date_default_timezone_set(get_timezone($_COOKIE['timezone'])); + @ob_start(); + + $theme = getConfig('theme'); + if ( $theme=='' || !file_exists('theme/'.$theme) ) $theme = 'classic.php'; + include 'theme/'.$theme; + + $html = '' . ob_get_clean(); + if ($_SERVER['Set-Cookie']!='') return output($html, $statusCode, [ 'Set-Cookie' => $_SERVER['Set-Cookie'], 'Content-Type' => 'text/html' ]); + return output($html,$statusCode); +} diff --git a/function/normal.php b/function/normal.php index 28dd362..b00ffbd 100644 --- a/function/normal.php +++ b/function/normal.php @@ -13,17 +13,19 @@ function getpath() function getGET() { - $getstr = urldecode(substr($_SERVER['REQUEST_URI'], strpos($_SERVER['REQUEST_URI'],'?'))); - while (substr($getstr, 0, 1) == '/' || substr($getstr, 0, 1) == '?') $getstr = substr($getstr, 1); - $getstrarr = explode("&",$getstr); - foreach ($getstrarr as $getvalues) { - if ($getvalues != '') { - $pos = strpos($getvalues, "="); + $p = strpos($_SERVER['REQUEST_URI'],'?'); + if ($p>0) { + $getstr = substr($_SERVER['REQUEST_URI'], $p+1); + $getstrarr = explode("&",$getstr); + foreach ($getstrarr as $getvalues) { + if ($getvalues != '') { + $pos = strpos($getvalues, "="); //echo $pos; - if ($pos > 0) { - $getarry[urldecode(substr($getvalues, 0, $pos))] = urldecode(substr($getvalues, $pos + 1)); - } else { - $getarry[urldecode($getvalues)] = true; + if ($pos > 0) { + $getarry[urldecode(substr($getvalues, 0, $pos))] = urldecode(substr($getvalues, $pos + 1)); + } else { + $getarry[urldecode($getvalues)] = true; + } } } } @@ -67,7 +69,7 @@ function get_refresh_token() savecache('access_token', $ret['access_token'], $ret['expires_in'] - 60); $str .= ' '; - return message($str, $constStr['WaitJumpIndex'][$constStr['language']]); + return message($str, getconstStr('WaitJumpIndex')); } return message('
' . $tmp['body'] . '
', $tmp['stat']); //return message('
' . json_encode($ret, JSON_PRETTY_PRINT) . '
', 500); @@ -75,7 +77,7 @@ function get_refresh_token() if ($_GET['install3']) { if (getConfig('Onedrive_ver')=='MS' || getConfig('Onedrive_ver')=='CN' || getConfig('Onedrive_ver')=='MSC') { return message(' - '.$constStr['JumptoOffice'][$constStr['language']].' + '.getconstStr('JumptoOffice').' - ', $constStr['Wait'][$constStr['language']].' 1s', 201); + ', getconstStr('Wait').' 1s', 201); } } if ($_GET['install2']) { @@ -95,12 +97,12 @@ function get_refresh_token() $tmp['client_secret'] = $_POST['client_secret']; } $response = setConfig($tmp); - $title = $constStr['MayinEnv'][$constStr['language']]; - $html = $constStr['Wait'][$constStr['language']] . ' 3s'; + $title = getconstStr('MayinEnv'); + $html = getconstStr('Wait') . ' 3s'; if (!$response) { $html = $response . '
Can not write config to file.
-'; +'; $title = 'Error'; } return message($html, $title, 201); @@ -112,7 +114,7 @@ Can not write config to file.
$tmp['language'] = $_POST['language']; $response = setConfig($tmp); if ($response) { - if ($constStr['language']!='zh-cn') { + if (getconstStr('language']!='zh-cn') { $linklang='en-us'; } else $linklang='zh-cn'; $ru = "https://developer.microsoft.com/".$linklang."/graph/quick-start?appID=_appId_&appName=_appName_&redirectUrl=".$_SERVER['redirect_uri']."&platform=option-php"; @@ -121,22 +123,22 @@ Can not write config to file.
$html = '
Onedrive_Ver:
-
-
-