-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathHandler.cpp
More file actions
109 lines (104 loc) · 3.12 KB
/
Copy pathHandler.cpp
File metadata and controls
109 lines (104 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include "http/Handler.h"
void Handler::bind(int sockfd)
{
this->sockfd = sockfd;
read_buffer.clear();
write_buffer.clear();
write_index = 0;
int old_option = fcntl(sockfd, F_GETFL);
int new_option = old_option | O_NONBLOCK;
fcntl(sockfd, F_SETFL, new_option);
state = READ;
http_request = new HttpRequest();
struct epoll_event temp_ep_event;
temp_ep_event.events = EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLONESHOT;
temp_ep_event.data.fd = sockfd;
epoll_ctl(Server::getEpollFd(), EPOLL_CTL_ADD, sockfd, &temp_ep_event);
}
void Handler::debind()
{
Log::log(string("debind fd ") + to_string(sockfd), DEBUG);
delete http_response;
http_response = nullptr;
delete http_request;
http_request = nullptr;
epoll_ctl(Server::getEpollFd(), EPOLL_CTL_DEL, sockfd, 0);
close(sockfd);
}
void Handler::run()
{
if (state == READ)
{
//进行解析
Status read_state = http_request->parse(read_buffer);
if (read_state == BAD_REQUEST){
throw runtime_error("bad request");
}
else if (read_state == READ_AGAIN){
struct epoll_event temp_ep_event;
temp_ep_event.events = EPOLLIN | EPOLLET | EPOLLRDHUP | EPOLLONESHOT;
temp_ep_event.data.fd = sockfd;
epoll_ctl(Server::getEpollFd(), EPOLL_CTL_MOD, sockfd, &temp_ep_event);
return;
}
http_response = new HttpResponse(read_state);
http_response->doRequest(http_request);
write_buffer = string(http_response->getResponse());
state = WRITE;
struct epoll_event temp_ep_event;
temp_ep_event.events = EPOLLOUT | EPOLLET | EPOLLRDHUP | EPOLLONESHOT;
temp_ep_event.data.fd = sockfd;
epoll_ctl(Server::getEpollFd(), EPOLL_CTL_MOD, sockfd, &temp_ep_event);
return;
}
}
void Handler::read()
{
int byte_read = 0;
char buffer[1000];
while (1)
{
byte_read = recv(sockfd, buffer, 900, 0);
if (byte_read == -1)
{
if (errno == EAGAIN || errno == EWOULDBLOCK)
break;
else
throw runtime_error("system error");
}
else if (byte_read == 0)
throw runtime_error("client closed");
read_buffer += buffer;
}
}
void Handler::write()
{
if (write_index >= write_buffer.size())
{
bind(sockfd);
return;
}
while (1)
{
int temp = send(sockfd, write_buffer.c_str() + write_index, write_buffer.size() - write_index, 0);
if (temp < 0)
{
if (errno == EAGAIN)
{
struct epoll_event temp_ep_event;
temp_ep_event.events = EPOLLOUT | EPOLLET | EPOLLRDHUP | EPOLLONESHOT;
temp_ep_event.data.fd = sockfd;
epoll_ctl(Server::getEpollFd(), EPOLL_CTL_MOD, sockfd, &temp_ep_event);
break;
}
else
throw runtime_error(strerror(errno));
}
write_index += temp;
if (write_index >= write_buffer.size())
{
debind();
break;
}
}
}