void AmBasicSipDialog::setStatus(Status new_status) { DBG("setting SIP dialog status: %s->%s\n", getStatusStr(), getStatusStr(new_status)); status = new_status; }
Network::Err Network::handleConnection(SocketData* conn) { int connSock = conn->fd; char* buffer = conn->readBuf; size_t toRead = readBufSize - conn->readLen; ssize_t receivedBytes = recv(connSock, buffer + conn->readLen, toRead, 0); if (receivedBytes == -1) { Log::err("recv(): %s", strerror(errno)); if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } else if (receivedBytes == 0) { Log::info("Closing disconnected socket"); if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } conn->readLen += receivedBytes; receivedBytes = conn->readLen; if (strnstr(buffer, "\r\n\r\n", receivedBytes) == nullptr && strnstr(buffer, "\r\r", receivedBytes) == nullptr && strnstr(buffer, "\n\n", receivedBytes) == nullptr) { if (receivedBytes == readBufSize) { if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } return Err::ReadMore; } char* rPos = (char*)memchr(buffer, '\r', receivedBytes); char* nPos = (char*)memchr(buffer, '\n', receivedBytes); char* lineEndPos = nPos; if (nPos == nullptr || (rPos != nullptr && rPos < nPos)) { lineEndPos = rPos; } RequestResult res; RequestErr status; size_t requestLineLen; if (lineEndPos == nullptr) { requestLineLen = receivedBytes; status = RequestErr::BAD_REQUEST; res.version = HttpVersion::V1_0; } else { requestLineLen = lineEndPos - buffer; status = readRequestLine(buffer, requestLineLen, res); } char pathBuff[1024]; const char* path = nullptr; switch (status) { case RequestErr::OK: { int unescapedLen = unescape(res.path, pathBuff, res.pathLen); if (unescapedLen == -1) { status = RequestErr::BAD_REQUEST; path = "/400.html"; } else { pathBuff[unescapedLen] = 0; path = pathBuff; } } break; case RequestErr::BAD_REQUEST: path = "/400.html"; break; case RequestErr::FORBIDDEN: path = "/403.html"; break; case RequestErr::NOT_FOUND: path = "/404.html"; break; case RequestErr::INTERNAL: path = "/500.html"; break; case RequestErr::NOT_IMPLEMENTED: path = "/501.html"; break; } if (strcmp(path, "/") == 0) { path = "/index.html"; } int file = open(path, O_RDONLY); if (file == -1) { status = RequestErr::NOT_FOUND; file = open("/404.html", O_RDONLY); if (file == -1) { Log::err("open(): %s, Failed to open 404.html", strerror(errno)); if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } } struct stat fileStat; if (fstat(file, &fileStat) == -1) { Log::err("fstat(): %s", strerror(errno)); if (close(file) == -1) { Log::err("close(): %s", strerror(errno)); } if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } if (res.version >= HttpVersion::V1_0) { char headerBuff[1024]; int headerLen = snprintf(headerBuff, sizeof(headerBuff), "HTTP/1.0 %3.3d %s\r\n", (int)status, getStatusStr(status)); const char* mimeType = mimeFinder->findMimeType(dup(file), path); if (lseek(file, 0, SEEK_SET) == -1) { Log::err("lseek(): %s", strerror(errno)); if (close(file) == -1) { Log::err("close(): %s", strerror(errno)); } if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } if (mimeType != nullptr) { headerLen += snprintf(headerBuff + headerLen, sizeof(headerBuff) - headerLen, "Content-Type: %s\r\n", mimeType); } headerLen += snprintf(headerBuff + headerLen, sizeof(headerBuff) - headerLen, "Content-Length: %ld\r\n\r\n", fileStat.st_size); if (send(connSock, headerBuff, headerLen, 0) == -1) { Log::err("send(): %s", strerror(errno)); if (close(file) == -1) { Log::err("close(): %s", strerror(errno)); } if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } } size_t bytesSent; if(res.method == HttpMethod::GET) { if ((bytesSent = sendfile(connSock, file, nullptr, fileStat.st_size)) == -1) { Log::err("sendfile(): %s", strerror(errno)); if (close(file) == -1) { Log::err("close(): %s", strerror(errno)); } if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::Process; } } if(close(file) == -1) { Log::err("close(): %s", strerror(errno)); } logStatus(buffer, requestLineLen, connSock, bytesSent, (int)status); if (close(connSock) == -1) { Log::err("close(): %s", strerror(errno)); } return Err::OK; }
const char* AmBasicSipDialog::getStatusStr() { return getStatusStr(status); }