Support more JSON / XML "like" mimetypes with debug output

This commit is contained in:
Jean-Christophe Amiel 2024-10-30 10:32:11 +01:00
parent 86a7b6bf29
commit afcd47fd01
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
5 changed files with 932 additions and 14 deletions

View File

@ -77,3 +77,92 @@ error: Assert failure
| expected: string <You have enough credit.> | expected: string <You have enough credit.>
| |
HTTP/1.1 200
Server: Werkzeug/<<<.*?>>> Python/<<<.*?>>>
Date: <<<.*?>>>
Content-Type: application/fhir+json
Content-Length: 902
Server: Flask Server
Connection: close
{"resourceType": "Practitioner", "id": "example", "text": {"status": "generated", "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n <p>Dr Adam Careful is a Referring Practitioner for Acme Hospital from 1-Jan 2012 to 31-Mar\n 2012</p>\n </div>"}, "identifier": [{"system": "http://www.acme.org/practitioners", "value": "23"}], "active": true, "name": [{"family": "Careful", "given": ["Adam"], "prefix": ["Dr"]}], "address": [{"use": "home", "line": ["534 Erewhon St"], "city": "PleasantVille", "state": "Vic", "postalCode": "3999"}], "qualification": [{"identifier": [{"system": "http://example.org/UniversityIdentifier", "value": "12345"}], "code": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/v2-0360/2.7", "code": "BS", "display": "Bachelor of Science"}], "text": "Bachelor of Science"}, "period": {"start": "1995"}, "issuer": {"display": "Example University"}}]}
error: Assert failure
--> tests_failed/error_format_long.hurl:34:0
|
| GET http://localhost:8000/error-format-long/fhir
| ...
34 | jsonpath "$.id" == "foo"
| actual: string <example>
| expected: string <foo>
|
HTTP/1.1 200
Server: Werkzeug/<<<.*?>>> Python/<<<.*?>>>
Date: <<<.*?>>>
Content-Type: text/csv; charset=utf-8
Content-Length: 726
Server: Flask Server
Connection: close
"Year","Score","Title"
1968,86,"Greetings"
1970,17,"Bloody Mama"
1970,73,"Hi, Mom!"
1971,40,"Born to Win"
1973,98,"Mean Streets"
1973,88,"Bang the Drum Slowly"
1974,97,"The Godfather, Part II"
1976,41,"The Last Tycoon"
1976,99,"Taxi Driver"
1977,47,"1900"
1977,67,"New York, New York"
1978,93,"The Deer Hunter"
1980,97,"Raging Bull"
1981,75,"True Confessions"
1983,90,"The King of Comedy"
1984,89,"Once Upon a Time in America"
1984,60,"Falling in Love"
1985,98,"Brazil"
1986,65,"The Mission"
1987,00,"Dear America: Letters Home From Vietnam"
1987,80,"The Untouchables"
1987,78,"Angel Heart"
1988,96,"Midnight Run"
1989,64,"Jacknife"
1989,47,"We're No Angels"
1990,88,"Awakenings"
1990,29,"Stanley & Iris"
1990,96,"Goodfellas"
error: Assert failure
--> tests_failed/error_format_long.hurl:42:0
|
| GET http://localhost:8000/error-format-long/csv
| ...
42 | body split "\n" nth 9 split "," nth 2 == "\"Taxi\""
| actual: string <"Taxi Driver">
| expected: string <"Taxi">
|
HTTP/1.1 200
Server: Werkzeug/<<<.*?>>> Python/<<<.*?>>>
Date: <<<.*?>>>
Content-Type: application/octet-stream
Content-Length: 4
Server: Flask Server
Connection: close
Bytes <deadbeef...>
error: Assert failure
--> tests_failed/error_format_long.hurl:50:0
|
| GET http://localhost:8000/error-format-long/bytes
| ...
50 | bytes == hex,beef;
| actual: byte array <deadbeef>
| expected: byte array <beef>
|

View File

@ -24,3 +24,27 @@ HTTP 200
Content-Type: application/problem+json Content-Type: application/problem+json
[Asserts] [Asserts]
jsonpath "$.title" == "You have enough credit." jsonpath "$.title" == "You have enough credit."
# "JSON like" mimetype are supported, like [FHIR](https://www.hl7.org/fhir/json.html)
GET http://localhost:8000/error-format-long/fhir
HTTP 200
Content-Type: application/fhir+json
[Asserts]
jsonpath "$.id" == "foo"
# Text like mimetype like CSV are supported
GET http://localhost:8000/error-format-long/csv
HTTP 200
Content-Type: text/csv; charset=utf-8
[Asserts]
body split "\n" nth 9 split "," nth 2 == "\"Taxi\""
# Bytestream are dumped as a raw bytes stream
GET http://localhost:8000/error-format-long/bytes
HTTP 200
Content-Type: application/octet-stream
[Asserts]
bytes == hex,beef;

View File

@ -1,7 +1,8 @@
import json import json
from io import BytesIO
from app import app from app import app
from flask import Response from flask import Response, make_response
@app.route("/error-format-long/html") @app.route("/error-format-long/html")
@ -37,3 +38,96 @@ def error_format_problem_json():
"accounts": ["/account/12345", "/account/67890"], "accounts": ["/account/12345", "/account/67890"],
} }
return Response(json.dumps(data), mimetype="application/problem+json") return Response(json.dumps(data), mimetype="application/problem+json")
@app.route("/error-format-long/fhir")
def error_format_fhir_json():
data = {
"resourceType": "Practitioner",
"id": "example",
"text": {
"status": "generated",
"div": '<div xmlns="http://www.w3.org/1999/xhtml">\n <p>Dr Adam Careful is a Referring Practitioner for Acme Hospital from 1-Jan 2012 to 31-Mar\n 2012</p>\n </div>',
},
"identifier": [{"system": "http://www.acme.org/practitioners", "value": "23"}],
"active": True,
"name": [{"family": "Careful", "given": ["Adam"], "prefix": ["Dr"]}],
"address": [
{
"use": "home",
"line": ["534 Erewhon St"],
"city": "PleasantVille",
"state": "Vic",
"postalCode": "3999",
}
],
"qualification": [
{
"identifier": [
{
"system": "http://example.org/UniversityIdentifier",
"value": "12345",
}
],
"code": {
"coding": [
{
"system": "http://terminology.hl7.org/CodeSystem/v2-0360/2.7",
"code": "BS",
"display": "Bachelor of Science",
}
],
"text": "Bachelor of Science",
},
"period": {"start": "1995"},
"issuer": {"display": "Example University"},
}
],
}
return Response(json.dumps(data), mimetype="application/fhir+json")
@app.route("/error-format-long/bytes")
def error_format_bytes():
result = BytesIO()
result.write(b"\xde\xad\xbe\xef")
data = result.getvalue()
resp = make_response(data)
resp.content_type = "application/octet-stream"
return resp
@app.route("/error-format-long/csv")
def error_format_csv():
data = """\
"Year","Score","Title"
1968,86,"Greetings"
1970,17,"Bloody Mama"
1970,73,"Hi, Mom!"
1971,40,"Born to Win"
1973,98,"Mean Streets"
1973,88,"Bang the Drum Slowly"
1974,97,"The Godfather, Part II"
1976,41,"The Last Tycoon"
1976,99,"Taxi Driver"
1977,47,"1900"
1977,67,"New York, New York"
1978,93,"The Deer Hunter"
1980,97,"Raging Bull"
1981,75,"True Confessions"
1983,90,"The King of Comedy"
1984,89,"Once Upon a Time in America"
1984,60,"Falling in Love"
1985,98,"Brazil"
1986,65,"The Mission"
1987,00,"Dear America: Letters Home From Vietnam"
1987,80,"The Untouchables"
1987,78,"Angel Heart"
1988,96,"Midnight Run"
1989,64,"Jacknife"
1989,47,"We're No Angels"
1990,88,"Awakenings"
1990,29,"Stanley & Iris"
1990,96,"Goodfellas"
"""
return Response(data, mimetype="text/csv")

View File

@ -77,3 +77,92 @@
 | expected: string <You have enough credit.>  | expected: string <You have enough credit.>
 |  |
HTTP/1.1 200
Server: Werkzeug/<<<.*?>>> Python/<<<.*?>>>
Date: <<<.*?>>>
Content-Type: application/fhir+json
Content-Length: 902
Server: Flask Server
Connection: close
{"resourceType": "Practitioner", "id": "example", "text": {"status": "generated", "div": "<div xmlns=\"http://www.w3.org/1999/xhtml\">\n <p>Dr Adam Careful is a Referring Practitioner for Acme Hospital from 1-Jan 2012 to 31-Mar\n 2012</p>\n </div>"}, "identifier": [{"system": "http://www.acme.org/practitioners", "value": "23"}], "active": true, "name": [{"family": "Careful", "given": ["Adam"], "prefix": ["Dr"]}], "address": [{"use": "home", "line": ["534 Erewhon St"], "city": "PleasantVille", "state": "Vic", "postalCode": "3999"}], "qualification": [{"identifier": [{"system": "http://example.org/UniversityIdentifier", "value": "12345"}], "code": {"coding": [{"system": "http://terminology.hl7.org/CodeSystem/v2-0360/2.7", "code": "BS", "display": "Bachelor of Science"}], "text": "Bachelor of Science"}, "period": {"start": "1995"}, "issuer": {"display": "Example University"}}]}
error: Assert failure
--> tests_failed/error_format_long.hurl:34:0
 |
 | GET http://localhost:8000/error-format-long/fhir
 | ...
34 | jsonpath "$.id" == "foo"
 | actual: string <example>
 | expected: string <foo>
 |
HTTP/1.1 200
Server: Werkzeug/<<<.*?>>> Python/<<<.*?>>>
Date: <<<.*?>>>
Content-Type: text/csv; charset=utf-8
Content-Length: 726
Server: Flask Server
Connection: close
"Year","Score","Title"
1968,86,"Greetings"
1970,17,"Bloody Mama"
1970,73,"Hi, Mom!"
1971,40,"Born to Win"
1973,98,"Mean Streets"
1973,88,"Bang the Drum Slowly"
1974,97,"The Godfather, Part II"
1976,41,"The Last Tycoon"
1976,99,"Taxi Driver"
1977,47,"1900"
1977,67,"New York, New York"
1978,93,"The Deer Hunter"
1980,97,"Raging Bull"
1981,75,"True Confessions"
1983,90,"The King of Comedy"
1984,89,"Once Upon a Time in America"
1984,60,"Falling in Love"
1985,98,"Brazil"
1986,65,"The Mission"
1987,00,"Dear America: Letters Home From Vietnam"
1987,80,"The Untouchables"
1987,78,"Angel Heart"
1988,96,"Midnight Run"
1989,64,"Jacknife"
1989,47,"We're No Angels"
1990,88,"Awakenings"
1990,29,"Stanley & Iris"
1990,96,"Goodfellas"
error: Assert failure
--> tests_failed/error_format_long.hurl:42:0
 |
 | GET http://localhost:8000/error-format-long/csv
 | ...
42 | body split "\n" nth 9 split "," nth 2 == "\"Taxi\""
 | actual: string <"Taxi Driver">
 | expected: string <"Taxi">
 |
HTTP/1.1 200
Server: Werkzeug/<<<.*?>>> Python/<<<.*?>>>
Date: <<<.*?>>>
Content-Type: application/octet-stream
Content-Length: 4
Server: Flask Server
Connection: close
Bytes <deadbeef...>
error: Assert failure
--> tests_failed/error_format_long.hurl:50:0
 |
 | GET http://localhost:8000/error-format-long/bytes
 | ...
50 | bytes == hex,beef;
 | actual: byte array <deadbeef>
 | expected: byte array <beef>
 |

View File

@ -19,33 +19,40 @@
// TODO: maybe add a proper MimeType enum (see <https://github.com/hyperium/mime>) // TODO: maybe add a proper MimeType enum (see <https://github.com/hyperium/mime>)
// as implementation / api example. // as implementation / api example.
use regex::Regex;
/// Returns true if binary data with this `content_type` can be decoded as text. /// Returns true if binary data with this `content_type` can be decoded as text.
pub fn is_kind_of_text(content_type: &str) -> bool { pub fn is_kind_of_text(content_type: &str) -> bool {
let content_types = [ let content_type = content_type.trim().to_lowercase();
"text/", content_type.contains("text/") || is_json(&content_type) || is_xml(&content_type)
"application/json",
"application/problem+json", // See https://datatracker.ietf.org/doc/html/rfc7807
"application/xml",
"application/x-www-form-urlencoded",
];
content_types.iter().any(|c| content_type.contains(c))
} }
/// Returns true if this `content_type` is HTML. /// Returns true if this `content_type` is HTML.
pub fn is_html(content_type: &str) -> bool { pub fn is_html(content_type: &str) -> bool {
let content_type = content_type.trim().to_lowercase();
content_type.starts_with("text/html") content_type.starts_with("text/html")
} }
/// Returns true if this `content_type` is HTML. /// Returns true if this `content_type` is HTML.
pub fn is_xml(content_type: &str) -> bool { pub fn is_xml(content_type: &str) -> bool {
content_type.starts_with("text/xml") || content_type.starts_with("application/xml") let content_type = content_type.trim().to_lowercase();
let patterns = [
r"^text/xml",
r"^application/xml",
r"^application/[a-z0-9-_.]+[+.]xml",
];
patterns
.iter()
.any(|p| Regex::new(p).unwrap().is_match(&content_type))
} }
/// Returns true if this `content_type` is JSON. /// Returns true if this `content_type` is JSON.
pub fn is_json(content_type: &str) -> bool { pub fn is_json(content_type: &str) -> bool {
content_type.starts_with("application/json") let content_type = content_type.trim().to_lowercase();
|| content_type.starts_with("application/problem+json") let patterns = [r"^application/json", r"^application/[a-z0-9-_.]+[+.-]json"];
patterns
.iter()
.any(|p| Regex::new(p).unwrap().is_match(&content_type))
} }
/// Extracts charset from mime-type String /// Extracts charset from mime-type String
@ -65,7 +72,7 @@ pub mod tests {
use super::*; use super::*;
#[test] #[test]
pub fn test_charset() { fn test_charset() {
assert_eq!( assert_eq!(
charset("text/plain; charset=utf-8"), charset("text/plain; charset=utf-8"),
Some("utf-8".to_string()) Some("utf-8".to_string())
@ -88,4 +95,619 @@ pub mod tests {
Some("utf-8".to_string()) Some("utf-8".to_string())
); );
} }
// Dataset for mimetypes issued from <https://www.iana.org/assignments/media-types/media-types.xhtml#application>
#[test]
fn test_is_json() {
let mime_types = [
"application/3gppHal+json",
"application/3gppHalForms+json",
"application/ace+json",
"application/activity+json",
"application/aif+json",
"application/alto-cdni+json",
"application/alto-cdnifilter+json",
"application/alto-costmap+json",
"application/alto-costmapfilter+json",
"application/alto-directory+json",
"application/alto-endpointprop+json",
"application/alto-endpointpropparams+json",
"application/alto-endpointcost+json",
"application/alto-endpointcostparams+json",
"application/alto-error+json",
"application/alto-networkmapfilter+json",
"application/alto-networkmap+json",
"application/alto-propmap+json",
"application/alto-propmapparams+json",
"application/alto-tips+json",
"application/alto-tipsparams+json",
"application/alto-updatestreamcontrol+json",
"application/alto-updatestreamparams+json",
"application/atsc-rdt+json",
"application/calendar+json",
"application/captive+json",
"application/city+json",
"application/coap-group+json",
"application/csvm+json",
"application/cwl+json",
"application/dicom+json",
"application/dns+json",
"application/elm+json",
"application/EmergencyCallData.LegacyESN+json",
"application/expect-ct-report+json",
"application/fhir+json",
"application/geo+json",
"application/geo+json-seq",
"application/geopose+json",
"application/geoxacml+json",
"application/jf2feed+json",
"application/jose+json",
"application/jrd+json",
"application/jscalendar+json",
"application/jscontact+json",
"application/json",
"application/json-patch+json",
"application/json-seq",
"application/jsonpath",
"application/jwk+json",
"application/jwk-set+json",
"application/ld+json",
"application/linkset+json",
"application/manifest+json",
"application/merge-patch+json",
"application/mud+json",
"application/ppsp-tracker+json",
"application/problem+json",
"application/prs.implied-object+json",
"application/prs.implied-object+json-seq",
"application/pvd+json",
"application/rdap+json",
"application/reputon+json",
"application/sarif-external-properties+json",
"application/sarif+json",
"application/scim+json",
"application/senml-etch+json",
"application/senml+json",
"application/sensml+json",
"application/spdx+json",
"application/stix+json",
"application/taxii+json",
"application/td+json",
"application/tlsrpt+json",
"application/tm+json",
"application/trust-chain+json",
"application/vcard+json",
"application/vnd.acm.addressxfer+json",
"application/vnd.acm.chatbot+json",
"application/vnd.amadeus+json",
"application/vnd.apache.thrift.json",
"application/vnd.api+json",
"application/vnd.aplextor.warrp+json",
"application/vnd.apothekende.reservation+json",
"application/vnd.artisan+json",
"application/vnd.avalon+json",
"application/vnd.bbf.usp.msg+json",
"application/vnd.bekitzur-stech+json",
"application/vnd.byu.uapi+json",
"application/vnd.capasystems-pg+json",
"application/vnd.cncf.helm.config.v1+json",
"application/vnd.collection.doc+json",
"application/vnd.collection+json",
"application/vnd.collection.next+json",
"application/vnd.coreos.ignition+json",
"application/vnd.cryptii.pipe+json",
"application/vnd.cyclonedx+json",
"application/vnd.datapackage+json",
"application/vnd.dataresource+json",
"application/vnd.document+json",
"application/vnd.drive+json",
"application/vnd.eclipse.ditto+json",
"application/vnd.eu.kasparian.car+json",
"application/vnd.futoin+json",
"application/vnd.gentics.grd+json",
"application/vnd.geo+json",
"application/vnd.gnu.taler.exchange+json",
"application/vnd.gnu.taler.merchant+json",
"application/vnd.hal+json",
"application/vnd.hc+json",
"application/vnd.heroku+json",
"application/vnd.hyper-item+json",
"application/vnd.hyper+json",
"application/vnd.hyperdrive+json",
"application/vnd.ims.lis.v2.result+json",
"application/vnd.ims.lti.v2.toolconsumerprofile+json",
"application/vnd.ims.lti.v2.toolproxy.id+json",
"application/vnd.ims.lti.v2.toolproxy+json",
"application/vnd.ims.lti.v2.toolsettings+json",
"application/vnd.ims.lti.v2.toolsettings.simple+json",
"application/vnd.ipld.dag-json",
"application/vnd.las.las+json",
"application/vnd.leap+json",
"application/vnd.mason+json",
"application/vnd.micro+json",
"application/vnd.miele+json",
"application/vnd.nacamar.ybrid+json",
"application/vnd.nato.bindingdataobject+json",
"application/vnd.nearst.inv+json",
"application/vnd.oai.workflows+json",
"application/vnd.oci.image.manifest.v1+json",
"application/vnd.oftn.l10n+json",
"application/vnd.oma.lwm2m+json",
"application/vnd.openvpi.dspx+json",
"application/vnd.oracle.resource+json",
"application/vnd.pagerduty+json",
"application/vnd.restful+json",
"application/vnd.seis+json",
"application/vnd.shootproof+json",
"application/vnd.shopkick+json",
"application/vnd.siren+json",
"application/vnd.syft+json",
"application/vnd.tableschema+json",
"application/vnd.think-cell.ppttc+json",
"application/vnd.uic.osdm+json",
"application/vnd.vel+json",
"application/vnd.veritone.aion+json",
"application/vnd.xacml+json",
"application/voucher-cms+json",
"application/webpush-options+json",
"application/yang-data+json",
"application/yang-patch+json",
"application/yang-sid+json",
];
for mime in &mime_types {
assert!(is_json(mime), "{mime} is a not a JSON mime type");
}
}
#[test]
fn test_is_xml() {
let mime_types = [
"application/3gpdash-qoe-report+xml",
"application/3gpp-ims+xml",
"application/atom+xml",
"application/atomcat+xml",
"application/atomdeleted+xml",
"application/atomsvc+xml",
"application/atsc-dwd+xml",
"application/atsc-held+xml",
"application/atsc-rsat+xml",
"application/auth-policy+xml",
"application/automationml-aml+xml",
"application/beep+xml",
"application/calendar+xml",
"application/ccmp+xml",
"application/ccxml+xml",
"application/cda+xml",
"application/cea-2018+xml",
"application/cellml+xml",
"application/clue_info+xml",
"application/clue+xml",
"application/cnrp+xml",
"application/conference-info+xml",
"application/cpl+xml",
"application/csta+xml",
"application/CSTAdata+xml",
"application/dash+xml",
"application/dash-patch+xml",
"application/davmount+xml",
"application/dialog-info+xml",
"application/dicom+xml",
"application/dskpp+xml",
"application/dssc+xml",
"application/elm+xml",
"application/EmergencyCallData.cap+xml",
"application/EmergencyCallData.Comment+xml",
"application/EmergencyCallData.Control+xml",
"application/EmergencyCallData.DeviceInfo+xml",
"application/EmergencyCallData.ProviderInfo+xml",
"application/EmergencyCallData.ServiceInfo+xml",
"application/EmergencyCallData.SubscriberInfo+xml",
"application/EmergencyCallData.VEDS+xml",
"application/emma+xml",
"application/emotionml+xml",
"application/epp+xml",
"application/fdt+xml",
"application/fhir+xml",
"application/framework-attributes+xml",
"application/geoxacml+xml",
"application/gml+xml",
"application/held+xml",
"application/hl7v2+xml",
"application/ibe-key-request+xml",
"application/ibe-pkg-reply+xml",
"application/im-iscomposing+xml",
"application/inkml+xml",
"application/its+xml",
"application/kpml-request+xml",
"application/kpml-response+xml",
"application/lgr+xml",
"application/load-control+xml",
"application/lost+xml",
"application/lostsync+xml",
"application/mads+xml",
"application/marcxml+xml",
"application/mathml+xml",
"application/mathml-content+xml",
"application/mathml-presentation+xml",
"application/mbms-associated-procedure-description+xml",
"application/mbms-deregister+xml",
"application/mbms-envelope+xml",
"application/mbms-msk-response+xml",
"application/mbms-msk+xml",
"application/mbms-protection-description+xml",
"application/mbms-reception-report+xml",
"application/mbms-register-response+xml",
"application/mbms-register+xml",
"application/mbms-schedule+xml",
"application/mbms-user-service-description+xml",
"application/media_control+xml",
"application/media-policy-dataset+xml",
"application/mediaservercontrol+xml",
"application/metalink4+xml",
"application/mets+xml",
"application/mmt-aei+xml",
"application/mmt-usd+xml",
"application/mods+xml",
"application/mrb-consumer+xml",
"application/mrb-publish+xml",
"application/msc-ivr+xml",
"application/msc-mixer+xml",
"application/nlsml+xml",
"application/odm+xml",
"application/oebps-package+xml",
"application/opc-nodeset+xml",
"application/p2p-overlay+xml",
"application/patch-ops-error+xml",
"application/pidf-diff+xml",
"application/pidf+xml",
"application/pls+xml",
"application/poc-settings+xml",
"application/problem+xml",
"application/provenance+xml",
"application/prs.implied-document+xml",
"application/prs.xsf+xml",
"application/pskc+xml",
"application/rdf+xml",
"application/route-apd+xml",
"application/route-s-tsid+xml",
"application/route-usd+xml",
"application/reginfo+xml",
"application/resource-lists-diff+xml",
"application/resource-lists+xml",
"application/rfc+xml",
"application/rlmi+xml",
"application/rls-services+xml",
"application/samlassertion+xml",
"application/samlmetadata+xml",
"application/sbml+xml",
"application/scaip+xml",
"application/senml+xml",
"application/sensml+xml",
"application/sep+xml",
"application/shf+xml",
"application/simple-filter+xml",
"application/smil+xml",
"application/soap+xml",
"application/sparql-results+xml",
"application/spirits-event+xml",
"application/srgs+xml",
"application/sru+xml",
"application/ssml+xml",
"application/swid+xml",
"application/tei+xml",
"application/thraud+xml",
"application/ttml+xml",
"application/urc-grpsheet+xml",
"application/urc-ressheet+xml",
"application/urc-targetdesc+xml",
"application/urc-uisocketdesc+xml",
"application/vcard+xml",
"application/vnd.1000minds.decision-model+xml",
"application/vnd.3gpp.access-transfer-events+xml",
"application/vnd.3gpp.bsf+xml",
"application/vnd.3gpp.crs+xml",
"application/vnd.3gpp.current-location-discovery+xml",
"application/vnd.3gpp.GMOP+xml",
"application/vnd.3gpp.mcdata-affiliation-command+xml",
"application/vnd.3gpp.mcdata-info+xml",
"application/vnd.3gpp.mcdata-msgstore-ctrl-request+xml",
"application/vnd.3gpp.mcdata-regroup+xml",
"application/vnd.3gpp.mcdata-service-config+xml",
"application/vnd.3gpp.mcdata-ue-config+xml",
"application/vnd.3gpp.mcdata-user-profile+xml",
"application/vnd.3gpp.mcptt-affiliation-command+xml",
"application/vnd.3gpp.mcptt-floor-request+xml",
"application/vnd.3gpp.mcptt-info+xml",
"application/vnd.3gpp.mcptt-location-info+xml",
"application/vnd.3gpp.mcptt-mbms-usage-info+xml",
"application/vnd.3gpp.mcptt-regroup+xml",
"application/vnd.3gpp.mcptt-service-config+xml",
"application/vnd.3gpp.mcptt-signed+xml",
"application/vnd.3gpp.mcptt-ue-config+xml",
"application/vnd.3gpp.mcptt-ue-init-config+xml",
"application/vnd.3gpp.mcptt-user-profile+xml",
"application/vnd.3gpp.mcvideo-affiliation-command+xml",
"application/vnd.3gpp.mcvideo-affiliation-info+xml",
"application/vnd.3gpp.mcvideo-info+xml",
"application/vnd.3gpp.mcvideo-location-info+xml",
"application/vnd.3gpp.mcvideo-mbms-usage-info+xml",
"application/vnd.3gpp.mcvideo-regroup+xml",
"application/vnd.3gpp.mcvideo-service-config+xml",
"application/vnd.3gpp.mcvideo-transmission-request+xml",
"application/vnd.3gpp.mcvideo-ue-config+xml",
"application/vnd.3gpp.mcvideo-user-profile+xml",
"application/vnd.3gpp.mid-call+xml",
"application/vnd.3gpp.pinapp-info+xml",
"application/vnd.3gpp-prose-pc3a+xml",
"application/vnd.3gpp-prose-pc3ach+xml",
"application/vnd.3gpp-prose-pc3ch+xml",
"application/vnd.3gpp-prose-pc8+xml",
"application/vnd.3gpp-prose+xml",
"application/vnd.3gpp.seal-group-doc+xml",
"application/vnd.3gpp.seal-info+xml",
"application/vnd.3gpp.seal-location-info+xml",
"application/vnd.3gpp.seal-mbms-usage-info+xml",
"application/vnd.3gpp.seal-network-QoS-management-info+xml",
"application/vnd.3gpp.seal-ue-config-info+xml",
"application/vnd.3gpp.seal-unicast-info+xml",
"application/vnd.3gpp.seal-user-profile-info+xml",
"application/vnd.3gpp.sms+xml",
"application/vnd.3gpp.srvcc-ext+xml",
"application/vnd.3gpp.SRVCC-info+xml",
"application/vnd.3gpp.state-and-event-info+xml",
"application/vnd.3gpp.ussd+xml",
"application/vnd.3gpp.vae-info+xml",
"application/vnd.3gpp2.bcmcsinfo+xml",
"application/vnd.adobe.xdp+xml",
"application/vnd.amundsen.maze+xml",
"application/vnd.apple.installer+xml",
"application/vnd.avistar+xml",
"application/vnd.balsamiq.bmml+xml",
"application/vnd.biopax.rdf+xml",
"application/vnd.c3voc.schedule+xml",
"application/vnd.chemdraw+xml",
"application/vnd.citationstyles.style+xml",
"application/vnd.criticaltools.wbs+xml",
"application/vnd.ctct.ws+xml",
"application/vnd.cyan.dean.root+xml",
"application/vnd.cyclonedx+xml",
"application/vnd.dece.ttml+xml",
"application/vnd.dm.delegation+xml",
"application/vnd.dvb.dvbisl+xml",
"application/vnd.dvb.notif-aggregate-root+xml",
"application/vnd.dvb.notif-container+xml",
"application/vnd.dvb.notif-generic+xml",
"application/vnd.dvb.notif-ia-msglist+xml",
"application/vnd.dvb.notif-ia-registration-request+xml",
"application/vnd.dvb.notif-ia-registration-response+xml",
"application/vnd.dvb.notif-init+xml",
"application/vnd.emclient.accessrequest+xml",
"application/vnd.eprints.data+xml",
"application/vnd.eszigno3+xml",
"application/vnd.etsi.aoc+xml",
"application/vnd.etsi.cug+xml",
"application/vnd.etsi.iptvcommand+xml",
"application/vnd.etsi.iptvdiscovery+xml",
"application/vnd.etsi.iptvprofile+xml",
"application/vnd.etsi.iptvsad-bc+xml",
"application/vnd.etsi.iptvsad-cod+xml",
"application/vnd.etsi.iptvsad-npvr+xml",
"application/vnd.etsi.iptvservice+xml",
"application/vnd.etsi.iptvsync+xml",
"application/vnd.etsi.iptvueprofile+xml",
"application/vnd.etsi.mcid+xml",
"application/vnd.etsi.overload-control-policy-dataset+xml",
"application/vnd.etsi.pstn+xml",
"application/vnd.etsi.sci+xml",
"application/vnd.etsi.simservs+xml",
"application/vnd.etsi.tsl+xml",
"application/vnd.fujifilm.fb.jfi+xml",
"application/vnd.gentoo.catmetadata+xml",
"application/vnd.gentoo.pkgmetadata+xml",
"application/vnd.geocube+xml",
"application/vnd.google-earth.kml+xml",
"application/vnd.gov.sk.e-form+xml",
"application/vnd.gov.sk.xmldatacontainer+xml",
"application/vnd.gpxsee.map+xml",
"application/vnd.hal+xml",
"application/vnd.HandHeld-Entertainment+xml",
"application/vnd.informedcontrol.rms+xml",
"application/vnd.infotech.project+xml",
"application/vnd.iptc.g2.catalogitem+xml",
"application/vnd.iptc.g2.conceptitem+xml",
"application/vnd.iptc.g2.knowledgeitem+xml",
"application/vnd.iptc.g2.newsitem+xml",
"application/vnd.iptc.g2.newsmessage+xml",
"application/vnd.iptc.g2.packageitem+xml",
"application/vnd.iptc.g2.planningitem+xml",
"application/vnd.irepository.package+xml",
"application/vnd.las.las+xml",
"application/vnd.liberty-request+xml",
"application/vnd.llamagraphics.life-balance.exchange+xml",
"application/vnd.marlin.drm.actiontoken+xml",
"application/vnd.marlin.drm.conftoken+xml",
"application/vnd.marlin.drm.license+xml",
"application/vnd.mozilla.xul+xml",
"application/vnd.ms-office.activeX+xml",
"application/vnd.ms-playready.initiator+xml",
"application/vnd.ms-PrintDeviceCapabilities+xml",
"application/vnd.ms-PrintSchemaTicket+xml",
"application/vnd.nato.bindingdataobject+xml",
"application/vnd.nokia.conml+xml",
"application/vnd.nokia.iptv.config+xml",
"application/vnd.nokia.landmark+xml",
"application/vnd.nokia.landmarkcollection+xml",
"application/vnd.nokia.n-gage.ac+xml",
"application/vnd.nokia.pcd+xml",
"application/vnd.oipf.contentaccessdownload+xml",
"application/vnd.oipf.contentaccessstreaming+xml",
"application/vnd.oipf.dae.svg+xml",
"application/vnd.oipf.dae.xhtml+xml",
"application/vnd.oipf.mippvcontrolmessage+xml",
"application/vnd.oipf.spdiscovery+xml",
"application/vnd.oipf.spdlist+xml",
"application/vnd.oipf.ueprofile+xml",
"application/vnd.oipf.userprofile+xml",
"application/vnd.oma.bcast.associated-procedure-parameter+xml",
"application/vnd.oma.bcast.drm-trigger+xml",
"application/vnd.oma.bcast.imd+xml",
"application/vnd.oma.bcast.notification+xml",
"application/vnd.oma.bcast.sgdd+xml",
"application/vnd.oma.bcast.smartcard-trigger+xml",
"application/vnd.oma.bcast.sprov+xml",
"application/vnd.oma.cab-address-book+xml",
"application/vnd.oma.cab-feature-handler+xml",
"application/vnd.oma.cab-pcc+xml",
"application/vnd.oma.cab-subs-invite+xml",
"application/vnd.oma.cab-user-prefs+xml",
"application/vnd.oma.dd2+xml",
"application/vnd.oma.drm.risd+xml",
"application/vnd.oma.group-usage-list+xml",
"application/vnd.oma.pal+xml",
"application/vnd.oma.poc.detailed-progress-report+xml",
"application/vnd.oma.poc.final-report+xml",
"application/vnd.oma.poc.groups+xml",
"application/vnd.oma.poc.invocation-descriptor+xml",
"application/vnd.oma.poc.optimized-progress-report+xml",
"application/vnd.oma.scidm.messages+xml",
"application/vnd.oma.xcap-directory+xml",
"application/vnd.omads-email+xml",
"application/vnd.omads-file+xml",
"application/vnd.omads-folder+xml",
"application/vnd.openblox.game+xml",
"application/vnd.openstreetmap.data+xml",
"application/vnd.openxmlformats-officedocument.custom-properties+xml",
"application/vnd.openxmlformats-officedocument.customXmlProperties+xml",
"application/vnd.openxmlformats-officedocument.drawing+xml",
"application/vnd.openxmlformats-officedocument.drawingml.chart+xml",
"application/vnd.openxmlformats-officedocument.drawingml.chartshapes+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramColors+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramData+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramLayout+xml",
"application/vnd.openxmlformats-officedocument.drawingml.diagramStyle+xml",
"application/vnd.openxmlformats-officedocument.extended-properties+xml",
"application/vnd.openxmlformats-officedocument.presentationml.commentAuthors+xml",
"application/vnd.openxmlformats-officedocument.presentationml.comments+xml",
"application/vnd.openxmlformats-officedocument.presentationml.handoutMaster+xml",
"application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml",
"application/vnd.openxmlformats-officedocument.presentationml.notesSlide+xml",
"application/vnd.openxmlformats-officedocument.presentationml.presentation.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.presProps+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slide+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideLayout+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideMaster+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideshow.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.slideUpdateInfo+xml",
"application/vnd.openxmlformats-officedocument.presentationml.tableStyles+xml",
"application/vnd.openxmlformats-officedocument.presentationml.tags+xml",
"application/vnd.openxmlformats-officedocument.presentationml.template.main+xml",
"application/vnd.openxmlformats-officedocument.presentationml.viewProps+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.calcChain+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.chartsheet+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.connections+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.dialogsheet+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.externalLink+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheDefinition+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotCacheRecords+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.pivotTable+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.queryTable+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionHeaders+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.revisionLog+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.table+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.tableSingleCells+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.template.main+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.userNames+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.volatileDependencies+xml",
"application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml",
"application/vnd.openxmlformats-officedocument.theme+xml",
"application/vnd.openxmlformats-officedocument.themeOverride+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.glossary+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.endnotes+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.fontTable+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.footer+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.footnotes+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.settings+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.styles+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.template.main+xml",
"application/vnd.openxmlformats-officedocument.wordprocessingml.webSettings+xml",
"application/vnd.openxmlformats-package.core-properties+xml",
"application/vnd.openxmlformats-package.digital-signature-xmlsignature+xml",
"application/vnd.openxmlformats-package.relationships+xml",
"application/vnd.otps.ct-kip+xml",
"application/vnd.paos.xml",
"application/vnd.poc.group-advertisement+xml",
"application/vnd.pwg-xhtml-print+xml",
"application/vnd.radisys.moml+xml",
"application/vnd.radisys.msml-audit-conf+xml",
"application/vnd.radisys.msml-audit-conn+xml",
"application/vnd.radisys.msml-audit-dialog+xml",
"application/vnd.radisys.msml-audit-stream+xml",
"application/vnd.radisys.msml-audit+xml",
"application/vnd.radisys.msml-conf+xml",
"application/vnd.radisys.msml-dialog-base+xml",
"application/vnd.radisys.msml-dialog-fax-detect+xml",
"application/vnd.radisys.msml-dialog-fax-sendrecv+xml",
"application/vnd.radisys.msml-dialog-group+xml",
"application/vnd.radisys.msml-dialog-speech+xml",
"application/vnd.radisys.msml-dialog-transform+xml",
"application/vnd.radisys.msml-dialog+xml",
"application/vnd.radisys.msml+xml",
"application/vnd.recordare.musicxml+xml",
"application/vnd.route66.link66+xml",
"application/vnd.software602.filler.form+xml",
"application/vnd.solent.sdkm+xml",
"application/vnd.sun.wadl+xml",
"application/vnd.sycle+xml",
"application/vnd.syncml.dmddf+xml",
"application/vnd.syncml.dmtnds+xml",
"application/vnd.syncml.dm+xml",
"application/vnd.syncml+xml",
"application/vnd.tmd.mediaflex.api+xml",
"application/vnd.uoml+xml",
"application/vnd.wv.csp+xml",
"application/vnd.wv.ssp+xml",
"application/vnd.xmi+xml",
"application/vnd.yamaha.openscoreformat.osfpvg+xml",
"application/vnd.zzazz.deck+xml",
"application/voicexml+xml",
"application/watcherinfo+xml",
"application/wsdl+xml",
"application/wspolicy+xml",
"application/xacml+xml",
"application/xcap-att+xml",
"application/xcap-caps+xml",
"application/xcap-diff+xml",
"application/xcap-el+xml",
"application/xcap-error+xml",
"application/xcap-ns+xml",
"application/xcon-conference-info-diff+xml",
"application/xcon-conference-info+xml",
"application/xenc+xml",
"application/xhtml+xml",
"application/xliff+xml",
"application/xml",
"application/xml-dtd",
"application/xml-external-parsed-entity",
"application/xml-patch+xml",
"application/xmpp+xml",
"application/xop+xml",
"application/xslt+xml",
"application/xv+xml",
"application/yang-data+xml",
"application/yang-patch+xml",
"application/yin+xml",
];
for mime in &mime_types {
assert!(is_xml(mime), "{mime} is a not a XML mime type");
}
}
} }