Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
k8s-ingress
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
3
Merge Requests
3
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
uplex-varnish
k8s-ingress
Commits
638d844b
Commit
638d844b
authored
Aug 27, 2020
by
Geoff Simmons
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Add helm deployments and a Makefile to the req-disposition tests.
parent
e83a841f
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
761 additions
and
0 deletions
+761
-0
Makefile
examples/req-disposition/Makefile
+228
-0
values-alt-builtin.yaml
examples/req-disposition/values-alt-builtin.yaml
+81
-0
values-builtin.yaml
examples/req-disposition/values-builtin.yaml
+100
-0
values-cacheability.yaml
examples/req-disposition/values-cacheability.yaml
+96
-0
values-cookie-pass.yaml
examples/req-disposition/values-cookie-pass.yaml
+81
-0
values-purge.yaml
examples/req-disposition/values-purge.yaml
+80
-0
values-url-whitelist.yaml
examples/req-disposition/values-url-whitelist.yaml
+95
-0
No files found.
examples/req-disposition/Makefile
0 → 100644
View file @
638d844b
# Copyright (c) 2020 UPLEX Nils Goroll Systemoptimierung
# All rights reserved
#
# Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
# GNU make is required.
mkpath
:=
$
(
abspath
$
(
lastword
$(MAKEFILE_LIST)
))
mkdir
:=
$
(
dir
$(mkpath)
)
CHARTDIR
=
$(mkdir)
/../../charts
TESTDIR
=
$(mkdir)
/../../test
all
:
deploy
deploy-builtin-helm
:
@
helm
install
viking-ingress-builtin
$(CHARTDIR)
/viking-test-app
\
--values
values-builtin.yaml
deploy-alt-builtin-helm
:
@
helm
install
viking-ingress-alt-builtin
$(CHARTDIR)
/viking-test-app
\
--values
values-alt-builtin.yaml
deploy-cookie-pass-helm
:
@
helm
install
viking-ingress-cookie-pass
$(CHARTDIR)
/viking-test-app
\
--values
values-cookie-pass.yaml
deploy-cacheability-helm
:
@
helm
install
viking-ingress-cacheability
$(CHARTDIR)
/viking-test-app
\
--values
values-cacheability.yaml
deploy-url-whitelist-helm
:
@
helm
install
viking-ingress-url-whitelist
$(CHARTDIR)
/viking-test-app
\
--values
values-url-whitelist.yaml
deploy-purge-helm
:
@
helm
install
viking-ingress-purge
$(CHARTDIR)
/viking-test-app
\
--values
values-purge.yaml
deploy-cafe
:
@
kubectl apply
-f
$(mkdir)
/../hello/cafe.yaml
@
kubectl apply
-f
$(mkdir)
/../hello/cafe-ingress.yaml
deploy-builtin-kubectl
:
deploy-cafe
@
kubectl apply
-f
builtin.yaml
deploy-alt-builtin-kubectl
:
deploy-cafe
@
kubectl apply
-f
alt-builtin.yaml
deploy-cookie-pass-kubectl
:
deploy-cafe
@
kubectl apply
-f
pass-on-session-cookie.yaml
deploy-cacheability-kubectl
:
deploy-cafe
@
kubectl apply
-f
cacheability.yaml
deploy-url-whitelist-kubectl
:
deploy-cafe
@
kubectl apply
-f
url-whitelist.yaml
deploy-purge-kubectl
:
deploy-cafe
@
kubectl apply
-f
purge-method.yaml
# TESTOPTS are passed to varnishtest, e.g.: make TESTOPTS=-v verify
verify-builtin
:
$(mkdir)
/verify_builtin.sh
verify-alt-builtin
:
$(mkdir)
/verify_alt-builtin.sh
verify-cookie-pass
:
$(mkdir)
/verify_pass-on-session-cookie.sh
verify-cacheability
:
$(mkdir)
/verify_cacheability.sh
verify-url-whitelist
:
$(mkdir)
/verify_url-whitelist.sh
verify-purge
:
$(mkdir)
/verify_purge.sh
wait
:
$(TESTDIR)
/wait.sh
app
=
varnish-ingress
undeploy-cafe
:
@
kubectl delete
-f
$(mkdir)
/../hello/cafe-ingress.yaml
@
kubectl delete
-f
$(mkdir)
/../hello/cafe.yaml
uninstall-builtin-kubectl
:
@
kubectl delete
-f
builtin.yaml
undeploy-builtin-kubectl
:
uninstall-builtin-kubectl undeploy-cafe wait
uninstall-alt-builtin-kubectl
:
@
kubectl delete
-f
alt-builtin.yaml
undeploy-alt-builtin-kubectl
:
uninstall-alt-builtin-kubectl undeploy-cafe wait
uninstall-cookie-pass-kubectl
:
@
kubectl delete
-f
pass-on-session-cookie.yaml
undeploy-cookie-pass-kubectl
:
uninstall-cookie-pass-kubectl undeploy-cafe wait
uninstall-cacheability-kubectl
:
@
kubectl delete
-f
cacheability.yaml
undeploy-cacheability-kubectl
:
uninstall-cacheability-kubectl undeploy-cafe wait
uninstall-url-whitelist-kubectl
:
@
kubectl delete
-f
url-whitelist.yaml
undeploy-url-whitelist-kubectl
:
uninstall-url-whitelist-kubectl undeploy-cafe wait
uninstall-purge-kubectl
:
@
kubectl delete
-f
purge-method.yaml
undeploy-purge-kubectl
:
uninstall-purge-kubectl undeploy-cafe wait
uninstall-builtin-helm
:
@
helm uninstall viking-ingress-builtin
undeploy-builtin-helm
:
uninstall-builtin-helm wait
uninstall-alt-builtin-helm
:
@
helm uninstall viking-ingress-alt-builtin
undeploy-alt-builtin-helm
:
uninstall-alt-builtin-helm wait
uninstall-cookie-pass-helm
:
@
helm uninstall viking-ingress-cookie-pass
undeploy-cookie-pass-helm
:
uninstall-cookie-pass-helm wait
uninstall-cacheability-helm
:
@
helm uninstall viking-ingress-cacheability
undeploy-cacheability-helm
:
uninstall-cacheability-helm wait
uninstall-url-whitelist-helm
:
@
helm uninstall viking-ingress-url-whitelist
undeploy-url-whitelist-helm
:
uninstall-url-whitelist-helm wait
uninstall-purge-helm
:
@
helm uninstall viking-ingress-purge
undeploy-purge-helm
:
uninstall-purge-helm wait
ifeq
($(DEPLOY),kubectl)
deploy-builtin
:
deploy-builtin-kubectl
undeploy-builtin
:
undeploy-builtin-kubectl
deploy-alt-builtin
:
deploy-alt-builtin-kubectl
undeploy-alt-builtin
:
undeploy-alt-builtin-kubectl
deploy-cookie-pass
:
deploy-cookie-pass-kubectl
undeploy-cookie-pass
:
undeploy-cookie-pass-kubectl
deploy-cacheability
:
deploy-cacheability-kubectl
undeploy-cacheability
:
undeploy-cacheability-kubectl
deploy-url-whitelist
:
deploy-url-whitelist-kubectl
undeploy-url-whitelist
:
undeploy-url-whitelist-kubectl
deploy-purge
:
deploy-purge-kubectl
undeploy-purge
:
undeploy-purge-kubectl
else
deploy-builtin
:
deploy-builtin-helm
undeploy-builtin
:
undeploy-builtin-helm
deploy-alt-builtin
:
deploy-alt-builtin-helm
undeploy-alt-builtin
:
undeploy-alt-builtin-helm
deploy-cookie-pass
:
deploy-cookie-pass-helm
undeploy-cookie-pass
:
undeploy-cookie-pass-helm
deploy-cacheability
:
deploy-cacheability-helm
undeploy-cacheability
:
undeploy-cacheability-helm
deploy-url-whitelist
:
deploy-url-whitelist-helm
undeploy-url-whitelist
:
undeploy-url-whitelist-helm
deploy-purge
:
deploy-purge-helm
undeploy-purge
:
undeploy-purge-helm
endif
deploy verify undeploy
:
ifndef
EXAMPLE
$(error
EXAMPLE
must
be
set
to
builtin,
...)
endif
ifeq
($(EXAMPLE),builtin)
deploy
:
deploy-builtin
verify
:
verify-builtin
undeploy
:
undeploy-builtin
else
ifeq
($(EXAMPLE),alt-builtin)
deploy
:
deploy-alt-builtin
verify
:
verify-alt-builtin
undeploy
:
undeploy-alt-builtin
else
ifeq
($(EXAMPLE),cookie-pass)
deploy
:
deploy-cookie-pass
verify
:
verify-cookie-pass
undeploy
:
undeploy-cookie-pass
else
ifeq
($(EXAMPLE),cacheability)
deploy
:
deploy-cacheability
verify
:
verify-cacheability
undeploy
:
undeploy-cacheability
else
ifeq
($(EXAMPLE),url-whitelist)
deploy
:
deploy-url-whitelist
verify
:
verify-url-whitelist
undeploy
:
undeploy-url-whitelist
else
ifeq
($(EXAMPLE),purge)
deploy
:
deploy-purge
verify
:
verify-purge
undeploy
:
undeploy-purge
endif
.PHONY
:
all $(MAKECMDGOALS)
examples/req-disposition/values-alt-builtin.yaml
0 → 100644
View file @
638d844b
apps
:
coffee
:
image
:
nginxdemos/hello:plain-text
replicas
:
2
tea
:
image
:
nginxdemos/hello:plain-text
replicas
:
3
ingress
:
name
:
cafe-ingress
rules
:
-
host
:
cafe.example.com
paths
:
-
path
:
/tea
app
:
tea
-
path
:
/coffee
app
:
coffee
vikingAdmSvc
:
varnish-ingress-admin
# Configuration for disposition of client requests that permits cache
# lookups for requests with Cookie or Authorization headers, and
# handles some requests differently from vcl_recv in builtin.vcl.
reqDisposition
:
# Requests for HTTP/1.1. without a Host header are rejected with
# 400 Bad Request, as in builtin.yaml and built-in vcl_recv.
-
conditions
:
-
comparand
:
req.http.Host
compare
:
not-exists
-
comparand
:
req.esi_level
count
:
0
-
comparand
:
req.proto
compare
:
prefix
values
:
-
HTTP/1.1
match-flags
:
case-insensitive
:
true
disposition
:
action
:
synth
status
:
400
# Requests with the CONNECT method invoke pipe mode. This may be
# appropriate for a WebSockets application. If you don't need pipe
# mode for any purpose, just include CONNECT in the array of
# request method names in the next stanza.
-
conditions
:
-
comparand
:
req.method
compare
:
equal
values
:
-
CONNECT
disposition
:
action
:
pipe
# Requests with any non-standard method get a synthetic 405 Method
# Not Allowed response.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
-
PUT
-
POST
-
TRACE
-
OPTIONS
-
DELETE
-
PATCH
disposition
:
action
:
synth
status
:
405
# Cache lookup is bypassed for requests whose method is neither of
# GET or HEAD.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
disposition
:
action
:
pass
examples/req-disposition/values-builtin.yaml
0 → 100644
View file @
638d844b
apps
:
coffee
:
image
:
nginxdemos/hello:plain-text
replicas
:
2
tea
:
image
:
nginxdemos/hello:plain-text
replicas
:
3
ingress
:
name
:
cafe-ingress
rules
:
-
host
:
cafe.example.com
paths
:
-
path
:
/tea
app
:
tea
-
path
:
/coffee
app
:
coffee
vikingAdmSvc
:
varnish-ingress-admin
# This configuration reconstructs vcl_recv from builtin.vcl,
# see:
# https://github.com/varnishcache/varnish-cache/blob/6.3/bin/varnishd/builtin.vcl
reqDisposition
:
# If the request method is "PRI", then send a synthetic "405
# Method Not Allowed" response.
-
conditions
:
-
comparand
:
req.method
compare
:
equal
values
:
-
PRI
disposition
:
action
:
synth
status
:
405
# Reject an HTTP/1.1 request with a synthetic "400 Bad Request"
# response if it doesn't have a Host header.
-
conditions
:
-
comparand
:
req.http.Host
compare
:
not-exists
-
comparand
:
req.esi_level
count
:
0
-
comparand
:
req.proto
compare
:
prefix
values
:
-
HTTP/1.1
match-flags
:
case-sensitive
:
false
disposition
:
action
:
synth
status
:
400
# Go to pipe mode for any request whose method is CONNECT, or a
# non-standard method.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
-
PUT
-
POST
-
TRACE
-
OPTIONS
-
DELETE
-
PATCH
disposition
:
action
:
pipe
# Bypass cache lookup if the request method is neither of GET or
# HEAD. Note that we only get here if the previous conditions did
# not evaluate to true, so the method must be one of PUT, POST,
# TRACE, OPTIONS, DELETE or PATCH.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
disposition
:
action
:
pass
# Bypass cache lookup if the request has a Cookie header.
-
conditions
:
-
comparand
:
req.http.Cookie
compare
:
exists
disposition
:
action
:
pass
# Bypass cache lookup if the request has an Authorization header;
# that is, if it is sending credentials for basic or proxy
# authentication.
-
conditions
:
-
comparand
:
req.http.Authorization
compare
:
exists
disposition
:
action
:
pass
# If none of the conditions evaluate to true, then the request
# proceeds to cache lookup.
examples/req-disposition/values-cacheability.yaml
0 → 100644
View file @
638d844b
apps
:
coffee
:
image
:
nginxdemos/hello:plain-text
replicas
:
2
tea
:
image
:
nginxdemos/hello:plain-text
replicas
:
3
ingress
:
name
:
cafe-ingress
rules
:
-
host
:
cafe.example.com
paths
:
-
path
:
/tea
app
:
tea
-
path
:
/coffee
app
:
coffee
vikingAdmSvc
:
varnish-ingress-admin
# Configuration for disposition of client requests that permits cache
# lookups for requests with Cookie or Authorization headers, and
# defines URL path patterns for which cache lookups are invoked or
# bypassed.
reqDisposition
:
# Requests for HTTP/1.1. without a Host header are rejected with
# 400 Bad Request, as in builtin.yaml and built-in vcl_recv.
-
conditions
:
-
comparand
:
req.http.Host
compare
:
not-exists
-
comparand
:
req.esi_level
count
:
0
-
comparand
:
req.proto
compare
:
prefix
values
:
-
HTTP/1.1
match-flags
:
case-insensitive
:
true
disposition
:
action
:
synth
status
:
400
# Requests with any non-standard method get a synthetic 405 Method
# Not Allowed response.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
-
PUT
-
POST
-
TRACE
-
OPTIONS
-
DELETE
-
PATCH
disposition
:
action
:
synth
status
:
405
# Cache lookup is bypassed for requests whose method is neither of
# GET or HEAD.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
disposition
:
action
:
pass
# Go to cache lookup (hash) if the URL ends in any of the patterns
# listed in values.
-
conditions
:
-
comparand
:
req.url
compare
:
match
values
:
-
\.png$
-
\.jpe?g$
-
\.css$
-
\.js$
disposition
:
action
:
hash
# Bypass cache lookup (pass) if the URL begins with any of the
# prefixes listed in values.
-
conditions
:
-
comparand
:
req.url
compare
:
prefix
values
:
-
/interactive/
-
/basket/
-
/personal/
-
/dynamic/
disposition
:
action
:
pass
examples/req-disposition/values-cookie-pass.yaml
0 → 100644
View file @
638d844b
apps
:
coffee
:
image
:
nginxdemos/hello:plain-text
replicas
:
2
tea
:
image
:
nginxdemos/hello:plain-text
replicas
:
3
ingress
:
name
:
cafe-ingress
rules
:
-
host
:
cafe.example.com
paths
:
-
path
:
/tea
app
:
tea
-
path
:
/coffee
app
:
coffee
vikingAdmSvc
:
varnish-ingress-admin
# Configuration for disposition of client requests that illustrates
# bypassing cache lookups for specific cookies.
reqDisposition
:
# Requests for HTTP/1.1. without a Host header are rejected with
# 400 Bad Request, as in builtin.yaml and built-in vcl_recv.
-
conditions
:
-
comparand
:
req.http.Host
compare
:
not-exists
-
comparand
:
req.esi_level
count
:
0
-
comparand
:
req.proto
compare
:
prefix
values
:
-
HTTP/1.1
match-flags
:
case-insensitive
:
true
disposition
:
action
:
synth
status
:
400
# Requests with any non-standard method get a synthetic 405 Method
# Not Allowed response.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
-
PUT
-
POST
-
TRACE
-
OPTIONS
-
DELETE
-
PATCH
-
CONNECT
disposition
:
action
:
synth
status
:
405
# Cache lookup is bypassed if the Cookie header includes either of
# the SESSION or LOGINID cookies, with their values constrained to
# specific forms. Cache lookup is permitted otherwise.
-
conditions
:
-
comparand
:
req.http.Cookie
compare
:
match
values
:
-
\bSESSIONID\s*=\s*[[:xdigit:]]{32}\b
-
\bLOGIN\s*=\s*\w+\b
disposition
:
action
:
pass
# Cache lookup is bypassed for requests whose method is neither of
# GET or HEAD.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
disposition
:
action
:
pass
examples/req-disposition/values-purge.yaml
0 → 100644
View file @
638d844b
apps
:
coffee
:
image
:
nginxdemos/hello:plain-text
replicas
:
2
tea
:
image
:
nginxdemos/hello:plain-text
replicas
:
3
ingress
:
name
:
cafe-ingress
rules
:
-
host
:
cafe.example.com
paths
:
-
path
:
/tea
app
:
tea
-
path
:
/coffee
app
:
coffee
vikingAdmSvc
:
varnish-ingress-admin
# Configuration for disposition of client requests that permits cache
# lookups for requests with Cookie or Authorization headers, and
# allows use of the PURGE request method to purge cache objects.
reqDisposition
:
# Requests for HTTP/1.1. without a Host header are rejected with
# 400 Bad Request, as in builtin.yaml and built-in vcl_recv.
-
conditions
:
-
comparand
:
req.http.Host
compare
:
not-exists
-
comparand
:
req.esi_level
count
:
0
-
comparand
:
req.proto
compare
:
prefix
values
:
-
HTTP/1.1
match-flags
:
case-insensitive
:
true
disposition
:
action
:
synth
status
:
400
# Divert to purge when the request method is PURGE.
# See: https://varnish-cache.org/docs/6.3/users-guide/purging.html
-
conditions
:
-
comparand
:
req.method
compare
:
equal
values
:
-
PURGE
disposition
:
action
:
purge
# Requests with any non-standard method get a synthetic 405 Method
# Not Allowed response.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
-
PUT
-
POST
-
TRACE
-
OPTIONS
-
DELETE
-
PATCH
-
CONNECT
disposition
:
action
:
synth
status
:
405
# Cache lookup is bypassed for requests whose method is neither of
# GET or HEAD.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
disposition
:
action
:
pass
examples/req-disposition/values-url-whitelist.yaml
0 → 100644
View file @
638d844b
apps
:
coffee
:
image
:
nginxdemos/hello:plain-text
replicas
:
2
tea
:
image
:
nginxdemos/hello:plain-text
replicas
:
3
ingress
:
name
:
cafe-ingress
rules
:
-
host
:
cafe.example.com
paths
:
-
path
:
/tea
app
:
tea
-
path
:
/coffee
app
:
coffee
vikingAdmSvc
:
varnish-ingress-admin
# Configuration for disposition of client requests that permits cache
# lookups for requests with Cookie or Authorization headers, and
# defines white- and blacklists for requests based on URL path prefixes.
reqDisposition
:
# Requests for HTTP/1.1. without a Host header are rejected with
# 400 Bad Request, as in builtin.yaml and built-in vcl_recv.
-
conditions
:
-
comparand
:
req.http.Host
compare
:
not-exists
-
comparand
:
req.esi_level
count
:
0
-
comparand
:
req.proto
compare
:
prefix
values
:
-
HTTP/1.1
match-flags
:
case-insensitive
:
true
disposition
:
action
:
synth
status
:
400
# Requests with any non-standard method get a synthetic 405 Method
# Not Allowed response.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
-
PUT
-
POST
-
TRACE
-
OPTIONS
-
DELETE
-
PATCH
-
CONNECT
disposition
:
action
:
synth
status
:
405
# A URL whitelist. Requests for URLs that do not have these
# prefixes get a synthetic 403 Forbidden response.
-
conditions
:
-
comparand
:
req.url
compare
:
not-prefix
values
:
-
/tea/sugar/
-
/coffee/sugar/
disposition
:
action
:
synth
status
:
403
# A URL blacklist. Requests for URLs with these prefixes get a
# synthetic 403 Forbidden response.
-
conditions
:
-
comparand
:
req.url
compare
:
prefix
values
:
-
/tea/sugar/black/
-
/coffee/sugar/black/
disposition
:
action
:
synth
status
:
403
reason
:
Blacklisted
# Cache lookup is bypassed for requests whose method is neither of
# GET or HEAD.
-
conditions
:
-
comparand
:
req.method
compare
:
not-equal
values
:
-
GET
-
HEAD
disposition
:
action
:
pass
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment