/* */ #include "HttpServer.h" #include "HttpHeader.h" #include "SocketCore.h" #include "HttpHeaderProcessor.h" #include "DlAbortEx.h" #include "message.h" #include "Util.h" #include "LogFactory.h" #include "Logger.h" namespace aria2 { HttpServer::HttpServer(const SharedHandle& socket, DownloadEngine* e): _socket(socket), _socketBuffer(socket), _e(e), _headerProcessor(new HttpHeaderProcessor()), _logger(LogFactory::getInstance()) {} HttpServer::~HttpServer() {} SharedHandle HttpServer::receiveRequest() { size_t size = 512; unsigned char buf[size]; _socket->peekData(buf, size); if(size == 0 && !(_socket->wantRead() || _socket->wantWrite())) { throw DlAbortEx(EX_EOF_FROM_PEER); } _headerProcessor->update(buf, size); if(!_headerProcessor->eoh()) { _socket->readData(buf, size); return SharedHandle(); } size_t putbackDataLength = _headerProcessor->getPutBackDataLength(); size -= putbackDataLength; _socket->readData(buf, size); SharedHandle header = _headerProcessor->getHttpRequestHeader(); if(!header.isNull()) { _logger->info("HTTP Server received request\n%s", _headerProcessor->getHeaderString().c_str()); _lastRequestHeader = header; _headerProcessor->clear(); } return header; } bool HttpServer::supportsPersistentConnection() const { std::string connection = Util::toLower(_lastRequestHeader->getFirst(HttpHeader::CONNECTION)); return connection.find(HttpHeader::CLOSE) == std::string::npos && (_lastRequestHeader->getVersion() == HttpHeader::HTTP_1_1 || connection.find("keep-alive") != std::string::npos); } void HttpServer::feedResponse(const std::string& text) { std::string header = "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n" "Content-Length: "+Util::uitos(text.size())+"\r\n"; if(!supportsPersistentConnection()) { header += "Connection: close\r\n"; } header += "\r\n"; _logger->debug("HTTP Server sends response:\n%s", header.c_str()); _socketBuffer.feedSendBuffer(header); _socketBuffer.feedSendBuffer(text); } ssize_t HttpServer::sendResponse() { return _socketBuffer.send(); } bool HttpServer::sendBufferIsEmpty() const { return _socketBuffer.sendBufferIsEmpty(); } } // namespace aria2