# HG changeset patch # User Igor Sysoev # Date 1073551637 0 # Node ID 4f81b931e9ff7bf500a16ebfdcebed293a83629b # Parent f57597ec524930dc0af1328577746f7f206738d6 nginx-0.0.1-2004-01-08-11:47:17 import diff --git a/src/core/nginx.c b/src/core/nginx.c --- a/src/core/nginx.c +++ b/src/core/nginx.c @@ -5,6 +5,7 @@ #include +static void ngx_master_process_cycle(ngx_cycle_t *cycle); static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); static ngx_int_t ngx_add_inherited_sockets(ngx_cycle_t *cycle, char **envp); static void ngx_exec_new_binary(ngx_cycle_t *cycle, char *const *argv); @@ -66,8 +67,7 @@ uid_t user; u_int ngx_connection_counter; -ngx_int_t ngx_master; -ngx_int_t ngx_single; +ngx_int_t ngx_process; ngx_int_t ngx_respawn; @@ -80,10 +80,8 @@ ngx_int_t ngx_change_binary; int main(int argc, char *const *argv, char **envp) { - struct timeval tv; ngx_fd_t fd; ngx_int_t i; - ngx_err_t err; ngx_log_t *log; ngx_cycle_t *cycle, init_cycle; ngx_open_file_t *file; @@ -140,16 +138,23 @@ int main(int argc, char *const *argv, ch ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); - if (ccf->single == 1) { - ngx_master = 0; - ngx_single = 1; + ngx_process = (ccf->single == 1) ? NGX_PROCESS_SINGLE : NGX_PROCESS_MASTER; + +#if (WIN32) + +#if 0 - } else { - ngx_master = 1; - ngx_single = 0; + if (run_as_service) { + if (ngx_servie(cycle->log) == NGX_ERROR) { + return 1; + } + + return 0; } -#if !(WIN32) +#endif + +#else /* STUB */ if (ccf->user.len) { @@ -205,12 +210,22 @@ int main(int argc, char *const *argv, ch #endif - /* a life cycle */ + ngx_master_process_cycle(cycle); + + return 0; +} + + +static void ngx_master_process_cycle(ngx_cycle_t *cycle) +{ + struct timeval tv; + ngx_int_t i; + ngx_err_t err; for ( ;; ) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "new cycle"); - if (ngx_master) { + if (ngx_process == NGX_PROCESS_MASTER) { ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL, "worker process", NGX_PROCESS_RESPAWN); @@ -227,10 +242,6 @@ int main(int argc, char *const *argv, ch } } -#if 0 - reconfigure = 0; - reopen = 0; -#endif /* a cycle with the same configuration */ @@ -242,7 +253,7 @@ int main(int argc, char *const *argv, ch err = 0; - if (ngx_single) { + if (ngx_process == NGX_PROCESS_SINGLE) { ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "worker cycle"); @@ -264,16 +275,18 @@ int main(int argc, char *const *argv, ch if (ngx_quit || ngx_terminate) { #if !(WIN32) +#if 0 if (ngx_delete_file(pidfile.name.data) == NGX_FILE_ERROR) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, ngx_delete_file_n " \"%s\" failed", pidfile.name.data); } #endif +#endif ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "exiting"); - if (ngx_master) { + if (ngx_process == NGX_PROCESS_MASTER) { ngx_signal_processes(cycle, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); @@ -293,6 +306,7 @@ int main(int argc, char *const *argv, ch ngx_respawn_processes(cycle); } +#if 0 if (ngx_change_binary) { ngx_change_binary = 0; ngx_log_error(NGX_LOG_INFO, cycle->log, 0, @@ -300,6 +314,7 @@ int main(int argc, char *const *argv, ch ngx_exec_new_binary(cycle, argv); /* TODO: quit workers */ } +#endif if (ngx_reconfigure) { ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring"); @@ -334,6 +349,8 @@ static void ngx_worker_process_cycle(ngx ngx_int_t i; ngx_listening_t *ls; + ngx_process = NGX_PROCESS_WORKER; + if (user) { if (setuid(user) == -1) { ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, diff --git a/src/core/nginx.h b/src/core/nginx.h --- a/src/core/nginx.h +++ b/src/core/nginx.h @@ -13,8 +13,7 @@ extern ngx_module_t ngx_core_module; extern ngx_uint_t ngx_connection_counter; -extern ngx_int_t ngx_master; -extern ngx_int_t ngx_single; +extern ngx_int_t ngx_process; #endif /* _NGINX_H_INCLUDED_ */ diff --git a/src/core/ngx_cycle.c b/src/core/ngx_cycle.c --- a/src/core/ngx_cycle.c +++ b/src/core/ngx_cycle.c @@ -309,7 +309,7 @@ ngx_log_debug(log, "OPEN: %d:%s" _ file[ return cycle; } - if (ngx_master) { + if (ngx_process == NGX_PROCESS_MASTER) { ngx_destroy_pool(old_cycle->pool); return cycle; } 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 @@ -277,6 +277,7 @@ static void ngx_http_init_request(ngx_ev static void ngx_http_process_request_line(ngx_event_t *rev) { + char *p; ssize_t n; ngx_int_t rc, offset; ngx_connection_t *c; @@ -307,11 +308,13 @@ static void ngx_http_process_request_lin /* the request line has been parsed successfully */ - /* TODO: we need to handle such URIs */ + /* TODO: we need to handle proxy URIs */ if (r->unusual_uri) { r->request_line.len = r->request_end - r->request_start; r->request_line.data = r->request_start; +#if 0 r->request_line.data[r->request_line.len] = '\0'; +#endif ngx_http_client_error(r, NGX_HTTP_PARSE_INVALID_REQUEST, NGX_HTTP_BAD_REQUEST); @@ -372,7 +375,6 @@ static void ngx_http_process_request_lin if (rc != NGX_OK) { r->request_line.len = r->request_end - r->request_start; r->request_line.data = r->request_start; - r->request_line.data[r->request_line.len] = '\0'; ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); return; @@ -482,6 +484,15 @@ static void ngx_http_process_request_lin /* there was error while a request line parsing */ + for (p = r->request_start; p < r->header_in->last; p++) { + if (*p == CR || *p == LF) { + break; + } + } + + r->request_line.len = p - r->request_start; + r->request_line.data = r->request_start; + ngx_http_client_error(r, rc, NGX_HTTP_BAD_REQUEST); return; @@ -1564,6 +1575,11 @@ static void ngx_http_client_error(ngx_ht ctx->client, ctx->url); } else { + if (error == NGX_HTTP_REQUEST_URI_TOO_LARGE) { + r->request_line.len = r->header_in->end - r->request_start; + r->request_line.data = r->request_start; + } + ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, client_header_errors[client_error - NGX_HTTP_CLIENT_ERROR], ctx->client); diff --git a/src/os/unix/ngx_process.c b/src/os/unix/ngx_process.c --- a/src/os/unix/ngx_process.c +++ b/src/os/unix/ngx_process.c @@ -8,6 +8,14 @@ static void ngx_exec_proc(ngx_cycle_t *c ngx_uint_t ngx_last_process; ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; +sigset_t ngx_sigmask; + + +void ngx_wait_events() +{ + sigsuspend(&ngx_sigmask); +} + ngx_int_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, diff --git a/src/os/unix/ngx_process.h b/src/os/unix/ngx_process.h --- a/src/os/unix/ngx_process.h +++ b/src/os/unix/ngx_process.h @@ -29,7 +29,9 @@ typedef struct { } ngx_exec_ctx_t; -#define ngx_getpid getpid +#define NGX_PROCESS_SINGLE 0 +#define NGX_PROCESS_MASTER 1 +#define NGX_PROCESS_WORKER 2 #define NGX_MAX_PROCESSES 1024 @@ -38,6 +40,8 @@ typedef struct { #define NGX_PROCESS_DETACHED -3 +#define ngx_getpid getpid + ngx_int_t ngx_spawn_process(ngx_cycle_t *cycle, ngx_spawn_proc_pt proc, void *data, char *name, ngx_int_t respawn); diff --git a/src/os/win32/ngx_service.c b/src/os/win32/ngx_service.c new file mode 100644 --- /dev/null +++ b/src/os/win32/ngx_service.c @@ -0,0 +1,124 @@ + +#define NGX_SERVICE_CONTROL_SHUTDOWN 128 +#define NGX_SERVICE_CONTROL_REOPEN 129 + + +SERVICE_TABLE_ENTRY st[] = { + { "nginx", service_main }, + { NULL, NULL } +}; + + +ngx_int_t ngx_service(ngx_log_t *log) +{ + /* primary thread */ + + /* StartServiceCtrlDispatcher() shouxpdl be called within 30 seconds */ + + if (StartServiceCtrlDispatcher(st) == 0) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "StartServiceCtrlDispatcher() failed"); + return NGX_ERROR; + } + + return NGX_OK; +} + + +void service_main(u_int argc, char **argv) +{ + SERVICE_STATUS status; + SERVICE_STATUS_HANDLE service; + + /* thread spawned by SCM */ + + service = RegisterServiceCtrlHandlerEx("nginx", service_handler, ctx); + if (service == INVALID_HANDLE_VALUE) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "RegisterServiceCtrlHandlerEx() failed"); + return; + } + + status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; + status.dwCurrentState = SERVICE_START_PENDING; + status.dwControlsAccepted = SERVICE_ACCEPT_STOP + |SERVICE_ACCEPT_PARAMCHANGE; + status.dwWin32ExitCode = NO_ERROR; + status.dwServiceSpecificExitCode = 0; + status.dwCheckPoint = 1; + status.dwWaitHint = 2000; + + /* SetServiceStatus() should be called within 80 seconds */ + + if (SetServiceStatus(service, &status) == 0) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "SetServiceStatus() failed"); + return; + } + + /* init */ + + status.dwCurrentState = SERVICE_RUNNING; + status.dwCheckPoint = 0; + status.dwWaitHint = 0; + + if (SetServiceStatus(service, &status) == 0) { + ngx_log_error(NGX_LOG_EMERG, log, ngx_errno, + "SetServiceStatus() failed"); + return; + } + + /* call master or worker loop */ + + /* + * master should use event notification and look status + * single should use iocp to get notifications from service handler + */ + +} + + +u_int service_handler(u_int control, u_int type, void *data, void *ctx) +{ + /* primary thread */ + + switch(control) { + + case SERVICE_CONTROL_INTERROGATE: + status = NGX_IOCP_INTERROGATE; + break; + + case SERVICE_CONTROL_STOP: + status = NGX_IOCP_STOP; + break; + + case SERVICE_CONTROL_PARAMCHANGE: + status = NGX_IOCP_RECONFIGURE; + break; + + case NGX_SERVICE_CONTROL_SHUTDOWN: + status = NGX_IOCP_REOPEN; + break; + + case NGX_SERVICE_CONTROL_REOPEN: + status = NGX_IOCP_REOPEN; + break; + + default: + return ERROR_CALL_NOT_IMPLEMENTED; + } + + if (ngx_single) { + if (PostQueuedCompletionStatus(iocp, ... status, ...) == 0) { + err = ngx_errno; + ngx_log_error(NGX_LOG_ALERT, log, err, + "PostQueuedCompletionStatus() failed"); + return err; + } + + } else { + Event + } + + return NO_ERROR; +}