| 266 | } |
| 267 | |
| 268 | static void HandleConnection(int clientFd) { |
| 269 | char buf[8192]; |
| 270 | ssize_t totalRead = 0; |
| 271 | |
| 272 | while (totalRead < (ssize_t)sizeof(buf) - 1) { |
| 273 | ssize_t n = recv(clientFd, buf + totalRead, sizeof(buf) - 1 - totalRead, 0); |
| 274 | if (n < 0) { |
| 275 | if (errno == EINTR) continue; |
| 276 | break; |
| 277 | } |
| 278 | if (n == 0) break; |
| 279 | totalRead += n; |
| 280 | buf[totalRead] = '\0'; |
| 281 | if (strstr(buf, "\r\n\r\n")) break; |
| 282 | } |
| 283 | |
| 284 | if (totalRead <= 0 || !strstr(buf, "\r\n\r\n")) { |
| 285 | close(clientFd); |
| 286 | return; |
| 287 | } |
| 288 | |
| 289 | std::string method, path; |
| 290 | if (!ParseRequestLine(buf, totalRead, method, path)) { |
| 291 | const char* resp = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n"; |
| 292 | send(clientFd, resp, strlen(resp), 0); |
| 293 | close(clientFd); |
| 294 | return; |
| 295 | } |
| 296 | |
| 297 | LOG("[HttpServer] %s %s", method.c_str(), path.c_str()); |
| 298 | |
| 299 | bool isDownload = (method == "GET" && path.rfind("/download/", 0) == 0); |
| 300 | bool isUpload = (method == "PUT" && path.rfind("/upload/", 0) == 0); |
| 301 | |
| 302 | if (!isDownload && !isUpload) { |
| 303 | const char* resp = "HTTP/1.1 404 Not Found\r\nContent-Length: 0\r\n\r\n"; |
| 304 | send(clientFd, resp, strlen(resp), 0); |
| 305 | close(clientFd); |
| 306 | return; |
| 307 | } |
| 308 | |
| 309 | // Parse: /{download|upload}/{accountId}/{appId}/{filename...} |
| 310 | std::string remainder = path.substr(isDownload ? 10 : 8); // skip "/download/" or "/upload/" |
| 311 | auto slash1 = remainder.find('/'); |
| 312 | if (slash1 == std::string::npos) { |
| 313 | const char* resp = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n"; |
| 314 | send(clientFd, resp, strlen(resp), 0); |
| 315 | close(clientFd); |
| 316 | return; |
| 317 | } |
| 318 | |
| 319 | uint32_t accountId; |
| 320 | try { accountId = std::stoul(remainder.substr(0, slash1)); } |
| 321 | catch (...) { |
| 322 | const char* resp = "HTTP/1.1 400 Bad Request\r\nContent-Length: 0\r\n\r\n"; |
| 323 | send(clientFd, resp, strlen(resp), 0); |
| 324 | close(clientFd); |
| 325 | return; |
no test coverage detected