in wicket-core/src/main/java/org/apache/wicket/core/request/mapper/CryptoMapper.java [418:541]
protected Url decryptEntireUrl(final Request request, final Url encryptedUrl)
{
Url url = new Url(request.getCharset());
List<String> encryptedSegments = encryptedUrl.getSegments();
if (encryptedSegments.isEmpty())
{
return null;
}
/*
* The first encrypted segment contains an encrypted version of the entire plain text url.
*/
String encryptedUrlString = encryptedSegments.get(0);
if (Strings.isEmpty(encryptedUrlString))
{
return null;
}
if (getMarkEncryptedUrls())
{
if (encryptedUrlString.startsWith(ENCRYPTED_URL_MARKER_PREFIX))
{
encryptedUrlString = encryptedUrlString.substring(ENCRYPTED_URL_MARKER_PREFIX.length());
}
else
{
return null;
}
}
String decryptedUrl;
try
{
decryptedUrl = getCrypt().decryptUrlSafe(encryptedUrlString);
}
catch (Exception e)
{
log.error("Error decrypting URL", e);
return null;
}
if (decryptedUrl == null)
{
if (getMarkEncryptedUrls())
{
throw new PageExpiredException("Encrypted URL is no longer decryptable");
}
else
{
return null;
}
}
Url originalUrl = Url.parse(decryptedUrl, request.getCharset());
int originalNumberOfSegments = originalUrl.getSegments().size();
int encryptedNumberOfSegments = encryptedUrl.getSegments().size();
if (originalNumberOfSegments > 0)
{
/*
* This should always be true. Home page URLs are the only ones without
* segments, and we don't encrypt those with this method.
*
* We always add the first segment of the URL, because we encrypt a URL like:
* /path/to/something
* to:
* /encrypted_full/hash/hash
*
* Notice the consistent number of segments. If we applied the following relative URL:
* ../../something
* then the resultant URL would be:
* /something
*
* Hence, the mere existence of the first, encrypted version of complete URL, segment
* tells us that the first segment of the original URL is still to be used.
*/
url.getSegments().add(originalUrl.getSegments().get(0));
}
HashedSegmentGenerator generator = new HashedSegmentGenerator(encryptedUrlString);
int segNo = 1;
for (; segNo < encryptedNumberOfSegments; segNo++)
{
if (segNo >= originalNumberOfSegments)
{
break;
}
String next = generator.next();
String encryptedSegment = encryptedSegments.get(segNo);
if (!next.equals(encryptedSegment))
{
/*
* This segment received from the browser is not the same as the expected segment generated
* by the HashSegmentGenerator. Hence it, and all subsequent segments are considered plain
* text siblings of the original encrypted url.
*/
break;
}
/*
* This segments matches the expected checksum, so we add the corresponding segment from the
* original URL.
*/
url.getSegments().add(originalUrl.getSegments().get(segNo));
}
/*
* Add all remaining segments from the encrypted url as plain text segments.
*/
for (; segNo < encryptedNumberOfSegments; segNo++)
{
// modified or additional segment
url.getSegments().add(encryptedUrl.getSegments().get(segNo));
}
url.getQueryParameters().addAll(originalUrl.getQueryParameters());
// WICKET-4923 additional parameters
url.getQueryParameters().addAll(encryptedUrl.getQueryParameters());
return url;
}