Append a trailing slash on file directory URLs. Thus a link to /directory will work just as well as a link to /directory/
Review URL: http://codereview.chromium.org/12620 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@5999 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
base
net/url_request
webkit/tools/test_shell
@ -26,7 +26,7 @@ void PathComponents(const std::wstring& path,
|
||||
std::wstring::size_type end = path.find(kPathSeparator, start);
|
||||
|
||||
// Special case the "/" or "\" directory. On Windows with a drive letter,
|
||||
// this code path won't hit, but the right thing should still happen.
|
||||
// this code path won't hit, but the right thing should still happen.
|
||||
// "E:\foo" will turn into "E:","foo".
|
||||
if (end == start) {
|
||||
components->push_back(std::wstring(path, 0, 1));
|
||||
@ -42,17 +42,28 @@ void PathComponents(const std::wstring& path,
|
||||
std::wstring component = std::wstring(path, start);
|
||||
components->push_back(component);
|
||||
}
|
||||
|
||||
bool EndsWithSeparator(std::wstring* path) {
|
||||
return EndsWithSeparator(*path);
|
||||
}
|
||||
|
||||
bool EndsWithSeparator(const std::wstring& path) {
|
||||
bool is_sep = (path.length() > 0 &&
|
||||
(path)[path.length() - 1] == kPathSeparator);
|
||||
|
||||
bool EndsWithSeparator(const FilePath& file_path) {
|
||||
std::wstring path = file_path.ToWStringHack();
|
||||
bool is_sep = (path.length() > 0 &&
|
||||
path[path.length() - 1] == kPathSeparator);
|
||||
return is_sep;
|
||||
}
|
||||
|
||||
bool EnsureEndsWithSeparator(FilePath* path) {
|
||||
if (!DirectoryExists(*path))
|
||||
return false;
|
||||
|
||||
if (EndsWithSeparator(*path))
|
||||
return true;
|
||||
|
||||
FilePath::StringType& path_str =
|
||||
const_cast<FilePath::StringType&>(path->value());
|
||||
path_str.append(&FilePath::kSeparators[0], 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void TrimTrailingSeparator(std::wstring* dir) {
|
||||
while (dir->length() > 1 && EndsWithSeparator(dir))
|
||||
dir->resize(dir->length() - 1);
|
||||
@ -315,6 +326,12 @@ bool AbsolutePath(std::wstring* path_str) {
|
||||
bool Delete(const std::wstring& path, bool recursive) {
|
||||
return Delete(FilePath::FromWStringHack(path), recursive);
|
||||
}
|
||||
bool EndsWithSeparator(std::wstring* path) {
|
||||
return EndsWithSeparator(FilePath::FromWStringHack(*path));
|
||||
}
|
||||
bool EndsWithSeparator(const std::wstring& path) {
|
||||
return EndsWithSeparator(FilePath::FromWStringHack(path));
|
||||
}
|
||||
bool Move(const std::wstring& from_path, const std::wstring& to_path) {
|
||||
return Move(FilePath::FromWStringHack(from_path),
|
||||
FilePath::FromWStringHack(to_path));
|
||||
|
@ -41,12 +41,17 @@ extern const wchar_t kPathSeparator;
|
||||
// Returns a vector of all of the components of the provided path.
|
||||
void PathComponents(const std::wstring& path,
|
||||
std::vector<std::wstring>* components);
|
||||
|
||||
|
||||
// Returns true if the given path ends with a path separator character.
|
||||
// TODO(erikkay): remove this pointer version
|
||||
bool EndsWithSeparator(const FilePath& path);
|
||||
// These two versions are both deprecated. TODO(estade): remove them.
|
||||
bool EndsWithSeparator(std::wstring* path);
|
||||
bool EndsWithSeparator(const std::wstring& path);
|
||||
|
||||
|
||||
// Makes sure that |path| ends with a separator IFF path is a directory that
|
||||
// exists. Returns true if |path| is an existing directory, false otherwise.
|
||||
bool EnsureEndsWithSeparator(FilePath* path);
|
||||
|
||||
// Modifies a string by trimming all trailing separators from the end.
|
||||
void TrimTrailingSeparator(std::wstring* dir);
|
||||
|
||||
|
@ -199,3 +199,24 @@ void URLRequestFileDirJob::CompleteRead() {
|
||||
}
|
||||
}
|
||||
|
||||
bool URLRequestFileDirJob::IsRedirectResponse(
|
||||
GURL* location, int* http_status_code) {
|
||||
// If the URL did not have a trailing slash, treat the response as a redirect
|
||||
// to the URL with a trailing slash appended.
|
||||
std::string path = request_->url().path();
|
||||
if (path.empty() || (path[path.size() - 1] != '/')) {
|
||||
// This happens when we discovered the file is a directory, so needs a
|
||||
// slash at the end of the path.
|
||||
std::string new_path = path;
|
||||
new_path.push_back('/');
|
||||
GURL::Replacements replacements;
|
||||
replacements.SetPathStr(new_path);
|
||||
|
||||
*location = request_->url().ReplaceComponents(replacements);
|
||||
*http_status_code = 301; // simulate a permanent redirect
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -24,6 +24,7 @@ class URLRequestFileDirJob
|
||||
virtual bool ReadRawData(char* buf, int buf_size, int *bytes_read);
|
||||
virtual bool GetMimeType(std::string* mime_type);
|
||||
virtual bool GetCharset(std::string* charset);
|
||||
virtual bool IsRedirectResponse(GURL* location, int* http_status_code);
|
||||
|
||||
// DirectoryLister::DirectoryListerDelegate methods:
|
||||
virtual void OnListFile(const file_util::FileEnumerator::FindInfo& data);
|
||||
|
@ -72,12 +72,9 @@ class URLRequestFileJob::AsyncResolver :
|
||||
URLRequestJob* URLRequestFileJob::Factory(
|
||||
URLRequest* request, const std::string& scheme) {
|
||||
FilePath file_path;
|
||||
if (net::FileURLToFilePath(request->url(), &file_path)) {
|
||||
if (file_util::DirectoryExists(file_path)) {
|
||||
// Only directories have trailing slashes.
|
||||
if (net::FileURLToFilePath(request->url(), &file_path) &&
|
||||
file_util::EnsureEndsWithSeparator(&file_path))
|
||||
return new URLRequestFileDirJob(request, file_path);
|
||||
}
|
||||
}
|
||||
|
||||
// Use a regular file request job for all non-directories (including invalid
|
||||
// file names).
|
||||
@ -167,13 +164,13 @@ void URLRequestFileJob::DidResolve(
|
||||
if (!request_)
|
||||
return;
|
||||
|
||||
is_directory_ = file_info.is_directory;
|
||||
DCHECK(!file_info.is_directory);
|
||||
|
||||
int rv = net::OK;
|
||||
if (!exists) {
|
||||
rv = net::ERR_FILE_NOT_FOUND;
|
||||
} else if (!is_directory_) {
|
||||
int flags = base::PLATFORM_FILE_OPEN |
|
||||
} else {
|
||||
int flags = base::PLATFORM_FILE_OPEN |
|
||||
base::PLATFORM_FILE_READ |
|
||||
base::PLATFORM_FILE_ASYNC;
|
||||
rv = stream_.Open(file_path_.ToWStringHack(), flags);
|
||||
@ -200,19 +197,6 @@ void URLRequestFileJob::DidRead(int result) {
|
||||
|
||||
bool URLRequestFileJob::IsRedirectResponse(
|
||||
GURL* location, int* http_status_code) {
|
||||
if (is_directory_) {
|
||||
// This happens when we discovered the file is a directory, so needs a
|
||||
// slash at the end of the path.
|
||||
std::string new_path = request_->url().path();
|
||||
new_path.push_back('/');
|
||||
GURL::Replacements replacements;
|
||||
replacements.SetPathStr(new_path);
|
||||
|
||||
*location = request_->url().ReplaceComponents(replacements);
|
||||
*http_status_code = 301; // simulate a permanent redirect
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(OS_WIN)
|
||||
std::wstring extension =
|
||||
file_util::GetFileExtensionFromPath(file_path_.value());
|
||||
|
@ -223,10 +223,11 @@ void TestWebViewDelegate::DidFailProvisionalLoadWithError(
|
||||
bool replace = extra_data && extra_data->pending_page_id != -1;
|
||||
|
||||
scoped_ptr<WebRequest> request(failed_request.Clone());
|
||||
request->SetURL(GURL("testshell-error:"));
|
||||
|
||||
std::string error_text =
|
||||
StringPrintf("Error loading url: %d", error.GetErrorCode());
|
||||
StringPrintf("Error %d when loading url %s", error.GetErrorCode(),
|
||||
request->GetURL().spec().c_str());
|
||||
request->SetURL(GURL("testshell-error:"));
|
||||
|
||||
frame->LoadAlternateHTMLString(request.get(), error_text,
|
||||
error.GetFailedURL(), replace);
|
||||
|
Reference in New Issue
Block a user