|
1
|
<?php
|
1
|
<?php
|
|
2
|
use Workerman\Worker;
|
2
|
use Workerman\Worker;
|
|
3
|
use Workerman\Timer;
|
3
|
use Workerman\Timer;
|
|
|
|
4
|
+use Tos\TosClient;
|
|
|
|
5
|
+use Tos\Exception\TosClientException;
|
|
|
|
6
|
+use Tos\Exception\TosServerException;
|
|
|
|
7
|
+use Tos\Model\PutObjectInput;
|
|
4
|
|
8
|
|
|
5
|
require_once __DIR__ . '/vendor/autoload.php';
|
9
|
require_once __DIR__ . '/vendor/autoload.php';
|
|
6
|
|
10
|
|
|
@@ -146,4 +150,101 @@ $ws_worker->onClose = function ($connection) use (&$clients, &$devices) { |
|
@@ -146,4 +150,101 @@ $ws_worker->onClose = function ($connection) use (&$clients, &$devices) { |
|
146
|
}
|
150
|
}
|
|
147
|
};
|
151
|
};
|
|
148
|
|
152
|
|
|
|
|
153
|
+// ---------------------------------------------------------
|
|
|
|
154
|
+// [New] HTTP Server for file uploads and static serving
|
|
|
|
155
|
+// ---------------------------------------------------------
|
|
|
|
156
|
+$http_worker = new Worker("http://0.0.0.0:8889");
|
|
|
|
157
|
+$http_worker->count = 1; // Single process for uploads
|
|
|
|
158
|
+$http_worker->onMessage = function ($connection, $request) {
|
|
|
|
159
|
+ // 1. Static File Serving (Simple implementation)
|
|
|
|
160
|
+ $path = $request->path();
|
|
|
|
161
|
+ if (strpos($path, '/uploads/') === 0) {
|
|
|
|
162
|
+ $file = __DIR__ . $path;
|
|
|
|
163
|
+ if (is_file($file)) {
|
|
|
|
164
|
+ $connection->send(new \Workerman\Protocols\Http\Response(
|
|
|
|
165
|
+ 200,
|
|
|
|
166
|
+ ['Content-Type' => mime_content_type($file)],
|
|
|
|
167
|
+ file_get_contents($file)
|
|
|
|
168
|
+ ));
|
|
|
|
169
|
+ return;
|
|
|
|
170
|
+ }
|
|
|
|
171
|
+ }
|
|
|
|
172
|
+
|
|
|
|
173
|
+ // 2. Upload Handler
|
|
|
|
174
|
+ if ($path === '/upload') {
|
|
|
|
175
|
+ $files = $request->file();
|
|
|
|
176
|
+
|
|
|
|
177
|
+ if (empty($files['file'])) {
|
|
|
|
178
|
+ $connection->send(new \Workerman\Protocols\Http\Response(400, [], json_encode(['ok' => false, 'error' => 'No file'])));
|
|
|
|
179
|
+ return;
|
|
|
|
180
|
+ }
|
|
|
|
181
|
+
|
|
|
|
182
|
+ $file = $files['file'];
|
|
|
|
183
|
+
|
|
|
|
184
|
+ // Validate Size (50MB)
|
|
|
|
185
|
+ if ($file['size'] > 50 * 1024 * 1024) {
|
|
|
|
186
|
+ $connection->send(new \Workerman\Protocols\Http\Response(400, [], json_encode(['ok' => false, 'error' => 'File too large (Max 50MB)'])));
|
|
|
|
187
|
+ return;
|
|
|
|
188
|
+ }
|
|
|
|
189
|
+
|
|
|
|
190
|
+ // Validate Extension
|
|
|
|
191
|
+ $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
|
|
|
|
192
|
+ // Supported: PDF, Excel, Image, Video
|
|
|
|
193
|
+ $allowed = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'mp4', 'pdf', 'xls', 'xlsx'];
|
|
|
|
194
|
+ if (!in_array($ext, $allowed)) {
|
|
|
|
195
|
+ $connection->send(new \Workerman\Protocols\Http\Response(400, [], json_encode(['ok' => false, 'error' => 'File type not allowed'])));
|
|
|
|
196
|
+ return;
|
|
|
|
197
|
+ }
|
|
|
|
198
|
+
|
|
|
|
199
|
+ // TOS Configuration (Keys from hsobs.php)
|
|
|
|
200
|
+ $ak = 'AKLTZjkyMzliYjQ5N2IyNDFjNDliMTBiY2E2ZmU5ODhjNTM';
|
|
|
|
201
|
+ $sk = 'WldKbE5XUmpPRGxqWmpZM05EUTBObUpqTTJSa01qVTNNMkprWmpsbU9Uaw==';
|
|
|
|
202
|
+ $endpoint = 'tos-cn-shanghai.volces.com';
|
|
|
|
203
|
+ $region = 'cn-shanghai';
|
|
|
|
204
|
+ $bucket = 'ocxun';
|
|
|
|
205
|
+
|
|
|
|
206
|
+ try {
|
|
|
|
207
|
+ $client = new TosClient([
|
|
|
|
208
|
+ 'region' => $region,
|
|
|
|
209
|
+ 'endpoint' => $endpoint,
|
|
|
|
210
|
+ 'ak' => $ak,
|
|
|
|
211
|
+ 'sk' => $sk,
|
|
|
|
212
|
+ ]);
|
|
|
|
213
|
+
|
|
|
|
214
|
+ // Generate Key
|
|
|
|
215
|
+ $uuid = bin2hex(random_bytes(8));
|
|
|
|
216
|
+ // TODO: 暂时使用 'guest',等待后续对接用户手机号功能
|
|
|
|
217
|
+ $userPhone = 'guest';
|
|
|
|
218
|
+ $objectKey = "clawdbot/{$userPhone}/{$uuid}.{$ext}";
|
|
|
|
219
|
+
|
|
|
|
220
|
+ // Read file content
|
|
|
|
221
|
+ $contentFn = fopen($file['tmp_name'], 'r');
|
|
|
|
222
|
+
|
|
|
|
223
|
+ // Upload using Object Input
|
|
|
|
224
|
+ $input = new PutObjectInput($bucket, $objectKey, $contentFn);
|
|
|
|
225
|
+ $input->setACL('public-read');
|
|
|
|
226
|
+
|
|
|
|
227
|
+ $client->putObject($input);
|
|
|
|
228
|
+
|
|
|
|
229
|
+ if (is_resource($contentFn)) {
|
|
|
|
230
|
+ fclose($contentFn);
|
|
|
|
231
|
+ }
|
|
|
|
232
|
+
|
|
|
|
233
|
+ // Generate URL
|
|
|
|
234
|
+ $url = "https://{$bucket}.{$endpoint}/{$objectKey}";
|
|
|
|
235
|
+
|
|
|
|
236
|
+ $connection->send(json_encode([
|
|
|
|
237
|
+ 'ok' => true,
|
|
|
|
238
|
+ 'url' => $url
|
|
|
|
239
|
+ ]));
|
|
|
|
240
|
+
|
|
|
|
241
|
+ } catch (Exception $e) {
|
|
|
|
242
|
+ $connection->send(new \Workerman\Protocols\Http\Response(500, [], json_encode(['ok' => false, 'error' => 'Upload failed: ' . $e->getMessage()])));
|
|
|
|
243
|
+ }
|
|
|
|
244
|
+ return;
|
|
|
|
245
|
+ }
|
|
|
|
246
|
+
|
|
|
|
247
|
+ $connection->send("Moltbot Relay HTTP Server");
|
|
|
|
248
|
+};
|
|
|
|
249
|
+
|
|
149
|
Worker::runAll(); |
250
|
Worker::runAll(); |