diff --git a/src/base.h b/src/base.h index 3ae04751..652cf2ef 100644 --- a/src/base.h +++ b/src/base.h @@ -131,7 +131,8 @@ typedef struct server_socket { sock_addr addr; int fd; - unsigned short is_ssl; + uint8_t is_ssl; + uint8_t srv_token_colon; unsigned short sidx; fdnode *fdn; diff --git a/src/http_cgi.c b/src/http_cgi.c index 0be57699..6a78f167 100644 --- a/src/http_cgi.c +++ b/src/http_cgi.c @@ -96,16 +96,13 @@ http_cgi_headers (request_st * const r, http_cgi_opts * const opts, http_cgi_hea { /* CGI-SPEC 6.1.2, FastCGI spec 6.3 and SCGI spec */ + /* note: string ptrs passed to cb() func must not be NULL */ + int rc = 0; - const connection * const con = r->con; - server_socket * const srv_sock = con->srv_socket; buffer * const tb = r->tmp_buf; const char *s; size_t n; - char buf[LI_ITOSTRING_LENGTH]; - sock_addr *addr; - sock_addr addrbuf; - char b2[INET6_ADDRSTRLEN + 1]; + char buf[INET6_ADDRSTRLEN + 1]; /*(also larger than LI_ITOSTRING_LENGTH)*/ /* (CONTENT_LENGTH must be first for SCGI) */ if (!opts->authorizer) @@ -237,50 +234,63 @@ http_cgi_headers (request_st * const r, http_cgi_opts * const opts, http_cgi_hea if (buffer_is_equal_string(&r->uri.scheme, CONST_STR_LEN("https"))) rc |= cb(vdata, CONST_STR_LEN("HTTPS"), CONST_STR_LEN("on")); - addr = &srv_sock->addr; - rc |= cb(vdata, CONST_STR_LEN("SERVER_PORT"), - buf, li_utostrn(buf,sizeof(buf),sock_addr_get_port(addr))); - - switch (sock_addr_get_family(addr)) { - case AF_INET: - case AF_INET6: - if (sock_addr_is_addr_wildcard(addr)) { + const connection * const con = r->con; + const server_socket * const srv_sock = con->srv_socket; + const size_t tlen = buffer_string_length(srv_sock->srv_token); + n = srv_sock->srv_token_colon; + if (n < tlen) { /*(n != tlen)*/ + s = srv_sock->srv_token->ptr+n+1; + n = tlen - (n+1); + } + else { + s = "0"; + n = 1; + } + rc |= cb(vdata, CONST_STR_LEN("SERVER_PORT"), s, n); + + n = 0; + switch (sock_addr_get_family(&srv_sock->addr)) { + case AF_INET: + case AF_INET6: + if (sock_addr_is_addr_wildcard(&srv_sock->addr)) { + sock_addr addrbuf; socklen_t addrlen = sizeof(addrbuf); if (0 == getsockname(con->fd,(struct sockaddr *)&addrbuf,&addrlen)){ - addr = &addrbuf; + /* future: might add a one- or two- element cache + * or use sock_addr_cache_inet_ntop_copy_buffer() into tb */ + s = sock_addr_inet_ntop(&addrbuf, buf, sizeof(buf)); + if (s) + n = strlen(s); + else + s = ""; } - else { + else s = ""; - break; - } } - s = sock_addr_inet_ntop(addr, b2, sizeof(b2)-1); - if (NULL == s) s = ""; + else { + s = srv_sock->srv_token->ptr; + n = srv_sock->srv_token_colon; + } break; - default: + default: s = ""; break; } - force_assert(s); - rc |= cb(vdata, CONST_STR_LEN("SERVER_ADDR"), s, strlen(s)); + rc |= cb(vdata, CONST_STR_LEN("SERVER_ADDR"), s, n); if (!buffer_string_is_empty(r->server_name)) { - size_t len = buffer_string_length(r->server_name); - - if (r->server_name->ptr[0] == '[') { - const char *colon = strstr(r->server_name->ptr, "]:"); - if (colon) len = (colon + 1) - r->server_name->ptr; + n = buffer_string_length(r->server_name); + s = r->server_name->ptr; + if (s[0] == '[') { + const char *colon = strstr(s, "]:"); + if (colon) n = (colon + 1) - s; } else { - const char *colon = strchr(r->server_name->ptr, ':'); - if (colon) len = colon - r->server_name->ptr; + const char *colon = strchr(s, ':'); + if (colon) n = colon - s; } - - rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"), - r->server_name->ptr, len); - } - else /* set to be same as SERVER_ADDR (above) */ - rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"), s, strlen(s)); + } /* else set to be same as SERVER_ADDR (above) */ + rc |= cb(vdata, CONST_STR_LEN("SERVER_NAME"), s, n); rc |= cb(vdata, CONST_STR_LEN("REMOTE_ADDR"), CONST_BUF_LEN(con->dst_addr_buf)); diff --git a/src/mod_accesslog.c b/src/mod_accesslog.c index 20bc7dca..f8f76df2 100644 --- a/src/mod_accesslog.c +++ b/src/mod_accesslog.c @@ -1062,38 +1062,25 @@ static int log_access_record (const request_st * const r, buffer * const b, form break; case FORMAT_LOCAL_ADDR: { - /* (perf: not using getsockname() and inet_ntop_cache_get_ip()) + /* (perf: not using getsockname() and + * sock_addr_cache_inet_ntop_copy_buffer()) * (still useful if admin has configured explicit listen IPs) */ - const char *colon; - buffer *srvtoken = con->srv_socket->srv_token; - if (srvtoken->ptr[0] == '[') { - colon = strstr(srvtoken->ptr, "]:"); - } else { - colon = strchr(srvtoken->ptr, ':'); - } - if (colon) { - buffer_append_string_len(b, srvtoken->ptr, (size_t)(colon - srvtoken->ptr)); - } else { - buffer_append_string_buffer(b, srvtoken); - } + const server_socket * const srv_sock = con->srv_socket; + buffer_append_string_len(b, srv_sock->srv_token->ptr, + srv_sock->srv_token_colon); } break; case FORMAT_SERVER_PORT: if (f->opt & FORMAT_FLAG_PORT_REMOTE) { buffer_append_int(b, sock_addr_get_port(&con->dst_addr)); } else { /* if (f->opt & FORMAT_FLAG_PORT_LOCAL) *//*(default)*/ - const char *colon; - buffer *srvtoken = ((server_socket*)(con->srv_socket))->srv_token; - if (srvtoken->ptr[0] == '[') { - colon = strstr(srvtoken->ptr, "]:"); - } else { - colon = strchr(srvtoken->ptr, ':'); - } - if (colon) { - buffer_append_string(b, colon+1); - } else { - buffer_append_int(b, con->srv->srvconf.port); - } + const server_socket * const srv_sock = con->srv_socket; + const buffer * const srv_token = srv_sock->srv_token; + const size_t tlen = buffer_string_length(srv_token); + size_t colon = srv_sock->srv_token_colon; + if (colon < tlen) /*(colon != tlen)*/ + buffer_append_string_len(b, srv_token->ptr+colon+1, + tlen - (colon+1)); } break; case FORMAT_QUERY_STRING: diff --git a/src/mod_magnet.c b/src/mod_magnet.c index b3180f2e..d7c86bc7 100644 --- a/src/mod_magnet.c +++ b/src/mod_magnet.c @@ -505,7 +505,7 @@ static buffer *magnet_env_get_buffer_by_id(request_st * const r, int id) { case MAGNET_ENV_REQUEST_ORIG_URI: dest = &r->target_orig; break; case MAGNET_ENV_REQUEST_PATH_INFO: dest = &r->pathinfo; break; case MAGNET_ENV_REQUEST_REMOTE_IP: dest = r->con->dst_addr_buf; break; - case MAGNET_ENV_REQUEST_SERVER_ADDR: + case MAGNET_ENV_REQUEST_SERVER_ADDR: /* local IP without port */ { const server_socket * const srv_socket = r->con->srv_socket; dest = r->tmp_buf; @@ -519,19 +519,14 @@ static buffer *magnet_env_get_buffer_by_id(request_st * const r, int id) { const int fd = r->con->fd; if (0 == getsockname(fd,(struct sockaddr *)&addrbuf,&addrlen)) { char buf[INET6_ADDRSTRLEN + 1]; - const char *s = sock_addr_inet_ntop(&addrbuf, buf, sizeof(buf)-1); + const char *s = sock_addr_inet_ntop(&addrbuf, buf, sizeof(buf)); if (NULL != s) buffer_copy_string_len(dest, s, strlen(s)); } } - else { - buffer_copy_buffer(dest, srv_socket->srv_token); - if (dest->ptr[0] != '[' || dest->ptr[buffer_string_length(dest)-1] != ']') { - char *s = strrchr(dest->ptr, ':'); - if (s != NULL) /* local IP without port */ - buffer_string_set_length(dest, s - dest->ptr); - } - } + else + buffer_copy_string_len(dest, srv_socket->srv_token->ptr, + srv_socket->srv_token_colon); break; default: break; diff --git a/src/network.c b/src/network.c index d08ad212..d4792fa3 100644 --- a/src/network.c +++ b/src/network.c @@ -197,6 +197,20 @@ static void network_merge_config(network_socket_config * const pconf, const conf } while ((++cpv)->k_id != -1); } +__attribute_pure__ +static uint8_t network_srv_token_colon (const buffer * const b) { + const char *colon = NULL; + const char * const p = b->ptr; + if (*p == '[') { + colon = strstr(p, "]:"); + if (colon) ++colon; + } + else if (*p != '/') { + colon = strchr(p, ':'); + } + return colon ? (uint8_t)(colon - p) : (uint8_t)buffer_string_length(b); +} + static int network_server_init(server *srv, network_socket_config *s, buffer *host_token, size_t sidx, int stdin_fd) { server_socket *srv_socket; const char *host; @@ -278,6 +292,8 @@ static int network_server_init(server *srv, network_socket_config *s, buffer *ho srv_socket->is_ssl = s->ssl_enabled; srv_socket->srv = srv; srv_socket->srv_token = buffer_init_buffer(host_token); + srv_socket->srv_token_colon = + network_srv_token_colon(srv_socket->srv_token); network_srv_sockets_append(srv, srv_socket); @@ -692,6 +708,8 @@ int network_init(server *srv, int stdin_fd) { sizeof(server_socket)); srv_socket->srv_token = buffer_init_buffer(srv_socket->srv_token); + srv_socket->srv_token_colon = + network_srv_token_colon(srv_socket->srv_token); network_srv_sockets_append(srv, srv_socket); } }