-
Notifications
You must be signed in to change notification settings - Fork 34
/
MultipartFormData.php
105 lines (86 loc) · 2.46 KB
/
MultipartFormData.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
<?php declare(strict_types=1);
namespace hollodotme\FastCGI\RequestContents;
use hollodotme\FastCGI\Interfaces\ComposesRequestContent;
use InvalidArgumentException;
use function base64_encode;
use function basename;
use function chunk_split;
use function file_exists;
use function file_get_contents;
use function implode;
use function sprintf;
final class MultipartFormData implements ComposesRequestContent
{
private const BOUNDARY_ID = '__X_FASTCGI_CLIENT_BOUNDARY__';
/** @var array<string, string> */
private $formData;
/** @var array<string, string> */
private $files;
/**
* @param array<string, string> $formData
* @param array<string, string> $files
*
* @throws InvalidArgumentException
*/
public function __construct( array $formData, array $files )
{
$this->formData = $formData;
$this->files = [];
foreach ( $files as $name => $filePath )
{
$this->addFile( (string)$name, (string)$filePath );
}
}
/**
* @param string $name
* @param string $filePath
*
* @throws InvalidArgumentException
*/
public function addFile( string $name, string $filePath ) : void
{
if ( !file_exists( $filePath ) )
{
throw new InvalidArgumentException( 'File does not exist: ' . $filePath );
}
$this->files[ $name ] = $filePath;
}
public function getContentType() : string
{
return 'multipart/form-data; boundary=' . self::BOUNDARY_ID;
}
public function getContent() : string
{
$data = [];
foreach ( $this->formData as $key => $value )
{
$data[] = $this->getFormDataContent( $key, $value );
}
foreach ( $this->files as $name => $filePath )
{
$data[] = $this->getFileDataContent( $name, $filePath );
}
$data[] = '--' . self::BOUNDARY_ID . "--\r\n\r\n";
return implode( "\r\n", $data );
}
private function getFormDataContent( string $key, string $value ) : string
{
$data = ['--' . self::BOUNDARY_ID];
$data[] = sprintf( "Content-Disposition: form-data; name=\"%s\"\r\n", $key );
$data[] = $value;
return implode( "\r\n", $data );
}
private function getFileDataContent( string $name, string $filePath ) : string
{
$data = ['--' . self::BOUNDARY_ID];
$data[] = sprintf(
'Content-Disposition: form-data; name="%s"; filename="%s"',
$name,
basename( $filePath )
);
$data[] = 'Content-Type: application/octet-stream';
$data[] = "Content-Transfer-Encoding: base64\r\n";
$data[] = trim( chunk_split( base64_encode( (string)file_get_contents( $filePath ) ) ) );
return implode( "\r\n", $data );
}
}