diff --git a/CHANGELOG.md b/CHANGELOG.md index be38f4a39..18cab02c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] ### Added - A CHANGELOG.md to track important changes +- User-Agent header with APIcast version and system information [PR #214](https://github.com/3scale/apicast/pull/214) ### Changed - Require openresty 1.11.2 [PR #194](https://github.com/3scale/apicast/pull/194) diff --git a/Makefile b/Makefile index a83f0a17a..a1bcc1d98 100644 --- a/Makefile +++ b/Makefile @@ -75,7 +75,7 @@ test-builder-image: builder-image clean ## Smoke test the builder image. Pass an @echo -e $(SEPARATOR) $(DOCKER_COMPOSE) run --rm test curl --fail -X POST http://gateway:8090/boot @echo -e $(SEPARATOR) - $(DOCKER_COMPOSE) run --rm -e THREESCALE_PORTAL_ENDPOINT=https://echo-api.3scale.net gateway /opt/app/libexec/boot | grep lua-resty-http + $(DOCKER_COMPOSE) run --rm -e THREESCALE_PORTAL_ENDPOINT=https://echo-api.3scale.net gateway /opt/app/libexec/boot | grep 'APIcast/' @echo -e $(SEPARATOR) test-runtime-image: export IMAGE_NAME = apicast-release-test diff --git a/apicast/conf.d/apicast.conf b/apicast/conf.d/apicast.conf index e1668259a..dc4fc82b6 100644 --- a/apicast/conf.d/apicast.conf +++ b/apicast/conf.d/apicast.conf @@ -1,4 +1,8 @@ -set_by_lua $deployment 'return os.getenv("THREESCALE_DEPLOYMENT_ENV");'; +set_by_lua $user_agent 'return require("user_agent")()'; +set_by_lua_block $deployment { + local user_agent = require('user_agent') + return user_agent.platform() .. '+' .. user_agent.deployment() +} # TODO: enable in the future when we support SSL # ssl_certificate_by_lua_block { require('module').call() } @@ -17,7 +21,8 @@ location = /threescale_authrep { proxy_http_version 1.1; proxy_pass $backend_endpoint$path; proxy_set_header Host "$backend_host"; - proxy_set_header X-3scale-User-Agent "nginx$deployment"; + proxy_set_header User-Agent "$user_agent"; + proxy_set_header X-3scale-User-Agent "$deployment"; proxy_set_header X-3scale-Version "$version"; proxy_set_header Connection ""; @@ -88,6 +93,9 @@ location = /_threescale/oauth_store_token { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host "$backend_host"; + proxy_set_header User-Agent "$user_agent"; + proxy_set_header X-3scale-User-Agent "$deployment"; + proxy_set_header X-3scale-Version "$version"; proxy_pass $backend_endpoint/services/$service_id/oauth_access_tokens.xml?$backend_authentication_type=$backend_authentication_value; } @@ -98,6 +106,9 @@ location = /_threescale/check_credentials { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host "$backend_host"; + proxy_set_header User-Agent "$user_agent"; + proxy_set_header X-3scale-User-Agent "$deployment"; + proxy_set_header X-3scale-Version "$version"; proxy_pass $backend_endpoint/transactions/oauth_authorize.xml?$backend_authentication_type=$backend_authentication_value&service_id=$service_id&$args; } @@ -105,7 +116,8 @@ location = /_threescale/check_credentials { location = /threescale_oauth_authrep { internal; proxy_set_header Host "$backend_host"; - proxy_set_header X-3scale-User-Agent "nginx$deployment"; + proxy_set_header User-Agent "$user_agent"; + proxy_set_header X-3scale-User-Agent "$deployment"; proxy_set_header X-3scale-Version "$version"; proxy_set_header X-3scale-OAuth2-Grant-Type "authorization_code"; diff --git a/apicast/src/apicast.lua b/apicast/src/apicast.lua index bf85ff89a..e3d203cc3 100644 --- a/apicast/src/apicast.lua +++ b/apicast/src/apicast.lua @@ -7,9 +7,11 @@ local tonumber = tonumber local math = math local getenv = os.getenv local reload_config = util.env_enabled('APICAST_RELOAD_CONFIG') +local user_agent = require('user_agent') local _M = { - _VERSION = '0.1' + _VERSION = '2.0', + _NAME = 'APIcast' } local missing_configuration = getenv('APICAST_MISSING_CONFIGURATION') or 'log' @@ -28,6 +30,8 @@ local function handle_missing_configuration(err) end function _M.init() + user_agent.cache() + math.randomseed(ngx.now()) -- First calls to math.random after a randomseed tend to be similar; discard them for _=1,3 do math.random() end diff --git a/apicast/src/configuration_loader/remote_v1.lua b/apicast/src/configuration_loader/remote_v1.lua index d411d5974..cd3edcc6c 100644 --- a/apicast/src/configuration_loader/remote_v1.lua +++ b/apicast/src/configuration_loader/remote_v1.lua @@ -8,6 +8,7 @@ local resty_url = require 'resty.url' local http = require "resty.http" local configuration = require 'configuration' local util = require 'util' +local user_agent = require 'user_agent' local _M = { version = '0.1' @@ -90,6 +91,8 @@ function _M.download(endpoint, _) headers['Authorization'] = "Basic " .. ngx.encode_base64(concat({ user or '', pass or '' }, ':')) end + headers['User-Agent'] = user_agent() + -- TODO: this does not fully implement HTTP spec, it first should send -- request without Authentication and then send it after gettting 401