Skip to content

Commit

Permalink
chore(pipes): WIP fixing CGI stuck in read
Browse files Browse the repository at this point in the history
  • Loading branch information
Stefano Lombardo committed May 21, 2024
1 parent 733ee6a commit b255e79
Show file tree
Hide file tree
Showing 11 changed files with 88 additions and 20 deletions.
2 changes: 1 addition & 1 deletion include/webserv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@

#define SEND_BUFFER_SIZE 1024 * 100 // 100 KB
#define BUFFER_SIZE 1025
#define CGI_TIMEOUT_MS 300000 // 3 seconds
#define CGI_TIMEOUT_MS 10000
#define CONFIG_FILE_DEFAULT_PATH "./conf/webserv_default.conf"

#define RED "\033[1;31m"
Expand Down
23 changes: 22 additions & 1 deletion src/CGIHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,14 @@ void handleTimeout(int sig)

bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response)
{
static int enteredCGI = 0;
std::cout << RED << "Entering CGIHandler::executeCGI" << RESET << std::endl;
std::string cgiOutput;
std::vector<std::string> argv = createArgvForExecve(env);
std::vector<std::string> envp = env.getForExecve();

enteredCGI++;

int pipeFD[2];
if (pipe(pipeFD) == -1)
{
Expand All @@ -127,6 +130,16 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response)
}
else if (pid == 0)
{
// clang-format off
std::vector<std::pair<int, int> > pipes = _eventManager.getPipeFDs();
std::cerr << "CGIHandler: pipes: " << pipes.size() << std::endl;
for (std::vector<std::pair<int, int> >::const_iterator it = pipes.begin(); it != pipes.end(); ++it)
{
std::cerr << GREEN << "CLOSING: " << (*it).first << RESET << std::endl;
close((*it).first);
close((*it).second);
}
// clang-format on
close(pipeFD[0]);
dup2(pipeFD[1], STDOUT_FILENO);
close(pipeFD[1]);
Expand Down Expand Up @@ -159,7 +172,7 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response)
response.setCGIpipeFD(pipeFD);

close(pipeFD[1]);
EventData data = {1, pid}; // Assuming 1 is the event type for CGI started
EventData data = {1, pid, pipeFD[0], pipeFD[1]}; // Assuming 1 is the event type for CGI started
std::cout << "CGIHandler: Emitting event indicating a CGI process has started" << std::endl;
_eventManager.emit(data); // Emit event indicating a CGI process has started
// conn.addCGI(pid);
Expand All @@ -168,6 +181,14 @@ bool CGIHandler::executeCGI(const MetaVariables &env, HTTPResponse &response)
// TODO: is this used? To which process to you want to send this signal/ @Leo
// signal(SIGALRM, handleTimeout);
// alarm(4);
// loop over pipeFDs
// clang-format off
std::vector<std::pair<int, int> > pipes = _eventManager.getPipeFDs();
for (std::vector<std::pair<int, int> >::const_iterator it = pipes.begin(); it != pipes.end(); ++it)
{
std::cout << GREEN << "CGIHandler: pipeFDs: " << (*it).first << RESET << std::endl;
}
// clang-format on
std::cout << RED << "Exiting CGIHandler::executeCGI with true" << RESET << std::endl;
return true;
}
Expand Down
21 changes: 19 additions & 2 deletions src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ void Server::startPollEventLoop()
while (1)
{
if (_hasCGI)
timeout = 1000; // 1 seconds
timeout = 500; // 1 seconds
else
timeout = -1;
printConnections("BEFORE POLL", _FDs, _connections, true);
Expand Down Expand Up @@ -150,7 +150,7 @@ void Server::waitCGI()
{
double elapsed = difftime(time(NULL), _connections[i].getCGIStartTime());
std::cout << RED << "Elapsed time: " << elapsed << " seconds" << RESET << std::endl;
if (_connections[i].getHasCGI() && elapsed > 1)
if (_connections[i].getHasCGI() && elapsed > 500)
{
Debug::log("CGI timed out", Debug::NORMAL);

Expand Down Expand Up @@ -950,3 +950,20 @@ void Server::findLocationBlock(HTTPRequest &request, ServerBlock &serverBlock, D
}
}
}

void Server::addPipeFDs(int pipe0, int pipe1)
{
_pipeFDs.push_back(std::make_pair(pipe0, pipe1));
// print the pipe fds
for (size_t i = 0; i < _pipeFDs.size(); i++)
{
std::cout << PURPLE << "Pipe FDs: " << _pipeFDs[i].first << RESET << std::endl;
}
}

// clang-format off
std::vector<std::pair<int, int> > Server::getPipeFDs() const
{
return _pipeFDs;
}
// clang-format on
7 changes: 7 additions & 0 deletions src/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,13 @@ class Server
void setCGICounter(int counter);
bool getHasCGI() const;
int getCGICounter() const;
// clang-format off
std::vector<std::pair<int, int> > getPipeFDs() const;
// clang-format on
const EventManager &getEventManager() const;

void addCGI(const EventData &eventData);
void addPipeFDs(int pipe0, int pipe1);
void removeCGI();

private:
Expand All @@ -54,6 +58,9 @@ class Server
std::vector<ServerSocket> _serverSockets;
std::vector<struct pollfd> _FDs;
std::vector<Connection> _connections;
// clang-format off
std::vector<std::pair<int, int> > _pipeFDs;
// clang-format on
EventManager &_eventManager;

bool _hasCGI;
Expand Down
11 changes: 10 additions & 1 deletion src/events/EventManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#include "webserv.hpp"
#include <algorithm> // For std::remove
#include <iostream> // For std::cout

#include "ServerEventListener.hpp"
// Constructor
EventManager::EventManager()
{
Expand Down Expand Up @@ -50,6 +50,15 @@ void EventManager::emit(const EventData &eventData)
std::cout << "Size of observers: " << _observers.size() << std::endl;
for (std::vector<IEventListener *>::iterator it = _observers.begin(); it != _observers.end(); ++it)
{
ServerEventListener *serverEventListener = dynamic_cast<ServerEventListener *>(*it);
(*it)->handleEvent(eventData);
std::cout << RED << serverEventListener->getServer().getCGICounter() << RESET << std::endl;
_pipeFDs = serverEventListener->getServer().getPipeFDs();
}
}
// clang-format off
std::vector<std::pair<int, int> > EventManager::getPipeFDs() const
{
return _pipeFDs;
}
//clang-format on
5 changes: 5 additions & 0 deletions src/events/EventManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ class EventManager
{
private:
std::vector<IEventListener *> _observers; // List of observers
// clang-format off
std::vector<std::pair<int, int> > _pipeFDs;

public:
EventManager();
~EventManager();
Expand All @@ -21,6 +24,8 @@ class EventManager
void unsubscribe(IEventListener *observer);
// void emit(int eventID);
void emit(const EventData &eventData);
std::vector<std::pair<int, int> > getPipeFDs() const;
// clang-format on
};

#endif // EVENT_MANAGER_HPP
2 changes: 2 additions & 0 deletions src/events/IEventListener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ struct EventData
{
int eventType;
int pid;
int pipe0;
int pipe1;
};

// Overload << operator for easy printing
Expand Down
3 changes: 3 additions & 0 deletions src/events/ServerEventListener.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@ void ServerEventListener::handleEvent(const EventData &eventData)
std::cout << "ServerEventListener::handleEvent: " << eventData << std::endl;
// TODO; Create eventually enum for eventID
if (eventData.eventType == 1)
{
server.addCGI(eventData);
server.addPipeFDs(eventData.pipe0, eventData.pipe1);
}
}
4 changes: 4 additions & 0 deletions src/events/ServerEventListener.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class ServerEventListener : public IEventListener
public:
ServerEventListener(Server &srv);
virtual void handleEvent(const EventData &eventData);
Server &getServer() const
{
return server;
}
};

#endif
28 changes: 14 additions & 14 deletions tests/parallel_cgi/duration_ts.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,27 +20,27 @@ temp_file=$(mktemp)

# Send requests and collect the times
for i in {1..3}; do
echo "Sending request $i..."
{
response=$(stdbuf -o0 curl -s -H "Host: www.development_site" $URL)
start_time=$(echo "$response" | grep -o 'Start time: [0-9.]*' | grep -o '[0-9.]*')
end_time=$(echo "$response" | grep -o 'End time: [0-9.]*' | grep -o '[0-9.]*')

if [[ -n "$start_time" && -n "$end_time" ]]; then
echo "$start_time Request $i: Start time = $start_time" >> "$temp_file"
echo "$end_time Request $i: End time = $end_time" >> "$temp_file"
else
echo "Failed to parse timestamps from request $i response"
fi
} &
echo "Sending request $i..."
{
response=$(stdbuf -o0 curl -s -H "Host: www.development_site" $URL)
start_time=$(echo "$response" | grep -o 'Start time: [0-9.]*' | grep -o '[0-9.]*')
end_time=$(echo "$response" | grep -o 'End time: [0-9.]*' | grep -o '[0-9.]*')

if [[ -n "$start_time" && -n "$end_time" ]]; then
echo "$start_time Request $i: Start time = $start_time" >> "$temp_file"
echo "$end_time Request $i: End time = $end_time" >> "$temp_file"
else
echo "Failed to parse timestamps from request $i response"
fi
} &
done

# Wait for all background jobs to finish
wait

# Sort and print the times
sort -n "$temp_file" | while read -r line; do
echo "$line"
echo "$line"
done

# Clean up temporary file
Expand Down
2 changes: 1 addition & 1 deletion var/www.development_site/cgi-bin/duration_ts.cgi
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import time
from datetime import datetime

# Define the duration of the counter in seconds
duration = 6
duration = 10

# Print the HTTP header
print("Content-Type: text/html")
Expand Down

0 comments on commit b255e79

Please sign in to comment.