URI Templates expansion and reverse-matching for C++

Overview

URI-template

Language C++ Github releases Coverage Status Conan Package License

This library implements URI Template with full support up to Level 4 providing expansion and match capabilities. It requires c++17 compiler support and has no dependencies.

What?

URI templates are a convenient way to describe a range of possible URI by making some parts of it variable. For example, a variety of resources:

  • http://example.com/~fred/
  • http://example.com/~mark/
  • http://example.com/~admin/
  • http://example.com/~guest/
  • http://example.com/~elephant/

Could be described by simple template – http://example.com/~{username}/.

Or, resources:

  • http://example.com/search?q=cat&lang=en
  • http://example.com/search?q=chien&lang=fr

Could be described by – http://example.com/search{?q,lang}.

A template is transformed into a URI by replacing each delimited expression with its value as defined by expansion rules and the values of variables.

URI Templates can also be used in reverse for the purpose of variable matching: comparing the template to a fully formed URI in order to extract the variables. It only works well if the template expressions are delimited by the beginning or end of the URI or by characters that cannot be part of the expansion, otherwise, some ambiguity is present. For example, a template http://example.com/{foo}{bar} matches http://example.com/foobar, but is is impossible to distinguish if:

  • foo='foobar' and bar is undefined; or
  • foo is undefined and bar='foobar'

Although, if you only interested if a template matches some URI with at least one possible set of values and does not care about values itself, then it is ok.

There is more to it. For better understanding please refer to RFC 6570.

Quickstart

URI Templates are presented as instances of URI::Template::Template class. It is basically a vector of parts, which can be either URI::Template::Literal or URI::Template::Expression. To make one you can use URI::Template::ParseTemplate() function or construct it by hand using:

  • URI::Template::Operator
  • URI::Template::Variable
  • URI::Template::Modifier

classes.

From there you can provide values for template variables with URI::Template::VarValue objects and expand it, or use URI::Template::MatchURI() to test if some URI matches a template, i.e. if it can be expanded from a template with correct values provided.

Example

Here is basic example how to parse, match and expand URI template:

#include <uri-template/uri-template.h>
#include <iostream>

int main() {
    const std::string uri = "http://example.com/search?q=cat&lang=en";
    // Parse the template
    const URI::Template::Template uri_template = URI::Template::ParseTemplate("http://example.com/search{?q,lang}");

    // Match it to the URI
    // &matched_values can be nullptr if you don't care about values.
    std::unordered_map<std::string, URI::Template::VarValue> matched_values;
    bool matched = URI::Template::MatchURI(uri_template, uri, &matched_values);

    // Print results
    std::cout << std::boolalpha;
    std::cout << "Template matched: " << matched << std::endl;
    for (const auto& [name, value] : matched_values) {
        std::cout << name << "=" << value << std::endl;
    }

    // Expand
    const std::string expanded_uri = URI::Template::ExpandTemplate(uri_template, matched_values);
    std::cout << "Template expanded: " << expanded_uri << std::endl;
}
g++ -std=c++17 example.cpp -luri-template

Output:

Template matched: true
lang=en
q=cat
Template expanded: http://example.com/search?q=cat&lang=en

Detailed description

For full API reference look here – https://tinkoffcreditsystems.github.io/uri-template/

How to use in your project

Generally, to use this library you need to tell your compiler where to lookup for its' headers and library. For gcc/clang it can be done via -I and -l flags. Any particular situation depends on what you are using to build your project.

Use installed

Easiest way is to install this library onto your system. To do so, execute these commands from uri-template folder (sudo may be required):

cmake -H. -Bbuild -DUCONFIG_BUILD_TESTING=OFF -DUCONFIG_BUILD_DOCS=OFF
cmake --build ./build --target install

This will put uri-template headers into system default folder. From there you should be able to use it like any other library (#include <uri-template/uri-template.h> and so on).

Manually

If you have installed uri-template then you only need to link with it via -luri-template. If you don't want to install, pass an -I flag with path to uri-template include folder and -l with path to library binary. For example, if you cloned it into ~/uri-template/ and build it there, then use -I~/uri-template/include -l~/uri-template/build/liburi-template.a when calling gcc or clang.

Cmake

If you have installed uri-template then use find_package(uri-template REQUIRED) and target_link_libraries(<your target> uri-template::uri-template). Alternatively, you can use cmake's add_subdirectory, ExternalProject, FetchContent to bring it and include in configure stage of you project.

Also, this may be helpful - https://cliutils.gitlab.io/modern-cmake/

How to build

This library supposed to be somewhat multi-platform, however, it was tested and mainly used on ubuntu and macOS.
Prefer out-of-source building:

cmake -H. -Bbuild
cmake --build ./build

To install (sudo may be required):

cmake -H. -Bbuild -DUCONFIG_BUILD_TESTING=OFF -DUCONFIG_BUILD_DOCS=OFF
cmake --build ./build --target install

Or test:

cmake -H. -Bbuild -DUCONFIG_BUILD_TESTING=ON
cmake --build ./build
cmake -E chdir ./build ctest --output-on-failure

All these commands assume you are in uconfig root folder

Cmake options

  • CMAKE_BUILD_TYPEbuild type. RelWithDebInfo by default.
  • BUILD_SHARED_LIBSbuild shared or static library. OFF by default.
  • UCONFIG_BUILD_TESTING – build included unit-tests. OFF by default.
  • UCONFIG_BUILD_DOCS – build html (sphinx) reference docs. OFF by default.

License

Developed at Tinkoff.ru in 2021.
Distibuted under Apache License 2.0 LICENSE. You may also obtain this license at https://www.apache.org/licenses/LICENSE-2.0.

Contacts

Author - [email protected]
Current maintainer - [email protected]

Issues
  • test: rename 'test' to 'tests' folder to conform common tree

    test: rename 'test' to 'tests' folder to conform common tree

    PR Checklist

    Please check if your PR fulfills the following requirements:

    • [x] The commit message follows Conventional Commits
    • [ ] Tests for the changes have been added (for bug fixes / features)
    • [ ] Docs have been added / updated (for bug fixes / features)

    PR Type

    What kind of change does this PR introduce?

    • [ ] Bugfix
    • [ ] Feature
    • [ ] Refactoring
    • [x] Code style update
    • [ ] Build or CI related changes
    • [ ] Documentation content changes

    What is the current behavior?

    Closes #

    What is the new behavior?

    Does this PR introduce a breaking change?

    • [ ] Yes
    • [x] No
    opened by i-vovk 1
Releases(v1.2.1)
cpp-netlib URI

Deprecation warning This library is still missing some features (including full Unicode support), and does not work on some of the newest compiler ver

C++ Network Library 126 Jul 28, 2022
Resolvidos do URI p/ Maratonas

URI_Resolvidos Resolvidos do URI p/ Maratonas Esse repositório contém diversos exercícios do URI, em sua maioria resolvidos, podendo conter um ou outr

null 2 Sep 30, 2021
Lightweight URL & URI parser (RFC 1738, RFC 3986)

Lightweight URL & URI parser (RFC 1738, RFC 3986) (C) Sergey Kosarevsky, 2015-2020 @corporateshark [email protected] http://www.linderdaum.com http://

Sergey Kosarevsky 81 Jun 21, 2022
Basic jam templates using Handmade libraries to get up and running quickly.

This is a selection of template projects to get up and running with for the Wheel Reinvention Jam. They are built on top of Handmade-inspired librarie

Handmade Network 13 Jun 19, 2022
Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services.

Pushpin is a reverse proxy server written in C++ that makes it easy to implement WebSocket, HTTP streaming, and HTTP long-polling services. The project is unique among realtime push solutions in that it is designed to address the needs of API creators. Pushpin is transparent to clients and integrates easily into an API stack.

Fanout 3.1k Aug 4, 2022
reverse proxy with web server and preview page

Reverse Proxy Dependencies Go Make Suport Termux (android/afsd kernel) linux (kernel) Install: Termux: 1 step: Install Go-lang, Git and Make pkg insta

AlbâniaSecurity-RT 7 Feb 19, 2022
zrp is a nat-passthrough reverse proxy written in modern c++.

zrp is a nat-passthrough reverse proxy written in modern c++. A major use case is to expose a local server via a remote server with public IP.

Coleman 11 Nov 23, 2021
Reverse-engineering client / gamedll (CZeror)

Half Life 1 SDK LICENSE Half Life 1 SDK Copyright© Valve Corp. THIS DOCUMENT DESCRIBES A CONTRACT BETWEEN YOU AND VALVE CORPORATION (“Valve”). PLEASE

null 5 Jul 10, 2022
Triton Python and C++ client libraries and example, and client examples for go, java and scala.

Triton Client Libraries and Examples To simplify communication with Triton, the Triton project provides several client libraries and examples of how t

Triton Inference Server 164 Aug 7, 2022
Encapsulates the two protocols of OpenVpn and Ikev2, you only need to enter the server IP and port number to realize the connection and status display, and the specific situation of the connection can be displayed at the same time。

NewVpnCore 封装了OpenVpn和Ikev2两种协议,只需要输入服务器IP和端口号即可实现连接和状态显示,同时可以显示连接的具体情况。 UniteVpn Core(第一版) 1. 模块说明 unitevpn:封装了vpn的操作和统一不同协议信息的模块 ikev2:IKEV2协议的源码 op

ZFashion 3 Jun 8, 2022
Like libevent and libuv, libhv provides event-loop with non-blocking IO and timer, but simpler api and richer protocols.

中文版 Intro Like libevent, libev, and libuv, libhv provides event-loop with non-blocking IO and timer, but simpler api and richer protocols. Features cr

ithewei 4.4k Aug 7, 2022
🌱Light and powerful C++ web framework for highly scalable and resource-efficient web application. It's zero-dependency and easy-portable.

Oat++ News Hey, meet the new oatpp version 1.2.5! See the changelog for details. Check out the new oatpp ORM - read more here. Oat++ is a modern Web F

Oat++ 5.6k Aug 10, 2022
Ole Christian Eidheim 737 Aug 6, 2022
A very simple, fast, multithreaded, platform independent HTTP and HTTPS server and client library implemented using C++11 and Boost.Asio.

A very simple, fast, multithreaded, platform independent HTTP and HTTPS server and client library implemented using C++11 and Boost.Asio. Created to be an easy way to make REST resources available from C++ applications.

Ole Christian Eidheim 2.3k Aug 12, 2022
Cross-platform, efficient, customizable, and robust asynchronous HTTP/WebSocket server C++14 library with the right balance between performance and ease of use

What Is RESTinio? RESTinio is a header-only C++14 library that gives you an embedded HTTP/Websocket server. It is based on standalone version of ASIO

Stiffstream 871 Aug 9, 2022
Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and 10K connections problem solution

CppServer Ultra fast and low latency asynchronous socket server & client C++ library with support TCP, SSL, UDP, HTTP, HTTPS, WebSocket protocols and

Ivan Shynkarenka 867 Aug 8, 2022
DNS and Target HTTP History Local Storage and Search

dooked DNS and Target HTTP History Local Storage and Search Installation Download Boost Library from the official website Extract the library into any

Michael Skelton 57 Aug 8, 2022
ASN intelligence information (IP to ASN mapping) collected and distributed in open source and transparent way

ASN Intelligence The main goal of this project to retrieve information required to map IP address to ASN number in open source and transparent way. Wh

Pavel Odintsov 60 Jun 27, 2021