Cgi stderr
This commit is contained in:
parent
7951478edf
commit
bf36dd74d8
@ -107,13 +107,16 @@ void Client::request()
|
||||
}
|
||||
|
||||
//
|
||||
void Client::setCgiSockets(CgiSocket *cgiStdIn, CgiSocket *cgiStdOut)
|
||||
void Client::setCgiSockets(CgiSocket *cgiStdIn, CgiSocket *cgiStdOut, CgiSocket *cgiStdErr)
|
||||
{
|
||||
server_.add(*cgiStdIn, EPOLLOUT, this); // write
|
||||
server_.add(*cgiStdOut, EPOLLIN, this); // read
|
||||
server_.add(*cgiStdErr, EPOLLIN, this); // error
|
||||
|
||||
|
||||
sockets_[cgiStdIn->getFd()] = cgiStdIn;
|
||||
sockets_[cgiStdOut->getFd()] = cgiStdOut;
|
||||
sockets_[cgiStdErr->getFd()] = cgiStdErr;
|
||||
}
|
||||
|
||||
void Client::removeCgiSocket(CgiSocket *cgiSocket)
|
||||
|
||||
@ -43,7 +43,7 @@ class Client
|
||||
[[nodiscard]] ASocket &getSocket(int fd = -1) const;
|
||||
|
||||
// void setStatusCode(int code);
|
||||
void setCgiSockets(CgiSocket *cgiStdIn, CgiSocket *cgiStdOut);
|
||||
void setCgiSockets(CgiSocket *cgiStdIn, CgiSocket *cgiStdOut, CgiSocket *cgiStdErr);
|
||||
void removeCgiSocket(CgiSocket *cgiSocket);
|
||||
|
||||
[[nodiscard]] HttpRequest &getHttpRequest() const noexcept;
|
||||
|
||||
@ -84,15 +84,47 @@ void CgiHandler::read()
|
||||
}
|
||||
}
|
||||
|
||||
void CgiHandler::setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_ptr<CgiSocket> cgiStdOut)
|
||||
void CgiHandler::error()
|
||||
{
|
||||
Log::trace(LOCATION);
|
||||
if (cgiStdErr_ == nullptr)
|
||||
{
|
||||
Log::error("CGI stderr socket is null");
|
||||
return;
|
||||
}
|
||||
char buffer[bufferSize_] = {}; // NOLINT(cppcoreguidelines-avoid-c-arrays)
|
||||
ssize_t bytesRead
|
||||
= cgiStdErr_->read(buffer, sizeof(buffer) - 1); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay)
|
||||
if (bytesRead < 0)
|
||||
{
|
||||
Log::error("Failed to read from CGI stderr, fd: " + std::to_string(cgiStdErr_->getFd()));
|
||||
}
|
||||
else if (bytesRead == 0)
|
||||
{
|
||||
Log::info("CGI process closed stderr, fd: " + std::to_string(cgiStdErr_->getFd()));
|
||||
request_.getClient().removeCgiSocket(cgiStdErr_.get());
|
||||
cgiStdErr_ = nullptr;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer[bytesRead] = '\0'; // NOLINT(cppcoreguidelines-pro-bounds-constant-array-index)
|
||||
Log::error("CGI stderr output (fd: " + std::to_string(cgiStdErr_->getFd()) + "): "
|
||||
+ std::string(buffer, static_cast<size_t>(bytesRead)));
|
||||
}
|
||||
}
|
||||
|
||||
void CgiHandler::setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_ptr<CgiSocket> cgiStdOut, std::unique_ptr<CgiSocket> cgiStdErr)
|
||||
{
|
||||
cgiStdIn->setCallback([this]() { write(); });
|
||||
cgiStdOut->setCallback([this]() { read(); });
|
||||
cgiStdErr->setCallback([this]() { error(); });
|
||||
|
||||
cgiStdOut_ = std::move(cgiStdOut);
|
||||
cgiStdIn_ = std::move(cgiStdIn);
|
||||
cgiStdErr_ = std::move(cgiStdErr);
|
||||
|
||||
request_.getClient().setCgiSockets(cgiStdIn_.get(), cgiStdOut_.get()); // write
|
||||
request_.getClient().setCgiSockets(cgiStdIn_.get(), cgiStdOut_.get(), cgiStdErr_.get()); // write
|
||||
|
||||
// TODO add to handler
|
||||
}
|
||||
|
||||
@ -21,7 +21,7 @@ class CgiHandler : public AHandler
|
||||
|
||||
void handle() override;
|
||||
void wait() noexcept;
|
||||
void setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_ptr<CgiSocket> cgiStdOut);
|
||||
void setCgiSockets(std::unique_ptr<CgiSocket> cgiStdIn, std::unique_ptr<CgiSocket> cgiStdOut, std::unique_ptr<CgiSocket> cgiStdErr);
|
||||
void setPid(int pid);
|
||||
|
||||
private:
|
||||
@ -31,6 +31,7 @@ class CgiHandler : public AHandler
|
||||
std::unique_ptr<CgiProcess> cgiProcess_;
|
||||
std::unique_ptr<CgiSocket> cgiStdIn_;
|
||||
std::unique_ptr<CgiSocket> cgiStdOut_;
|
||||
std::unique_ptr<CgiSocket> cgiStdErr_;
|
||||
void parseCgiOutput();
|
||||
void parseCgiHeaders(std::string &headers);
|
||||
void parseCgiBody();
|
||||
@ -41,4 +42,5 @@ class CgiHandler : public AHandler
|
||||
|
||||
void write();
|
||||
void read();
|
||||
void error();
|
||||
};
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#include <csignal>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
@ -34,8 +35,9 @@ void CgiProcess::spawn()
|
||||
|
||||
int pipeStdin[2];
|
||||
int pipeStdout[2];
|
||||
int pipeStderr[2];
|
||||
|
||||
if (pipe(pipeStdin) == -1 || pipe(pipeStdout) == -1)
|
||||
if (pipe(pipeStdin) == -1 || pipe(pipeStdout) == -1 || pipe(pipeStderr) == -1)
|
||||
{
|
||||
throw std::runtime_error("Failed to create pipes");
|
||||
}
|
||||
@ -47,19 +49,25 @@ void CgiProcess::spawn()
|
||||
close(pipeStdin[1]);
|
||||
close(pipeStdout[0]);
|
||||
close(pipeStdout[1]);
|
||||
close(pipeStderr[0]);
|
||||
close(pipeStderr[1]);
|
||||
throw std::runtime_error("Failed to fork");
|
||||
}
|
||||
if (_pid == 0)
|
||||
{
|
||||
dup2(pipeStdin[0], STDIN_FILENO);
|
||||
dup2(pipeStdout[1], STDOUT_FILENO);
|
||||
dup2(pipeStderr[1], STDERR_FILENO);
|
||||
|
||||
close(pipeStdin[0]);
|
||||
close(pipeStdin[1]);
|
||||
close(pipeStdout[0]);
|
||||
close(pipeStdout[1]);
|
||||
close(pipeStderr[0]);
|
||||
close(pipeStderr[1]);
|
||||
|
||||
// Log::debug("Executing CGI: " + cgiPath);
|
||||
std::cerr << "Executing CGI: " << cgiPath << std::endl;
|
||||
|
||||
// Prepare arguments
|
||||
std::string fullPath = uri.getFullPath();
|
||||
@ -76,14 +84,17 @@ void CgiProcess::spawn()
|
||||
// Parent process
|
||||
auto cgiStdIn = std::make_unique<CgiSocket>(pipeStdin[1]);
|
||||
auto cgiStdOut = std::make_unique<CgiSocket>(pipeStdout[0]);
|
||||
auto cgiStdErr = std::make_unique<CgiSocket>(pipeStderr[0]);
|
||||
|
||||
close(pipeStdin[0]);
|
||||
close(pipeStdout[1]);
|
||||
close(pipeStderr[1]);
|
||||
|
||||
Log::debug("CGI process forked with PID: " + std::to_string(_pid));
|
||||
|
||||
// request_.getClient().setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut)); // move the sockets to the
|
||||
// client
|
||||
handler_.setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut));
|
||||
handler_.setCgiSockets(std::move(cgiStdIn), std::move(cgiStdOut), std::move(cgiStdErr));
|
||||
handler_.setPid(_pid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,6 +103,11 @@ void URI::parseFullpath()
|
||||
}
|
||||
else if (!baseName_.empty()) // not file or dir, but we have a baseName already
|
||||
{
|
||||
if (pathInfo_.empty())
|
||||
{
|
||||
pathInfo_ = "/";
|
||||
}
|
||||
|
||||
pathInfo_ = FileUtils::joinPath(pathInfo_, segment);
|
||||
}
|
||||
else // not file or dir, and no baseName yet
|
||||
@ -124,8 +129,7 @@ void URI::parseFullpath()
|
||||
}
|
||||
}
|
||||
}
|
||||
Log::debug("URI parseFullpath results",
|
||||
{{"dir", dir_}, {"baseName", baseName_}, {"pathInfo", pathInfo_}});
|
||||
Log::debug("URI parseFullpath results", {{"dir", dir_}, {"baseName", baseName_}, {"pathInfo", pathInfo_}});
|
||||
fullPath_ = FileUtils::joinPath(dir_, baseName_);
|
||||
}
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@ ASocket::ASocket(int fd) : fd_(fd)
|
||||
|
||||
ASocket::~ASocket()
|
||||
{
|
||||
Log::trace(LOCATION);
|
||||
Log::trace(LOCATION + "Closing socket fd: " + std::to_string(fd_));
|
||||
if (fd_ != -1)
|
||||
{
|
||||
close(fd_);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user