Skip to content

Commit

Permalink
Push the first release candidate.
Browse files Browse the repository at this point in the history
  • Loading branch information
Zegnat committed Nov 3, 2015
1 parent e0cee17 commit c3ea2cd
Show file tree
Hide file tree
Showing 3 changed files with 173 additions and 2 deletions.
35 changes: 33 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,33 @@
# server-php
PhotoBackup server implementation in PHP
# PhotoBackup PHP server

A minimal PhotoBackup API endpoint developed in PHP.

## Goals

1. **Easy to run.** Minimal configuration and the widest possible server
compatibility make this PhotoBackup implementation a great starting point!

2. **Easy to review.** All the code is extensively described through [PSR-5][]
DocComments and should be easy to read along.

[PSR-5]: https://github.com/phpDocumentor/fig-standards/tree/master/proposed

## Setting up

1. Download the latest release from GitHub:

https://github.com/PhotoBackup/server-php/releases/latest

2. Open `index.php` and change the value of `$Password` to the password you want
to use for PhotoBackup.

3. Upload `index.php` and the `photos` folder to your web host.

4. Configure the server address in your PhotoBackup client to match the URL for
your `index.php`-file. E.g. `http://example.com/photobackup/index.php`.

## License

The PhotoBackup PHP server is licensed under the OSI version of the MIT license.
It lets you do anything with the code as long as proper attribution is given.
Please see LICENSE.
139 changes: 139 additions & 0 deletions index.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
<?php
/**
* A minimal PhotoBackup API endpoint developed in PHP.
*
* @version 1.0.0-rc.1
* @author Martijn van der Ven <[email protected]>
* @copyright 2015 Martijn van der Ven
* @license http://opensource.org/licenses/MIT The MIT License
*/

/**
* The password required to upload to this server.
*
* The password is currently stored as clear text here. PHP code is not normally
* readable by third-parties so this should be safe enough. Many applications
* store database credentials in this way as well. A secondary and safer way is
* being considered for the next version.
*
* @global string $Password A string (encapsulated by quotes).
*/
$Password = 'example';

/**
* The directory where files should be uploaded to.
*
* This directory path is relative to this index.php file and should not end
* with a /. It should point to an existing directory on the server.
*
* @global string $MediaRoot A string (encapsulated by quotes).
*/
$MediaRoot = 'photos';

// -----------------------------------------------------------------------------
// NO CONFIGURATION NECCESSARY BEYOND THIS POINT.
// -----------------------------------------------------------------------------

/**
* Establish what HTTP version is being used by the server.
*/
if (isset($_SERVER['SERVER_PROTOCOL'])) {
$protocol = $_SERVER['SERVER_PROTOCOL'];
} else {
$protocol = 'HTTP/1.0';
}

/**
* Find out if the client is requesting the test page.
*/
$request = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$testing = substr($request, -5) === '/test';

/**
* If no data has been POSTed to the server and the client did not request the
* test page, exit imidiately.
*/
if (empty($_POST) && !$testing) {
exit();
}

/**
* If the client did not submit a password, or the submitted password did not
* match this server's password, exit with HTTP code 403.
*/
if (
!isset($_POST['password']) ||
$_POST['password'] !== hash('sha512', $Password)
) {
header($protocol . ' 403 Forbidden');
exit();
}

/**
* If the upload destination folder does not exist or is not writable by PHP,
* exit with HTTP code 500.
*/
if (
!file_exists($MediaRoot) ||
!is_dir($MediaRoot) ||
!is_writable($MediaRoot)
) {
header($protocol . ' 500 Internal Server Error');
exit();
}

/**
* If we were only supposed to test the server, end here.
*/
if ($testing) {
exit();
}

/**
* If the client did not submit a filesize, exit with HTTP code 400.
*/
if (!isset($_POST['filesize'])) {
header($protocol . ' 400 Bad Request');
exit();
}

/**
* If the client did not upload a file, or something went wrong in the upload
* process, exit with HTTP code 401.
*/
if (
!isset($_FILES['upfile']) ||
$_FILES['upfile']['error'] !== UPLOAD_ERR_OK ||
!is_uploaded_file($_FILES['upfile']['tmp_name'])
) {
header($protocol . ' 401 Unauthorized');
exit();
}

/**
* If the client submitted filesize did not match the uploaded file's size, exit
* with HTTP code 411.
*/
if (intval($_POST['filesize']) !== $_FILES['upfile']['size']) {
header($protocol . ' 411 Length Required');
exit();
}

/**
* Sanitize the file name to maximise server operating system compatibility and
* minimize possible attacks against this implementation.
*/
$filename = preg_replace('@\s+@', '-', $_FILES['upfile']['name']);
$filename = preg_replace('@[^0-9a-z._-]@i', '', $filename);
$target = $MediaRoot . '/' . $filename;

/**
* Move the uploaded file into the target directory. If anything did not work,
* exit with HTTP code 500.
*/
if (!move_uploaded_file($_FILES["upfile"]["tmp_name"], $target)) {
header($protocol . ' 500 Internal Server Error');
exit();
}

exit();
1 change: 1 addition & 0 deletions photos/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<!DOCTYPE html>

0 comments on commit c3ea2cd

Please sign in to comment.