Reputation: 792
I have cookies in my HTTP header like so:
Set-Cookie: frontend=ovsu0p8khivgvp29samlago1q0; adminhtml=6df3s767g199d7mmk49dgni4t7; external_no_cache=1; ZDEDebuggerPresent=php,phtml,php3
and I need to extract the 26 character string that comes after frontend (e.g. ovsu0p8khivgvp29samlago1q0
). The following regular expression matches that for me:
(?<=frontend=)(.*)(?=;)
However, I am using Varnish Cache and can only use a regex replace. Therefore, to extract that cookie value (26 character frontend
string) I need to match all characters that do not match that pattern (so I can replace them with ''
).
I've done a fair bit of Googling but so far have drawn a blank. I've tried the following
[^((?<=frontend=)[A-Za-z0-9]{26}(?=;))]
which matches random characters, including the ones I want to preserveI'd be grateful if someone could point me in the right direction, or note where I might have gone wrong.
Upvotes: 0
Views: 2007
Reputation: 2981
The Set-Cookie response header is a bit magical in Varnish, since the backends tend to send multiple headers with the same name. This is prohibited by the RFC, but the defacto way to do it.
If you are using Varnish 3.0 you can use the Header VMOD, it can parse the response and extract what you need:
https://github.com/varnish/libvmod-header
Upvotes: 2
Reputation: 44259
Do you have control over the replacement string? If so, you can go with Ωmega's answer, and use $1
in your replacement string to write the frontend
value back.
Otherwise, you could use this:
^Set-Cookie:.*(?!frontend=)|(?<=frontend=.{26}).*$
This will match everything from the start of the string, until frontend=
is encountered. Or it will match everything that has frontend=
exactly 26 characters to the left of it and up until the end of the string. If those 26 characters are a variable length, it would get signigicantly more complicated, because only .NET supports variable-length lookbehinds.
For your last question. Let's have a look at your regex:
[^((?<=frontend=)[A-Za-z0-9]{26}(?=;))]
Well, firstly the negative character class [^...]
you tried to surround you pattern with, doesn't really work like this. It is still a character class, so it matches only a single character that is not inside that class. But it gets even more complicated (and I wonder why it matches at all). So firstly the character class should be closed by the first ]
. This character class matches anything that is not (
, ?
, <
, =
, )
, a letter or a digit. Then the {26}
is applied to that, so we are trying to find 26 of those characters. Then the (?=;)
which asserts that those 26 characters are followed by ;
. Now comes what should not work. The closing )
should actually throw and error. And the final ]
would just be interpreted as a literal ]
.
There are some regex flavors which allow for nesting of character classes (Java does). In this case, you would simply have a character class equivalent to [^a-zA-Z0-9(){}?<=;]
. But as far as I could google it, Varnish uses PCRE, and in PCRE your regex should simply not compile.
Upvotes: 1
Reputation: 43673
Use regex pattern
^Set-Cookie:.*?\bfrontend=([^;]*)
and the "26 character string that comes after frontend" will be in group 1
(usually referred to in the replacement string as $1
)
Upvotes: 1