Example #1
0
void AmBasicSipDialog::setStatus(Status new_status) 
{
  DBG("setting SIP dialog status: %s->%s\n",
      getStatusStr(), getStatusStr(new_status));

  status = new_status;
}
Example #2
0
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;
}
Example #3
0
const char* AmBasicSipDialog::getStatusStr()
{
  return getStatusStr(status);
}