92 lines
5.9 KiB
XML
92 lines
5.9 KiB
XML
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1600 900" role="img" aria-labelledby="title desc">
|
||
<title id="title">Контракт безопасной загрузки аватара</title>
|
||
<desc id="desc">Схема из четырёх шагов: браузер, временный файл PHP, проверка, закрытое хранилище.</desc>
|
||
<defs>
|
||
<linearGradient id="background" x1="0" y1="0" x2="1" y2="1">
|
||
<stop offset="0" stop-color="#f6f8fc"/>
|
||
<stop offset="1" stop-color="#eef4f3"/>
|
||
</linearGradient>
|
||
<filter id="shadow" x="-20%" y="-20%" width="140%" height="140%">
|
||
<feDropShadow dx="0" dy="14" stdDeviation="18" flood-color="#123049" flood-opacity=".12"/>
|
||
</filter>
|
||
<marker id="arrow" viewBox="0 0 12 12" refX="11" refY="6" markerWidth="10" markerHeight="10" orient="auto">
|
||
<path d="M 0 1 L 11 6 L 0 11 z" fill="#6b7d8d"/>
|
||
</marker>
|
||
<style>
|
||
.title { font: 700 44px Inter, Arial, sans-serif; fill: #17324a; }
|
||
.subtitle { font: 400 23px Inter, Arial, sans-serif; fill: #597080; }
|
||
.step { font: 700 18px Inter, Arial, sans-serif; fill: #75909f; letter-spacing: 1.8px; }
|
||
.card-title { font: 700 28px Inter, Arial, sans-serif; fill: #17324a; }
|
||
.card-text { font: 400 20px Inter, Arial, sans-serif; fill: #466174; }
|
||
.code { font: 600 18px Menlo, Consolas, monospace; fill: #1f6672; }
|
||
.badge { font: 700 16px Inter, Arial, sans-serif; fill: #2e5267; }
|
||
.note { font: 600 18px Inter, Arial, sans-serif; fill: #36536a; }
|
||
</style>
|
||
</defs>
|
||
<rect width="1600" height="900" fill="url(#background)"/>
|
||
<path d="M0 684 C260 613 404 779 643 692 S1139 590 1600 717 V900 H0Z" fill="#e4f0ef"/>
|
||
<text x="106" y="116" class="title">Загрузка аватара: решение принимается до переноса</text>
|
||
<text x="106" y="158" class="subtitle">Клиент присылает файл. Приложение выбирает допустимый тип, размеры и собственный ключ.</text>
|
||
|
||
<line x1="390" y1="435" x2="481" y2="435" stroke="#6b7d8d" stroke-width="7" stroke-linecap="round" marker-end="url(#arrow)"/>
|
||
<line x1="765" y1="435" x2="856" y2="435" stroke="#6b7d8d" stroke-width="7" stroke-linecap="round" marker-end="url(#arrow)"/>
|
||
<line x1="1140" y1="435" x2="1231" y2="435" stroke="#6b7d8d" stroke-width="7" stroke-linecap="round" marker-end="url(#arrow)"/>
|
||
|
||
<g filter="url(#shadow)">
|
||
<rect x="106" y="286" width="284" height="302" rx="24" fill="#ffffff"/>
|
||
<rect x="106" y="286" width="284" height="12" rx="6" fill="#ea8847"/>
|
||
<circle cx="154" cy="344" r="25" fill="#fce3d1"/>
|
||
<text x="146" y="351" class="badge" fill="#c8692b">1</text>
|
||
<text x="194" y="351" class="step">КЛИЕНТ</text>
|
||
<text x="142" y="412" class="card-title">Форма</text>
|
||
<text x="142" y="452" class="code">name=avatar</text>
|
||
<text x="142" y="496" class="card-text">имя и Content-Type</text>
|
||
<text x="142" y="526" class="card-text">остаются входом,</text>
|
||
<text x="142" y="556" class="card-text">а не решением.</text>
|
||
</g>
|
||
|
||
<g filter="url(#shadow)">
|
||
<rect x="481" y="286" width="284" height="302" rx="24" fill="#ffffff"/>
|
||
<rect x="481" y="286" width="284" height="12" rx="6" fill="#6994c6"/>
|
||
<circle cx="529" cy="344" r="25" fill="#dceafa"/>
|
||
<text x="521" y="351" class="badge" fill="#4374af">2</text>
|
||
<text x="569" y="351" class="step">PHP</text>
|
||
<text x="517" y="412" class="card-title">Временный файл</text>
|
||
<text x="517" y="452" class="code">$_FILES</text>
|
||
<text x="517" y="496" class="card-text">error · size · tmp_name</text>
|
||
<text x="517" y="526" class="card-text">Сначала убеждаемся,</text>
|
||
<text x="517" y="556" class="card-text">что доставка завершилась.</text>
|
||
</g>
|
||
|
||
<g filter="url(#shadow)">
|
||
<rect x="856" y="286" width="284" height="302" rx="24" fill="#ffffff"/>
|
||
<rect x="856" y="286" width="284" height="12" rx="6" fill="#4eaa93"/>
|
||
<circle cx="904" cy="344" r="25" fill="#d6f1e8"/>
|
||
<text x="896" y="351" class="badge" fill="#27846e">3</text>
|
||
<text x="944" y="351" class="step">ПРОВЕРКА</text>
|
||
<text x="892" y="412" class="card-title">Контракт</text>
|
||
<text x="892" y="452" class="code">finfo_file()</text>
|
||
<text x="892" y="496" class="card-text">JPEG / PNG · 2 МБ</text>
|
||
<text x="892" y="526" class="card-text">размеры изображения</text>
|
||
<text x="892" y="556" class="card-text">и белый список.</text>
|
||
</g>
|
||
|
||
<g filter="url(#shadow)">
|
||
<rect x="1231" y="286" width="284" height="302" rx="24" fill="#ffffff"/>
|
||
<rect x="1231" y="286" width="284" height="12" rx="6" fill="#5d7f90"/>
|
||
<circle cx="1279" cy="344" r="25" fill="#dce8ed"/>
|
||
<text x="1271" y="351" class="badge" fill="#39586b">4</text>
|
||
<text x="1319" y="351" class="step">ХРАНИЛИЩЕ</text>
|
||
<text x="1267" y="412" class="card-title">Закрытый каталог</text>
|
||
<text x="1267" y="452" class="code">7f4a...c2.png</text>
|
||
<text x="1267" y="496" class="card-text">свой ключ приложения,</text>
|
||
<text x="1267" y="526" class="card-text">никакого пути из</text>
|
||
<text x="1267" y="556" class="card-text">исходного имени.</text>
|
||
</g>
|
||
|
||
<rect x="106" y="688" width="1409" height="88" rx="20" fill="#ffffff" stroke="#c9dcda" stroke-width="2"/>
|
||
<circle cx="158" cy="732" r="18" fill="#4eaa93"/>
|
||
<path d="M149 732 l7 7 l13 -16" fill="none" stroke="#ffffff" stroke-width="5" stroke-linecap="round" stroke-linejoin="round"/>
|
||
<text x="202" y="740" class="note">Перенос происходит только после проверки: из браузера в каталог попадает не «файл с именем», а запись, соответствующая контракту.</text>
|
||
</svg>
|