@@ -30,37 +30,27 @@ void usage()
30
30
}
31
31
32
32
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
- }
46
33
47
34
void forward_response (const char * key , int infd , int outfd )
48
35
{
49
36
rio_t rio ;
50
- Rio_readinitb (& rio , infd );
37
+ rio_readinitb (& rio , infd );
51
38
52
39
char buf [MAXLINE ];
53
40
struct Bytes response ;
54
41
bytes_malloc (& response );
55
42
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 ;
59
47
}
60
48
61
49
bytes_append (& response , buf );
62
50
63
- Rio_readlineb (& rio , buf , MAXLINE );
51
+ if (!rio_readlineb_ww (& rio , buf , MAXLINE )) {
52
+ goto FORWARD_RESPONSE_RETURN ;
53
+ }
64
54
char header_name [MAXLINE ], header_value [MAXLINE ];
65
55
int content_length = 0 ;
66
56
while (strcmp (buf , "\r\n" )) {
@@ -69,26 +59,34 @@ void forward_response(const char *key, int infd, int outfd)
69
59
content_length = atoi (header_value );
70
60
}
71
61
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
+ }
73
65
}
74
66
bytes_append (& response , buf );
75
67
76
68
if (content_length == 0 ) {
77
69
// TODO: error handling
78
- return ;
70
+ fprintf (stderr , "Content-length is 0\n" );
71
+ goto FORWARD_RESPONSE_RETURN ;
79
72
} else {
80
73
#ifdef DEBUG
81
74
fprintf (stderr , "Content-length: %d\n" , content_length );
82
75
#endif
83
76
// 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
+ }
86
85
bytes_appendn (& response , content_buf , (size_t )content_length );
87
- Free (content_buf );
86
+ free (content_buf );
88
87
}
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 ;
92
90
}
93
91
94
92
@@ -97,36 +95,40 @@ void forward_response(const char *key, int infd, int outfd)
97
95
// fprintf(stderr, "response:\n%s", string_cstr(response));
98
96
#endif
99
97
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
+ }
103
103
104
104
if (bytes_length (response ) < MAX_OBJECT_SIZE ) {
105
- P (& mutex );
105
+ sem_wait (& mutex );
106
106
lru_cache_insert (& lru_cache , key , bytes_buf (response ),
107
107
bytes_length (response ));
108
- V (& mutex );
108
+ sem_post (& mutex );
109
109
}
110
+ FORWARD_RESPONSE_RETURN :
110
111
bytes_free (& response );
111
112
}
112
113
113
114
void forward (int fromfd )
114
115
{
115
116
rio_t rio ;
116
- Rio_readinitb (& rio , fromfd );
117
+ rio_readinitb (& rio , fromfd );
117
118
char linebuf [MAXLINE ], method [MAXLINE ], uri [MAXLINE ],
118
119
version [MAXLINE ], host [MAXLINE ],
119
120
port [MAXLINE ], dir [MAXLINE ],
120
121
request_buf [MAXBUF ],
121
122
header_name [MAXLINE ],
122
123
header_value [MAXLINE ];
123
124
124
- if (!Rio_readlineb (& rio , linebuf , MAXLINE )) {
125
+ if (!rio_readlineb_ww (& rio , linebuf , MAXLINE )) {
125
126
return ;
126
127
}
127
128
sscanf (linebuf , "%s %s %s" , method , uri , version );
128
- if (strcasecmp (method , "GET" )) {
129
+ if (strcasecmp (method , "GET" ) != 0 ) {
129
130
// TODO
131
+ fprintf (stderr , "[ERROR] method is not GET\n" );
130
132
return ;
131
133
}
132
134
parse_uri (uri , host , port , dir );
@@ -136,22 +138,24 @@ void forward(int fromfd)
136
138
137
139
char formated_uri [MAXLINE ];
138
140
sprintf (formated_uri , "%s:%s%s" , host , port , dir );
139
- P (& mutex );
141
+ sem_wait (& mutex );
140
142
lru_cache_node_t * pnode = lru_cache_find (& lru_cache , formated_uri );
141
143
142
144
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 );
145
147
return ;
146
148
}
147
- V (& mutex );
149
+ sem_post (& mutex );
148
150
149
151
sprintf (request_buf , "%s %s %s\r\n" , method , dir , version );
150
152
151
153
int has_host = 0 ;
152
154
// 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 ) {
155
159
parse_header (linebuf , header_name , header_value );
156
160
// printf("header %s : %s\n", header_name, header_value);
157
161
if (strcasecmp (header_name , "Host" ) == 0 ) {
@@ -166,7 +170,9 @@ void forward(int fromfd)
166
170
} else {
167
171
sprintf (request_buf , "%s%s" , request_buf , linebuf );
168
172
}
169
- Rio_readlineb (& rio , linebuf , MAXLINE );
173
+ if (rio_readlineb_ww (& rio , linebuf , MAXLINE ) < 0 ) {
174
+ return ;
175
+ }
170
176
}
171
177
if (!has_host ) {
172
178
sprintf (request_buf , "%s%s: %s:%s\r\n" , request_buf , "Host" ,
@@ -186,53 +192,67 @@ void forward(int fromfd)
186
192
#ifdef DEBUG
187
193
fprintf (stderr , "request buf:\n%s\n" , request_buf );
188
194
#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
+ }
191
203
192
204
// receive data
193
205
// read_response(clientfd);
194
206
195
207
forward_response (formated_uri , clientfd , fromfd );
196
- Close (clientfd );
208
+ close_ww (clientfd );
197
209
}
198
210
199
211
void * thread (void * vargp )
200
212
{
201
213
int connfd = * ((int * )vargp );
202
- Pthread_detach (pthread_self ());
203
- Free (vargp );
214
+ pthread_detach (pthread_self ());
215
+ free (vargp );
204
216
forward (connfd );
205
- Close (connfd );
217
+ close (connfd );
206
218
return NULL ;
207
219
}
208
220
209
221
222
+ void sigpipe_handler (int sig )
223
+ {
224
+ fprintf (stderr , "[WARNING] Catch a sigpipe signal\n" );
225
+ }
226
+
210
227
211
228
int main (int argc , char * * argv )
212
229
{
213
- // printf("%s%s%s", user_agent_hdr, accept_hdr, accept_encoding_hdr);
214
-
215
230
if (argc != 2 ) {
216
231
usage ();
217
232
}
233
+ Signal (SIGPIPE , sigpipe_handler );
218
234
int listenfd = Open_listenfd (argv [1 ]);
219
235
struct sockaddr_storage clientaddr ;
220
236
socklen_t clientlen = sizeof (clientaddr );
221
237
int * connfdp ;
222
238
lru_cache_init (& lru_cache , MAX_CACHE_SIZE );
223
- Sem_init (& mutex , 0 , 1 );
239
+ sem_init (& mutex , 0 , 1 );
224
240
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
+ }
226
246
* connfdp = Accept (listenfd ,
227
247
(SA * )& clientaddr ,
228
248
& clientlen );
229
249
if (* connfdp == -1 ) {
230
- Free (connfdp );
250
+ free (connfdp );
231
251
// TODO: error report
232
252
} else {
233
253
// TODO: use thread pool
234
254
pthread_t tid ;
235
- Pthread_create (& tid , NULL , thread , connfdp );
255
+ pthread_create (& tid , NULL , thread , connfdp );
236
256
}
237
257
}
238
258
lru_cache_free (& lru_cache );
0 commit comments