msd Backup hinzugefügt
This commit is contained in:
11
msd/vendor/visualappeal/php-auto-update/.editorconfig
vendored
Normal file
11
msd/vendor/visualappeal/php-auto-update/.editorconfig
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
charset = utf-8
|
||||
end_of_line = lf
|
||||
indent_size = 4
|
||||
indent_style = space
|
||||
insert_final_newline = true
|
||||
max_line_length = 120
|
||||
tab_width = 4
|
||||
trim_trailing_whitespace = true
|
39
msd/vendor/visualappeal/php-auto-update/.github/workflows/phpunit.yml
vendored
Normal file
39
msd/vendor/visualappeal/php-auto-update/.github/workflows/phpunit.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
name: PHPUnit
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ master ]
|
||||
pull_request:
|
||||
branches: [ master ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
php-versions: ['7.3', '7.4', '8.0', '8.1']
|
||||
|
||||
name: PHPUnit ${{ matrix.php-versions }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
- name: Validate composer.json and composer.lock
|
||||
run: composer validate
|
||||
|
||||
- name: Cache Composer packages
|
||||
id: composer-cache
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: vendor
|
||||
key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-php-
|
||||
|
||||
- name: Install dependencies
|
||||
if: steps.composer-cache.outputs.cache-hit != 'true'
|
||||
run: composer install --prefer-dist --no-progress --no-suggest
|
||||
|
||||
- name: Run test suite
|
||||
run: composer run-script test
|
5
msd/vendor/visualappeal/php-auto-update/.gitignore
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
/example/update/temp/*
|
||||
/vendor/
|
||||
|
||||
*.cache
|
||||
composer.lock
|
12
msd/vendor/visualappeal/php-auto-update/Dockerfile
vendored
Normal file
12
msd/vendor/visualappeal/php-auto-update/Dockerfile
vendored
Normal file
@ -0,0 +1,12 @@
|
||||
FROM php:8.0-apache
|
||||
|
||||
MAINTAINER VisualAppeal <tim@visualappeal.de>
|
||||
|
||||
RUN apt-get update && apt-get install -y libzip-dev libcurl4-openssl-dev
|
||||
RUN docker-php-ext-install -j$(nproc) zip curl
|
||||
|
||||
ADD ./vendor /var/www/html/vendor
|
||||
ADD ./example /var/www/html/example
|
||||
ADD ./src /var/www/html/src
|
||||
|
||||
RUN chown -R www-data:www-data /var/www/html/example
|
7
msd/vendor/visualappeal/php-auto-update/LICENSE.md
vendored
Normal file
7
msd/vendor/visualappeal/php-auto-update/LICENSE.md
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
Copyright 2017 VisualAppeal GbR
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
29
msd/vendor/visualappeal/php-auto-update/README.md
vendored
Normal file
29
msd/vendor/visualappeal/php-auto-update/README.md
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
[](https://github.com/VisualAppeal/PHP-Auto-Update/actions/workflows/phpunit.yml)
|
||||
|
||||
With this library your users can automatically update their instance of your application to the newest version. I created it as a proof of concept and don't know if it is used somewhere. So please use this library with caution because it can potentially make your users software nonfunctional if something goes wrong.
|
||||
|
||||
## Installation
|
||||
|
||||
* Install the library via composer [visualappeal/php-auto-update](https://packagist.org/packages/visualappeal/php-auto-update)
|
||||
* Create an update file/method in your application with your update routine (see `example/client/update/index.php`)
|
||||
* Create a `update.json` or `update.ini` on your server (where the client should get the updates, see `example/server/update.json` or `example/server/update.ini`)
|
||||
|
||||
**Important: Please notice that PHP needs write permissions to update the files on the webserver**
|
||||
|
||||
## Example
|
||||
|
||||
You can start an example docker container via `docker-compose up` and see the example by visiting `http://127.0.0.1:8080/example/client/`
|
||||
|
||||
## Client
|
||||
|
||||
### Caching
|
||||
|
||||
The library supports the `desarrolla2/cache` component, and you should use it! Otherwise, the client will download the update ini/json file on every request.
|
||||
|
||||
## Server
|
||||
|
||||
Your server needs at least one file which will be downloaded from the client to check for updates. This can be a json or an ini file. See `example/server/` for examples. The ini section key respectively the json key is the version. This library uses semantic versioning to compare the versions. See [semver.org](http://semver.org/) for details. The ini/json value is the absolute url to the update zip file. Since the library supports incremental updates, the zip file only need to contain the changes since the last version. The zip files do not need to be placed on the same server, they can be uploaded to S3 or another cloud storage, too.
|
||||
|
||||
## Documentation
|
||||
|
||||
For the documentation see the comments in `src/AutoUpdate.php` or the example in the `example` directory.
|
16
msd/vendor/visualappeal/php-auto-update/SECURITY.md
vendored
Normal file
16
msd/vendor/visualappeal/php-auto-update/SECURITY.md
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# Security Policy
|
||||
|
||||
## Supported Versions
|
||||
|
||||
The following php versions are currently supported:
|
||||
|
||||
| Version | Supported |
|
||||
| ------- | ------------------ |
|
||||
| 7.2 | :white_check_mark: |
|
||||
| 7.3 | :white_check_mark: |
|
||||
| 7.4 | :white_check_mark: |
|
||||
| 8.0 | :white_check_mark: |
|
||||
|
||||
## Reporting a Vulnerability
|
||||
|
||||
If you find a security vulnerability, please write an email to tim@visualappeal.de.
|
37
msd/vendor/visualappeal/php-auto-update/composer.json
vendored
Normal file
37
msd/vendor/visualappeal/php-auto-update/composer.json
vendored
Normal file
@ -0,0 +1,37 @@
|
||||
{
|
||||
"name": "visualappeal/php-auto-update",
|
||||
"description": "Autoupdater for PHP",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Tim Helfensdörfer",
|
||||
"email": "tim@visualappeal.de"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"ext-curl": "*",
|
||||
"ext-zip": "*",
|
||||
"php": ">=7.2.0",
|
||||
"desarrolla2/cache": "^3.0",
|
||||
"monolog/monolog": "^2.1",
|
||||
"composer/semver": "^3.0",
|
||||
"psr/log": "1.1.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"roave/security-advisories": "dev-master",
|
||||
"phpunit/phpunit": "^9.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"VisualAppeal\\": "src/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test": "phpunit -c tests/UnitTests.xml"
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
}
|
||||
}
|
7
msd/vendor/visualappeal/php-auto-update/docker-compose.yaml
vendored
Normal file
7
msd/vendor/visualappeal/php-auto-update/docker-compose.yaml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
version: '3'
|
||||
|
||||
services:
|
||||
app:
|
||||
build: .
|
||||
ports:
|
||||
- 8080:80
|
1
msd/vendor/visualappeal/php-auto-update/example/client/files/file1.php
vendored
Normal file
1
msd/vendor/visualappeal/php-auto-update/example/client/files/file1.php
vendored
Normal file
@ -0,0 +1 @@
|
||||
This is file 1. Version 0.1.0
|
1
msd/vendor/visualappeal/php-auto-update/example/client/files/file2.php
vendored
Normal file
1
msd/vendor/visualappeal/php-auto-update/example/client/files/file2.php
vendored
Normal file
@ -0,0 +1 @@
|
||||
This is file 2. Version 0.1.0
|
19
msd/vendor/visualappeal/php-auto-update/example/client/index.php
vendored
Normal file
19
msd/vendor/visualappeal/php-auto-update/example/client/index.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>PHP Auto Update</title>
|
||||
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div class="container mt-4">
|
||||
<p>This is the test index.</p>
|
||||
|
||||
<p><a class="btn btn-primary" href="/example/client/update/index.php">Update now!</a></p>
|
||||
|
||||
<p>Contents of <code>somefile.php</code>:</p>
|
||||
<pre><code><?php require(__DIR__ . '/somefile.php'); ?></code></pre>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
1
msd/vendor/visualappeal/php-auto-update/example/client/somefile.php
vendored
Normal file
1
msd/vendor/visualappeal/php-auto-update/example/client/somefile.php
vendored
Normal file
@ -0,0 +1 @@
|
||||
This is some file. Version 0.1.0
|
2
msd/vendor/visualappeal/php-auto-update/example/client/update/.gitignore
vendored
Normal file
2
msd/vendor/visualappeal/php-auto-update/example/client/update/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
!.gitignore
|
||||
update.log
|
1019
msd/vendor/visualappeal/php-auto-update/src/AutoUpdate.php
vendored
Normal file
1019
msd/vendor/visualappeal/php-auto-update/src/AutoUpdate.php
vendored
Normal file
File diff suppressed because it is too large
Load Diff
5
msd/vendor/visualappeal/php-auto-update/src/Exceptions/DownloadException.php
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/src/Exceptions/DownloadException.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php namespace VisualAppeal\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class DownloadException extends Exception {}
|
5
msd/vendor/visualappeal/php-auto-update/src/Exceptions/ParserException.php
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/src/Exceptions/ParserException.php
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
<?php namespace VisualAppeal\Exceptions;
|
||||
|
||||
use Exception;
|
||||
|
||||
class ParserException extends Exception {}
|
181
msd/vendor/visualappeal/php-auto-update/tests/AutoUpdateTest.php
vendored
Normal file
181
msd/vendor/visualappeal/php-auto-update/tests/AutoUpdateTest.php
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
|
||||
require(__DIR__ . '/../vendor/autoload.php');
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
use VisualAppeal\AutoUpdate;
|
||||
use VisualAppeal\Exceptions\DownloadException;
|
||||
use VisualAppeal\Exceptions\ParserException;
|
||||
|
||||
class AutoUpdateTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* AutoUpdate instance.
|
||||
*
|
||||
* @var AutoUpdate
|
||||
*/
|
||||
private $_update;
|
||||
|
||||
/**
|
||||
* Setup the auto update.
|
||||
*/
|
||||
protected function setUp(): void
|
||||
{
|
||||
$this->_update = new AutoUpdate(__DIR__ . DIRECTORY_SEPARATOR . 'temp', __DIR__ . DIRECTORY_SEPARATOR . 'install');
|
||||
$this->_update->setCurrentVersion('0.1.0');
|
||||
$this->_update->setUpdateUrl(__DIR__ . DIRECTORY_SEPARATOR . 'fixtures');
|
||||
$logger = new Monolog\Logger("default");
|
||||
$logger->pushHandler(new Monolog\Handler\StreamHandler(__DIR__ . DIRECTORY_SEPARATOR . 'temp' . DIRECTORY_SEPARATOR . 'update.log'));
|
||||
$this->_update->setLogger($logger);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unset the auto update.
|
||||
*/
|
||||
protected function tearDown(): void
|
||||
{
|
||||
unset($this->_update);
|
||||
$this->_update = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test creation of class instance.
|
||||
*/
|
||||
public function testInit(): void
|
||||
{
|
||||
self::assertInstanceOf(AutoUpdate::class, $this->_update);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if errors get catched if no update file was found.
|
||||
*
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testErrorUpdateCheck(): void
|
||||
{
|
||||
$this->expectException(DownloadException::class);
|
||||
|
||||
$this->_update->setUpdateFile('404.json');
|
||||
$this->_update->checkUpdate();
|
||||
|
||||
self::assertFalse($this->_update->newVersionAvailable());
|
||||
self::assertCount(0, $this->_update->getVersionsToUpdate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if new update is available with a json file.
|
||||
*
|
||||
* @throws DownloadException
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testJsonNewVersion(): void
|
||||
{
|
||||
$this->_update->setUpdateFile('updateAvailable.json');
|
||||
$response = $this->_update->checkUpdate();
|
||||
|
||||
self::assertTrue($response);
|
||||
self::assertTrue($this->_update->newVersionAvailable());
|
||||
self::assertEquals('0.2.1', $this->_update->getLatestVersion());
|
||||
|
||||
$newVersions = $this->_update->getVersionsToUpdate();
|
||||
self::assertCount(2, $newVersions);
|
||||
self::assertEquals('0.2.0', $newVersions[0]);
|
||||
self::assertEquals('0.2.1', $newVersions[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if NO new update is available with a json file.
|
||||
*
|
||||
* @throws DownloadException
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testJsonNoNewVersion(): void
|
||||
{
|
||||
$this->_update->setUpdateFile('noUpdateAvailable.json');
|
||||
$response = $this->_update->checkUpdate();
|
||||
|
||||
self::assertEquals(AutoUpdate::NO_UPDATE_AVAILABLE, $response);
|
||||
self::assertFalse($this->_update->newVersionAvailable());
|
||||
self::assertCount(0, $this->_update->getVersionsToUpdate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if new update is available with a ini file.
|
||||
*
|
||||
* @throws DownloadException
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testIniNewVersion(): void
|
||||
{
|
||||
$this->_update->setUpdateFile('updateAvailable.ini');
|
||||
$response = $this->_update->checkUpdate();
|
||||
|
||||
self::assertTrue($response);
|
||||
self::assertTrue($this->_update->newVersionAvailable());
|
||||
self::assertEquals('0.2.1', $this->_update->getLatestVersion());
|
||||
|
||||
$newVersions = $this->_update->getVersionsToUpdate();
|
||||
self::assertCount(2, $newVersions);
|
||||
self::assertEquals('0.2.0', $newVersions[0]);
|
||||
self::assertEquals('0.2.1', $newVersions[1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if NO new update is available with a ini file.
|
||||
*
|
||||
* @throws DownloadException
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testIniNoNewVersion(): void
|
||||
{
|
||||
$this->_update->setUpdateFile('noUpdateAvailable.ini');
|
||||
$response = $this->_update->checkUpdate();
|
||||
|
||||
self::assertEquals(AutoUpdate::NO_UPDATE_AVAILABLE, $response);
|
||||
self::assertFalse($this->_update->newVersionAvailable());
|
||||
self::assertCount(0, $this->_update->getVersionsToUpdate());
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that a new dev version is available.
|
||||
*
|
||||
* @throws DownloadException
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testBranchDev(): void
|
||||
{
|
||||
$this->_update->setUpdateFile('updateAvailable.json');
|
||||
$this->_update->setBranch('dev');
|
||||
$response = $this->_update->checkUpdate();
|
||||
|
||||
self::assertTrue($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that no new master version is available
|
||||
*
|
||||
* @throws DownloadException
|
||||
* @throws ParserException|\Psr\SimpleCache\InvalidArgumentException
|
||||
*/
|
||||
public function testBranchMaster(): void
|
||||
{
|
||||
$this->_update->setUpdateFile('noUpdateAvailable.json');
|
||||
$this->_update->setBranch('master');
|
||||
$response = $this->_update->checkUpdate();
|
||||
|
||||
self::assertEquals(AutoUpdate::NO_UPDATE_AVAILABLE, $response);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the trailing slash method.
|
||||
*/
|
||||
public function testTrailingSlashes(): void
|
||||
{
|
||||
$dir = DIRECTORY_SEPARATOR . 'test';
|
||||
self::assertEquals(DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR, $this->_update->addTrailingSlash($dir));
|
||||
|
||||
$dir = DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR;
|
||||
self::assertEquals(DIRECTORY_SEPARATOR . 'test' . DIRECTORY_SEPARATOR, $this->_update->addTrailingSlash($dir));
|
||||
}
|
||||
}
|
7
msd/vendor/visualappeal/php-auto-update/tests/UnitTests.xml
vendored
Normal file
7
msd/vendor/visualappeal/php-auto-update/tests/UnitTests.xml
vendored
Normal file
@ -0,0 +1,7 @@
|
||||
<phpunit>
|
||||
<testsuites>
|
||||
<testsuite name="unit">
|
||||
<directory>./</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
</phpunit>
|
8
msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.ini
vendored
Normal file
8
msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.ini
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
[0.1.0]
|
||||
url = http://127.0.0.1:80/example/server/0.1.0.zip
|
||||
|
||||
[0.0.1]
|
||||
url = http://127.0.0.1:80/example/server/0.0.1.zip
|
||||
|
||||
[0.0.4]
|
||||
url = http://127.0.0.1:80/example/server/0.0.4.zip
|
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
|
||||
"0.0.1": "http://127.0.0.1:80/example/server/0.0.1.zip",
|
||||
"0.0.4": "http://127.0.0.1:80/example/server/0.0.4.zip"
|
||||
}
|
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json.master
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/noUpdateAvailable.json.master
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
|
||||
"0.0.1": "http://127.0.0.1:80/example/server/0.0.1.zip",
|
||||
"0.0.4": "http://127.0.0.1:80/example/server/0.0.4.zip"
|
||||
}
|
8
msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.ini
vendored
Normal file
8
msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.ini
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
[0.1.0]
|
||||
url = http://127.0.0.1:80/example/server/0.1.0.zip
|
||||
|
||||
[0.2.0]
|
||||
url = http://127.0.0.1:80/example/server/0.2.0.zip
|
||||
|
||||
[0.2.1]
|
||||
url = http://127.0.0.1:80/example/server/0.2.1.zip
|
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
|
||||
"0.2.0": "http://127.0.0.1:80/example/server/0.2.0.zip",
|
||||
"0.2.1": "http://127.0.0.1:80/example/server/0.2.1.zip"
|
||||
}
|
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json.dev
vendored
Normal file
5
msd/vendor/visualappeal/php-auto-update/tests/fixtures/updateAvailable.json.dev
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
{
|
||||
"0.1.0": "http://127.0.0.1:80/example/server/0.1.0.zip",
|
||||
"0.2.0": "http://127.0.0.1:80/example/server/0.2.0.zip",
|
||||
"0.2.1": "http://127.0.0.1:80/example/server/0.2.1.zip"
|
||||
}
|
Reference in New Issue
Block a user