<?php
require_once("common.php");
if ($_SERVER["REQUEST_METHOD"] !== "POST")
{
	header("Content-Type: text/html; charset=UTF-8");
	croak("<h1>water you doing");
}

//
// check that we have all required headers

$wark = '';
if (isset($_SERVER['HTTP_X_UP2K_WARK']))
	$wark = $_SERVER['HTTP_X_UP2K_WARK'];

$hash = '';
if (isset($_SERVER['HTTP_X_UP2K_HASH']))
	$hash = $_SERVER['HTTP_X_UP2K_HASH'];

if (strlen($hash) != 43 || strlen($wark) != 32)
	croak("missing or invalid headers");

if (sanitize_hash($wark) !== $wark ||
	sanitize_hash($hash) !== $hash)
	croak('naw');

//
// check against stored hist

$path = "hist/{$wark}.1";
if (!file_exists($path))
	croak("could not load wark {$wark}");

$sd = json_decode(file_get_contents($path), true);

if (!in_array($hash, $sd['hash']))
	croak("invalid hash {$hash} for wark {$wark}");

//
// check if we have the chunk already

@mkdir("part/{$wark}", 0711);
$part = "part/{$wark}/{$hash}";
if (file_exists("{$part}.ok"))
{
	error_log('i already have that part');
	exit(0);
}

//
// copy chunk in

$ifh = fopen("php://input", 'rb');
if (FALSE === $ifh)
	throw new Exception(
		"failed to open php stdin for wark {$wark} / fsum {$fsum}");

$ofh = fopen($part, 'wb');
if (FALSE === $ofh)
	throw new Exception(
		"failed to open output file for wark {$wark} / fsum {$fsum}: [{$part}]");

while (!feof($ifh))
{
	$buf = fread($ifh, 8192);
	$nwrite = fwrite($ofh, $buf);
	
	if ($nwrite !== strlen($buf))
		throw new Exception(
			"failed to stream chunk for wark {$wark} / fsum {$fsum} [{$part}]; " .
			"wrote {$nwrite} bytes, expected " . strlen($buf));
}
fclose($ofh);
fclose($ifh);

//
// verify hash and create .ok flag

$local = rtrim(strtr(base64_encode(hash_file(
	'sha256', $part, true)), "+/", "-_"), '=');

if ($local !== $hash)
	croak("your hash {$hash} does not match server hash {$local}");

file_put_contents("${part}.ok", "xD");

