Skip to content

Commit 002e49d

Browse files
author
Wei Li
committed
error handling
1 parent 6212640 commit 002e49d

File tree

4 files changed

+159
-53
lines changed

4 files changed

+159
-53
lines changed

proxylab-handout/csapp.c

+71
Original file line numberDiff line numberDiff line change
@@ -920,6 +920,47 @@ ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
920920
return rc;
921921
}
922922

923+
924+
ssize_t rio_readn_ww(int fd, void *usrbuf, size_t n)
925+
{
926+
ssize_t rc;
927+
if ((rc = rio_readn(fd, usrbuf, n)) < 0) {
928+
fprintf(stderr, "[ERROR] read from %d failed\n",
929+
fd);
930+
}
931+
return rc;
932+
}
933+
934+
ssize_t rio_writen_ww(int fd, void *usrbuf, size_t n)
935+
{
936+
ssize_t rc;
937+
if ((rc = rio_writen(fd, usrbuf, n)) < 0) {
938+
fprintf(stderr, "[ERROR] write to %d failed\n",
939+
fd);
940+
}
941+
return rc;
942+
}
943+
944+
ssize_t rio_readnb_ww(rio_t *rp, void *usrbuf, size_t n)
945+
{
946+
ssize_t rc;
947+
if ((rc = rio_readnb(rp, usrbuf, n)) < 0) {
948+
fprintf(stderr, "[ERROR] read from %d failed\n",
949+
rp->rio_fd);
950+
}
951+
return rc;
952+
}
953+
954+
ssize_t rio_readlineb_ww(rio_t *rp, void *usrbuf, size_t maxlen)
955+
{
956+
ssize_t rc;
957+
if ((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0) {
958+
fprintf(stderr, "[ERROR] read from %d failed\n",
959+
rp->rio_fd);
960+
}
961+
return rc;
962+
}
963+
923964
/********************************
924965
* Client/server helper functions
925966
********************************/
@@ -1033,6 +1074,36 @@ int Open_listenfd(char *port)
10331074
return rc;
10341075
}
10351076

1077+
int open_clientfd_ww(char *hostname, char *port)
1078+
{
1079+
int rc;
1080+
if ((rc = open_clientfd(hostname, port)) < 0) {
1081+
fprintf(stderr, "[ERROR] open %s:%s failed\n",
1082+
hostname, port);
1083+
}
1084+
return rc;
1085+
}
1086+
1087+
int open_listenfd_ww(char *port)
1088+
{
1089+
int rc;
1090+
1091+
if ((rc = open_listenfd(port)) < 0) {
1092+
fprintf(stderr, "[ERROR] listen on %s failed\n",
1093+
port);
1094+
}
1095+
return rc;
1096+
}
1097+
1098+
void close_ww(int fd)
1099+
{
1100+
if (close(fd) < 0) {
1101+
fprintf(stderr, "[ERROR] %d is closed failed\n",
1102+
fd);
1103+
}
1104+
}
1105+
1106+
10361107
/* $end csapp.c */
10371108

10381109

proxylab-handout/csapp.h

+14
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,13 @@ void Rio_readinitb(rio_t *rp, int fd);
186186
ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n);
187187
ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen);
188188

189+
190+
/* rio read with warning message if error happended */
191+
ssize_t rio_readn_ww(int fd, void *usrbuf, size_t n);
192+
ssize_t rio_writen_ww(int fd, void *usrbuf, size_t n);
193+
ssize_t rio_readnb_ww(rio_t *rp, void *usrbuf, size_t n);
194+
ssize_t rio_readlineb_ww(rio_t *rp, void *usrbuf, size_t maxlen);
195+
189196
/* Reentrant protocol-independent client/server helpers */
190197
int open_clientfd(char *hostname, char *port);
191198
int open_listenfd(char *port);
@@ -195,5 +202,12 @@ int Open_clientfd(char *hostname, char *port);
195202
int Open_listenfd(char *port);
196203

197204

205+
/* reentrant protocol-independent client/server helpers with warning
206+
* message if error happended*/
207+
int open_clientfd_ww(char *hostname, char *porT);
208+
int open_listenfd_ww(char *port);
209+
void close_ww(int fd);
210+
211+
198212
#endif /* __CSAPP_H__ */
199213
/* $end csapp.h */

proxylab-handout/proxy.c

+73-53
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,27 @@ void usage()
3030
}
3131

3232

33-
void read_response(int infd)
34-
{
35-
rio_t rio;
36-
Rio_readinitb(&rio, infd);
37-
38-
char buf[MAXLINE];
39-
40-
while (Rio_readlineb(&rio, buf, MAXLINE)) {
41-
// TODO: empty return
42-
43-
printf("%s", buf);
44-
}
45-
}
4633

4734
void forward_response(const char *key, int infd, int outfd)
4835
{
4936
rio_t rio;
50-
Rio_readinitb(&rio, infd);
37+
rio_readinitb(&rio, infd);
5138

5239
char buf[MAXLINE];
5340
struct Bytes response;
5441
bytes_malloc(&response);
5542

56-
if (!Rio_readlineb(&rio, buf, MAXLINE)) {
57-
//TODO: error report
58-
return;
43+
if (!rio_readlineb_ww(&rio, buf, MAXLINE)) {
44+
// goto is used here to makes sure that
45+
// the bytes are freed.
46+
goto FORWARD_RESPONSE_RETURN;
5947
}
6048

6149
bytes_append(&response, buf);
6250

63-
Rio_readlineb(&rio, buf, MAXLINE);
51+
if (!rio_readlineb_ww(&rio, buf, MAXLINE)) {
52+
goto FORWARD_RESPONSE_RETURN;
53+
}
6454
char header_name[MAXLINE], header_value[MAXLINE];
6555
int content_length = 0;
6656
while (strcmp(buf, "\r\n")) {
@@ -69,26 +59,34 @@ void forward_response(const char *key, int infd, int outfd)
6959
content_length = atoi(header_value);
7060
}
7161
bytes_append(&response, buf);
72-
Rio_readlineb(&rio, buf, MAXLINE);
62+
if (!rio_readlineb_ww(&rio, buf, MAXLINE) < 0) {
63+
goto FORWARD_RESPONSE_RETURN;
64+
}
7365
}
7466
bytes_append(&response, buf);
7567

7668
if (content_length == 0) {
7769
// TODO: error handling
78-
return;
70+
fprintf(stderr, "Content-length is 0\n");
71+
goto FORWARD_RESPONSE_RETURN;
7972
} else {
8073
#ifdef DEBUG
8174
fprintf(stderr, "Content-length: %d\n", content_length);
8275
#endif
8376
// read content
84-
char *content_buf = (char *)Malloc((content_length+1)*sizeof(char));
85-
Rio_readnb(&rio, content_buf, content_length);
77+
char *content_buf = (char *)malloc((content_length+1)*sizeof(char));
78+
if (content_buf == NULL) {
79+
fprintf(stderr, "malloc failed\n");
80+
goto FORWARD_RESPONSE_RETURN;
81+
}
82+
if (!rio_readnb_ww(&rio, content_buf, content_length)) {
83+
goto FORWARD_RESPONSE_RETURN;
84+
}
8685
bytes_appendn(&response, content_buf, (size_t)content_length);
87-
Free(content_buf);
86+
free(content_buf);
8887
}
89-
if (Rio_readlineb(&rio, buf, MAXLINE) != 0) {
90-
// TODO: error handling
91-
return;
88+
if (rio_readlineb_ww(&rio, buf, MAXLINE) != 0) {
89+
goto FORWARD_RESPONSE_RETURN;
9290
}
9391

9492

@@ -97,36 +95,40 @@ void forward_response(const char *key, int infd, int outfd)
9795
// fprintf(stderr, "response:\n%s", string_cstr(response));
9896
#endif
9997

100-
Rio_writen(outfd,
101-
bytes_buf(response),
102-
bytes_length(response));
98+
if (!rio_writen_ww(outfd,
99+
bytes_buf(response),
100+
bytes_length(response))) {
101+
goto FORWARD_RESPONSE_RETURN;
102+
}
103103

104104
if (bytes_length(response) < MAX_OBJECT_SIZE) {
105-
P(&mutex);
105+
sem_wait(&mutex);
106106
lru_cache_insert(&lru_cache, key, bytes_buf(response),
107107
bytes_length(response));
108-
V(&mutex);
108+
sem_post(&mutex);
109109
}
110+
FORWARD_RESPONSE_RETURN:
110111
bytes_free(&response);
111112
}
112113

113114
void forward(int fromfd)
114115
{
115116
rio_t rio;
116-
Rio_readinitb(&rio, fromfd);
117+
rio_readinitb(&rio, fromfd);
117118
char linebuf[MAXLINE], method[MAXLINE], uri[MAXLINE],
118119
version[MAXLINE], host[MAXLINE],
119120
port[MAXLINE], dir[MAXLINE],
120121
request_buf[MAXBUF],
121122
header_name[MAXLINE],
122123
header_value[MAXLINE];
123124

124-
if (!Rio_readlineb(&rio, linebuf, MAXLINE)) {
125+
if (!rio_readlineb_ww(&rio, linebuf, MAXLINE)) {
125126
return;
126127
}
127128
sscanf(linebuf, "%s %s %s", method, uri, version);
128-
if (strcasecmp(method, "GET")) {
129+
if (strcasecmp(method, "GET") != 0) {
129130
// TODO
131+
fprintf(stderr, "[ERROR] method is not GET\n");
130132
return;
131133
}
132134
parse_uri(uri, host, port, dir);
@@ -136,22 +138,24 @@ void forward(int fromfd)
136138

137139
char formated_uri[MAXLINE];
138140
sprintf(formated_uri, "%s:%s%s", host, port, dir);
139-
P(&mutex);
141+
sem_wait(&mutex);
140142
lru_cache_node_t *pnode = lru_cache_find(&lru_cache, formated_uri);
141143

142144
if (pnode) {
143-
Rio_writen(fromfd, pnode->value, pnode->value_len);
144-
V(&mutex);
145+
rio_writen_ww(fromfd, pnode->value, pnode->value_len);
146+
sem_post(&mutex);
145147
return;
146148
}
147-
V(&mutex);
149+
sem_post(&mutex);
148150

149151
sprintf(request_buf, "%s %s %s\r\n", method, dir, version);
150152

151153
int has_host = 0;
152154
// request headers
153-
Rio_readlineb(&rio, linebuf, MAXLINE);
154-
while (strcmp(linebuf, "\r\n")) {
155+
if (rio_readlineb_ww(&rio, linebuf, MAXLINE) < 0) {
156+
return;
157+
}
158+
while (strcmp(linebuf, "\r\n") != 0) {
155159
parse_header(linebuf, header_name, header_value);
156160
// printf("header %s : %s\n", header_name, header_value);
157161
if (strcasecmp(header_name, "Host") == 0) {
@@ -166,7 +170,9 @@ void forward(int fromfd)
166170
} else {
167171
sprintf(request_buf, "%s%s", request_buf, linebuf);
168172
}
169-
Rio_readlineb(&rio, linebuf, MAXLINE);
173+
if (rio_readlineb_ww(&rio, linebuf, MAXLINE) < 0) {
174+
return;
175+
}
170176
}
171177
if (!has_host) {
172178
sprintf(request_buf, "%s%s: %s:%s\r\n", request_buf, "Host",
@@ -186,53 +192,67 @@ void forward(int fromfd)
186192
#ifdef DEBUG
187193
fprintf(stderr, "request buf:\n%s\n", request_buf);
188194
#endif
189-
int clientfd = Open_clientfd(host, port);
190-
Rio_writen(clientfd, request_buf, strlen(request_buf));
195+
int clientfd = open_clientfd_ww(host, port);
196+
if (clientfd < 0) {
197+
return ;
198+
}
199+
if (rio_writen_ww(clientfd, request_buf, strlen(request_buf)) < 0) {
200+
close_ww(clientfd);
201+
return;
202+
}
191203

192204
// receive data
193205
// read_response(clientfd);
194206

195207
forward_response(formated_uri, clientfd, fromfd);
196-
Close(clientfd);
208+
close_ww(clientfd);
197209
}
198210

199211
void *thread(void *vargp)
200212
{
201213
int connfd = *((int*)vargp);
202-
Pthread_detach(pthread_self());
203-
Free(vargp);
214+
pthread_detach(pthread_self());
215+
free(vargp);
204216
forward(connfd);
205-
Close(connfd);
217+
close(connfd);
206218
return NULL;
207219
}
208220

209221

222+
void sigpipe_handler(int sig)
223+
{
224+
fprintf(stderr, "[WARNING] Catch a sigpipe signal\n");
225+
}
226+
210227

211228
int main(int argc, char **argv)
212229
{
213-
// printf("%s%s%s", user_agent_hdr, accept_hdr, accept_encoding_hdr);
214-
215230
if (argc != 2) {
216231
usage();
217232
}
233+
Signal(SIGPIPE, sigpipe_handler);
218234
int listenfd = Open_listenfd(argv[1]);
219235
struct sockaddr_storage clientaddr;
220236
socklen_t clientlen = sizeof(clientaddr);
221237
int *connfdp;
222238
lru_cache_init(&lru_cache, MAX_CACHE_SIZE);
223-
Sem_init(&mutex, 0, 1);
239+
sem_init(&mutex, 0, 1);
224240
while (1) {
225-
connfdp = Malloc(sizeof(int));
241+
connfdp = malloc(sizeof(int));
242+
if (connfdp == NULL) {
243+
fprintf(stderr, "malloc failed\n");
244+
continue;
245+
}
226246
*connfdp = Accept(listenfd,
227247
(SA *)&clientaddr,
228248
&clientlen);
229249
if (*connfdp == -1) {
230-
Free(connfdp);
250+
free(connfdp);
231251
// TODO: error report
232252
} else {
233253
// TODO: use thread pool
234254
pthread_t tid;
235-
Pthread_create(&tid, NULL, thread, connfdp);
255+
pthread_create(&tid, NULL, thread, connfdp);
236256
}
237257
}
238258
lru_cache_free(&lru_cache);

proxylab-handout/util.h

+1
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@ void parse_uri(const char *uri, char *host, char *port, char *dir);
1818

1919
void parse_header(const char *line, char *name, char *value);
2020

21+
2122
#endif

0 commit comments

Comments
 (0)