|
| 1 | +Hermitage |
| 2 | +========= |
| 3 | + |
| 4 | +How often do you have to store images, uploaded by users? |
| 5 | +Rather, very often. |
| 6 | +Give these images mobile applications are not so simple, because there are many devices with different parameters. |
| 7 | +What to do? Help comes from Hermitage. |
| 8 | + |
| 9 | +Hermitage is a micro-service based on Slim that provides storage, |
| 10 | +delivery and modification of your images for the desired clients and devices. Hermitage can: |
| 11 | +* Take and give the image through the simple REST API |
| 12 | +* Use as a repository local file system, or Amazon S3. If this is not enough, you can easily write your own adapter |
| 13 | +* Give the image in one of a few preset formats. Add your own - a matter of seconds! |
| 14 | + |
| 15 | +And all this is out of the box. Amazing! In addition, hermitage is very easy and simple to use. |
| 16 | +This document will be enough to understand. So, let's begin! |
| 17 | + |
| 18 | + |
| 19 | +# Installation |
| 20 | + |
| 21 | +Initially, you need to install composer lib and after that to add a config file, |
| 22 | +set environment and create index file for your web-server. |
| 23 | +You need to do it manually, or you may use pre-setted skeleton |
| 24 | +([Hermitage Skeleton](https://github.com/LiveTyping/hermitage-skeleton)) and skip this section. |
| 25 | + |
| 26 | +Run the [Composer](https://getcomposer.org) command to install: |
| 27 | + |
| 28 | +```bash |
| 29 | +composer require livetyping/hermitage ~0.1 |
| 30 | +``` |
| 31 | + |
| 32 | +### Config file |
| 33 | + |
| 34 | +You may put your config in `config/main.php` or so. |
| 35 | + |
| 36 | +```php |
| 37 | +return [ |
| 38 | + 'root-dir' => dirname(__DIR__), |
| 39 | + 'storage-dir' => dirname(__DIR__) . '/storage', |
| 40 | + |
| 41 | + // your versions |
| 42 | + 'images.versions' => [ |
| 43 | + /** |
| 44 | + * '{version-name}' => [ |
| 45 | + * 'type' => '{manipulator-name}', |
| 46 | + * // manipulator options |
| 47 | + * ], |
| 48 | + */ |
| 49 | + 'mini' => [ |
| 50 | + 'type' => 'resize', |
| 51 | + 'height' => 200, |
| 52 | + 'width' => 200, |
| 53 | + ], |
| 54 | + 'small' => [ |
| 55 | + 'type' => 'resize', |
| 56 | + 'height' => 400, |
| 57 | + 'width' => 400, |
| 58 | + ], |
| 59 | + 'thumb' => [ |
| 60 | + 'type' => 'fit', |
| 61 | + 'height' => 100, |
| 62 | + 'width' => 100, |
| 63 | + ], |
| 64 | + ], |
| 65 | + |
| 66 | + // parameters for optimization an original image |
| 67 | + 'images.optimization-params' => ['maxHeight' => 800, 'maxWidth' => 800, 'interlace' => true], |
| 68 | + 'images.manipulator-map' => [ |
| 69 | + 'resize' => \livetyping\hermitage\foundation\images\processor\manipulators\Resize::class, |
| 70 | + 'fit' => \livetyping\hermitage\foundation\images\processor\manipulators\Fit::class, |
| 71 | + ], |
| 72 | + 'images.manager-config' => ['driver' => 'gd'], |
| 73 | + |
| 74 | + // slim framework settings |
| 75 | + 'settings.httpVersion' => '1.1', |
| 76 | + 'settings.responseChunkSize' => 4096, |
| 77 | + 'settings.displayErrorDetails' => false, |
| 78 | +]; |
| 79 | +``` |
| 80 | + |
| 81 | +### Environment variables |
| 82 | + |
| 83 | +Copy the `.env.example` file to the local `.env` and configure it: |
| 84 | + |
| 85 | +```bash |
| 86 | +cp vendor/livetyping/hermitage/.env.example .env |
| 87 | +``` |
| 88 | + |
| 89 | +The local `.env` file looks like this: |
| 90 | + |
| 91 | +``` |
| 92 | +AUTH_SECRET=changeme |
| 93 | +
|
| 94 | +### |
| 95 | +# Adapter |
| 96 | +## |
| 97 | +STORAGE_ADAPTER=local |
| 98 | +
|
| 99 | +# AWS S3 |
| 100 | +#STORAGE_ADAPTER=s3 |
| 101 | +#STORAGE_S3_REGION= |
| 102 | +#STORAGE_S3_BUCKET= |
| 103 | +#STORAGE_S3_KEY= |
| 104 | +#STORAGE_S3_SECRET= |
| 105 | +``` |
| 106 | + |
| 107 | +***NOTE:*** Set `AUTH_SECRET` to some random string. |
| 108 | + |
| 109 | +### Index file |
| 110 | + |
| 111 | +You may put it in `public/index.php` or so. |
| 112 | + |
| 113 | +```php |
| 114 | +require __DIR__ . '/../vendor/autoload.php'; |
| 115 | + |
| 116 | +$sources = new \livetyping\hermitage\app\Sources([ |
| 117 | + // path to your config |
| 118 | + __DIR__ . '/../config/main.php', |
| 119 | +]); |
| 120 | + |
| 121 | +// load environment variables from the `.env` file if it exists |
| 122 | +livetyping\hermitage\bootstrap\load_dotenv(dirname(__DIR__)); |
| 123 | +livetyping\hermitage\bootstrap\app($sources)->run(); |
| 124 | +``` |
| 125 | + |
| 126 | +# REST API |
| 127 | + |
| 128 | +Hermitage provides simple API to upload, download and delete your images. |
| 129 | + |
| 130 | +### Signing write requests |
| 131 | + |
| 132 | +To be able to write to Hermitage the user agent will have to specify two request headers: |
| 133 | +`X-Authenticate-Signature` and `X-Authenticate-Timestamp`. |
| 134 | + |
| 135 | +`X-Authenticate-Signature` is, like the access token, an HMAC (also using SHA-256 and the secret key). |
| 136 | + |
| 137 | +The data for the hash is generated using the following elements: |
| 138 | + |
| 139 | +* HTTP method (POST or DELETE) |
| 140 | +* The URI |
| 141 | +* UTC timestamp (integer only) |
| 142 | + |
| 143 | +These elements are concatenated in the above order with `|` as a delimiter character, |
| 144 | +and a hash is generated using the secret key. |
| 145 | +The following snippet shows how this can be accomplished in PHP when deleting an image: |
| 146 | + |
| 147 | +```php |
| 148 | +$timestamp = (new DateTime('now', new DateTimeZone('UTC')))->getTimestamp(); |
| 149 | +$filename = '<filename>'; |
| 150 | +$secret = '<secret value>'; |
| 151 | +$method = 'DELETE'; |
| 152 | + |
| 153 | +// The URI |
| 154 | +$uri = "http://hermitage/{$filename}"; |
| 155 | + |
| 156 | +// Data for the hash |
| 157 | +$data = implode('|', [$method, $uri, $timestamp]); |
| 158 | + |
| 159 | +// Generate the signature |
| 160 | +$signature = hash_hmac('sha256', $data, $secret); |
| 161 | + |
| 162 | +// Request the uri |
| 163 | +$ch = curl_init(); |
| 164 | +curl_setopt_array($ch, [ |
| 165 | + CURLOPT_URL => $url, |
| 166 | + CURLOPT_CUSTOMREQUEST => $method, |
| 167 | + CURLOPT_HTTPHEADER => [ |
| 168 | + 'X-Authenticate-Timestamp' => $timestamp, |
| 169 | + 'X-Authenticate-Signature' => $signature, |
| 170 | + ], |
| 171 | +]); |
| 172 | +curl_exec($ch); |
| 173 | +curl_close($ch); |
| 174 | +``` |
| 175 | + |
| 176 | +### Upload |
| 177 | + |
| 178 | +```bash |
| 179 | +curl -XPOST http://hermitage --data-binary @<image.jpg> -H "Content-Type: image/jpeg" -H "X-Authenticate-Timestamp: <timestamp>" -H "X-Authenticate-Signature: <signature>" |
| 180 | +``` |
| 181 | + |
| 182 | +results in: |
| 183 | + |
| 184 | +```json |
| 185 | +{ |
| 186 | + "filename": "generated/path/to/file.jpg" |
| 187 | +} |
| 188 | +``` |
| 189 | + |
| 190 | +### Delete |
| 191 | + |
| 192 | +Deleting images from Hermitage is accomplished by requesting the image URIs using `HTTP DELETE`. |
| 193 | + |
| 194 | +```bash |
| 195 | +curl -XDELETE http://hermitage/<filename> -H "X-Authenticate-Timestamp: <timestamp>" -H "X-Authenticate-Signature: <signature>" |
| 196 | +``` |
| 197 | + |
| 198 | +### Get |
| 199 | + |
| 200 | +Getting an original (optimized) version of the image: |
| 201 | + |
| 202 | +```bash |
| 203 | +curl http://hermitage/<filename> |
| 204 | +``` |
| 205 | + |
| 206 | +Getting another version of the image: |
| 207 | + |
| 208 | +```bash |
| 209 | +curl http://hermitage/<filename>:<version> |
| 210 | +``` |
| 211 | + |
| 212 | +where `<version>` is the version name of the image from config file (like "small", "thumb", etc.) |
| 213 | + |
| 214 | +# License |
| 215 | + |
| 216 | +Hermitage is licensed under the MIT license. |
| 217 | + |
| 218 | +See the [LICENSE](LICENSE) file for more information. |
0 commit comments