Open u413-284-si opened 5 days ago
[re3, last point]
this separation was required to avoid sending fds/sockets to the wrong connection...() function as several sockets and pipe fds can be triggering events at the same time
Could you elaborate on this?
I think firing for a specific connection could be
This means we could just check if the firing fd corresponds to the connection status. If not, just return. E.g. if connection_status == Connection::SendToCGI and fd == connection.clientFd -> return
This would eliminate the second dispatch function with the switch case, which could be integrated into the existing switch.
[re3, last point]
this separation was required to avoid sending fds/sockets to the wrong connection...() function as several sockets and pipe fds can be triggering events at the same time
Could you elaborate on this?
I think firing for a specific connection could be
* clientFd * pipeToCGIWriteEnd * pipeFromCGIReadEnd
This means we could just check if the firing fd corresponds to the connection status. If not, just return. E.g. if connection_status == Connection::SendToCGI and fd == connection.clientFd -> return
This would eliminate the second dispatch function with the switch case, which could be integrated into the existing switch.
If I were to do that I would need to cover not only the two cases where a CGI action is asked for, but also all the other cases e.g. Connection::ReceiveBody where maybe a pipe fd comes in, but it should be the clientFd.
Just tried it out, it would look like this:
if ((connection.m_status == Connection::ReceiveFromCGI || connection.m_status == Connection::SendToCGI)
&& clientFd == connection.m_clientFd) {
return;
}
if ((connection.m_status == Connection::Idle || connection.m_status == Connection::ReceiveHeader
|| connection.m_status == Connection::ReceiveBody || connection.m_status == Connection::BuildResponse
|| connection.m_status == Connection::SendResponse)
&& clientFd != connection.m_clientFd) {
return;
}
If we were to integrate this before the switch, it would kinda render the switch useless, don't you think? Besides that it's pretty ugly. But yeah, that way we could loose the other handle function (which is honestly also ugly... not rly happy with either solutions, yet lacking an elegant one)
I meant to add this check in the specific connection.. function.
E.g. connectionReceiveHeader() would have
if (clientFd != connection.clientfd) // if NOT equal then don't work
return;
And likewise connectionSendToCGI() would have
if (clientFd == connection.clientfd) // if equal then don't work
return;
This way the switch would route every connection status and each connection.. function makes sure that only correct fds are handled
Ah, that makes more sense. Adapted and tested it. Works. Removed handleCGIConnections()
Ah, that makes more sense. Adapted and tested it. Works. Removed handleCGIConnections()
After change unittest does not compile because of changed function signature
Bug: we fork-exec but do not close file descriptors (mainly sockets, but also the epoll instance).
Reproduce: run with valgrind --trace-children=yes --track-fds=yes and execute cgi script.
Solution: "correct" way would be to mark the sockets and epoll with a "close-on-exec-flag". However we can't do it everywhere, because of limited functions allowed:
epoll_create()
, flag can only be set with epoll_create1()
socket()
we could also pass SOCK_CLOEXECaccept()
, flag can only be set with accept4()
pipe()
can receive O_CLOEXEC flag.Alternative would be to just close by hand:
Note: since the destructor of ConfigFileParser() never gets called, the opened configfile also isn't closed. Should be fixed by #53, since file can be closed after read in as string
(edited)
Overview
re 1.
re 2.
re 3.
re 4.
re 5.
re 6.
re 7.
closes #18 closes #60