util/UriUtil: split
This commit is contained in:
parent
ade712d711
commit
40a2880857
|
@ -27,7 +27,7 @@
|
|||
|
||||
#ifdef ENABLE_CURL
|
||||
#include "RemoteTagCache.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
#include "client/Client.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "ls.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#ifdef ENABLE_DATABASE
|
||||
#include "storage/StorageInterface.hxx"
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
#include "fs/FileInfo.hxx"
|
||||
#include "fs/DirectoryReader.hxx"
|
||||
#include "util/StringCompare.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "fs/FileSystem.hxx"
|
||||
#include "fs/io/FileOutputStream.hxx"
|
||||
#include "fs/io/BufferedOutputStream.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
static void
|
||||
playlist_print_path(BufferedOutputStream &os, const Path path)
|
||||
|
|
|
@ -23,12 +23,12 @@
|
|||
#include "db/plugins/simple/Directory.hxx"
|
||||
#include "storage/StorageInterface.hxx"
|
||||
#include "storage/FileInfo.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/FileInfo.hxx"
|
||||
#include "tag/Builder.hxx"
|
||||
#include "TagFile.hxx"
|
||||
#include "TagStream.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#ifdef ENABLE_ARCHIVE
|
||||
#include "TagArchive.hxx"
|
||||
|
|
|
@ -22,11 +22,11 @@
|
|||
#include "tag/Handler.hxx"
|
||||
#include "tag/Builder.hxx"
|
||||
#include "util/MimeType.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "decoder/DecoderList.hxx"
|
||||
#include "decoder/DecoderPlugin.hxx"
|
||||
#include "input/InputStream.hxx"
|
||||
#include "thread/Mutex.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
#include "client/Response.hxx"
|
||||
#include "util/CharUtil.hxx"
|
||||
#include "util/StringView.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "tag/Handler.hxx"
|
||||
#include "tag/Generic.hxx"
|
||||
#include "TagStream.hxx"
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include "thread/Cond.hxx"
|
||||
#include "system/Error.hxx"
|
||||
#include "util/MimeType.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
class GetChromaprintCommand final
|
||||
: public ThreadBackgroundCommand, ChromaprintDecoderClient, InputStreamHandler
|
||||
|
|
|
@ -38,8 +38,8 @@
|
|||
#include "Mapper.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "time/ChronoUtil.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "LocateUri.hxx"
|
||||
|
||||
bool
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
#include "input/Error.hxx"
|
||||
#include "util/Alloc.hxx"
|
||||
#include "util/StringCompare.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <exception>
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "DecoderList.hxx"
|
||||
#include "system/Error.hxx"
|
||||
#include "util/MimeType.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
#include "util/ScopeExit.hxx"
|
||||
#include "util/StringFormat.hxx"
|
||||
#include "util/StringView.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "util/Domain.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include "UniqueIxml.hxx"
|
||||
#include "Device.hxx"
|
||||
#include "ixmlwrap.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriRelative.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/SplitString.hxx"
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include "input/Registry.hxx"
|
||||
#include "input/InputPlugin.hxx"
|
||||
#include "client/Response.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
@ -38,7 +38,7 @@ void print_supported_uri_schemes_to_fp(FILE *fp)
|
|||
plugin->ForeachSupportedUri([&](const char* uri) {
|
||||
protocols.emplace(uri);
|
||||
});
|
||||
|
||||
|
||||
for (auto protocol : protocols) {
|
||||
fprintf(fp, " %s", protocol.c_str());
|
||||
}
|
||||
|
|
|
@ -33,9 +33,9 @@
|
|||
#include "plugins/EmbeddedCuePlaylistPlugin.hxx"
|
||||
#include "input/InputStream.hxx"
|
||||
#include "util/MimeType.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
#include "util/StringView.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "config/Data.hxx"
|
||||
#include "config/Block.hxx"
|
||||
|
||||
|
|
|
@ -22,8 +22,8 @@
|
|||
#include "tag/Tag.hxx"
|
||||
#include "tag/Builder.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "song/DetachedSong.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
|
|
@ -20,10 +20,10 @@
|
|||
#include "PlaylistStream.hxx"
|
||||
#include "PlaylistRegistry.hxx"
|
||||
#include "SongEnumerator.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "input/InputStream.hxx"
|
||||
#include "input/LocalOpen.hxx"
|
||||
#include "fs/Path.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <exception>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
#include "BaseSongFilter.hxx"
|
||||
#include "Escape.hxx"
|
||||
#include "LightSong.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriRelative.hxx"
|
||||
|
||||
std::string
|
||||
BaseSongFilter::ToExpression() const noexcept
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "song/DetachedSong.hxx"
|
||||
#include "song/LightSong.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
#include "fs/Traits.hxx"
|
||||
|
||||
DetachedSong::DetachedSong(const LightSong &other)
|
||||
|
|
|
@ -24,8 +24,8 @@
|
|||
#include "config/Data.hxx"
|
||||
#include "fs/StandardDirectory.hxx"
|
||||
#include "fs/CheckFile.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/RuntimeError.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
static std::unique_ptr<Storage>
|
||||
CreateConfiguredStorageUri(EventLoop &event_loop, const char *uri)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2003-2016 The Music Player Daemon Project
|
||||
* Copyright 2003-2019 The Music Player Daemon Project
|
||||
* http://www.musicpd.org
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -38,7 +38,7 @@
|
|||
#include "util/RuntimeError.hxx"
|
||||
#include "util/StringCompare.hxx"
|
||||
#include "util/StringFormat.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
* Copyright 2008-2019 Max Kellermann <max.kellermann@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - 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 COPYRIGHT HOLDERS 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 THE
|
||||
* FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#include "UriExtract.hxx"
|
||||
#include "CharUtil.hxx"
|
||||
#include "StringView.hxx"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static constexpr bool
|
||||
IsValidSchemeStart(char ch)
|
||||
{
|
||||
return IsLowerAlphaASCII(ch);
|
||||
}
|
||||
|
||||
static constexpr bool
|
||||
IsValidSchemeChar(char ch)
|
||||
{
|
||||
return IsLowerAlphaASCII(ch) || IsDigitASCII(ch) ||
|
||||
ch == '+' || ch == '.' || ch == '-';
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsValidScheme(StringView p) noexcept
|
||||
{
|
||||
if (p.empty() || !IsValidSchemeStart(p.front()))
|
||||
return false;
|
||||
|
||||
for (size_t i = 1; i < p.size; ++i)
|
||||
if (!IsValidSchemeChar(p[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URI part after the scheme specification (and after the
|
||||
* double slash).
|
||||
*/
|
||||
gcc_pure
|
||||
static const char *
|
||||
uri_after_scheme(const char *uri) noexcept
|
||||
{
|
||||
if (uri[0] == '/' && uri[1] == '/' && uri[2] != '/')
|
||||
return uri + 2;
|
||||
|
||||
const char *colon = strchr(uri, ':');
|
||||
return colon != nullptr &&
|
||||
IsValidScheme({uri, colon}) &&
|
||||
colon[1] == '/' && colon[2] == '/'
|
||||
? colon + 3
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
uri_has_scheme(const char *uri) noexcept
|
||||
{
|
||||
return strstr(uri, "://") != nullptr;
|
||||
}
|
||||
|
||||
std::string
|
||||
uri_get_scheme(const char *uri) noexcept
|
||||
{
|
||||
const char *end = strstr(uri, "://");
|
||||
if (end == nullptr)
|
||||
end = uri;
|
||||
|
||||
return std::string(uri, end);
|
||||
}
|
||||
|
||||
const char *
|
||||
uri_get_path(const char *uri) noexcept
|
||||
{
|
||||
const char *ap = uri_after_scheme(uri);
|
||||
if (ap != nullptr)
|
||||
return strchr(ap, '/');
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
/* suffixes should be ascii only characters */
|
||||
const char *
|
||||
uri_get_suffix(const char *uri) noexcept
|
||||
{
|
||||
const char *suffix = strrchr(uri, '.');
|
||||
if (suffix == nullptr || suffix == uri ||
|
||||
suffix[-1] == '/' || suffix[-1] == '\\')
|
||||
return nullptr;
|
||||
|
||||
++suffix;
|
||||
|
||||
if (strpbrk(suffix, "/\\") != nullptr)
|
||||
return nullptr;
|
||||
|
||||
return suffix;
|
||||
}
|
||||
|
||||
const char *
|
||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept
|
||||
{
|
||||
const char *suffix = uri_get_suffix(uri);
|
||||
if (suffix == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const char *q = strchr(suffix, '?');
|
||||
if (q != nullptr && size_t(q - suffix) < sizeof(buffer.data)) {
|
||||
memcpy(buffer.data, suffix, q - suffix);
|
||||
buffer.data[q - suffix] = 0;
|
||||
suffix = buffer.data;
|
||||
}
|
||||
|
||||
return suffix;
|
||||
}
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright 2008-2019 Max Kellermann <max.kellermann@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - 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 COPYRIGHT HOLDERS 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 THE
|
||||
* FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef URI_EXTRACT_HXX
|
||||
#define URI_EXTRACT_HXX
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Checks whether the specified URI has a scheme in the form
|
||||
* "scheme://".
|
||||
*/
|
||||
gcc_pure
|
||||
bool
|
||||
uri_has_scheme(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the scheme name of the specified URI, or an empty string.
|
||||
*/
|
||||
gcc_pure
|
||||
std::string
|
||||
uri_get_scheme(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the URI path (including the query string) or nullptr if the
|
||||
* given URI has no path.
|
||||
*/
|
||||
gcc_pure gcc_nonnull_all
|
||||
const char *
|
||||
uri_get_path(const char *uri) noexcept;
|
||||
|
||||
gcc_pure
|
||||
const char *
|
||||
uri_get_suffix(const char *uri) noexcept;
|
||||
|
||||
struct UriSuffixBuffer {
|
||||
char data[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the file name suffix, ignoring the query string.
|
||||
*/
|
||||
gcc_pure
|
||||
const char *
|
||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept;
|
||||
|
||||
#endif
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright 2008-2019 Max Kellermann <max.kellermann@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - 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 COPYRIGHT HOLDERS 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 THE
|
||||
* FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#include "UriRelative.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
bool
|
||||
uri_is_child(const char *parent, const char *child) noexcept
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(parent != nullptr);
|
||||
assert(child != nullptr);
|
||||
#endif
|
||||
|
||||
const size_t parent_length = strlen(parent);
|
||||
return memcmp(parent, child, parent_length) == 0 &&
|
||||
child[parent_length] == '/';
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
uri_is_child_or_same(const char *parent, const char *child) noexcept
|
||||
{
|
||||
return strcmp(parent, child) == 0 || uri_is_child(parent, child);
|
||||
}
|
||||
|
||||
std::string
|
||||
uri_apply_base(const std::string &uri, const std::string &base) noexcept
|
||||
{
|
||||
if (uri.front() == '/') {
|
||||
/* absolute path: replace the whole URI path in base */
|
||||
|
||||
auto i = base.find("://");
|
||||
if (i == base.npos)
|
||||
/* no scheme: override base completely */
|
||||
return uri;
|
||||
|
||||
/* find the first slash after the host part */
|
||||
i = base.find('/', i + 3);
|
||||
if (i == base.npos)
|
||||
/* there's no URI path - simply append uri */
|
||||
i = base.length();
|
||||
|
||||
return base.substr(0, i) + uri;
|
||||
}
|
||||
|
||||
std::string out(base);
|
||||
if (out.back() != '/')
|
||||
out.push_back('/');
|
||||
|
||||
out += uri;
|
||||
return out;
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright 2008-2019 Max Kellermann <max.kellermann@gmail.com>
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* - Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* - 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 COPYRIGHT HOLDERS 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 THE
|
||||
* FOUNDATION 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.
|
||||
*/
|
||||
|
||||
#ifndef URI_RELATIVE_HXX
|
||||
#define URI_RELATIVE_HXX
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Check whether #child specifies a resource "inside" the directory
|
||||
* specified by #parent. If the strings are equal, the function
|
||||
* returns false.
|
||||
*/
|
||||
gcc_pure gcc_nonnull_all
|
||||
bool
|
||||
uri_is_child(const char *parent, const char *child) noexcept;
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
bool
|
||||
uri_is_child_or_same(const char *parent, const char *child) noexcept;
|
||||
|
||||
/**
|
||||
* Translate the given URI in the context of #base. For example,
|
||||
* uri_apply_base("foo", "http://bar/a/")=="http://bar/a/foo".
|
||||
*/
|
||||
gcc_pure
|
||||
std::string
|
||||
uri_apply_base(const std::string &uri, const std::string &base) noexcept;
|
||||
|
||||
#endif
|
|
@ -29,117 +29,10 @@
|
|||
|
||||
#include "UriUtil.hxx"
|
||||
#include "ASCII.hxx"
|
||||
#include "CharUtil.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
static constexpr bool
|
||||
IsValidSchemeStart(char ch)
|
||||
{
|
||||
return IsLowerAlphaASCII(ch);
|
||||
}
|
||||
|
||||
static constexpr bool
|
||||
IsValidSchemeChar(char ch)
|
||||
{
|
||||
return IsLowerAlphaASCII(ch) || IsDigitASCII(ch) ||
|
||||
ch == '+' || ch == '.' || ch == '-';
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
static bool
|
||||
IsValidScheme(StringView p) noexcept
|
||||
{
|
||||
if (p.empty() || !IsValidSchemeStart(p.front()))
|
||||
return false;
|
||||
|
||||
for (size_t i = 1; i < p.size; ++i)
|
||||
if (!IsValidSchemeChar(p[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URI part after the scheme specification (and after the
|
||||
* double slash).
|
||||
*/
|
||||
gcc_pure
|
||||
static const char *
|
||||
uri_after_scheme(const char *uri) noexcept
|
||||
{
|
||||
if (uri[0] == '/' && uri[1] == '/' && uri[2] != '/')
|
||||
return uri + 2;
|
||||
|
||||
const char *colon = strchr(uri, ':');
|
||||
return colon != nullptr &&
|
||||
IsValidScheme({uri, colon}) &&
|
||||
colon[1] == '/' && colon[2] == '/'
|
||||
? colon + 3
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
uri_has_scheme(const char *uri) noexcept
|
||||
{
|
||||
return strstr(uri, "://") != nullptr;
|
||||
}
|
||||
|
||||
std::string
|
||||
uri_get_scheme(const char *uri) noexcept
|
||||
{
|
||||
const char *end = strstr(uri, "://");
|
||||
if (end == nullptr)
|
||||
end = uri;
|
||||
|
||||
return std::string(uri, end);
|
||||
}
|
||||
|
||||
const char *
|
||||
uri_get_path(const char *uri) noexcept
|
||||
{
|
||||
const char *ap = uri_after_scheme(uri);
|
||||
if (ap != nullptr)
|
||||
return strchr(ap, '/');
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
/* suffixes should be ascii only characters */
|
||||
const char *
|
||||
uri_get_suffix(const char *uri) noexcept
|
||||
{
|
||||
const char *suffix = strrchr(uri, '.');
|
||||
if (suffix == nullptr || suffix == uri ||
|
||||
suffix[-1] == '/' || suffix[-1] == '\\')
|
||||
return nullptr;
|
||||
|
||||
++suffix;
|
||||
|
||||
if (strpbrk(suffix, "/\\") != nullptr)
|
||||
return nullptr;
|
||||
|
||||
return suffix;
|
||||
}
|
||||
|
||||
const char *
|
||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept
|
||||
{
|
||||
const char *suffix = uri_get_suffix(uri);
|
||||
if (suffix == nullptr)
|
||||
return nullptr;
|
||||
|
||||
const char *q = strchr(suffix, '?');
|
||||
if (q != nullptr && size_t(q - suffix) < sizeof(buffer.data)) {
|
||||
memcpy(buffer.data, suffix, q - suffix);
|
||||
buffer.data[q - suffix] = 0;
|
||||
suffix = buffer.data;
|
||||
}
|
||||
|
||||
return suffix;
|
||||
}
|
||||
|
||||
static const char *
|
||||
verify_uri_segment(const char *p) noexcept
|
||||
{
|
||||
|
@ -210,52 +103,3 @@ uri_remove_auth(const char *uri) noexcept
|
|||
result.erase(auth - uri, at + 1 - auth);
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
uri_is_child(const char *parent, const char *child) noexcept
|
||||
{
|
||||
#if !CLANG_CHECK_VERSION(3,6)
|
||||
/* disabled on clang due to -Wtautological-pointer-compare */
|
||||
assert(parent != nullptr);
|
||||
assert(child != nullptr);
|
||||
#endif
|
||||
|
||||
const size_t parent_length = strlen(parent);
|
||||
return memcmp(parent, child, parent_length) == 0 &&
|
||||
child[parent_length] == '/';
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
uri_is_child_or_same(const char *parent, const char *child) noexcept
|
||||
{
|
||||
return strcmp(parent, child) == 0 || uri_is_child(parent, child);
|
||||
}
|
||||
|
||||
std::string
|
||||
uri_apply_base(const std::string &uri, const std::string &base) noexcept
|
||||
{
|
||||
if (uri.front() == '/') {
|
||||
/* absolute path: replace the whole URI path in base */
|
||||
|
||||
auto i = base.find("://");
|
||||
if (i == base.npos)
|
||||
/* no scheme: override base completely */
|
||||
return uri;
|
||||
|
||||
/* find the first slash after the host part */
|
||||
i = base.find('/', i + 3);
|
||||
if (i == base.npos)
|
||||
/* there's no URI path - simply append uri */
|
||||
i = base.length();
|
||||
|
||||
return base.substr(0, i) + uri;
|
||||
}
|
||||
|
||||
std::string out(base);
|
||||
if (out.back() != '/')
|
||||
out.push_back('/');
|
||||
|
||||
out += uri;
|
||||
return out;
|
||||
}
|
||||
|
|
|
@ -34,44 +34,6 @@
|
|||
|
||||
#include <string>
|
||||
|
||||
/**
|
||||
* Checks whether the specified URI has a scheme in the form
|
||||
* "scheme://".
|
||||
*/
|
||||
gcc_pure
|
||||
bool
|
||||
uri_has_scheme(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the scheme name of the specified URI, or an empty string.
|
||||
*/
|
||||
gcc_pure
|
||||
std::string
|
||||
uri_get_scheme(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Returns the URI path (including the query string) or nullptr if the
|
||||
* given URI has no path.
|
||||
*/
|
||||
gcc_pure gcc_nonnull_all
|
||||
const char *
|
||||
uri_get_path(const char *uri) noexcept;
|
||||
|
||||
gcc_pure
|
||||
const char *
|
||||
uri_get_suffix(const char *uri) noexcept;
|
||||
|
||||
struct UriSuffixBuffer {
|
||||
char data[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the file name suffix, ignoring the query string.
|
||||
*/
|
||||
gcc_pure
|
||||
const char *
|
||||
uri_get_suffix(const char *uri, UriSuffixBuffer &buffer) noexcept;
|
||||
|
||||
/**
|
||||
* Returns true if this is a safe "local" URI:
|
||||
*
|
||||
|
@ -94,25 +56,4 @@ gcc_pure
|
|||
std::string
|
||||
uri_remove_auth(const char *uri) noexcept;
|
||||
|
||||
/**
|
||||
* Check whether #child specifies a resource "inside" the directory
|
||||
* specified by #parent. If the strings are equal, the function
|
||||
* returns false.
|
||||
*/
|
||||
gcc_pure gcc_nonnull_all
|
||||
bool
|
||||
uri_is_child(const char *parent, const char *child) noexcept;
|
||||
|
||||
gcc_pure gcc_nonnull_all
|
||||
bool
|
||||
uri_is_child_or_same(const char *parent, const char *child) noexcept;
|
||||
|
||||
/**
|
||||
* Translate the given URI in the context of #base. For example,
|
||||
* uri_apply_base("foo", "http://bar/a/")=="http://bar/a/foo".
|
||||
*/
|
||||
gcc_pure
|
||||
std::string
|
||||
uri_apply_base(const std::string &uri, const std::string &base) noexcept;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -17,6 +17,8 @@ util = static_library(
|
|||
'SplitString.cxx',
|
||||
'FormatString.cxx',
|
||||
'Tokenizer.cxx',
|
||||
'UriExtract.cxx',
|
||||
'UriRelative.cxx',
|
||||
'UriUtil.cxx',
|
||||
'LazyRandomEngine.cxx',
|
||||
'HugeAllocator.cxx',
|
||||
|
|
|
@ -25,8 +25,8 @@
|
|||
#include "fs/Path.hxx"
|
||||
#include "fs/io/StdioOutputStream.hxx"
|
||||
#include "fs/io/BufferedOutputStream.hxx"
|
||||
#include "util/UriUtil.hxx"
|
||||
#include "util/PrintException.hxx"
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Unit tests for src/util/
|
||||
*/
|
||||
|
||||
#include "util/UriExtract.hxx"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(UriExtract, Suffix)
|
||||
{
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar"));
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo.jpg/bar"));
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg"), "jpg");
|
||||
EXPECT_STREQ(uri_get_suffix("/foo.png/bar.jpg"), "jpg");
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix(".jpg"));
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/.jpg"));
|
||||
|
||||
/* the first overload does not eliminate the query
|
||||
string */
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg?query_string"),
|
||||
"jpg?query_string");
|
||||
|
||||
/* ... but the second one does */
|
||||
UriSuffixBuffer buffer;
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg?query_string", buffer),
|
||||
"jpg");
|
||||
|
||||
/* repeat some of the above tests with the second overload */
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar", buffer));
|
||||
EXPECT_EQ((const char *)nullptr,
|
||||
uri_get_suffix("/foo.jpg/bar", buffer));
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg", buffer), "jpg");
|
||||
}
|
|
@ -6,32 +6,6 @@
|
|||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
TEST(UriUtil, Suffix)
|
||||
{
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar"));
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo.jpg/bar"));
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg"), "jpg");
|
||||
EXPECT_STREQ(uri_get_suffix("/foo.png/bar.jpg"), "jpg");
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix(".jpg"));
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/.jpg"));
|
||||
|
||||
/* the first overload does not eliminate the query
|
||||
string */
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg?query_string"),
|
||||
"jpg?query_string");
|
||||
|
||||
/* ... but the second one does */
|
||||
UriSuffixBuffer buffer;
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg?query_string", buffer),
|
||||
"jpg");
|
||||
|
||||
/* repeat some of the above tests with the second overload */
|
||||
EXPECT_EQ((const char *)nullptr, uri_get_suffix("/foo/bar", buffer));
|
||||
EXPECT_EQ((const char *)nullptr,
|
||||
uri_get_suffix("/foo.jpg/bar", buffer));
|
||||
EXPECT_STREQ(uri_get_suffix("/foo/bar.jpg", buffer), "jpg");
|
||||
}
|
||||
|
||||
TEST(UriUtil, RemoveAuth)
|
||||
{
|
||||
EXPECT_EQ(std::string(),
|
||||
|
|
|
@ -37,6 +37,7 @@ test('TestUtil', executable(
|
|||
'TestDivideString.cxx',
|
||||
'TestMimeType.cxx',
|
||||
'TestSplitString.cxx',
|
||||
'TestUriExtract.cxx',
|
||||
'TestUriUtil.cxx',
|
||||
'test_byte_reverse.cxx',
|
||||
include_directories: inc,
|
||||
|
|
Loading…
Reference in New Issue