# HG changeset patch # User Igor Sysoev # Date 1094570962 0 # Node ID 0526206251f6d30ff9d36ef32e6aa2a8d191473e # Parent b9bd635011de1debeee7ea63bd4678262b9affea nginx-0.0.10-2004-09-07-19:29:22 import diff --git a/auto/make b/auto/make --- a/auto/make +++ b/auto/make @@ -1,7 +1,8 @@ mkdir -p $OBJS/src/core $OBJS/src/event $OBJS/src/event/modules \ $OBJS/src/os/unix $OBJS/src/os/win32 \ - $OBJS/src/http $OBJS/src/http/modules $OBJS/src/http/modules/proxy + $OBJS/src/http $OBJS/src/http/modules $OBJS/src/http/modules/proxy \ + $OBJS/src/imap echo "CC = $CC" > $MAKEFILE @@ -18,13 +19,15 @@ if [ $MAKE_SL = YES ]; then echo >> $MAKEFILE fi -all_inc="$CORE_INCS $OBJS $HTTP_INCS" +all_inc="$CORE_INCS $OBJS $HTTP_INCS $IMAP_INCS" all_inc=`echo " $all_inc" | sed -e "s/ \([^ ]\)/ $INCOPT\1/g"` all_inc=`echo $all_inc | sed -e "s/\//$DIRSEP/g"` echo "ALL_INCS = $all_inc" >> $MAKEFILE echo >> $MAKEFILE +all_srcs="$CORE_SRCS" + # CORE_DEPS @@ -60,38 +63,84 @@ echo "CORE_INCS = $inc" echo >> $MAKEFILE -# HTTP_DEPS +if [ $HTTP = YES ]; then + + all_srcs="$all_srcs $HTTP_SRCS" + + # HTTP_DEPS + + if [ $MAKE_SL = YES ]; then + echo $ngx_n "HTTP_DEPS =" $ngx_c >> $MAKEFILE + else + echo "HTTP_DEPS = \\" >> $MAKEFILE + fi -if [ $MAKE_SL = YES ]; then - echo $ngx_n "HTTP_DEPS =" $ngx_c >> $MAKEFILE -else - echo "HTTP_DEPS = \\" >> $MAKEFILE -fi + for dep in $HTTP_DEPS + do + dep=`echo $dep | sed -e "s/\//$DIRSEP/g"` -for dep in $HTTP_DEPS -do - dep=`echo $dep | sed -e "s/\//$DIRSEP/g"` + if [ $MAKE_SL = YES ]; then + echo $ngx_n " $dep" $ngx_c >> $MAKEFILE + else + echo " $dep \\" >> $MAKEFILE + fi + done + echo >> $MAKEFILE + + + # HTTP_INCS if [ $MAKE_SL = YES ]; then - echo $ngx_n " $dep" $ngx_c >> $MAKEFILE - else - echo " $dep \\" >> $MAKEFILE + echo >> $MAKEFILE fi -done -echo >> $MAKEFILE + + inc="$HTTP_INCS $OBJS" + inc=`echo " $inc" | sed -e "s/ \([^ ]\)/ $INCOPT\1/g" -e "s/\//$DIRSEP/g"` + + echo "HTTP_INCS = $inc" >> $MAKEFILE + echo >> $MAKEFILE + +fi -# HTTP_INCS +if [ $IMAP = YES ]; then + + all_srcs="$all_srcs $IMAP_SRCS" + + # IMAP_DEPS -if [ $MAKE_SL = YES ]; then - echo >> $MAKEFILE -fi + if [ $MAKE_SL = YES ]; then + echo $ngx_n "IMAP_DEPS =" $ngx_c >> $MAKEFILE + else + echo "IMAP_DEPS = \\" >> $MAKEFILE + fi + + for dep in $IMAP_DEPS + do + dep=`echo $dep | sed -e "s/\//$DIRSEP/g"` -inc="$HTTP_INCS $OBJS" -inc=`echo " $inc" | sed -e "s/ \([^ ]\)/ $INCOPT\1/g" -e "s/\//$DIRSEP/g"` + if [ $MAKE_SL = YES ]; then + echo $ngx_n " $dep" $ngx_c >> $MAKEFILE + else + echo " $dep \\" >> $MAKEFILE + fi + done + echo >> $MAKEFILE + + + # IMAP_INCS -echo "HTTP_INCS = $inc" >> $MAKEFILE -echo >> $MAKEFILE + if [ $MAKE_SL = YES ]; then + echo >> $MAKEFILE + fi + + inc="$IMAP_INCS $OBJS" + inc=`echo " $inc" | sed -e "s/ \([^ ]\)/ $INCOPT\1/g" -e "s/\//$DIRSEP/g"` + + echo "IMAP_INCS = $inc" >> $MAKEFILE + echo >> $MAKEFILE + +fi # nginx @@ -105,7 +154,7 @@ fi # nginx deps -for src in $CORE_SRCS $HTTP_SRCS +for src in $all_srcs do obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/" -e "s/\.S\$/.$OBJEXT/"` obj=`echo $OBJS/$obj | sed -e "s/\//$DIRSEP/g"` @@ -142,7 +191,7 @@ fi # nginx build sources -for src in $CORE_SRCS $HTTP_SRCS +for src in $all_srcs do obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/" -e "s/\.S\$/.$OBJEXT/"` obj=`echo $OBJS/$obj | sed -e "s/\//$DIRSEP/g"` @@ -223,33 +272,72 @@ done # http sources -deps="\$(CORE_DEPS) \$(HTTP_DEPS)" +if [ $HTTP = YES ]; then + + deps="\$(CORE_DEPS) \$(HTTP_DEPS)" + + if [ $PCH != NO ]; then + args="\$(CFLAGS) $USEPCH \$(ALL_INCS)" + else + args="\$(CFLAGS) $USEPCH \$(CORE_INCS) \$(HTTP_INCS)" + fi -if [ $PCH != NO ]; then - args="\$(CFLAGS) $USEPCH \$(ALL_INCS)" -else - args="\$(CFLAGS) $USEPCH \$(CORE_INCS) \$(HTTP_INCS)" + for src in $HTTP_SRCS + do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + obj=`echo $OBJS/$obj | sed -e "s/\//$DIRSEP/g"` + src=`echo $src | sed -e "s/\//$DIRSEP/g"` + + if [ $MAKE_SL = YES ]; then + echo "$obj: $src $deps" >> $MAKEFILE + echo " \$(CC) $COMPOPT $args $OBJOUT$obj $src" >> $MAKEFILE + echo >> $MAKEFILE + else + echo "$obj: \\" >> $MAKEFILE + echo " $src $deps" >> $MAKEFILE + echo " \$(CC) $COMPOPT $args \\" >> $MAKEFILE + echo " $OBJOUT$obj \\" >> $MAKEFILE + echo " $src" >> $MAKEFILE + echo >> $MAKEFILE + fi + done + fi -for src in $HTTP_SRCS -do - obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` - obj=`echo $OBJS/$obj | sed -e "s/\//$DIRSEP/g"` - src=`echo $src | sed -e "s/\//$DIRSEP/g"` + +# imap sources + +if [ $IMAP = YES ]; then + + deps="\$(CORE_DEPS) \$(IMAP_DEPS)" + + if [ $PCH != NO ]; then + args="\$(CFLAGS) $USEPCH \$(ALL_INCS)" + else + args="\$(CFLAGS) $USEPCH \$(CORE_INCS) \$(IMAP_INCS)" + fi - if [ $MAKE_SL = YES ]; then - echo "$obj: $src $deps" >> $MAKEFILE - echo " \$(CC) $COMPOPT $args $OBJOUT$obj $src" >> $MAKEFILE - echo >> $MAKEFILE - else - echo "$obj: \\" >> $MAKEFILE - echo " $src $deps" >> $MAKEFILE - echo " \$(CC) $COMPOPT $args \\" >> $MAKEFILE - echo " $OBJOUT$obj \\" >> $MAKEFILE - echo " $src" >> $MAKEFILE - echo >> $MAKEFILE - fi -done + for src in $IMAP_SRCS + do + obj=`echo $src | sed -e "s/\.c\$/.$OBJEXT/"` + obj=`echo $OBJS/$obj | sed -e "s/\//$DIRSEP/g"` + src=`echo $src | sed -e "s/\//$DIRSEP/g"` + + if [ $MAKE_SL = YES ]; then + echo "$obj: $src $deps" >> $MAKEFILE + echo " \$(CC) $COMPOPT $args $OBJOUT$obj $src" >> $MAKEFILE + echo >> $MAKEFILE + else + echo "$obj: \\" >> $MAKEFILE + echo " $src $deps" >> $MAKEFILE + echo " \$(CC) $COMPOPT $args \\" >> $MAKEFILE + echo " $OBJOUT$obj \\" >> $MAKEFILE + echo " $src" >> $MAKEFILE + echo >> $MAKEFILE + fi + done + +fi # precompiled headers diff --git a/auto/modules b/auto/modules --- a/auto/modules +++ b/auto/modules @@ -136,6 +136,12 @@ if [ $HTTP = YES ]; then $HTTP_NOT_MODIFIED_FILTER_MODULE" fi +IMAP_MODULES=$IMAP_MODULE + +if [ $IMAP = YES ]; then + modules="$modules $IMAP_MODULES" +fi + echo "#include " > $NGX_MODULES_C echo "#include " >> $NGX_MODULES_C diff --git a/auto/options b/auto/options --- a/auto/options +++ b/auto/options @@ -40,6 +40,8 @@ HTTP_STATUS=YES HTTP_REWRITE=YES HTTP_PROXY=YES +IMAP=NO + USE_PCRE=NO PCRE=NONE PCRE_OPT= @@ -101,6 +103,8 @@ do --without-http_rewrite_module) HTTP_REWRITE=NO ;; --without-http_proxy_module) HTTP_PROXY=NO ;; + --with-imap) IMAP=YES ;; + --with-cc=*) CC="$value" ;; --with-cpp=*) CPP="$value" ;; --with-cc-opt=*) CC_OPT="$value" ;; diff --git a/auto/sources b/auto/sources --- a/auto/sources +++ b/auto/sources @@ -4,46 +4,46 @@ CORE_MODULES="ngx_core_module ngx_errlog CORE_INCS="src/core" CORE_DEPS="src/core/nginx.h \ - src/core/ngx_config.h \ - src/core/ngx_core.h \ - src/core/ngx_log.h \ - src/core/ngx_palloc.h \ - src/core/ngx_array.h \ - src/core/ngx_list.h \ - src/core/ngx_table.h \ - src/core/ngx_buf.h \ - src/core/ngx_string.h \ - src/core/ngx_parse.h \ - src/core/ngx_inet.h \ - src/core/ngx_file.h \ - src/core/ngx_crc.h \ - src/core/ngx_rbtree.h \ - src/core/ngx_radix_tree.h \ - src/core/ngx_times.h \ - src/core/ngx_connection.h \ - src/core/ngx_cycle.h \ - src/core/ngx_conf_file.h \ - src/core/ngx_garbage_collector.h" + src/core/ngx_config.h \ + src/core/ngx_core.h \ + src/core/ngx_log.h \ + src/core/ngx_palloc.h \ + src/core/ngx_array.h \ + src/core/ngx_list.h \ + src/core/ngx_table.h \ + src/core/ngx_buf.h \ + src/core/ngx_string.h \ + src/core/ngx_parse.h \ + src/core/ngx_inet.h \ + src/core/ngx_file.h \ + src/core/ngx_crc.h \ + src/core/ngx_rbtree.h \ + src/core/ngx_radix_tree.h \ + src/core/ngx_times.h \ + src/core/ngx_connection.h \ + src/core/ngx_cycle.h \ + src/core/ngx_conf_file.h \ + src/core/ngx_garbage_collector.h" CORE_SRCS="src/core/nginx.c \ - src/core/ngx_log.c \ - src/core/ngx_palloc.c \ - src/core/ngx_array.c \ - src/core/ngx_list.c \ - src/core/ngx_buf.c \ - src/core/ngx_output_chain.c \ - src/core/ngx_string.c \ - src/core/ngx_parse.c \ - src/core/ngx_inet.c \ - src/core/ngx_file.c \ - src/core/ngx_rbtree.c \ - src/core/ngx_radix_tree.c \ - src/core/ngx_times.c \ - src/core/ngx_connection.c \ - src/core/ngx_cycle.c \ - src/core/ngx_spinlock.c \ - src/core/ngx_conf_file.c \ - src/core/ngx_garbage_collector.c" + src/core/ngx_log.c \ + src/core/ngx_palloc.c \ + src/core/ngx_array.c \ + src/core/ngx_list.c \ + src/core/ngx_buf.c \ + src/core/ngx_output_chain.c \ + src/core/ngx_string.c \ + src/core/ngx_parse.c \ + src/core/ngx_inet.c \ + src/core/ngx_file.c \ + src/core/ngx_rbtree.c \ + src/core/ngx_radix_tree.c \ + src/core/ngx_times.c \ + src/core/ngx_connection.c \ + src/core/ngx_cycle.c \ + src/core/ngx_spinlock.c \ + src/core/ngx_conf_file.c \ + src/core/ngx_garbage_collector.c" REGEX_DEPS=src/core/ngx_regex.h @@ -128,6 +128,7 @@ UNIX_SRCS="$CORE_SRCS $EVENT_SRCS \ src/os/unix/ngx_socket.c \ src/os/unix/ngx_recv.c \ src/os/unix/ngx_readv_chain.c \ + src/os/unix/ngx_send.c \ src/os/unix/ngx_writev_chain.c \ src/os/unix/ngx_channel.c \ src/os/unix/ngx_shared.c \ @@ -191,8 +192,8 @@ WIN32_SRCS="$CORE_SRCS $EVENT_SRCS \ HTTP_MODULES="ngx_http_module \ - ngx_http_core_module \ - ngx_http_log_module" + ngx_http_core_module \ + ngx_http_log_module" HTTP_FILE_CACHE_MODULE=ngx_http_cache_module @@ -214,30 +215,30 @@ HTTP_INDEX_MODULE=ngx_http_index_module HTTP_INCS="src/http src/http/modules" HTTP_DEPS="src/http/ngx_http.h \ - src/http/ngx_http_request.h \ - src/http/ngx_http_config.h \ - src/http/ngx_http_core_module.h \ - src/http/ngx_http_cache.h \ - src/http/ngx_http_busy_lock.h \ - src/http/ngx_http_log_handler.h" + src/http/ngx_http_request.h \ + src/http/ngx_http_config.h \ + src/http/ngx_http_core_module.h \ + src/http/ngx_http_cache.h \ + src/http/ngx_http_busy_lock.h \ + src/http/ngx_http_log_handler.h" HTTP_SRCS="src/http/ngx_http.c \ - src/http/ngx_http_core_module.c \ - src/http/ngx_http_special_response.c \ - src/http/ngx_http_request.c \ - src/http/ngx_http_parse.c \ - src/http/ngx_http_header_filter.c \ - src/http/ngx_http_write_filter.c \ - src/http/ngx_http_copy_filter.c \ - src/http/ngx_http_log_handler.c \ - src/http/ngx_http_request_body.c \ - src/http/ngx_http_parse_time.c \ - src/http/modules/ngx_http_static_handler.c \ - src/http/modules/ngx_http_index_handler.c \ - src/http/modules/ngx_http_chunked_filter.c \ - src/http/modules/ngx_http_range_filter.c \ - src/http/modules/ngx_http_headers_filter.c \ - src/http/modules/ngx_http_not_modified_filter.c" + src/http/ngx_http_core_module.c \ + src/http/ngx_http_special_response.c \ + src/http/ngx_http_request.c \ + src/http/ngx_http_parse.c \ + src/http/ngx_http_header_filter.c \ + src/http/ngx_http_write_filter.c \ + src/http/ngx_http_copy_filter.c \ + src/http/ngx_http_log_handler.c \ + src/http/ngx_http_request_body.c \ + src/http/ngx_http_parse_time.c \ + src/http/modules/ngx_http_static_handler.c \ + src/http/modules/ngx_http_index_handler.c \ + src/http/modules/ngx_http_chunked_filter.c \ + src/http/modules/ngx_http_range_filter.c \ + src/http/modules/ngx_http_headers_filter.c \ + src/http/modules/ngx_http_not_modified_filter.c" # STUB HTTP_SRCS="$HTTP_SRCS src/http/ngx_http_busy_lock.c" @@ -283,9 +284,18 @@ HTTP_PROXY_MODULE=ngx_http_proxy_module HTTP_PROXY_INCS="src/http/modules/proxy" HTTP_PROXY_DEPS=src/http/modules/proxy/ngx_http_proxy_handler.h HTTP_PROXY_SRCS="src/http/modules/proxy/ngx_http_proxy_handler.c \ - src/http/modules/proxy/ngx_http_proxy_upstream.c \ - src/http/modules/proxy/ngx_http_proxy_parse.c \ - src/http/modules/proxy/ngx_http_proxy_header.c" + src/http/modules/proxy/ngx_http_proxy_upstream.c \ + src/http/modules/proxy/ngx_http_proxy_parse.c \ + src/http/modules/proxy/ngx_http_proxy_header.c" # STUB -# src/http/modules/proxy/ngx_http_proxy_cache.c \ +# src/http/modules/proxy/ngx_http_proxy_cache.c \ + + +IMAP_INCS="src/imap" + +IMAP_DEPS="src/imap/ngx_imap.h" + +IMAP_MODULE=ngx_imap_module +IMAP_SRCS="src/imap/ngx_imap.c \ + src/imap/ngx_imap_handler.c" diff --git a/auto/unix b/auto/unix --- a/auto/unix +++ b/auto/unix @@ -32,6 +32,8 @@ ngx_type="socklen_t"; ngx_types="uint32_ ngx_type="in_addr_t"; ngx_types="uint32_t"; . auto/types/typedef +ngx_type="in_port_t"; ngx_types="u_short"; . auto/types/typedef + ngx_type="rlim_t"; ngx_types="int"; . auto/types/typedef . auto/types/uintptr_t diff --git a/src/core/ngx_array.h b/src/core/ngx_array.h --- a/src/core/ngx_array.h +++ b/src/core/ngx_array.h @@ -41,5 +41,7 @@ ngx_inline static ngx_int_t ngx_array_in ngx_test_null(a.elts, ngx_palloc(p, n * s), rc); \ a.nelts = 0; a.size = s; a.nalloc = n; a.pool = p; +#define ngx_array_push ngx_push_array + #endif /* _NGX_ARRAY_H_INCLUDED_ */ diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c --- a/src/core/ngx_connection.c +++ b/src/core/ngx_connection.c @@ -7,6 +7,55 @@ ngx_os_io_t ngx_io; +ngx_listening_t *ngx_listening_inet_stream_socket(ngx_conf_t *cf, + in_addr_t addr, + in_port_t port) +{ + size_t len; + ngx_listening_t *ls; + struct sockaddr_in *addr_in; + + if (!(ls = ngx_array_push(&cf->cycle->listening))) { + return NULL; + } + + ngx_memzero(ls, sizeof(ngx_listening_t)); + + if (!(addr_in = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)))) { + return NULL; + } + +#if (HAVE_SIN_LEN) + addr_in->sin_len = sizeof(struct sockaddr_in); +#endif + addr_in->sin_family = AF_INET; + addr_in->sin_addr.s_addr = addr; + addr_in->sin_port = htons(port); + + if (!(ls->addr_text.data = ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6))) { + return NULL; + } + + len = ngx_inet_ntop(AF_INET, &addr, ls->addr_text.data, INET_ADDRSTRLEN); + ls->addr_text.len = ngx_snprintf((char *) ls->addr_text.data + len, + 6, ":%d", port); + + ls->fd = (ngx_socket_t) -1; + ls->family = AF_INET; + ls->type = SOCK_STREAM; + ls->protocol = IPPROTO_IP; +#if (WIN32) + ls->flags = WSA_FLAG_OVERLAPPED; +#endif + ls->sockaddr = (struct sockaddr *) addr_in; + ls->socklen = sizeof(struct sockaddr_in); + ls->addr = offsetof(struct sockaddr_in, sin_addr); + ls->addr_text_max_len = INET_ADDRSTRLEN; + + return ls; +} + + ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle) { ngx_uint_t i; @@ -251,6 +300,110 @@ void ngx_close_listening_sockets(ngx_cyc } +void ngx_close_connection(ngx_connection_t *c) +{ + ngx_socket_t fd; + + if (c->pool == NULL) { + ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); + return; + } + +#if (NGX_OPENSSL) + + if (c->ssl) { + if (ngx_ssl_shutdown(c) == NGX_AGAIN) { + c->read->event_handler = ngx_ssl_close_handler; + c->write->event_handler = ngx_ssl_close_handler; + return; + } + } + +#endif + + if (c->read->timer_set) { + ngx_del_timer(c->read); + } + + if (c->write->timer_set) { + ngx_del_timer(c->write); + } + + if (ngx_del_conn) { + ngx_del_conn(c, NGX_CLOSE_EVENT); + + } else { + if (c->read->active || c->read->disabled) { + ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); + } + + if (c->write->active || c->write->disabled) { + ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); + } + } + +#if (NGX_THREADS) + + /* + * we have to clean the connection information before the closing + * because another thread may reopen the same file descriptor + * before we clean the connection + */ + + if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) { + + if (c->read->prev) { + ngx_delete_posted_event(c->read); + } + + if (c->write->prev) { + ngx_delete_posted_event(c->write); + } + + c->read->closed = 1; + c->write->closed = 1; + + if (c->single_connection) { + ngx_unlock(&c->lock); + c->read->locked = 0; + c->write->locked = 0; + } + + ngx_mutex_unlock(ngx_posted_events_mutex); + } + +#else + + if (c->read->prev) { + ngx_delete_posted_event(c->read); + } + + if (c->write->prev) { + ngx_delete_posted_event(c->write); + } + + c->read->closed = 1; + c->write->closed = 1; + +#endif + + fd = c->fd; + c->fd = (ngx_socket_t) -1; + c->data = NULL; + + ngx_destroy_pool(c->pool); + + if (ngx_close_socket(fd) == -1) { + + /* we use ngx_cycle->log because c->log was in c->pool */ + + ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, + ngx_close_socket_n " failed"); + } +} + + + ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text) { ngx_uint_t level; diff --git a/src/core/ngx_connection.h b/src/core/ngx_connection.h --- a/src/core/ngx_connection.h +++ b/src/core/ngx_connection.h @@ -129,9 +129,13 @@ struct ngx_connection_s { #endif +ngx_listening_t *ngx_listening_inet_stream_socket(ngx_conf_t *cf, + in_addr_t addr, + in_port_t port); ngx_int_t ngx_set_inherited_sockets(ngx_cycle_t *cycle); ngx_int_t ngx_open_listening_sockets(ngx_cycle_t *cycle); void ngx_close_listening_sockets(ngx_cycle_t *cycle); +void ngx_close_connection(ngx_connection_t *c); ngx_int_t ngx_connection_error(ngx_connection_t *c, ngx_err_t err, char *text); diff --git a/src/core/ngx_log.c b/src/core/ngx_log.c --- a/src/core/ngx_log.c +++ b/src/core/ngx_log.c @@ -47,7 +47,8 @@ static const char *err_levels[] = { }; static const char *debug_levels[] = { - "debug_core", "debug_alloc", "debug_mutex", "debug_event", "debug_http" + "debug_core", "debug_alloc", "debug_mutex", "debug_event", + "debug_http", "debug_imap" }; diff --git a/src/core/ngx_log.h b/src/core/ngx_log.h --- a/src/core/ngx_log.h +++ b/src/core/ngx_log.h @@ -21,9 +21,15 @@ #define NGX_LOG_DEBUG_MUTEX 0x040 #define NGX_LOG_DEBUG_EVENT 0x080 #define NGX_LOG_DEBUG_HTTP 0x100 +#define NGX_LOG_DEBUG_IMAP 0x200 + +/* + * after the adding a new debug level do not forget to update + * debug_levels[] in src/core/ngx_log.c + */ #define NGX_LOG_DEBUG_FIRST NGX_LOG_DEBUG_CORE -#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_HTTP +#define NGX_LOG_DEBUG_LAST NGX_LOG_DEBUG_IMAP #define NGX_LOG_DEBUG_CONNECTION 0x80000000 #define NGX_LOG_DEBUG_ALL 0x7ffffff0 diff --git a/src/event/ngx_event.h b/src/event/ngx_event.h --- a/src/event/ngx_event.h +++ b/src/event/ngx_event.h @@ -388,6 +388,7 @@ extern ngx_event_actions_t ngx_event_a #define ngx_recv ngx_io.recv #define ngx_recv_chain ngx_io.recv_chain +#define ngx_send ngx_io.send #define ngx_send_chain ngx_io.send_chain diff --git a/src/event/ngx_event_connect.c b/src/event/ngx_event_connect.c --- a/src/event/ngx_event_connect.c +++ b/src/event/ngx_event_connect.c @@ -252,7 +252,7 @@ int ngx_event_connect_peer(ngx_peer_conn ngx_memzero(&addr, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; - addr.sin_port = (u_short) peer->port; + addr.sin_port = peer->port; addr.sin_addr.s_addr = peer->addr; ngx_log_debug2(NGX_LOG_DEBUG_EVENT, pc->log, 0, diff --git a/src/http/modules/ngx_http_userid_filter.c b/src/http/modules/ngx_http_userid_filter.c --- a/src/http/modules/ngx_http_userid_filter.c +++ b/src/http/modules/ngx_http_userid_filter.c @@ -281,7 +281,6 @@ static ngx_int_t ngx_http_userid_set_uid size_t len; socklen_t slen; struct sockaddr_in addr_in; - uint32_t service; ngx_str_t src, dst; ngx_table_elt_t *set_cookie; @@ -542,7 +541,7 @@ char *ngx_conf_check_domain(ngx_conf_t * if (domain->len == 4 && ngx_strcmp(domain->data, "none") == 0) { domain->len = 1; - domain->data = "."; + domain->data = (u_char *) "."; } return NGX_CONF_OK; diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.c b/src/http/modules/proxy/ngx_http_proxy_handler.c --- a/src/http/modules/proxy/ngx_http_proxy_handler.c +++ b/src/http/modules/proxy/ngx_http_proxy_handler.c @@ -1234,7 +1234,7 @@ static char *ngx_http_proxy_parse_upstre u->default_port = 1; } - u->port = htons((u_short) u->port); + u->port = htons(u->port); return NULL; } } @@ -1265,7 +1265,7 @@ static char *ngx_http_proxy_parse_upstre if (u->port_text.len > 0) { u->port = ngx_atoi(u->port_text.data, u->port_text.len); if (u->port > 0) { - u->port = htons((u_short) u->port); + u->port = htons(u->port); return NULL; } } diff --git a/src/http/modules/proxy/ngx_http_proxy_handler.h b/src/http/modules/proxy/ngx_http_proxy_handler.h --- a/src/http/modules/proxy/ngx_http_proxy_handler.h +++ b/src/http/modules/proxy/ngx_http_proxy_handler.h @@ -41,7 +41,7 @@ typedef struct { ngx_str_t port_text; ngx_str_t *location; - ngx_int_t port; + in_port_t port; unsigned default_port:1; } ngx_http_proxy_upstream_conf_t; diff --git a/src/http/ngx_http.c b/src/http/ngx_http.c --- a/src/http/ngx_http.c +++ b/src/http/ngx_http.c @@ -500,48 +500,12 @@ static char *ngx_http_block(ngx_conf_t * in_addr = in_port[p].addrs.elts; while (a < in_port[p].addrs.nelts) { - if (!(ls = ngx_push_array(&cf->cycle->listening))) { - return NGX_CONF_ERROR; - } - - ngx_memzero(ls, sizeof(ngx_listening_t)); - - addr_in = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in)); - if (addr_in == NULL) { + ls = ngx_listening_inet_stream_socket(cf, in_addr[a].addr, + in_port[p].port); + if (ls == NULL) { return NGX_CONF_ERROR; } -#if (HAVE_SIN_LEN) - addr_in->sin_len = sizeof(struct sockaddr_in); -#endif - addr_in->sin_family = AF_INET; - addr_in->sin_addr.s_addr = in_addr[a].addr; - addr_in->sin_port = htons((u_short) in_port[p].port); - - ls->addr_text.data = ngx_palloc(cf->pool, INET_ADDRSTRLEN + 6); - if (ls->addr_text.data == NULL) { - return NGX_CONF_ERROR; - } - - ls->addr_text.len = ngx_inet_ntop(AF_INET, &in_addr[a].addr, - ls->addr_text.data, - INET_ADDRSTRLEN), - - ls->addr_text.len += ngx_snprintf((char *) ls->addr_text.data - + ls->addr_text.len, - 6, ":%d", in_port[p].port); - - ls->fd = (ngx_socket_t) -1; - ls->family = AF_INET; - ls->type = SOCK_STREAM; - ls->protocol = IPPROTO_IP; -#if (WIN32) - ls->flags = WSA_FLAG_OVERLAPPED; -#endif - ls->sockaddr = (struct sockaddr *) addr_in; - ls->socklen = sizeof(struct sockaddr_in); - ls->addr = offsetof(struct sockaddr_in, sin_addr); - ls->addr_text_max_len = INET_ADDRSTRLEN; ls->backlog = -1; #if 0 #if 0 diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c --- a/src/http/ngx_http_core_module.c +++ b/src/http/ngx_http_core_module.c @@ -1473,7 +1473,8 @@ static char *ngx_set_listen(ngx_conf_t * ngx_http_core_srv_conf_t *scf = conf; u_char *addr; - u_int p; + ngx_int_t port; + ngx_uint_t p; struct hostent *h; ngx_str_t *args; ngx_http_listen_t *ls; @@ -1505,14 +1506,14 @@ static char *ngx_set_listen(ngx_conf_t * p = 0; } - ls->port = ngx_atoi(&addr[p], args[1].len - p); - if (ls->port == NGX_ERROR && p == 0) { + port = ngx_atoi(&addr[p], args[1].len - p); + if (port == NGX_ERROR && p == 0) { /* "listen host" */ ls->port = 80; - } else if ((ls->port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */ - || (ls->port < 1 || ls->port > 65536)) { /* "listen 99999" */ + } else if ((port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */ + || (port < 1 || port > 65536)) { /* "listen 99999" */ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0, "invalid port \"%s\" in \"%s\" directive, " @@ -1523,6 +1524,7 @@ static char *ngx_set_listen(ngx_conf_t * } else if (p == 0) { ls->addr = INADDR_ANY; + ls->port = (in_port_t) port; return NGX_CONF_OK; } diff --git a/src/http/ngx_http_core_module.h b/src/http/ngx_http_core_module.h --- a/src/http/ngx_http_core_module.h +++ b/src/http/ngx_http_core_module.h @@ -9,7 +9,7 @@ typedef struct { in_addr_t addr; - int port; + in_port_t port; int family; ngx_str_t file_name; int line; @@ -78,7 +78,7 @@ typedef struct { /* list of structures to find core_srv_conf quickly at run time */ typedef struct { - int port; + in_port_t port; ngx_str_t port_name; ngx_array_t addrs; /* array of ngx_http_in_addr_t */ } ngx_http_in_port_t; diff --git a/src/http/ngx_http_parse.c b/src/http/ngx_http_parse.c --- a/src/http/ngx_http_parse.c +++ b/src/http/ngx_http_parse.c @@ -3,6 +3,7 @@ #include #include + ngx_int_t ngx_http_parse_request_line(ngx_http_request_t *r) { u_char ch, *p, *m; diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c --- a/src/http/ngx_http_request.c +++ b/src/http/ngx_http_request.c @@ -1899,109 +1899,10 @@ void ngx_ssl_close_handler(ngx_event_t * void ngx_http_close_connection(ngx_connection_t *c) { - ngx_socket_t fd; - ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "close http connection: %d", c->fd); - if (c->pool == NULL) { - ngx_log_error(NGX_LOG_ALERT, c->log, 0, "connection already closed"); - return; - } - -#if (NGX_HTTP_SSL) - - if (c->ssl) { - if (ngx_ssl_shutdown(c) == NGX_AGAIN) { - c->read->event_handler = ngx_ssl_close_handler; - c->write->event_handler = ngx_ssl_close_handler; - return; - } - } - -#endif - - if (c->read->timer_set) { - ngx_del_timer(c->read); - } - - if (c->write->timer_set) { - ngx_del_timer(c->write); - } - - if (ngx_del_conn) { - ngx_del_conn(c, NGX_CLOSE_EVENT); - - } else { - if (c->read->active || c->read->disabled) { - ngx_del_event(c->read, NGX_READ_EVENT, NGX_CLOSE_EVENT); - } - - if (c->write->active || c->write->disabled) { - ngx_del_event(c->write, NGX_WRITE_EVENT, NGX_CLOSE_EVENT); - } - } - - /* - * we have to clean the connection information before the closing - * because another thread may reopen the same file descriptor - * before we clean the connection - */ - -#if (NGX_THREADS) - - if (ngx_mutex_lock(ngx_posted_events_mutex) == NGX_OK) { - - if (c->read->prev) { - ngx_delete_posted_event(c->read); - } - - if (c->write->prev) { - ngx_delete_posted_event(c->write); - } - - c->read->closed = 1; - c->write->closed = 1; - - if (c->single_connection) { - ngx_unlock(&c->lock); - c->read->locked = 0; - c->write->locked = 0; - } - - ngx_mutex_unlock(ngx_posted_events_mutex); - } - -#else - - if (c->read->prev) { - ngx_delete_posted_event(c->read); - } - - if (c->write->prev) { - ngx_delete_posted_event(c->write); - } - - c->read->closed = 1; - c->write->closed = 1; - -#endif - - fd = c->fd; - c->fd = (ngx_socket_t) -1; - c->data = NULL; - - ngx_destroy_pool(c->pool); - - if (ngx_close_socket(fd) == -1) { - - /* we use ngx_cycle->log because c->log was in c->pool */ - - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, - ngx_close_socket_n " failed"); - } - - return; + ngx_close_connection(c); } diff --git a/src/imap/ngx_imap.c b/src/imap/ngx_imap.c --- a/src/imap/ngx_imap.c +++ b/src/imap/ngx_imap.c @@ -2,6 +2,10 @@ #include #include #include +#include + + +static char *ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static ngx_command_t ngx_imap_commands[] = { @@ -30,5 +34,28 @@ ngx_module_t ngx_imap_module = { ngx_imap_commands, /* module directives */ NGX_CORE_MODULE, /* module type */ NULL, /* init module */ - NULL /* init child */ + NULL /* init process */ }; + + +static char *ngx_imap_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) +{ + ngx_listening_t *ls; + + /* STUB */ + + ls = ngx_listening_inet_stream_socket(cf, 0, 8110); + if (ls == NULL) { + return NGX_CONF_ERROR; + } + + ls->backlog = -1; + ls->handler = ngx_imap_init_connection; + ls->pool_size = 16384; + /* ls->post_accept_timeout = 0; */ + ls->log = cf->cycle->new_log; + + /* */ + + return NGX_CONF_OK; +} diff --git a/src/imap/ngx_imap.h b/src/imap/ngx_imap.h new file mode 100644 --- /dev/null +++ b/src/imap/ngx_imap.h @@ -0,0 +1,32 @@ +#ifndef _NGX_IMAP_H_INCLUDED_ +#define _NGX_IMAP_H_INCLUDED_ + + +#include +#include + + +typedef struct { + ngx_chain_t *send; +} ngx_imap_request_t; + + +#define NGX_POP3_USER 1 +#define NGX_POP3_PASS 2 +#define NGX_POP3_APOP 3 +#define NGX_POP3_STAT 4 +#define NGX_POP3_LIST 5 +#define NGX_POP3_RETR 6 +#define NGX_POP3_DELE 7 +#define NGX_POP3_NOOP 8 +#define NGX_POP3_RSET 9 +#define NGX_POP3_TOP 10 +#define NGX_POP3_UIDL 11 +#define NGX_POP3_QUIT 12 + + +void ngx_imap_init_connection(ngx_connection_t *c); +void ngx_imap_close_connection(ngx_connection_t *c); + + +#endif /* _NGX_IMAP_H_INCLUDED_ */ diff --git a/src/imap/ngx_imap_handler.c b/src/imap/ngx_imap_handler.c --- a/src/imap/ngx_imap_handler.c +++ b/src/imap/ngx_imap_handler.c @@ -2,18 +2,56 @@ #include #include #include +#include +#include + + +static void ngx_imap_auth_state(ngx_event_t *rev); + + +static char pop3_greeting[] = "+OK " NGINX_VER " ready" CRLF; +static char imap_greeting[] = "* OK " NGINX_VER " ready" CRLF; void ngx_imap_init_connection(ngx_connection_t *c) { + ngx_int_t rc; + ngx_log_debug0(NGX_LOG_DEBUG_IMAP, c->log, 0, "imap init connection"); - if (ngx_close_socket(c->fd) == -1) { + c->log_error = NGX_ERROR_INFO; + + rc = ngx_send(c, pop3_greeting, sizeof(pop3_greeting) - 1); - /* we use ngx_cycle->log because c->log was in c->pool */ + if (rc == NGX_ERROR) { + ngx_imap_close_connection(c); + return; + } - ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_socket_errno, - ngx_close_socket_n " failed"); + c->read->event_handler = ngx_imap_auth_state; + + if (ngx_handle_read_event(c->read, 0) == NGX_ERROR) { + ngx_imap_close_connection(c); + return; } } + + +static void ngx_imap_auth_state(ngx_event_t *rev) +{ + ngx_connection_t *c; + + c = rev->data; + + ngx_imap_close_connection(c); +} + + +void ngx_imap_close_connection(ngx_connection_t *c) +{ + ngx_log_debug1(NGX_LOG_DEBUG_IMAP, c->log, 0, + "close imap connection: %d", c->fd); + + ngx_close_connection(c); +} diff --git a/src/imap/ngx_imap_parse.c b/src/imap/ngx_imap_parse.c new file mode 100644 --- /dev/null +++ b/src/imap/ngx_imap_parse.c @@ -0,0 +1,68 @@ + +#include +#include +#include +#include + + +ngx_int_t ngx_pop3_parse_command(ngx_imap_request_t *r) +{ + u_char ch, *p, *c; + enum { + sw_start = 0, + sw_done + } state; + + while (p < r->buf->last && state < sw_done) { + ch = *p++; + + switch (state) { + + /* POP3 commands */ + case sw_start: + if (ch == ' ') { + c = r->buf->start; + + if (p - 1 - m == 4) { + + if (*c == 'U' && *(c + 1) == 'S' + && *(c + 2) == 'E' && *(c + 3) == 'R') + { + r->command = NGX_POP3_USER; + + } else if (*c == 'P' && *(c + 1) == 'A' + && *(c + 2) == 'A' && *(c + 3) == 'S') + { + r->method = NGX_POP3_PASS; + + } else if (*c == 'Q' && *(c + 1) == 'U' + && *(c + 2) == 'I' && *(c + 3) == 'T') + { + r->method = NGX_POP3_QUIT; + + } else if (*c == 'N' && *(c + 1) == 'O' + && *(c + 2) == 'O' && *(c + 3) == 'P') + { + r->method = NGX_POP3_NOOP; + } + } + + state = sw_spaces_before_arg; + break; + } + + if (ch < 'A' || ch > 'Z') { + return NGX_IMAP_PARSE_INVALID_COMMAND; + } + + break; + } + + /* suppress warning */ + case sw_done: + break; + } + } + + return NGX_OK; +} diff --git a/src/os/unix/ngx_freebsd_init.c b/src/os/unix/ngx_freebsd_init.c --- a/src/os/unix/ngx_freebsd_init.c +++ b/src/os/unix/ngx_freebsd_init.c @@ -20,7 +20,7 @@ int ngx_freebsd_kern_ipc_zero_copy_send; ngx_os_io_t ngx_os_io = { ngx_unix_recv, ngx_readv_chain, - NULL, + ngx_unix_send, #if (HAVE_SENDFILE) ngx_freebsd_sendfile_chain, NGX_IO_SENDFILE diff --git a/src/os/unix/ngx_linux_init.c b/src/os/unix/ngx_linux_init.c --- a/src/os/unix/ngx_linux_init.c +++ b/src/os/unix/ngx_linux_init.c @@ -12,7 +12,7 @@ int ngx_linux_rtsig_max; ngx_os_io_t ngx_os_io = { ngx_unix_recv, ngx_readv_chain, - NULL, + ngx_unix_send, #if (HAVE_SENDFILE) ngx_linux_sendfile_chain, NGX_IO_SENDFILE diff --git a/src/os/unix/ngx_os.h b/src/os/unix/ngx_os.h --- a/src/os/unix/ngx_os.h +++ b/src/os/unix/ngx_os.h @@ -33,7 +33,7 @@ typedef struct { ngx_recv_chain_pt recv_chain; ngx_send_pt send; ngx_send_chain_pt send_chain; - int flags; + ngx_uint_t flags; } ngx_os_io_t; @@ -46,6 +46,7 @@ int ngx_posix_post_conf_init(ngx_log_t * ssize_t ngx_unix_recv(ngx_connection_t *c, u_char *buf, size_t size); ssize_t ngx_readv_chain(ngx_connection_t *c, ngx_chain_t *entry); +ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size); ngx_chain_t *ngx_writev_chain(ngx_connection_t *c, ngx_chain_t *in, off_t limit); diff --git a/src/os/unix/ngx_send.c b/src/os/unix/ngx_send.c new file mode 100644 --- /dev/null +++ b/src/os/unix/ngx_send.c @@ -0,0 +1,63 @@ + +#include +#include +#include + + +ssize_t ngx_unix_send(ngx_connection_t *c, u_char *buf, size_t size) +{ + ssize_t n; + ngx_err_t err; + ngx_event_t *wev; + + wev = c->write; + +#if (HAVE_KQUEUE) + + if ((ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) && wev->pending_eof) { + ngx_log_error(NGX_LOG_INFO, c->log, wev->kq_errno, + "kevent() reported about an closed connection"); + + wev->error = 1; + return NGX_ERROR; + } + +#endif + + for ( ;; ) { + n = send(c->fd, buf, size, 0); + + ngx_log_debug3(NGX_LOG_DEBUG_EVENT, c->log, 0, + "send: fd:%d %d of %d", c->fd, n, size); + + if (n > 0) { + if (n < (ssize_t) size) { + wev->ready = 0; + } + + return n; + } + + err = ngx_socket_errno; + + if (n == 0) { + ngx_log_error(NGX_LOG_ALERT, c->log, err, "send() returned zero"); + } + + if (err == NGX_EAGAIN || err == NGX_EINTR) { + wev->ready = 0; + + ngx_log_debug0(NGX_LOG_DEBUG_EVENT, c->log, err, + "send() not ready"); + + if (err == NGX_EAGAIN) { + return NGX_AGAIN; + } + + } else { + wev->error = 1; + ngx_connection_error(c, err, "recv() failed"); + return NGX_ERROR; + } + } +} diff --git a/src/os/unix/ngx_solaris_init.c b/src/os/unix/ngx_solaris_init.c --- a/src/os/unix/ngx_solaris_init.c +++ b/src/os/unix/ngx_solaris_init.c @@ -11,7 +11,7 @@ char ngx_solaris_version[50]; ngx_os_io_t ngx_os_io = { ngx_unix_recv, ngx_readv_chain, - NULL, + ngx_unix_send, #if (HAVE_SENDFILE) ngx_solaris_sendfilev_chain, NGX_IO_SENDFILE diff --git a/src/os/win32/ngx_os.h b/src/os/win32/ngx_os.h --- a/src/os/win32/ngx_os.h +++ b/src/os/win32/ngx_os.h @@ -32,7 +32,7 @@ typedef struct { ngx_recv_chain_pt recv_chain; ngx_send_pt send; ngx_send_chain_pt send_chain; - int flags; + ngx_uint_t flags; } ngx_os_io_t;