
x filter requests by method and endpoint
x parse query parameters (typed)
x re-serialize query parameters into upstream request URL
x method/body for denied requests
x create full request objects in tests
x "completeness" over all the below query types and parameters
x real fatcat+scholar request tests
x minimize tokio feature flags
x package/release
    x  generate .deb file
    x  Makefile
    x  manpage
    x  example config
    x  README
    x  push git repo
x version flag ("--version")
x deb: include systemd unit file, and register it (?)
x Dockerfile
x systemd unit file
x add config (/etc/) to debian package config file list
x more methods/endpoints
    x  CORS headers on many more responses
    x  OPTIONS, HEAD for ping
    x  HEAD eg, for ping
    x  _mapping
    x  index bare
x headers
    x  enable CORS headers in the proxy itself?
    x  HEAD requests
    x  'Via' header
x gitlab ci
x error handling
    x  refactor error categories
    x  return correct status code
    x  pretty-print errors better
    x  return a proper error when upstream is unavailable
- play with https://search.qa.fatcat.wiki and observable (javascript)
- update README
    => summary
    => installation + configuration
    => development
- bump version
- push to crates.io
- tests
    x "get", "_doc", "_source"
    x parse error
    x unsupported query type
    - parse example_config.toml
- nginx example config
- histogram agg interval 0.0 (?)
- suggestions in search queries
    https://www.elastic.co/guide/en/elasticsearch/reference/7.9/search-suggesters.html
- config
    x  all indices as "unsafe_mode"
    => distinct file schema from config object (eg, no "Option" in object)
    => ProxyConfig in Box? less cloning?
- refactor unwrap() into error handling
- IPv6?

parse method+path (index) -> which validation method
method+path+params+body -> status, upstream request


## general endpoints

- ping
    (?)
x basic info
    GET /
x scroll
    POST /_search/scroll
x clear scroll
    DELETE /_search/scroll

## per-index endpoints

- basic info; mapping
    GET /<index>
    GET /<index>/_mapping
x count
    GET /<index>/_count
x get document
    GET /<index>/_doc/<_id>
    GET /<index>/_source/<_id>
x search
    GET /<index>/_search
    POST /<index>/_search

later:

- multi-get (`_mget`)
- multi-search (`_msearch`)

## query types

compound:
x bool
x boosting
x constant_score
    filter (query)
    boost (float, optional)

fulltext:
x match
    <field>
        (bare str allowed)
        query (str)
x match_phrase
    <field>
        (bare str allowed)
        value (str)
x multi_match
x query_string
- simple_query_string

term-level:
x exists
    field (str)
x ids
    values (array of str)
x prefix
x range
    <field>
        gt, gte, lt, lte: str or number
- NOT regex (?)
x term
    <field>
        value: str or number
x terms
    does not support "lookup" from other indices
    <field>
        (array of str or number)
x wildcard
    <field>
        value (str)
        boost (float, optional)
        rewrite (str, optional)
x match_all
    boost (float, optional)
x match_none
    boost (float, optional)


TODO:
- terms_set
- span queries
- fuzzy (configurable)

## additional stuff

- headers
    - HTTP content-encoding: gzip
    x content-type header; always JSON?
    - set "Via" header in responses (indicating proxy version/context)
- https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html
- logging
- switch from 'url' to 'percent-encoding' (?)
- https://github.com/elastic/search-ui
