Changeset d076f16 in mainline
- Timestamp:
- 2017-09-28T17:01:16Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 91b60499
- Parents:
- 7b616e2
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/websrv/websrv.c
r7b616e2 rd076f16 75 75 static uint16_t port = DEFAULT_PORT; 76 76 77 static char rbuf[BUFFER_SIZE]; 78 static size_t rbuf_out; 79 static size_t rbuf_in; 80 81 static char lbuf[BUFFER_SIZE + 1]; 82 static size_t lbuf_used; 83 84 static char fbuf[BUFFER_SIZE]; 77 typedef struct { 78 tcp_conn_t *conn; 79 80 char rbuf[BUFFER_SIZE]; 81 size_t rbuf_out; 82 size_t rbuf_in; 83 84 char lbuf[BUFFER_SIZE + 1]; 85 size_t lbuf_used; 86 } recv_t; 85 87 86 88 static bool verbose = false; … … 131 133 "</html>\r\n"; 132 134 135 136 static int recv_create(tcp_conn_t *conn, recv_t **rrecv) 137 { 138 recv_t *recv; 139 140 recv = calloc(1, sizeof(recv_t)); 141 if (recv == NULL) 142 return ENOMEM; 143 144 recv->conn = conn; 145 recv->rbuf_out = 0; 146 recv->rbuf_in = 0; 147 recv->lbuf_used = 0; 148 149 *rrecv = recv; 150 return EOK; 151 } 152 153 static void recv_destroy(recv_t *recv) 154 { 155 free(recv); 156 } 157 133 158 /** Receive one character (with buffering) */ 134 static int recv_char( tcp_conn_t *conn, char *c)159 static int recv_char(recv_t *recv, char *c) 135 160 { 136 161 size_t nrecv; 137 162 int rc; 138 163 139 if (r buf_out ==rbuf_in) {140 r buf_out = 0;141 r buf_in = 0;142 143 rc = tcp_conn_recv_wait( conn,rbuf, BUFFER_SIZE, &nrecv);164 if (recv->rbuf_out == recv->rbuf_in) { 165 recv->rbuf_out = 0; 166 recv->rbuf_in = 0; 167 168 rc = tcp_conn_recv_wait(recv->conn, recv->rbuf, BUFFER_SIZE, &nrecv); 144 169 if (rc != EOK) { 145 170 fprintf(stderr, "tcp_conn_recv() failed (%d)\n", rc); … … 147 172 } 148 173 149 r buf_in = nrecv;150 } 151 152 *c = r buf[rbuf_out++];174 recv->rbuf_in = nrecv; 175 } 176 177 *c = recv->rbuf[recv->rbuf_out++]; 153 178 return EOK; 154 179 } 155 180 156 181 /** Receive one line with length limit */ 157 static int recv_line( tcp_conn_t *conn)158 { 159 char *bp = lbuf;182 static int recv_line(recv_t *recv, char **rbuf) 183 { 184 char *bp = recv->lbuf; 160 185 char c = '\0'; 161 186 162 while (bp < lbuf + BUFFER_SIZE) {187 while (bp < recv->lbuf + BUFFER_SIZE) { 163 188 char prev = c; 164 int rc = recv_char( conn, &c);189 int rc = recv_char(recv, &c); 165 190 166 191 if (rc != EOK) … … 172 197 } 173 198 174 lbuf_used = bp -lbuf;199 recv->lbuf_used = bp - recv->lbuf; 175 200 *bp = '\0'; 176 201 177 if (bp == lbuf + BUFFER_SIZE)202 if (bp == recv->lbuf + BUFFER_SIZE) 178 203 return ELIMIT; 179 204 205 *rbuf = recv->lbuf; 180 206 return EOK; 181 207 } … … 218 244 static int uri_get(const char *uri, tcp_conn_t *conn) 219 245 { 246 char *fbuf = NULL; 247 char *fname = NULL; 248 int rc; 249 int fd = -1; 250 251 fbuf = calloc(BUFFER_SIZE, 1); 252 if (fbuf == NULL) { 253 rc = ENOMEM; 254 goto out; 255 } 256 220 257 if (str_cmp(uri, "/") == 0) 221 258 uri = "/index.html"; 222 259 223 char *fname; 224 int rc = asprintf(&fname, "%s%s", WEB_ROOT, uri); 225 if (rc < 0) 226 return ENOMEM; 227 228 int fd = vfs_lookup_open(fname, WALK_REGULAR, MODE_READ); 260 rc = asprintf(&fname, "%s%s", WEB_ROOT, uri); 261 if (rc < 0) { 262 rc = ENOMEM; 263 goto out; 264 } 265 266 fd = vfs_lookup_open(fname, WALK_REGULAR, MODE_READ); 229 267 if (fd < 0) { 230 268 rc = send_response(conn, msg_not_found); 231 free(fname); 232 return rc; 269 goto out; 233 270 } 234 271 235 272 free(fname); 273 fname = NULL; 236 274 237 275 rc = send_response(conn, msg_ok); 238 276 if (rc != EOK) 239 return rc;277 goto out; 240 278 241 279 aoff64_t pos = 0; … … 246 284 247 285 if (nr < 0) { 248 vfs_put(fd);249 return EIO;286 rc = EIO; 287 goto out; 250 288 } 251 289 … … 253 291 if (rc != EOK) { 254 292 fprintf(stderr, "tcp_conn_send() failed\n"); 255 vfs_put(fd); 256 return rc; 293 goto out; 257 294 } 258 295 } 259 296 260 vfs_put(fd); 261 262 return EOK; 263 } 264 265 static int req_process(tcp_conn_t *conn) 266 { 267 int rc = recv_line(conn); 297 rc = EOK; 298 out: 299 if (fd >= 0) 300 vfs_put(fd); 301 free(fname); 302 free(fbuf); 303 return rc; 304 } 305 306 static int req_process(tcp_conn_t *conn, recv_t *recv) 307 { 308 char *reqline = NULL; 309 310 int rc = recv_line(recv, &reqline); 268 311 if (rc != EOK) { 269 312 fprintf(stderr, "recv_line() failed\n"); … … 272 315 273 316 if (verbose) 274 fprintf(stderr, "Request: %s", lbuf);275 276 if (str_lcmp( lbuf, "GET ", 4) != 0) {317 fprintf(stderr, "Request: %s", reqline); 318 319 if (str_lcmp(reqline, "GET ", 4) != 0) { 277 320 rc = send_response(conn, msg_not_implemented); 278 321 return rc; 279 322 } 280 323 281 char *uri = lbuf+ 4;324 char *uri = reqline + 4; 282 325 char *end_uri = str_chr(uri, ' '); 283 326 if (end_uri == NULL) { 284 end_uri = lbuf + lbuf_used- 2;327 end_uri = reqline + str_size(reqline) - 2; 285 328 assert(*end_uri == '\r'); 286 329 } … … 300 343 static void usage(void) 301 344 { 302 printf("S keletalserver\n"345 printf("Simple web server\n" 303 346 "\n" 304 347 "Usage: " NAME " [options]\n" … … 363 406 { 364 407 int rc; 408 recv_t *recv = NULL; 365 409 366 410 if (verbose) 367 411 fprintf(stderr, "New connection, waiting for request\n"); 368 412 369 rbuf_out = 0; 370 rbuf_in = 0; 371 372 rc = req_process(conn); 413 rc = recv_create(conn, &recv); 414 if (rc != EOK) { 415 fprintf(stderr, "Out of memory.\n"); 416 goto error; 417 } 418 419 rc = req_process(conn, recv); 373 420 if (rc != EOK) { 374 421 fprintf(stderr, "Error processing request (%s)\n", 375 422 str_error(rc)); 376 return;377 } 378 423 goto error; 424 } 425 379 426 rc = tcp_conn_send_fin(conn); 380 427 if (rc != EOK) { 381 428 fprintf(stderr, "Error sending FIN.\n"); 382 return; 383 } 429 goto error; 430 } 431 432 recv_destroy(recv); 433 return; 434 error: 435 rc = tcp_conn_reset(conn); 436 if (rc != EOK) 437 fprintf(stderr, "Error resetting connection.\n"); 438 439 recv_destroy(recv); 384 440 } 385 441
Note:
See TracChangeset
for help on using the changeset viewer.