blob: 30676d0585d3a5ca00087876aefc7eeace6b0ab0 [file] [log] [blame]
// Copyright 2011 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// Author: matterbury@google.com (Matt Atterbury)
#include "net/instaweb/rewriter/public/test_url_namer.h"
#include <cstddef> // for size_t
#include "base/logging.h"
#include "net/instaweb/rewriter/public/domain_lawyer.h"
#include "net/instaweb/rewriter/public/output_resource.h"
#include "net/instaweb/rewriter/public/resource_namer.h"
#include "net/instaweb/rewriter/public/rewrite_options.h"
#include "pagespeed/kernel/base/string_util.h" // for StringPiece
#include "pagespeed/kernel/http/google_url.h"
namespace net_instaweb {
const char kTopDomain[] = "http://cdn.com";
bool TestUrlNamer::use_normal_encoding_ = false;
bool TestUrlNamer::proxy_mode_ = false;
TestUrlNamer::TestUrlNamer() {
// Reset these whenever a new one is constructed so that changes from the
// default don't carry over between tests.
use_normal_encoding_ = false;
proxy_mode_ = false;
}
TestUrlNamer::~TestUrlNamer() {
}
GoogleString TestUrlNamer::Encode(const RewriteOptions* rewrite_options,
const OutputResource& output_resource,
EncodeOption encode_option) const {
// Some test requires us to use normal encoding, so off we go!
if (use_normal_encoding_) {
return UrlNamer::Encode(rewrite_options, output_resource, encode_option);
}
DCHECK(rewrite_options != NULL);
GoogleUrl base_gurl(output_resource.resolved_base());
// If there is any sharding or rewriting enabled then various tests don't
// work if we rewrite the domain or path, so in that case revert to normal.
if (rewrite_options->domain_lawyer()->can_rewrite_domains()) {
return UrlNamer::Encode(rewrite_options, output_resource, encode_option);
}
// TEST only handles http/https schemes, so bail if it's anything else.
if (base_gurl.Scheme() != "http" && base_gurl.Scheme() != "https") {
return UrlNamer::Encode(rewrite_options, output_resource, encode_option);
}
// The base might already be the encoded, such as when the resource is
// created from a cached output by RewriteContext, and we must not encode
// an already encoded URL.
if (IsPathEncoded(base_gurl) && IsOriginEncoded(base_gurl)) {
return StrCat(kTopDomain,
base_gurl.PathSansLeaf(),
output_resource.full_name().Encode());
} else {
return EncodeUrl(output_resource.original_base(),
output_resource.unmapped_base(),
base_gurl.PathAndLeaf(),
output_resource.full_name());
}
}
bool TestUrlNamer::Decode(const GoogleUrl& request_url, const RewriteOptions*,
GoogleUrl* owner_domain,
GoogleString* decoded) const {
if (!IsPathEncoded(request_url)) {
return false;
}
StringPiece request_path = request_url.PathSansLeaf();
StringPieceVector path_vector;
SplitStringPieceToVector(request_path, "/", &path_vector, false);
*decoded = StrCat(path_vector[3], "://", path_vector[4]);
for (size_t i = 5, n = path_vector.size() - 1; i < n; ++i) {
StrAppend(decoded, "/", path_vector[i]);
}
StrAppend(decoded, "/", request_url.LeafWithQuery());
return true;
}
GoogleString TestUrlNamer::EncodeUrl(const StringPiece& original_base,
const StringPiece& unmapped_base,
const StringPiece& resolved_path,
const ResourceNamer& leaf_details) {
GoogleUrl original_base_gurl(original_base);
StringPiece original_base_scheme(original_base_gurl.Scheme());
StringPiece original_base_host(original_base_gurl.HostAndPort());
GoogleUrl unmapped_base_gurl(unmapped_base);
StringPiece unmapped_base_scheme(unmapped_base_gurl.Scheme());
StringPiece unmapped_base_host(unmapped_base_gurl.HostAndPort());
return StrCat(kTopDomain,
StrCat("/", original_base_scheme,
"/", original_base_host,
"/", unmapped_base_scheme,
"/", unmapped_base_host),
resolved_path,
leaf_details.Encode());
}
bool TestUrlNamer::IsProxyEncoded(const GoogleUrl& url) const {
if (!url.IsWebValid()) {
return false;
}
GoogleString url_origin = url.Origin().as_string();
if (url_origin == kTopDomain) {
return true;
}
return false;
}
bool TestUrlNamer::IsOriginEncoded(const GoogleUrl& url) const {
GoogleString url_origin = url.Origin().as_string();
if (url_origin == kTopDomain) {
return true;
}
return false;
}
bool TestUrlNamer::IsPathEncoded(const GoogleUrl& url) const {
StringPieceVector path_vector;
SplitStringPieceToVector(url.PathSansLeaf(), "/", &path_vector, false);
// original-scheme/original-domain/unmapped-scheme/unmapped-domain/...
if (path_vector.size() < 5) {
return false;
}
if (path_vector[1] != "http" && path_vector[1] != "https") {
return false;
}
if (path_vector[3] != "http" && path_vector[3] != "https") {
return false;
}
return true;
}
} // namespace net_instaweb