forked from reactphp/http
-
Notifications
You must be signed in to change notification settings - Fork 0
/
12-upload.php
138 lines (119 loc) · 4.31 KB
/
12-upload.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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
<?php
// Simple HTML form with file upload
// Launch demo and use your favorite browser or CLI tool to test form submissions
//
// $ php examples/12-upload.php 8080
// $ curl --form name=test --form age=30 http://localhost:8080/
// $ curl --form name=hi --form [email protected] http://localhost:8080/
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UploadedFileInterface;
use React\EventLoop\Factory;
use React\Http\Middleware\LimitConcurrentRequestsMiddleware;
use React\Http\Middleware\RequestBodyBufferMiddleware;
use React\Http\Middleware\RequestBodyParserMiddleware;
use React\Http\Response;
use React\Http\StreamingServer;
require __DIR__ . '/../vendor/autoload.php';
$loop = Factory::create();
$handler = function (ServerRequestInterface $request) {
if ($request->getMethod() === 'POST') {
// Take form input values from POST values (for illustration purposes only!)
// Does not actually validate data here
$body = $request->getParsedBody();
$name = isset($body['name']) && is_string($body['name']) ? htmlspecialchars($body['name']) : 'n/a';
$age = isset($body['age']) && is_string($body['age']) ? (int)$body['age'] : 'n/a';
// Show uploaded avatar as image (for illustration purposes only!)
// Real applications should validate the file data to ensure this is
// actually an image and not rely on the client media type.
$avatar = 'n/a';
$uploads = $request->getUploadedFiles();
if (isset($uploads['avatar']) && $uploads['avatar'] instanceof UploadedFileInterface) {
/* @var $file UploadedFileInterface */
$file = $uploads['avatar'];
if ($file->getError() === UPLOAD_ERR_OK) {
// Note that moveFile() is not available due to its blocking nature.
// You can use your favorite data store to simply dump the file
// contents via `(string)$file->getStream()` instead.
// Here, we simply use an inline image to send back to client:
$avatar = '<img src="data:'. $file->getClientMediaType() . ';base64,' . base64_encode($file->getStream()) . '" /> (' . $file->getSize() . ' bytes)';
} elseif ($file->getError() === UPLOAD_ERR_INI_SIZE) {
$avatar = 'upload exceeds file size limit';
} else {
// Real applications should probably check the error number and
// should print some human-friendly text
$avatar = 'upload error ' . $file->getError();
}
}
$dump = htmlspecialchars(
var_export($request->getParsedBody(), true) .
PHP_EOL .
var_export($request->getUploadedFiles(), true)
);
$body = <<<BODY
Name: $name
Age: $age
Avatar $avatar
<pre>
$dump
</pre>
BODY;
} else {
$body = <<<BODY
<form method="POST" enctype="multipart/form-data">
<label>
Your name
<input type="text" name="name" required />
</label>
<label>
Your age
<input type="number" name="age" min="9" max="99" required />
</label>
<label>
Upload avatar (optional, 100KB max)
<input type="file" name="avatar" />
</label>
<button type="submit">
» Submit
</button>
</form>
BODY;
}
$html = <<<HTML
<!DOCTYPE html>
<html>
<head>
<style>
body{
background-color: #eee;
color: #aaa;
}
label{
display: block;
margin-bottom: .5em;
}
</style>
<body>
$body
</body>
</html>
HTML;
return new Response(
200,
array(
'Content-Type' => 'text/html; charset=UTF-8'
),
$html
);
};
// Note how this example explicitly uses the advanced `StreamingServer` to apply
// custom request buffering limits below before running our request handler.
$server = new StreamingServer(array(
new LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers, queue otherwise
new RequestBodyBufferMiddleware(8 * 1024 * 1024), // 8 MiB max, ignore body otherwise
new RequestBodyParserMiddleware(100 * 1024, 1), // 1 file with 100 KiB max, reject upload otherwise
$handler
));
$socket = new \React\Socket\Server(isset($argv[1]) ? $argv[1] : '0.0.0.0:0', $loop);
$server->listen($socket);
echo 'Listening on ' . str_replace('tcp:', 'http:', $socket->getAddress()) . PHP_EOL;
$loop->run();