Changeset 2116
- Timestamp:
- 03/02/2008 03:42:14 PM (6 months ago)
- Location:
- trunk
- Files:
-
- 2 modified
-
NEWS (modified) (1 diff)
-
src/mod_cgi.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/NEWS
r2110 r2116 20 20 * fix sending source of cgi script instead of 500 error if fork fails 21 21 * fix min-procs handling in mod_scgi.c, just set to max-procs (patch from #623) 22 * mod_cgi: add a event-handler for STDERR_FILENO and log it with ERROR() 22 23 23 24 - 1.5.0-r19.. - -
trunk/src/mod_cgi.c
r2108 r2116 78 78 79 79 iosocket *sock; 80 iosocket *sock_err; 80 81 iosocket *wb_sock; 81 82 82 83 chunkqueue *rb; 84 chunkqueue *rb_err; 83 85 chunkqueue *wb; 84 86 … … 93 95 94 96 sess->sock = iosocket_init(); 97 sess->sock_err = iosocket_init(); 95 98 sess->wb_sock = iosocket_init(); 96 99 sess->wb = chunkqueue_init(); 97 100 sess->rb = chunkqueue_init(); 101 sess->rb_err = chunkqueue_init(); 98 102 99 103 return sess; … … 104 108 105 109 iosocket_free(sess->sock); 110 iosocket_free(sess->sock_err); 106 111 iosocket_free(sess->wb_sock); 107 112 108 113 chunkqueue_free(sess->wb); 109 114 chunkqueue_free(sess->rb); 115 chunkqueue_free(sess->rb_err); 110 116 111 117 free(sess); … … 402 408 } 403 409 410 if (sess->sock_err->fd != -1) { 411 /* close connection to the cgi-script */ 412 fdevent_event_del(srv->ev, sess->sock_err); 413 fdevent_unregister(srv->ev, sess->sock_err); 414 } 415 404 416 if (sess->wb_sock->fd != -1) { 405 417 close(sess->wb_sock->fd); … … 547 559 } 548 560 561 /* so all cgi errors have the same source line as origin */ 562 static void cgi_log_err(const char *msg) { 563 ERROR("error from cgi: %s", msg); 564 } 565 566 static void cgi_copy_err(chunkqueue *cq) { 567 buffer *line = buffer_init(); 568 chunk *c; 569 570 for (c = cq->first; c; c = c->next) { 571 off_t we_have; 572 char *str, *nl; 573 574 if (c->type != MEM_CHUNK) { 575 ERROR("%s", "wrong chunk type"); 576 chunk_set_done(c); 577 continue; 578 } 579 580 we_have = c->mem->used - 1 - c->offset; 581 str = c->mem->ptr + c->offset; 582 if (we_have <= 0) continue; 583 584 for ( ; NULL != (nl = strchr(str, '\n')); str = nl+1) { 585 *nl = '\0'; 586 if (!buffer_is_empty(line)) { 587 buffer_append_string(line, str); 588 cgi_log_err(SAFE_BUF_STR(line)); 589 buffer_reset(line); 590 } else { 591 cgi_log_err(str); 592 } 593 } 594 if (*str) { 595 buffer_append_string(line, str); 596 } 597 chunk_set_done(c); 598 } 599 600 if (!buffer_is_empty(line)) { 601 cgi_log_err(SAFE_BUF_STR(line)); 602 } 603 chunkqueue_remove_finished_chunks(cq); 604 } 605 606 static handler_t cgi_handle_err_fdevent(void *s, void *ctx, int revents) { 607 server *srv = (server *)s; 608 cgi_session *sess = ctx; 609 connection *con = sess->remote_con; 610 611 if (revents & FDEVENT_IN) { 612 switch (srv->network_backend_read(srv, con, sess->sock_err, sess->rb_err)) { 613 case NETWORK_STATUS_CONNECTION_CLOSE: 614 fdevent_event_del(srv->ev, sess->sock_err); 615 616 /* connection closed. close the read chunkqueue. */ 617 sess->rb_err->is_closed = 1; 618 break; 619 case NETWORK_STATUS_SUCCESS: 620 break; 621 default: 622 ERROR("%s", "oops, we failed to read"); 623 break; 624 } 625 626 cgi_copy_err(sess->rb_err); 627 } 628 629 if (revents & FDEVENT_ERR) { 630 fdevent_event_del(srv->ev, sess->sock_err); 631 } 632 633 return HANDLER_FINISHED; 634 } 635 549 636 550 637 static int cgi_env_add(char_array *env, const char *key, size_t key_len, const char *val, size_t val_len) { … … 581 668 int to_cgi_fds[2]; 582 669 int from_cgi_fds[2]; 670 int from_cgi_err_fds[2]; 583 671 struct stat st; 584 672 … … 601 689 602 690 if (pipe(from_cgi_fds)) { 691 close(to_cgi_fds[0]); close(to_cgi_fds[1]); 692 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno)); 693 return -1; 694 } 695 696 if (pipe(from_cgi_err_fds)) { 697 close(to_cgi_fds[0]); close(to_cgi_fds[1]); 698 close(from_cgi_fds[0]); close(from_cgi_fds[1]); 603 699 log_error_write(srv, __FILE__, __LINE__, "ss", "pipe failed:", strerror(errno)); 604 700 return -1; … … 626 722 close(from_cgi_fds[0]); 627 723 724 /* move stderr to from_cgi_err_fd[1] */ 725 close(STDERR_FILENO); 726 dup2(from_cgi_err_fds[1], STDERR_FILENO); 727 close(from_cgi_err_fds[1]); 728 /* not needed */ 729 close(from_cgi_err_fds[0]); 730 628 731 /* move the stdin to to_cgi_fd[0] */ 629 732 close(STDIN_FILENO); … … 632 735 /* not needed */ 633 736 close(to_cgi_fds[1]); 634 635 /**636 * FIXME: add a event-handler for STDERR_FILENO and let it LOG()637 */638 639 close(STDERR_FILENO);640 737 641 738 /* create environment */ … … 860 957 /* error */ 861 958 ERROR("fork() failed: %s", strerror(errno)); 959 close(to_cgi_fds[0]); close(to_cgi_fds[1]); 960 close(from_cgi_fds[0]); close(from_cgi_fds[1]); 961 close(from_cgi_err_fds[0]); close(from_cgi_err_fds[1]); 862 962 return -1; 863 963 break; … … 867 967 868 968 close(from_cgi_fds[1]); 969 close(from_cgi_err_fds[1]); 869 970 close(to_cgi_fds[0]); 870 971 … … 882 983 sess->sock->fd = from_cgi_fds[0]; 883 984 sess->sock->type = IOSOCKET_TYPE_PIPE; 985 sess->sock_err->fd = from_cgi_err_fds[0]; 986 sess->sock_err->type = IOSOCKET_TYPE_PIPE; 884 987 sess->wb_sock->fd = to_cgi_fds[1]; 885 988 sess->wb_sock->type = IOSOCKET_TYPE_PIPE; … … 893 996 } 894 997 998 if (-1 == fdevent_fcntl_set(srv->ev, sess->sock_err)) { 999 log_error_write(srv, __FILE__, __LINE__, "ss", "fcntl failed: ", strerror(errno)); 1000 1001 cgi_session_free(sess); 1002 1003 return -1; 1004 } 1005 895 1006 con->plugin_ctx[p->id] = sess; 896 1007 897 1008 fdevent_register(srv->ev, sess->sock, cgi_handle_fdevent, sess); 898 1009 fdevent_event_add(srv->ev, sess->sock, FDEVENT_IN); 1010 1011 fdevent_register(srv->ev, sess->sock_err, cgi_handle_err_fdevent, sess); 1012 fdevent_event_add(srv->ev, sess->sock_err, FDEVENT_IN); 899 1013 900 1014 sess->state = CGI_STATE_READ_RESPONSE_HEADER; … … 1090 1204 fdevent_unregister(srv->ev, sess->sock); 1091 1205 1206 fdevent_event_del(srv->ev, sess->sock_err); 1207 fdevent_unregister(srv->ev, sess->sock_err); 1208 1092 1209 cgi_session_free(sess); 1093 1210 sess = NULL; … … 1113 1230 fdevent_event_del(srv->ev, sess->sock); 1114 1231 fdevent_unregister(srv->ev, sess->sock); 1232 1233 fdevent_event_del(srv->ev, sess->sock_err); 1234 fdevent_unregister(srv->ev, sess->sock_err); 1115 1235 1116 1236 cgi_session_free(sess);

