Skip to content

Commit 1d817e7

Browse files
마석우마석우
마석우
authored and
마석우
committed
🐛 fix: kqueue process debugging
1 parent f078d95 commit 1d817e7

File tree

9 files changed

+239
-31
lines changed

9 files changed

+239
-31
lines changed

.vscode/settings.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
"functional": "cpp",
7373
"iterator": "cpp",
7474
"filesystem": "cpp",
75-
"memory_resource": "cpp"
75+
"memory_resource": "cpp",
76+
"list": "cpp"
7677
}
7778
}

response/CgiHandler.cpp

+19-4
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,21 @@ int CgiHandler::executeCgi()
8989
std::string cgi_file = _location_info->getCommonDirective()._cgi_path[extension];
9090
char *argv[4];
9191
int result = -1;
92-
char **envp = convertEnv();
92+
char **env;
93+
94+
if (!(env = (char**)malloc(sizeof(char*) * (_cgi_env.size() + 1))))
95+
{
96+
return NULL;
97+
}
98+
int i = 0;
99+
for (std::map<std::string, std::string>::iterator it = _cgi_env.begin(); it != _cgi_env.end(); it++)
100+
{
101+
env[i] = strdup((it->first + "=" + it->second).c_str());
102+
i++;
103+
}
104+
env[i] = NULL;
105+
// char **envp = convertEnv();
106+
cgi_file += "/php-cgi";
93107
argv[0] = const_cast<char*>(cgi_file.c_str());
94108
argv[1] = const_cast<char*>(_client_socket->getRequest()->getPath().c_str());
95109
argv[2] = 0;
@@ -98,14 +112,15 @@ int CgiHandler::executeCgi()
98112
argv[2] = const_cast<char*>(_client_socket->getRequest()->getQuery().c_str());
99113
}
100114
argv[3] = 0;
101-
102-
if (envp == NULL)
115+
if (env == NULL)
116+
{
103117
return 500;
118+
}
104119
dup2(write_fd[0],STDIN_FILENO);
105120
dup2(read_fd[1], STDOUT_FILENO);
106121
close(write_fd[1]);
107122
close(read_fd[0]);
108-
if ((result = execve(argv[0], argv, envp)) == -1)
123+
if ((result = execve(argv[0], argv, env)) == -1)
109124
{
110125
exit(result);
111126
}

server/ClientSocket.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ bool ClientSocket::isCGI(const std::string &path)
8787
std::string type;
8888
type = getExtension(path);
8989
std::map<std::string, std::string> cgi_path = _request->getRoute()->getCommonDirective()._cgi_path;
90+
std::cout << "cgi_path = " << type << std::endl;
9091
if (cgi_path.find(type) != cgi_path.end())
9192
{
9293
return 1;
@@ -123,6 +124,7 @@ void ClientSocket::setGetFd()
123124
}
124125
if (_request->getRoute()->getCommonDirective()._autoindex)
125126
{
127+
setStage(MAKE_AUTOINDEX);
126128
if (getFileType(entity_file)) // 존재하는 파일 or 디렉토리
127129
{
128130
// resource content에 autoindex 만들기 (_request->getFile() 기준)

server/ClientSocket.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ enum Stage
1111
END_OF_REQUEST, //리퀘스터 파싱 완료
1212
SET_RESOURCE, // 리소스 세팅 시작
1313
MAKE_RESPONSE, // 세팅된 리소스로 응답 보내줌
14+
MAKE_AUTOINDEX,
1415
FILE_READ,
1516
FILE_WRITE,
1617
CLOSE,

server/Server.cpp

+34-23
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ void Server::acceptGetClientFd(ServerSocket *server_socket)
5353

5454
void Server::keventProcess()
5555
{
56+
int flag = 0;
5657
serverConnect(); // config server의 서버별 kqueue등록
5758
if ((_kq._kq_fd = kqueue()) == -1)
5859
std::cout << " errorororororo" << std::endl;
@@ -92,10 +93,11 @@ void Server::keventProcess()
9293
}
9394
case CLIENT_SOCKET:
9495
{
95-
ClientSocket *client_socket = dynamic_cast<ClientSocket *>(_socket[_kq._event_list[i].ident]);
96-
std::cout << client_socket << std::endl;
96+
ClientSocket *client_socket = reinterpret_cast<ClientSocket *>(_socket[_kq._event_list[i].ident]);
97+
std::cout <<"client socket = " << client_socket << std::endl;
9798
int error = 0;
9899

100+
std::cout << "ehlo" << std::endl;
99101
if (client_socket->getStage() == GET_REQUEST)
100102
{
101103
if (client_socket->getRequest() == 0)
@@ -117,20 +119,23 @@ void Server::keventProcess()
117119
std::cout << "request error" << std::endl;
118120
continue;
119121
}
120-
client_socket->setResourceFd();
121122
client_socket->setStage(SET_RESOURCE);
123+
client_socket->setResourceFd();
122124
int read_fd = client_socket->getResource()->getReadFd();
123125
int write_fd = client_socket->getResource()->getWriteFd();
124-
if (read_fd != -1)
125-
{
126-
_kq.addEvent(EVFILT_READ, read_fd, NULL);
127-
_socket[read_fd] = client_socket;
128-
}
129-
if (write_fd != -1)
130-
{
131-
_kq.addEvent(EVFILT_WRITE, write_fd, NULL);
132-
_socket[write_fd] = client_socket;
133-
}
126+
if (client_socket->getStage() == SET_RESOURCE)
127+
{
128+
if (read_fd != -1)
129+
{
130+
_kq.addEvent(EVFILT_READ, read_fd, NULL);
131+
_socket[read_fd] = client_socket;
132+
}
133+
if (write_fd != -1)
134+
{
135+
_kq.addEvent(EVFILT_WRITE, write_fd, NULL);
136+
_socket[write_fd] = client_socket;
137+
}
138+
}
134139
}
135140
else if(client_socket->getStage() == SET_RESOURCE)
136141
{
@@ -139,12 +144,13 @@ void Server::keventProcess()
139144
memset(buffer, 0, BUFFERSIZE);
140145
if (client_socket->getResource()->getPid() > 0)
141146
{ // cgi
147+
std::cout << "pid check ====== " << std::endl;
142148
ret = waitpid(client_socket->getResource()->getPid(), &stat, WNOHANG);
143149
if (ret < 0)
144150
{
145151
std::cout << "process error!!!" << std::endl;
146152
_kq.removeEvent(EV_DELETE, client_socket->getResource()->getReadFd(), NULL);
147-
_socket.erase(client_socket->getResource()->getReadFd());
153+
// _socket.erase(client_socket->getResource()->getReadFd());
148154
close(client_socket->getResource()->getReadFd());
149155
continue ;
150156
// process error
@@ -159,7 +165,7 @@ void Server::keventProcess()
159165
// cgi error
160166
std::cout << "cgi error!!!" << std::endl;
161167
_kq.removeEvent(EV_DELETE, client_socket->getResource()->getReadFd(), NULL);
162-
_socket.erase(client_socket->getResource()->getReadFd());
168+
// _socket.erase(client_socket->getResource()->getReadFd());
163169
close(client_socket->getResource()->getReadFd());
164170
continue ;
165171
}
@@ -178,8 +184,8 @@ void Server::keventProcess()
178184
{
179185
client_socket->setStage(MAKE_RESPONSE);
180186
client_socket->getResponse()->makeResponse();
181-
_kq.removeEvent(EV_DELETE, client_socket->getResource()->getReadFd(), NULL);
182-
_socket.erase(client_socket->getResource()->getReadFd());
187+
// _kq.removeEvent(EV_DELETE, client_socket->getResource()->getReadFd(), NULL);
188+
// _socket.erase(client_socket->getResource()->getReadFd());
183189
close(client_socket->getResource()->getReadFd());
184190
}
185191
}
@@ -200,7 +206,7 @@ void Server::keventProcess()
200206
client_socket->setStage(MAKE_RESPONSE);
201207
client_socket->getResponse()->makeResponse();
202208
_kq.removeEvent(EV_DELETE, _kq._event_list[i].ident, NULL);
203-
_socket.erase(_kq._event_list[i].ident);
209+
// _socket.erase(_kq._event_list[i].ident);
204210
close(_kq._event_list[i].ident);
205211
}
206212
}
@@ -214,25 +220,30 @@ void Server::keventProcess()
214220
{
215221
case CLIENT_SOCKET:
216222
{
217-
ClientSocket *client_socket = dynamic_cast<ClientSocket *>(_socket[_kq._event_list[i].ident]);
223+
ClientSocket *client_socket = reinterpret_cast<ClientSocket *>(_socket[_kq._event_list[i].ident]);
218224
//response 보내주는거
219-
if (client_socket != 0 && client_socket->getRequest() != 0 && client_socket->getStage() == MAKE_RESPONSE) // + 리소스도 다 읽었으면
225+
if (client_socket != 0 && client_socket->getRequest() != 0 && (client_socket->getStage() == MAKE_RESPONSE || client_socket->getStage() == MAKE_AUTOINDEX)) // + 리소스도 다 읽었으면
220226
{
221227
std::cout << "EVFILT_WRITE - fd[" << _kq._event_list[i].ident << "]: " << client_socket << std::endl;
222228
client_socket->sendResponse();
223-
_socket.erase(_kq._event_list[i].ident);
229+
// _socket.erase(_kq._event_list[i].ident);
224230
close(_kq._event_list[i].ident);
225231
}
226232
else if (client_socket->getStage() == SET_RESOURCE)
227233
{
228234
// cgi & POST
229235
// POST 요청 다 받아오면 파일(resource write_fd)에 request body를 한번에 쓰기
230236
int n;
237+
if (flag == 0)
238+
{
239+
std::cout << " write_fd = " << client_socket->getResource()->getWriteFd() << "content" << client_socket->getResource()->getContent().c_str() << std::endl;
240+
flag = 1;
241+
}
231242
n = write(client_socket->getResource()->getWriteFd(), client_socket->getResource()->getContent().c_str(), client_socket->getResource()->getContent().size());
232243
if (n < 0)
233244
{
234245
//error
235-
std::cout << "write error" << std::endl;
246+
// std::cout << "write error" << std::endl;
236247
continue ;
237248
}
238249
if (n < client_socket->getResource()->getContent().size())
@@ -244,7 +255,7 @@ void Server::keventProcess()
244255
client_socket->setStage(MAKE_RESPONSE);
245256
client_socket->getResponse()->makeResponse();
246257
_kq.removeEvent(EV_DELETE, client_socket->getResource()->getWriteFd(), NULL);
247-
_socket.erase(client_socket->getResource()->getWriteFd());
258+
// _socket.erase(client_socket->getResource()->getWriteFd());
248259
close(client_socket->getResource()->getWriteFd());
249260
//makeResponse()
250261
} // resource write_fd (cgi pipe) 에 쓰기 <- 정확히 뭘쓰는지?? // entity를 보내줘야 한다

setting/default.conf

+3-3
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ http {
1010
listen 127.0.0.1; #default 80 port, 근데 80 포트로 설정시 bind 에러 발생
1111

1212
server_name hyospark.dev;
13-
root ./www;
13+
root /Users/maseog-u/Desktop/develop/webserv/newweb;
1414
index static_file/index.html static_file/index.php;
1515
cgi_path ./www/php;
1616

@@ -32,7 +32,7 @@ http {
3232
autoindex on;
3333

3434
server_name jwoo.com;
35-
root ./www; // 본인 path로 수정
35+
root /Users/maseog-u/Desktop/develop/webserv/newweb; // 본인 path로 수정
3636
index static_file/index.html;
3737
error_page 403 403.html;
3838
cgi_path php ./www/php;
@@ -63,7 +63,7 @@ http {
6363
listen 127.0.0.1:8080;
6464
cgi_path ./www/php;
6565
server_name sma.com;
66-
root /Users/hyo/42Seoul/5_circle/Webserv/www;
66+
root /Users/maseog-u/Desktop/develop/webserv/newweb;
6767
index static_file/index.html;
6868
client_limit_body_size 100000;
6969
request_limit_header_size 1000;

test.cpp

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <stdio.h>
2+
#include <stdlib.h>
3+
#include <string.h>
4+
#include <iostream>
5+
#include <string>
6+
7+
void cgiSetEnv()
8+
{
9+
cgi_env["SERVER_PROTOCOL"]
10+
cgi_env["SERVER_PORT"]
11+
cgi_env["SERVER_NAME"]
12+
cgi_env["SERVER_SOFTWARE"]
13+
cgi_env["REQUEST_METHOD"]
14+
cgi_env["PATH_INFO"]
15+
cgi_env["PATH_TRANSLATED"]
16+
cgi_env["GATEWAY_INTERFACE"]
17+
cgi_env["SCRIPT_NAME"]
18+
cgi_env["QUERY_STRING"]
19+
cgi_env["REMOTE_ADDR"]
20+
cgi_env["REMOTE_USER"]
21+
cgi_env["REMOTE_HOST"]
22+
cgi_env["CONTENT_LENGTH"]
23+
cgi_env["CONTENT_TYPE"]
24+
cgi_env["REQUEST_URI"]
25+
26+
27+
28+
SERVER_PROTOCOL = HTTP/version 클라이언트 요청이 사용하는 프로토콜
29+
REQUEST_METHOD = HTTP_method HTML 폼이 사용하는 METHOD
30+
PATH_INFO = extra_path 클라이언트에 의해 전달되는 추가 PATH 정보
31+
PATH_TRANSLATED = trans1/extra_path PATH_INFO의 가상 경로(path)를 물리적인 경로로 변환
32+
SCRIPT_NAME = /path/script_name 실행된 스크립트에 대한 가상 경로
33+
QUERY_STRING = query_string URL에서 "?" 다음에 오는 질의어 문자열
34+
REMOTE_ADDR = ###,###,### 클라이언트의 IP주소
35+
REMOTE_HOST = domain.name 클라이언트의 호스트 이름
36+
REMOTE_USER = name 접근 권한을 얻은 사용자의 검증된 이름
37+
REMOTE_IDENT = name 검증 데몬을 이용해 서버로부터 검증된 원거리 사용자 이름. 이 변수의 용도는 로그인 에만 한정
38+
CONTENT_LENGTH = length POST 방식일 경우 클라이언트에서 보내진 사용자 입력의 길이를 표시
39+
CONTENT_TYPE = MIME_TYPE 클라이언트
40+
}

webserv

721 KB
Binary file not shown.

0 commit comments

Comments
 (0)