nginx-0.0.1-2003-05-29-17:02:09 import

This commit is contained in:
Igor Sysoev 2003-05-29 13:02:09 +00:00
parent 6253ca1b62
commit 1393325df8
15 changed files with 520 additions and 113 deletions

View File

@ -90,8 +90,8 @@ int main(int argc, char *const *argv)
conf.module_type = NGX_CORE_MODULE; conf.module_type = NGX_CORE_MODULE;
conf.cmd_type = NGX_MAIN_CONF; conf.cmd_type = NGX_MAIN_CONF;
conf_file.len = sizeof("nginx.conf") - 1; conf_file.len = sizeof(NGINX_CONF) - 1;
conf_file.data = "nginx.conf"; conf_file.data = NGINX_CONF;
if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) { if (ngx_conf_parse(&conf, &conf_file) != NGX_CONF_OK) {
return 1; return 1;

View File

@ -2,7 +2,8 @@
#define _NGINX_H_INCLUDED_ #define _NGINX_H_INCLUDED_
#define NGINX_VER "nginx/0.0.1" #define NGINX_VER "nginx/0.0.1"
#define NGINX_CONF "nginx.conf"
extern int ngx_max_module; extern int ngx_max_module;

View File

@ -52,9 +52,11 @@ char *ngx_cpystrn(char *dst, char *src, size_t n);
int ngx_rstrncmp(char *s1, char *s2, size_t n); int ngx_rstrncmp(char *s1, char *s2, size_t n);
int ngx_atoi(char *line, size_t n); int ngx_atoi(char *line, size_t n);
#define ngx_qsort qsort
#define ngx_value_helper(n) #n
#define ngx_value(n) ngx_value_helper(n) #define ngx_value_helper(n) #n
#define ngx_value(n) ngx_value_helper(n)
#endif /* _NGX_STRING_H_INCLUDED_ */ #endif /* _NGX_STRING_H_INCLUDED_ */

View File

@ -9,7 +9,7 @@
#define DEF_CONNECTIONS 1024 #define DEF_CONNECTIONS 1024
extern ngx_event_module_t ngx_select_module_ctx; extern ngx_module_t ngx_select_module;
#if (HAVE_KQUEUE) #if (HAVE_KQUEUE)
#include <ngx_kqueue_module.h> #include <ngx_kqueue_module.h>
@ -122,12 +122,11 @@ ngx_module_t ngx_event_module = {
int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log) int ngx_pre_thread(ngx_array_t *ls, ngx_pool_t *pool, ngx_log_t *log)
{ {
int m, i, fd; int m, i, fd;
ngx_listen_t *s;
ngx_listen_t *s; ngx_event_t *ev;
ngx_event_t *ev; ngx_connection_t *c;
ngx_connection_t *c; ngx_event_conf_t *ecf;
ngx_event_conf_t *ecf;
ngx_event_module_t *module; ngx_event_module_t *module;
ecf = ngx_event_get_conf(ngx_event_module); ecf = ngx_event_get_conf(ngx_event_module);

View File

@ -90,9 +90,7 @@ struct ngx_event_s {
unsigned ignore_econnreset:1; unsigned ignore_econnreset:1;
unsigned unexpected_eof:1; unsigned unexpected_eof:1;
#if (HAVE_DEFERRED_ACCEPT)
unsigned deferred_accept:1; unsigned deferred_accept:1;
#endif
#if (HAVE_KQUEUE) #if (HAVE_KQUEUE)
unsigned eof:1; unsigned eof:1;
@ -277,6 +275,7 @@ typedef struct {
#define ngx_process_events ngx_event_actions.process #define ngx_process_events ngx_event_actions.process
#define ngx_add_event ngx_event_actions.add #define ngx_add_event ngx_event_actions.add
#define ngx_del_event ngx_event_actions.del #define ngx_del_event ngx_event_actions.del
#define ngx_add_conn ngx_event_actions.add_conn
#define ngx_del_conn ngx_event_actions.del_conn #define ngx_del_conn ngx_event_actions.del_conn
#if 0 #if 0

View File

@ -1,11 +1,9 @@
#include <nginx.h>
#include <ngx_config.h> #include <ngx_config.h>
#include <ngx_core.h> #include <ngx_core.h>
#include <ngx_types.h>
#include <ngx_log.h> #include <nginx.h>
#include <ngx_connection.h>
#include <ngx_event.h> #include <ngx_event.h>
@ -19,18 +17,17 @@ void ngx_event_accept(ngx_event_t *ev)
ngx_socket_t s; ngx_socket_t s;
ngx_event_t *rev, *wev; ngx_event_t *rev, *wev;
ngx_connection_t *c, *ls; ngx_connection_t *c, *ls;
ngx_event_conf_t *ecf;
ls = (ngx_connection_t *) ev->data; ecf = ngx_event_get_conf(ngx_event_module);
ls = ev->data;
ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _ ngx_log_debug(ev->log, "ngx_event_accept: accept ready: %d" _
ev->available); ev->available);
ev->ready = 0; ev->ready = 0;
#if 0
/* DEBUG */ ev->available++;
#endif
do { do {
/* Create the pool before accept() to avoid copy the sockaddr. /* Create the pool before accept() to avoid copy the sockaddr.
@ -52,16 +49,37 @@ void ngx_event_accept(ngx_event_t *ev)
s = accept(ls->fd, sa, &len); s = accept(ls->fd, sa, &len);
if (s == -1) { if (s == -1) {
err = ngx_socket_errno; err = ngx_socket_errno;
ngx_destroy_pool(pool);
if (err == NGX_EAGAIN) { if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_NOTICE, ev->log, err, ngx_log_error(NGX_LOG_NOTICE, ev->log, err,
"EAGAIN while accept %s", ls->addr_text.data); "EAGAIN while accept() %s", ls->addr_text.data);
return; return;
} }
ngx_log_error(NGX_LOG_ALERT, ev->log, err, ngx_log_error(NGX_LOG_ALERT, ev->log, err,
"accept %s failed", ls->addr_text.data); "accept() %s failed", ls->addr_text.data);
ngx_destroy_pool(pool);
return;
}
if (s >= ecf->connections) {
ngx_log_error(NGX_LOG_ALERT, ev->log, 0,
"accept() %s returned socket #%d while "
"only %d connections was configured, "
"sleeping for 1 second",
ls->addr_text.data, s, ecf->connections);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
ls->addr_text.data);
}
sleep(1);
ngx_destroy_pool(pool);
return; return;
} }
@ -73,6 +91,14 @@ void ngx_event_accept(ngx_event_t *ev)
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_blocking_n " %s failed", ngx_blocking_n " %s failed",
ls->addr_text.data); ls->addr_text.data);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
ls->addr_text.data);
}
ngx_destroy_pool(pool);
return; return;
} }
} }
@ -83,6 +109,14 @@ void ngx_event_accept(ngx_event_t *ev)
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno, ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_nonblocking_n " %s failed", ngx_nonblocking_n " %s failed",
ls->addr_text.data); ls->addr_text.data);
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
ls->addr_text.data);
}
ngx_destroy_pool(pool);
return; return;
} }
} }
@ -133,28 +167,28 @@ void ngx_event_accept(ngx_event_t *ev)
ngx_memcpy(c->log, ev->log, sizeof(ngx_log_t)); ngx_memcpy(c->log, ev->log, sizeof(ngx_log_t));
rev->log = wev->log = c->log; rev->log = wev->log = c->log;
/* STUB: x86: SP: xadd ?, MT: lock xadd, MP: lock xadd, shared */ /* STUB: x86: MT: lock xadd, MP: lock xadd, shared */
c->number = ngx_connection_counter++; c->number = ngx_connection_counter++;
ngx_log_debug(ev->log, "ngx_event_accept: accept: %d, %d" _ ngx_log_debug(ev->log, "accept: %d, %d" _ s _ c->number);
s _ c->number);
#if (HAVE_DEFERRED_ACCEPT) if (ev->deferred_accept) {
if (ev->accept_filter) {
rev->ready = 1; rev->ready = 1;
} }
#endif
#if (HAVE_EDGE_EVENT) /* epoll */ if (ngx_add_conn) {
if (ngx_add_conn(c) == NGX_ERROR) {
if (ngx_close_socket(s) == -1) {
ngx_log_error(NGX_LOG_ALERT, ev->log, ngx_socket_errno,
ngx_close_socket_n " %s failed",
ls->addr_text.data);
}
if (ngx_event_flags & NGX_HAVE_EDGE_EVENT) { ngx_destroy_pool(pool);
if (ngx_edge_add_event(ev) == NGX_ERROR) {
return; return;
} }
} }
#endif
ls->handler(c); ls->handler(c);
if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) { if (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT) {

View File

@ -59,7 +59,7 @@ int ngx_http_index_handler(ngx_http_request_t *r)
{ {
int i, rc, test_dir; int i, rc, test_dir;
char *name, *file; char *name, *file;
ngx_str_t loc, *index; ngx_str_t redirect, *index;
ngx_err_t err; ngx_err_t err;
ngx_fd_t fd; ngx_fd_t fd;
ngx_http_index_conf_t *icf; ngx_http_index_conf_t *icf;
@ -74,14 +74,14 @@ int ngx_http_index_handler(ngx_http_request_t *r)
+ icf->max_index_len), + icf->max_index_len),
NGX_HTTP_INTERNAL_SERVER_ERROR); NGX_HTTP_INTERNAL_SERVER_ERROR);
loc.data = ngx_cpystrn(r->path.data, clcf->doc_root.data, redirect.data = ngx_cpymem(r->path.data, clcf->doc_root.data,
clcf->doc_root.len + 1); clcf->doc_root.len);
file = ngx_cpystrn(loc.data, r->uri.data, r->uri.len + 1); file = ngx_cpystrn(redirect.data, r->uri.data, r->uri.len + 1);
r->path.len = file - r->path.data; r->path.len = file - r->path.data;
test_dir = 1; test_dir = 1;
index = (ngx_str_t *) icf->indices.elts; index = icf->indices.elts;
for (i = 0; i < icf->indices.nelts; i++) { for (i = 0; i < icf->indices.nelts; i++) {
if (index[i].data[0] != '/') { if (index[i].data[0] != '/') {
@ -136,18 +136,15 @@ ngx_log_error(NGX_LOG_DEBUG, r->connection->log, err,
if (index[i].data[0] == '/') { if (index[i].data[0] == '/') {
r->file.name.len = index[i].len; r->file.name.len = index[i].len;
loc.len = index[i].len; redirect.len = index[i].len;
loc.data = index[i].data; redirect.data = index[i].data;
} else { } else {
loc.len = r->uri.len + index[i].len; redirect.len = r->uri.len + index[i].len;
r->file.name.len = clcf->doc_root.len + r->uri.len r->file.name.len = clcf->doc_root.len + r->uri.len + index[i].len;
+ index[i].len;
} }
/* STUB */ r->exten.len = 4; r->exten.data = "html"; return ngx_http_internal_redirect(r, &redirect, NULL);
return ngx_http_internal_redirect(r, loc);
} }
return NGX_DECLINED; return NGX_DECLINED;
@ -177,7 +174,6 @@ ngx_log_debug(r->connection->log, "IS_DIR: %s" _ r->path.data);
} }
ngx_log_error(NGX_LOG_CRIT, r->connection->log, r->path_err, ngx_log_error(NGX_LOG_CRIT, r->connection->log, r->path_err,
"ngx_http_index_test_dir: "
ngx_file_type_n " %s failed", r->path.data); ngx_file_type_n " %s failed", r->path.data);
return NGX_HTTP_INTERNAL_SERVER_ERROR; return NGX_HTTP_INTERNAL_SERVER_ERROR;
@ -263,7 +259,7 @@ static char *ngx_http_index_merge_conf(ngx_pool_t *p, void *parent, void *child)
} }
/* TODO: check duplicate indices */ /* TODO: warn about duplicate indices */
static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd, static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf) void *conf)
@ -283,7 +279,9 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
for (i = 1; i < cf->args->nelts; i++) { for (i = 1; i < cf->args->nelts; i++) {
if (value[i].len == 0) { if (value[i].len == 0) {
return "is invalid"; ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
"index \"%s\" is invalid", value[1].data);
return ngx_conf_errstr;
} }
ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR); ngx_test_null(index, ngx_push_array(&icf->indices), NGX_CONF_ERROR);
@ -295,5 +293,5 @@ static char *ngx_http_index_set_index(ngx_conf_t *cf, ngx_command_t *cmd,
} }
} }
return NULL; return NGX_CONF_OK;
} }

63
src/http/ngx_http_cache.c Normal file
View File

@ -0,0 +1,63 @@
#define NGX_HTTP_CACHE_ENTRY_DELETED 0x00000001
#define NGX_HTTP_CACHE_ENTRY_MMAPED 0x00000002
/* "/" -> "/index.html" in ngx_http_index_handler */
#define NGX_HTTP_CACHE_ENTRY_URI 0x00000004
#define NGX_HTTP_CACHE_FILTER_FLAGS 0xFFFF0000
typedef struct {
ngx_fd_t fd;
off_t size;
void *data;
time_t accessed;
time_t last_modified;
time_t updated; /* no needed with kqueue */
int refs;
int flags;
} ngx_http_cache_entry_t;
typedef struct {
u_int32_t crc;
ngx_str_t uri;
ngx_http_cache_t *cache;
} ngx_http_cache_hash_entry_t;
typedef struct {
ngx_http_cache_t *cache;
u_int32_t crc;
int n;
} ngx_http_cache_handle_t;
int ngx_http_cache_get(ngx_http_cache_hash_t *cache_hash,
ngx_str_t *uri, ngx_http_cache_handle_t *h)
{
int hi;
ngx_http_cache_hash_entry_t *entry;
h->crc = ngx_crc32(uri->data, uri->len);
hi = h->crc % cache_hash->size;
entry = cache_hash[hi].elts;
for (i = 0; i < cache_hash[hi].nelts; i++) {
if (entry[i].crc == crc
&& entry[i].uri.len == uri->len
&& ngx_strncmp(entry[i].uri.data, uri->data, uri->len) == 0
{
h->cache = entry[i].cache;
h->cache->refs++;
h->n = hi;
return NGX_OK;
}
}
return NGX_ERROR;
}

View File

@ -28,10 +28,13 @@ static char *ngx_http_core_merge_loc_conf(ngx_pool_t *pool,
static int ngx_http_core_init(ngx_pool_t *pool); static int ngx_http_core_init(ngx_pool_t *pool);
static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy); static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy);
static int ngx_cmp_locations(const void *first, const void *second);
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd,
void *dummy); void *dummy);
static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_types_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd,
void *conf);
static ngx_command_t ngx_http_core_commands[] = { static ngx_command_t ngx_http_core_commands[] = {
@ -41,7 +44,7 @@ static ngx_command_t ngx_http_core_commands[] = {
ngx_server_block, ngx_server_block,
0, 0,
0, 0,
NULL,}, NULL},
{ngx_string("connection_pool_size"), {ngx_string("connection_pool_size"),
NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1, NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
@ -99,6 +102,13 @@ static ngx_command_t ngx_http_core_commands[] = {
0, 0,
NULL}, NULL},
{ngx_string("server_name"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_ANY,
ngx_set_server_name,
NGX_HTTP_SRV_CONF_OFFSET,
0,
NULL},
{ngx_string("types"), {ngx_string("types"),
NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF
|NGX_CONF_BLOCK|NGX_CONF_NOARGS, |NGX_CONF_BLOCK|NGX_CONF_NOARGS,
@ -215,8 +225,10 @@ ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data);
continue; continue;
} }
rc = ngx_rstrncmp(r->uri.data, clcfp[i]->name.data, rc = ngx_strncmp(r->uri.data, clcfp[i]->name.data,
clcfp[i]->name.len); clcfp[i]->name.len);
ngx_log_debug(r->connection->log, "rc: %d" _ rc);
if (rc < 0) { if (rc < 0) {
break; break;
@ -235,9 +247,10 @@ ngx_log_debug(r->connection->log, "trans: %s" _ clcfp[i]->name.data);
/* run translation phase */ /* run translation phase */
h = (ngx_http_handler_pt *) ngx_http_translate_handlers.elts; h = ngx_http_translate_handlers.elts;
for (i = ngx_http_translate_handlers.nelts; i > 0; /* void */) { for (i = ngx_http_translate_handlers.nelts - 1; i >= 0; i--) {
rc = h[--i](r);
rc = h[i](r);
if (rc == NGX_DECLINED) { if (rc == NGX_DECLINED) {
continue; continue;
@ -457,21 +470,46 @@ int ngx_http_error(ngx_http_request_t *r, int error)
} }
int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri) int ngx_http_internal_redirect(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args)
{ {
ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri.data); int i;
r->uri.len = uri.len; ngx_log_debug(r->connection->log, "internal redirect: '%s'" _ uri->data);
r->uri.data = uri.data;
/* BROKEN, NEEDED ? */ r->uri.len = uri->len;
/* r->exten */ r->uri.data = uri->data;
r->uri_start = uri.data;
r->uri_end = uri.data + uri.len; if (args) {
/**/ r->args.len = args->len;
r->args.data = args->data;
}
r->exten.len = 0;
r->exten.data = NULL;
for (i = uri->len - 1; i > 1; i--) {
if (uri->data[i] == '.' && uri->data[i - 1] != '/') {
r->exten.len = uri->len - i - 1;
if (r->exten.len > 0) {
ngx_test_null(r->exten.data,
ngx_palloc(r->pool, r->exten.len + 1),
NGX_HTTP_INTERNAL_SERVER_ERROR);
ngx_cpystrn(r->exten.data, &uri->data[i + 1], r->exten.len + 1);
}
break;
} else if (uri->data[i] == '/') {
break;
}
}
ngx_http_handler(r); ngx_http_handler(r);
return 0;
return NGX_OK;
} }
@ -554,10 +592,26 @@ static char *ngx_server_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
rv = ngx_conf_parse(cf, NULL); rv = ngx_conf_parse(cf, NULL);
*cf = pcf; *cf = pcf;
if (rv != NGX_CONF_OK) {
return rv;
}
ngx_qsort(cscf->locations.elts, cscf->locations.nelts,
sizeof(void *), ngx_cmp_locations);
return rv; return rv;
} }
static int ngx_cmp_locations(const void *first, const void *second)
{
ngx_http_core_loc_conf_t *one = *(ngx_http_core_loc_conf_t **) first;
ngx_http_core_loc_conf_t *two = *(ngx_http_core_loc_conf_t **) second;
return ngx_strcmp(one->name.data, two->name.data);
}
static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy) static char *ngx_location_block(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
{ {
int m; int m;
@ -724,6 +778,7 @@ static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool,
ngx_http_core_srv_conf_t *prev = (ngx_http_core_srv_conf_t *) parent; ngx_http_core_srv_conf_t *prev = (ngx_http_core_srv_conf_t *) parent;
ngx_http_core_srv_conf_t *conf = (ngx_http_core_srv_conf_t *) child; ngx_http_core_srv_conf_t *conf = (ngx_http_core_srv_conf_t *) child;
ngx_err_t err;
ngx_http_listen_t *l; ngx_http_listen_t *l;
ngx_http_server_name_t *n; ngx_http_server_name_t *n;
@ -740,10 +795,15 @@ static char *ngx_http_core_merge_srv_conf(ngx_pool_t *pool,
ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR); ngx_test_null(n, ngx_push_array(&conf->server_names), NGX_CONF_ERROR);
ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN), ngx_test_null(n->name.data, ngx_palloc(pool, NGX_MAXHOSTNAMELEN),
NGX_CONF_ERROR); NGX_CONF_ERROR);
if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) { if (gethostname(n->name.data, NGX_MAXHOSTNAMELEN) == -1) {
/* TODO: need ngx_errno here */ err = ngx_errno;
return "gethostname() failed"; ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
"gethostname() failed (%d: %s)",
err, ngx_strerror(err));
return ngx_conf_errstr;
} }
n->name.len = ngx_strlen(n->name.data); n->name.len = ngx_strlen(n->name.data);
n->core_srv_conf = conf; n->core_srv_conf = conf;
} }
@ -868,7 +928,7 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ngx_http_listen_t *ls; ngx_http_listen_t *ls;
/* TODO: check duplicate 'listen' directives, /* TODO: check duplicate 'listen' directives,
add resolved name to server names */ add resolved name to server names ??? */
ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR); ngx_test_null(ls, ngx_push_array(&scf->listen), NGX_CONF_ERROR);
@ -879,37 +939,75 @@ static char *ngx_set_listen(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
ls->file_name = cf->conf_file->file.name; ls->file_name = cf->conf_file->file.name;
ls->line = cf->conf_file->line; ls->line = cf->conf_file->line;
args = (ngx_str_t *) cf->args->elts; args = cf->args->elts;
addr = args[1].data; addr = args[1].data;
for (p = 0; p < args[1].len; p++) { for (p = 0; p < args[1].len; p++) {
if (addr[p] == ':') { if (addr[p] == ':') {
addr[p++] = '\0'; addr[p++] = '\0';
ls->addr = inet_addr(addr);
if (ls->addr == INADDR_NONE) {
h = gethostbyname(addr);
if (h == NULL || h->h_addr_list[0] == NULL) {
return "can not resolve host name";
}
ls->addr = *(u_int32_t *)(h->h_addr_list[0]);
}
break; break;
} }
} }
if (p == args[1].len) { if (p == args[1].len) {
ls->addr = INADDR_ANY; /* no ":" in the "listen" */
p = 0; p = 0;
} }
ls->port = ngx_atoi(&addr[p], args[1].len - p); ls->port = ngx_atoi(&addr[p], args[1].len - p);
if (ls->port < 1 || ls->port > 65536) { if (ls->port == NGX_ERROR && p == 0) {
return "port must be between 1 and 65535";
/* "listen host" */
ls->port = 80;
} else if ((ls->port == NGX_ERROR && p != 0) /* "listen host:NONNUMBER" */
|| (ls->port < 1 || ls->port > 65536)) { /* "listen 99999" */
ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
"invalid port \"%s\", "
"it must be a number between 1 and 65535",
&addr[p]);
return ngx_conf_errstr;
} else if (p == 0) {
ls->addr = INADDR_ANY;
return NGX_CONF_OK;
}
ls->addr = inet_addr(addr);
if (ls->addr == INADDR_NONE) {
h = gethostbyname(addr);
if (h == NULL || h->h_addr_list[0] == NULL) {
ngx_snprintf(ngx_conf_errstr, sizeof(ngx_conf_errstr) - 1,
"can not resolve host \"%s\"", addr);
return ngx_conf_errstr;
}
ls->addr = *(u_int32_t *)(h->h_addr_list[0]);
} }
return NGX_CONF_OK; return NGX_CONF_OK;
} }
static char *ngx_set_server_name(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
ngx_http_core_srv_conf_t *scf = (ngx_http_core_srv_conf_t *) conf;
ngx_str_t *args;
ngx_http_server_name_t *sn;
/* TODO: several names */
/* TODO: warn about duplicate 'server_name' directives */
ngx_test_null(sn, ngx_push_array(&scf->server_names), NGX_CONF_ERROR);
args = cf->args->elts;
sn->name.len = args[1].len;
sn->name.data = args[1].data;
sn->core_srv_conf = scf;
return NGX_CONF_OK;
}

View File

@ -138,7 +138,8 @@ extern int ngx_http_max_module;
int ngx_http_core_translate_handler(ngx_http_request_t *r); int ngx_http_core_translate_handler(ngx_http_request_t *r);
int ngx_http_internal_redirect(ngx_http_request_t *r, ngx_str_t uri); int ngx_http_internal_redirect(ngx_http_request_t *r,
ngx_str_t *uri, ngx_str_t *args);
int ngx_http_error(ngx_http_request_t *r, int error); int ngx_http_error(ngx_http_request_t *r, int error);

View File

@ -24,6 +24,8 @@ typedef int ngx_err_t;
#define ngx_socket_errno errno #define ngx_socket_errno errno
#define ngx_set_socket_errno(err) errno = err #define ngx_set_socket_errno(err) errno = err
#define ngx_strerror(err) strerror(err)
#define ngx_strerror_r(err, errstr, size) \ #define ngx_strerror_r(err, errstr, size) \
ngx_cpystrn(errstr, strerror(err), size) - (errstr) ngx_cpystrn(errstr, strerror(err), size) - (errstr)

View File

@ -2,6 +2,7 @@
#include <ngx_freebsd_init.h> #include <ngx_freebsd_init.h>
/* FreeBSD 3.4 at least */
char ngx_freebsd_kern_ostype[20]; char ngx_freebsd_kern_ostype[20];
char ngx_freebsd_kern_osrelease[20]; char ngx_freebsd_kern_osrelease[20];
int ngx_freebsd_kern_osreldate; int ngx_freebsd_kern_osreldate;
@ -9,6 +10,9 @@ int ngx_freebsd_hw_ncpu;
int ngx_freebsd_net_inet_tcp_sendspace; int ngx_freebsd_net_inet_tcp_sendspace;
int ngx_freebsd_sendfile_nbytes_bug; int ngx_freebsd_sendfile_nbytes_bug;
/* FreeBSD 5.0 */
int ngx_freebsd_kern_ipc_zero_copy_send;
ngx_os_io_t ngx_os_io = { ngx_os_io_t ngx_os_io = {
ngx_unix_recv, ngx_unix_recv,
@ -19,9 +23,35 @@ ngx_os_io_t ngx_os_io = {
}; };
typedef struct {
char *name;
int *value;
size_t size;
} sysctl_t;
sysctl_t sysctls[] = {
{"hw.ncpu",
&ngx_freebsd_hw_ncpu,
sizeof(int)},
{"net.inet.tcp.sendspace",
&ngx_freebsd_net_inet_tcp_sendspace,
sizeof(int)},
{"kern.ipc.zero_copy.send",
&ngx_freebsd_kern_ipc_zero_copy_send,
sizeof(int)},
{NULL, NULL, 0}
};
int ngx_os_init(ngx_log_t *log) int ngx_os_init(ngx_log_t *log)
{ {
size_t size; int i;
size_t size;
ngx_err_t err;
size = 20; size = 20;
if (sysctlbyname("kern.ostype", if (sysctlbyname("kern.ostype",
@ -85,28 +115,23 @@ int ngx_os_init(ngx_log_t *log)
#endif /* HAVE_FREEBSD_SENDFILE */ #endif /* HAVE_FREEBSD_SENDFILE */
size = 4; for (i = 0; sysctls[i].name; i++) {
if (sysctlbyname("hw.ncpu", &ngx_freebsd_hw_ncpu, &size, NULL, 0) == -1) { *sysctls[i].value = 0;
ngx_log_error(NGX_LOG_ALERT, log, errno, size = sysctls[i].size;
"sysctlbyname(hw.ncpu) failed"); if (sysctlbyname(sysctls[i].name, sysctls[i].value, &size, NULL, 0)
return NGX_ERROR; == -1) {
err = errno;
if (err != NGX_ENOENT) {
ngx_log_error(NGX_LOG_ALERT, log, err,
"sysctlbyname(%s) failed", sysctls[i].name);
return NGX_ERROR;
}
} else {
ngx_log_error(NGX_LOG_INFO, log, 0, "%s: %d",
sysctls[i].name, *sysctls[i].value);
}
} }
ngx_log_error(NGX_LOG_INFO, log, 0, "hw.ncpu: %d", ngx_freebsd_hw_ncpu);
size = 4;
if (sysctlbyname("net.inet.tcp.sendspace",
&ngx_freebsd_net_inet_tcp_sendspace,
&size, NULL, 0) == -1)
{
ngx_log_error(NGX_LOG_ALERT, log, errno,
"sysctlbyname(net.inet.tcp.sendspace) failed");
return NGX_ERROR;
}
ngx_log_error(NGX_LOG_INFO, log, 0, "net.inet.tcp.sendspace: %d",
ngx_freebsd_net_inet_tcp_sendspace);
return ngx_posix_init(log); return ngx_posix_init(log);
} }

View File

@ -26,6 +26,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h>
typedef unsigned int u_int; typedef unsigned int u_int;

View File

@ -0,0 +1,183 @@
#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_linux_init.h>
ngx_chain_t *ngx_linux_sendfile_chain(ngx_connection_t *c, ngx_chain_t *in)
{
int rc, on, off;
char *prev;
size_t hsize, size;
ssize_t sent;
struct iovec *iov;
struct sf_hdtr hdtr;
ngx_err_t err;
ngx_array_t header, trailer;
ngx_hunk_t *file;
ngx_chain_t *ce;
ce = in;
file = NULL;
hsize = 0;
on = 1;
off = 0;
ngx_init_array(header, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
ngx_init_array(trailer, c->pool, 10, sizeof(struct iovec), NGX_CHAIN_ERROR);
/* create the header iovec */
if (ngx_hunk_in_memory_only(ce->hunk)) {
prev = NULL;
iov = NULL;
/* create the iovec and coalesce the neighbouring chain entries */
while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
if (prev == ce->hunk->pos) {
iov->iov_len += ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
} else {
ngx_test_null(iov, ngx_push_array(&header), NGX_CHAIN_ERROR);
iov->iov_base = ce->hunk->pos;
iov->iov_len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
}
if (ngx_freebsd_sendfile_nbytes_bug) {
hsize += ce->hunk->last - ce->hunk->pos;
}
ce = ce->next;
}
}
/* TODO: coalesce the neighbouring file hunks */
if (ce && (ce->hunk->type & NGX_HUNK_FILE)) {
file = ce->hunk;
ce = ce->next;
}
/* create the trailer iovec */
if (ce && ngx_hunk_in_memory_only(ce->hunk)) {
prev = NULL;
iov = NULL;
/* create the iovec and coalesce the neighbouring chain entries */
while (ce && ngx_hunk_in_memory_only(ce->hunk)) {
if (prev == ce->hunk->pos) {
iov->iov_len += ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
} else {
ngx_test_null(iov, ngx_push_array(&trailer), NGX_CHAIN_ERROR);
iov->iov_base = ce->hunk->pos;
iov->iov_len = ce->hunk->last - ce->hunk->pos;
prev = ce->hunk->last;
}
ce = ce->next;
}
}
if (file) {
if (setsockopt(c->fd, IPPROTO_TCP, TCP_CORK,
(const void *) &on, sizeof(int)) == -1) {
ngx_log_error(NGX_LOG_CRIT, c->log, err,
"setsockopt(TCP_CORK, 1) failed");
return NGX_CHAIN_ERROR;
}
rc = sendfile(c->fd, file->file->fd, file->file_pos,
(size_t) (file->file_last - file->file_pos));
if (rc == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EAGAIN");
} else if (err == NGX_EINTR) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "senfile() EINTR");
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err, "sendfile() failed");
return NGX_CHAIN_ERROR;
}
}
sent = rc > 0 ? rc : 0;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "sendfile: %d, @%qd %d:%d" _
rc _ file->file_pos _ sent _
(size_t) (file->file_last - file->file_pos));
#endif
} else {
rc = writev(c->fd, (struct iovec *) header.elts, header.nelts);
if (rc == -1) {
err = ngx_errno;
if (err == NGX_EAGAIN) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EAGAIN");
} else if (err == NGX_EINTR) {
ngx_log_error(NGX_LOG_INFO, c->log, err, "writev() EINTR");
} else {
ngx_log_error(NGX_LOG_CRIT, c->log, err, "writev() failed");
return NGX_CHAIN_ERROR;
}
}
sent = rc > 0 ? rc : 0;
#if (NGX_DEBUG_WRITE_CHAIN)
ngx_log_debug(c->log, "writev: %d" _ sent);
#endif
}
c->sent += sent;
for (ce = in; ce && sent > 0; ce = ce->next) {
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
size = ce->hunk->last - ce->hunk->pos;
} else {
size = ce->hunk->file_last - ce->hunk->file_pos;
}
if (sent >= size) {
sent -= size;
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
ce->hunk->pos = ce->hunk->last;
}
if (ce->hunk->type & NGX_HUNK_FILE) {
ce->hunk->file_pos = ce->hunk->file_last;
}
continue;
}
if (ce->hunk->type & NGX_HUNK_IN_MEMORY) {
ce->hunk->pos += sent;
}
if (ce->hunk->type & NGX_HUNK_FILE) {
ce->hunk->file_pos += sent;
}
break;
}
ngx_destroy_array(&trailer);
ngx_destroy_array(&header);
return ce;
}

View File

@ -22,6 +22,7 @@
#include <sys/socket.h> #include <sys/socket.h>
#include <netinet/in.h> #include <netinet/in.h>
#include <arpa/inet.h> #include <arpa/inet.h>
#include <netdb.h>
typedef uint32_t u_int32_t; typedef uint32_t u_int32_t;