| 169 | } |
| 170 | |
| 171 | bool HttpServerCommand::execute() |
| 172 | { |
| 173 | if (e_->getRequestGroupMan()->downloadFinished() || e_->isHaltRequested()) { |
| 174 | return true; |
| 175 | } |
| 176 | try { |
| 177 | if (socket_->isReadable(0) || (writeCheck_ && socket_->isWritable(0)) || |
| 178 | socket_->getRecvBufferedLength() || |
| 179 | !httpServer_->getSocketRecvBuffer()->bufferEmpty()) { |
| 180 | timeoutTimer_ = global::wallclock(); |
| 181 | |
| 182 | #ifdef ENABLE_SSL |
| 183 | if (httpServer_->getSecure()) { |
| 184 | // tlsAccept() just returns true if handshake has already |
| 185 | // finished. |
| 186 | if (!socket_->tlsAccept()) { |
| 187 | updateWriteCheck(); |
| 188 | e_->addCommand(std::unique_ptr<Command>(this)); |
| 189 | return false; |
| 190 | } |
| 191 | } |
| 192 | #endif // ENABLE_SSL |
| 193 | |
| 194 | if (!httpServer_->receiveRequest()) { |
| 195 | updateWriteCheck(); |
| 196 | e_->addCommand(std::unique_ptr<Command>(this)); |
| 197 | return false; |
| 198 | } |
| 199 | // CORS preflight request uses OPTIONS method. It is not |
| 200 | // restricted by authentication. |
| 201 | if (!httpServer_->authenticate() && |
| 202 | httpServer_->getMethod() != "OPTIONS") { |
| 203 | httpServer_->disableKeepAlive(); |
| 204 | httpServer_->feedResponse( |
| 205 | 401, "WWW-Authenticate: Basic realm=\"aria2\"\r\n"); |
| 206 | e_->addCommand(make_unique<HttpServerResponseCommand>( |
| 207 | getCuid(), httpServer_, e_, socket_)); |
| 208 | e_->setNoWait(true); |
| 209 | return true; |
| 210 | } |
| 211 | auto& header = httpServer_->getRequestHeader(); |
| 212 | if (header->fieldContains(HttpHeader::UPGRADE, "websocket") && |
| 213 | header->fieldContains(HttpHeader::CONNECTION, "upgrade")) { |
| 214 | #ifdef ENABLE_WEBSOCKET |
| 215 | int status = websocketHandshake(header.get()); |
| 216 | if (status == 101) { |
| 217 | std::string serverKey = createWebSocketServerKey( |
| 218 | header->find(HttpHeader::SEC_WEBSOCKET_KEY)); |
| 219 | httpServer_->feedUpgradeResponse( |
| 220 | "websocket", |
| 221 | fmt("Sec-WebSocket-Accept: %s\r\n", serverKey.c_str())); |
| 222 | e_->addCommand(make_unique<rpc::WebSocketResponseCommand>( |
| 223 | getCuid(), httpServer_, e_, socket_)); |
| 224 | } |
| 225 | else { |
| 226 | if (status == 426) { |
| 227 | httpServer_->feedResponse(426, "Sec-WebSocket-Version: 13\r\n"); |
| 228 | } |
nothing calls this directly
no test coverage detected