From 3aaa3d1e80284b4c4dd39cd83b73f586e2831d5d Mon Sep 17 00:00:00 2001 From: Bryan Newbold Date: Mon, 24 Aug 2020 21:37:17 -0700 Subject: move request body parsing to module/file --- src/lib.rs | 243 +-------------------------------------------- src/parse.rs | 242 ++++++++++++++++++++++++++++++++++++++++++++ tests/parse_es_requests.rs | 2 +- 3 files changed, 245 insertions(+), 242 deletions(-) create mode 100644 src/parse.rs diff --git a/src/lib.rs b/src/lib.rs index 9f5b8a2..5fd54c9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,9 +1,9 @@ +use serde::{Serialize, Deserialize}; use hyper::{Request, Body, Method, Uri}; use http::request; -use serde::{Serialize, Deserialize}; -use std::collections::HashMap; +pub mod parse; #[derive(Default, Deserialize, Debug, Clone)] pub struct ProxyConfig { @@ -29,245 +29,6 @@ impl ProxyConfig { } } -#[derive(Serialize, Deserialize, Debug)] -pub struct ApiRequest { - pub method: String, - pub path_and_query: String, - pub body: Option, -} - -pub struct UrlQueryParams { - pub allow_no_indices: Option, - pub allow_partial_search_results: Option, - pub batched_reduce_size: Option, - pub ccs_minimize_roundtrips: Option, - pub docvalue_fields: Option, // array of strings, comma-separated - pub expand_wildcards: Option, - pub explain: Option, - pub from: Option, - pub ignore_throttled: Option, - pub ignore_unavailable: Option, - pub max_concurrent_shard_requests: Option, - pub pre_filter_shard_size: Option, - pub preference: Option, - pub q: Option, - pub request_cache: Option, - pub rest_total_hits_as_int: Option, - pub routing: Option, - pub scroll: Option, // string is "time value" - pub search_type: Option, - pub seq_no_primary_term: Option, - pub size: Option, - pub sort: Option, // array of strings, comma-separated - pub _source: Option, // TODO: bool or string - pub _source_excludes: Option, // array of strings, comma-separated - pub _source_includes: Option, // array of strings, comma-separated - pub stats: Option, - pub stored_fields: Option, // array of strings, comma-separated - pub suggest_field: Option, - pub suggest_text: Option, - pub terminate_after: Option, - pub timeout: Option, // string is "time units" - pub track_scores: Option, - pub track_total_hits: Option, // XXX: bool or integer - pub typed_keys: Option, - pub version: Option, -} - -// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html -#[derive(Serialize, Deserialize, Debug)] -#[serde(deny_unknown_fields)] -pub struct SearchBody { - pub query: Option, - pub highlight: Option, - pub collapse: Option, - pub post_filter: Option, // TODO: leaf query only? - pub rescore: Option, // TODO: single or an array of rescore objects - // script_fields disabled - - // https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html - pub sort: Option>, - - pub slice: Option, - pub stored_fields: Option, // array of strings, or "_none_" - - // overlap with URL query parameters - pub docvalue_fields: Option>, - pub explain: Option, - pub from: Option, - pub min_score: Option, - pub seq_no_primary_term: Option, - pub size: Option, - pub _source: Option, // XXX: bool, string, or object - pub terminate_after: Option, - pub timeout: Option, // string is "time units" -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(deny_unknown_fields)] -pub struct ScrollBody { - pub scroll_id: String, - pub scroll: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ApiSlice { - id: u32, - max: u32, - field: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ApiRescore{ - pub query: Option, - pub window_size: Option, -} - -// TODO: could revert to having query types as an enum, with flattening -#[derive(Serialize, Deserialize, Debug)] -pub struct ApiQuery { - // compound queries - #[serde(rename = "bool")] - bool_query: Option, - boosting: Option, - constant_score: Option, - - // fulltext (leaf) queries - - // term-level (leaf) queries - #[serde(rename = "match")] - match_query: Option>, - match_phrase: Option>, - query_string: Option, - - // other - nested: Option, - rescore_query: Option>, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ApiHighlight{ - // TODO: fields could also be an array of strings? - fields: HashMap, - - #[serde(flatten)] - settings: HighlightField, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum SortMapValue { - String(String), - Object { order: String, mode: Option }, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum SortElement{ - String(String), - Object(HashMap), -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum DocValOrString { - String(String), - Object {field: String, format: Option}, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum QueryFieldOrString { - Object(QueryField), - String(String), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct QueryField{ - query: String, - fuzziness: Option, - slop: Option, - boost: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct BoolQuery { - must: Option>, - filter: Option>, - should: Option>, - must_not: Option>, - minimum_should_match: Option, - boost: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct NestedQuery { - path: String, - query: Box, - score_mode: Option, - ignore_unmapped: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct BoostingQuery { - positive: Box, - negative: Box, - negative_boost: f64, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ConstantScoreQuery { - filter: Box, - boost: Option, -} - -// https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html -#[derive(Serialize, Deserialize, Debug)] -pub struct HighlightField{ - boundary_chars: Option, - boundary_max_scan: Option, - boundary_scanner: Option, - boundary_scanner_locale: Option, - encoder: Option, - force_source: Option, - fragmenter: Option, - fragment_offset: Option, - fragment_size: Option, - highlight_query: Option, - matched_fields: Option>, - no_match_size: Option, - number_of_fragments: Option, - order: Option, - phrase_limit: Option, - pre_tags: Option>, - post_tags: Option>, - require_field_match: Option, - tags_schema: Option, - #[serde(rename = "type")] - highlight_type: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct ApiCollapse{ - field: String, - inner_hits: Option, -} - -#[derive(Serialize, Deserialize, Debug)] -#[serde(untagged)] -pub enum InnerHitsOneOrMore { - Single(InnerHits), - Multiple(Vec), -} - -#[derive(Serialize, Deserialize, Debug)] -pub struct InnerHits { - from: Option, - size: Option, - sort: Option>, - name: Option, -} - #[derive(Debug)] pub enum ParsedRequest { Malformed(String), diff --git a/src/parse.rs b/src/parse.rs new file mode 100644 index 0000000..a4cdc3c --- /dev/null +++ b/src/parse.rs @@ -0,0 +1,242 @@ + +use serde::{Serialize, Deserialize}; +use std::collections::HashMap; + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiRequest { + pub method: String, + pub path_and_query: String, + pub body: Option, +} + +pub struct UrlQueryParams { + pub allow_no_indices: Option, + pub allow_partial_search_results: Option, + pub batched_reduce_size: Option, + pub ccs_minimize_roundtrips: Option, + pub docvalue_fields: Option, // array of strings, comma-separated + pub expand_wildcards: Option, + pub explain: Option, + pub from: Option, + pub ignore_throttled: Option, + pub ignore_unavailable: Option, + pub max_concurrent_shard_requests: Option, + pub pre_filter_shard_size: Option, + pub preference: Option, + pub q: Option, + pub request_cache: Option, + pub rest_total_hits_as_int: Option, + pub routing: Option, + pub scroll: Option, // string is "time value" + pub search_type: Option, + pub seq_no_primary_term: Option, + pub size: Option, + pub sort: Option, // array of strings, comma-separated + pub _source: Option, // TODO: bool or string + pub _source_excludes: Option, // array of strings, comma-separated + pub _source_includes: Option, // array of strings, comma-separated + pub stats: Option, + pub stored_fields: Option, // array of strings, comma-separated + pub suggest_field: Option, + pub suggest_text: Option, + pub terminate_after: Option, + pub timeout: Option, // string is "time units" + pub track_scores: Option, + pub track_total_hits: Option, // XXX: bool or integer + pub typed_keys: Option, + pub version: Option, +} + +// https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html +#[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] +pub struct SearchBody { + pub query: Option, + pub highlight: Option, + pub collapse: Option, + pub post_filter: Option, // TODO: leaf query only? + pub rescore: Option, // TODO: single or an array of rescore objects + // script_fields disabled + + // https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html + pub sort: Option>, + + pub slice: Option, + pub stored_fields: Option, // array of strings, or "_none_" + + // overlap with URL query parameters + pub docvalue_fields: Option>, + pub explain: Option, + pub from: Option, + pub min_score: Option, + pub seq_no_primary_term: Option, + pub size: Option, + pub _source: Option, // XXX: bool, string, or object + pub terminate_after: Option, + pub timeout: Option, // string is "time units" +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(deny_unknown_fields)] +pub struct ScrollBody { + pub scroll_id: String, + pub scroll: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiSlice { + id: u32, + max: u32, + field: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiRescore{ + pub query: Option, + pub window_size: Option, +} + +// TODO: could revert to having query types as an enum, with flattening +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiQuery { + // compound queries + #[serde(rename = "bool")] + bool_query: Option, + boosting: Option, + constant_score: Option, + + // fulltext (leaf) queries + + // term-level (leaf) queries + #[serde(rename = "match")] + match_query: Option>, + match_phrase: Option>, + query_string: Option, + + // other + nested: Option, + rescore_query: Option>, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiHighlight{ + // TODO: fields could also be an array of strings? + fields: HashMap, + + #[serde(flatten)] + settings: HighlightField, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum SortMapValue { + String(String), + Object { order: String, mode: Option }, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum SortElement{ + String(String), + Object(HashMap), +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum DocValOrString { + String(String), + Object {field: String, format: Option}, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum QueryFieldOrString { + Object(QueryField), + String(String), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct QueryField{ + query: String, + fuzziness: Option, + slop: Option, + boost: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct BoolQuery { + must: Option>, + filter: Option>, + should: Option>, + must_not: Option>, + minimum_should_match: Option, + boost: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct NestedQuery { + path: String, + query: Box, + score_mode: Option, + ignore_unmapped: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct BoostingQuery { + positive: Box, + negative: Box, + negative_boost: f64, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ConstantScoreQuery { + filter: Box, + boost: Option, +} + +// https://www.elastic.co/guide/en/elasticsearch/reference/current/highlighting.html +#[derive(Serialize, Deserialize, Debug)] +pub struct HighlightField{ + boundary_chars: Option, + boundary_max_scan: Option, + boundary_scanner: Option, + boundary_scanner_locale: Option, + encoder: Option, + force_source: Option, + fragmenter: Option, + fragment_offset: Option, + fragment_size: Option, + highlight_query: Option, + matched_fields: Option>, + no_match_size: Option, + number_of_fragments: Option, + order: Option, + phrase_limit: Option, + pre_tags: Option>, + post_tags: Option>, + require_field_match: Option, + tags_schema: Option, + #[serde(rename = "type")] + highlight_type: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct ApiCollapse{ + field: String, + inner_hits: Option, +} + +#[derive(Serialize, Deserialize, Debug)] +#[serde(untagged)] +pub enum InnerHitsOneOrMore { + Single(InnerHits), + Multiple(Vec), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct InnerHits { + from: Option, + size: Option, + sort: Option>, + name: Option, +} diff --git a/tests/parse_es_requests.rs b/tests/parse_es_requests.rs index a4950c0..c34dfad 100644 --- a/tests/parse_es_requests.rs +++ b/tests/parse_es_requests.rs @@ -1,7 +1,7 @@ use std::fs; use std::ffi::OsStr; -use es_public_proxy::{ScrollBody, SearchBody}; +use es_public_proxy::parse::{ScrollBody, SearchBody}; mod common; -- cgit v1.2.3