changeset 220:4f81b931e9ff

nginx-0.0.1-2004-01-08-11:47:17 import
author Igor Sysoev <igor@sysoev.ru>
date Thu, 08 Jan 2004 08:47:17 +0000
parents f57597ec5249
children 401154e21826
files src/core/nginx.c src/core/nginx.h src/core/ngx_cycle.c src/http/ngx_http_request.c src/os/unix/ngx_process.c src/os/unix/ngx_process.h src/os/win32/ngx_service.c
diffstat 7 files changed, 193 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/src/core/nginx.c
+++ b/src/core/nginx.c
@@ -5,6 +5,7 @@
 #include <nginx.h>
 
 
+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,
--- 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_ */
--- 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;
     }
--- 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);
--- 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,
--- 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);
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;
+}