Add support for LINK, UNLINK, PURGE, LOCK, UNLOCK, PROPFIND and VIEW HTTP method

This commit is contained in:
jcamiel 2022-11-29 17:00:03 +01:00
parent e4bcf0b94f
commit 44f43bcf73
No known key found for this signature in database
GPG Key ID: 07FF11CFD55356CC
18 changed files with 250 additions and 28 deletions

View File

@ -7,7 +7,7 @@
<option name="HEX_PREFIX" value="" />
<option name="NUM_POSTFIXES" value="" />
</options>
<keywords keywords="GET;HEAD;POST;PUT;DELETE;CONNECT;DELETE;OPTIONS;TRACE;PATCH" ignore_case="false" />
<keywords keywords="GET;HEAD;POST;PUT;DELETE;CONNECT;DELETE;OPTIONS;TRACE;PATCH;LINK;UNLINK;PURGE;LOCK;UNLOCK;PROPFIND;VIEW" ignore_case="false" />
<keywords2 keywords="[Asserts];[Captures];[Cookies];[FormParams];[MultipartFormData];[QueryStringParams];[Options]" ignore_case="false" />
<keywords3 keywords="status;url;header;cookie;body;xpath;jsonpath;regex;variable;duration;sha256;md5;bytes;HTTP;HTTP/*;HTTP/1.0;HTTP/1.1;HTTP/2" ignore_case="false"/>
<keywords4 keywords="&lt;;&lt;=;==;!=;&gt;;&gt;=;contains;count;exists;includes;not;startsWith;endsWith;matches;isFloat;isBoolean;isString;isCollection" ignore_case="false" />

View File

@ -5,7 +5,7 @@ if exists("b:current_syntax")
finish
endif
syntax keyword method GET POST PUT DELETE CONNECT OPTIONS TRACE PATCH nextgroup=url skipwhite
syntax keyword method GET POST PUT DELETE CONNECT OPTIONS TRACE PATCH LINK UNLINK PURGE LOCK UNLOCK PROPFIND VIEW nextgroup=url skipwhite
syntax match url "\S\+" contained
syntax match version "HTTP" nextgroup=status skipwhite
syntax match version "HTTP/1\.0" nextgroup=status skipwhite

View File

@ -2,6 +2,6 @@ error: Parsing method
--> tests_error_parser/invalid_character_at_end.hurl:3:1
|
3 | XXX
| ^ the HTTP method is not valid. Available HTTP Methods are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE or PATCH
| ^ the HTTP method is not valid. Valid values are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH, LINK, UNLINK, PURGE, LOCK, UNLOCK, PROPFIND or VIEW
|

View File

@ -2,6 +2,6 @@ error: Parsing request section name
--> tests_error_parser/invalid_section.hurl:2:2
|
2 | [Asserts]
| ^ the section is not valid. Valid values are QueryStringParams, FormParams, MultipartFormData or Cookies
| ^ the section is not valid. Valid values are QueryStringParams, FormParams, MultipartFormData, Cookies or Options
|

View File

@ -2,6 +2,6 @@ error: Parsing request section name
--> tests_error_parser/section_name.hurl:2:2
|
2 | [Unknown]
| ^ the section is not valid. Valid values are QueryStringParams, FormParams, MultipartFormData or Cookies
| ^ the section is not valid. Valid values are QueryStringParams, FormParams, MultipartFormData, Cookies or Options
|

View File

@ -0,0 +1,16 @@
curl 'http://localhost:8000/methods/get'
curl 'http://localhost:8000/methods/head' --head
curl 'http://localhost:8000/methods/post' -X POST
curl 'http://localhost:8000/methods/put' -X PUT
curl 'http://localhost:8000/methods/delete' -X DELETE
curl 'http://localhost:8000/methods/connect' -X CONNECT
curl 'http://localhost:8000/methods/options' -X OPTIONS
curl 'http://localhost:8000/methods/trace' -X TRACE
curl 'http://localhost:8000/methods/patch' -X PATCH
curl 'http://localhost:8000/methods/link' -X LINK
curl 'http://localhost:8000/methods/unlink' -X UNLINK
curl 'http://localhost:8000/methods/purge' -X PURGE
curl 'http://localhost:8000/methods/lock' -X LOCK
curl 'http://localhost:8000/methods/unlock' -X UNLOCK
curl 'http://localhost:8000/methods/propfind' -X PROPFIND
curl 'http://localhost:8000/methods/view' -X VIEW

View File

@ -0,0 +1,48 @@
<pre><code class="language-hurl"><span class="hurl-entry"><span class="request"><span class="line"><span class="method">GET</span> <span class="url">http://localhost:8000/methods/get</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">HEAD</span> <span class="url">http://localhost:8000/methods/head</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">POST</span> <span class="url">http://localhost:8000/methods/post</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">PUT</span> <span class="url">http://localhost:8000/methods/put</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">DELETE</span> <span class="url">http://localhost:8000/methods/delete</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">CONNECT</span> <span class="url">http://localhost:8000/methods/connect</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">OPTIONS</span> <span class="url">http://localhost:8000/methods/options</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">TRACE</span> <span class="url">http://localhost:8000/methods/trace</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">PATCH</span> <span class="url">http://localhost:8000/methods/patch</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">LINK</span> <span class="url">http://localhost:8000/methods/link</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">UNLINK</span> <span class="url">http://localhost:8000/methods/unlink</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">PURGE</span> <span class="url">http://localhost:8000/methods/purge</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">LOCK</span> <span class="url">http://localhost:8000/methods/lock</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">UNLOCK</span> <span class="url">http://localhost:8000/methods/unlock</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">PROPFIND</span> <span class="url">http://localhost:8000/methods/propfind</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span><span class="hurl-entry"><span class="request"><span class="line"></span>
<span class="line"><span class="method">VIEW</span> <span class="url">http://localhost:8000/methods/view</span></span>
</span><span class="response"><span class="line"><span class="version">HTTP</span> <span class="number">200</span></span>
</span></span></code></pre>

View File

@ -0,0 +1,47 @@
GET http://localhost:8000/methods/get
HTTP 200
HEAD http://localhost:8000/methods/head
HTTP 200
POST http://localhost:8000/methods/post
HTTP 200
PUT http://localhost:8000/methods/put
HTTP 200
DELETE http://localhost:8000/methods/delete
HTTP 200
CONNECT http://localhost:8000/methods/connect
HTTP 200
OPTIONS http://localhost:8000/methods/options
HTTP 200
TRACE http://localhost:8000/methods/trace
HTTP 200
PATCH http://localhost:8000/methods/patch
HTTP 200
LINK http://localhost:8000/methods/link
HTTP 200
UNLINK http://localhost:8000/methods/unlink
HTTP 200
PURGE http://localhost:8000/methods/purge
HTTP 200
LOCK http://localhost:8000/methods/lock
HTTP 200
UNLOCK http://localhost:8000/methods/unlock
HTTP 200
PROPFIND http://localhost:8000/methods/propfind
HTTP 200
VIEW http://localhost:8000/methods/view
HTTP 200

View File

@ -0,0 +1 @@
{"entries":[{"request":{"method":"GET","url":"http://localhost:8000/methods/get"},"response":{"status":200}},{"request":{"method":"HEAD","url":"http://localhost:8000/methods/head"},"response":{"status":200}},{"request":{"method":"POST","url":"http://localhost:8000/methods/post"},"response":{"status":200}},{"request":{"method":"PUT","url":"http://localhost:8000/methods/put"},"response":{"status":200}},{"request":{"method":"DELETE","url":"http://localhost:8000/methods/delete"},"response":{"status":200}},{"request":{"method":"CONNECT","url":"http://localhost:8000/methods/connect"},"response":{"status":200}},{"request":{"method":"OPTIONS","url":"http://localhost:8000/methods/options"},"response":{"status":200}},{"request":{"method":"TRACE","url":"http://localhost:8000/methods/trace"},"response":{"status":200}},{"request":{"method":"PATCH","url":"http://localhost:8000/methods/patch"},"response":{"status":200}},{"request":{"method":"LINK","url":"http://localhost:8000/methods/link"},"response":{"status":200}},{"request":{"method":"UNLINK","url":"http://localhost:8000/methods/unlink"},"response":{"status":200}},{"request":{"method":"PURGE","url":"http://localhost:8000/methods/purge"},"response":{"status":200}},{"request":{"method":"LOCK","url":"http://localhost:8000/methods/lock"},"response":{"status":200}},{"request":{"method":"UNLOCK","url":"http://localhost:8000/methods/unlock"},"response":{"status":200}},{"request":{"method":"PROPFIND","url":"http://localhost:8000/methods/propfind"},"response":{"status":200}},{"request":{"method":"VIEW","url":"http://localhost:8000/methods/view"},"response":{"status":200}}]}

View File

@ -0,0 +1,81 @@
from app import app
@app.route("/methods/get")
def method_get():
return ""
@app.route("/methods/head")
def method_head():
return ""
@app.route("/methods/post", methods=["POST"])
def method_post():
return ""
@app.route("/methods/put", methods=["PUT"])
def method_put():
return ""
@app.route("/methods/delete", methods=["DELETE"])
def method_delete():
return ""
@app.route("/methods/connect", methods=["CONNECT"])
def method_connect():
return ""
@app.route("/methods/options", methods=["OPTIONS"])
def method_options():
return ""
@app.route("/methods/trace", methods=["TRACE"])
def method_trace():
return ""
@app.route("/methods/patch", methods=["PATCH"])
def method_patch():
return ""
@app.route("/methods/link", methods=["LINK"])
def method_link():
return ""
@app.route("/methods/unlink", methods=["UNLINK"])
def method_unlink():
return ""
@app.route("/methods/purge", methods=["PURGE"])
def method_purge():
return ""
@app.route("/methods/lock", methods=["LOCK"])
def method_lock():
return ""
@app.route("/methods/unlock", methods=["UNLOCK"])
def method_unlock():
return ""
@app.route("/methods/propfind", methods=["PROPFIND"])
def method_propfind():
return ""
@app.route("/methods/view", methods=["VIEW"])
def method_view():
return ""

View File

@ -385,17 +385,9 @@ impl Client {
/// Sets HTTP method.
fn set_method(&mut self, method: &Method) {
match method {
Method::Get => self.handle.custom_request("GET").unwrap(),
Method::Post => self.handle.custom_request("POST").unwrap(),
Method::Put => self.handle.custom_request("PUT").unwrap(),
Method::Head => self.handle.custom_request("HEAD").unwrap(),
Method::Delete => self.handle.custom_request("DELETE").unwrap(),
Method::Connect => self.handle.custom_request("CONNECT").unwrap(),
Method::Options => self.handle.custom_request("OPTIONS").unwrap(),
Method::Trace => self.handle.custom_request("TRACE").unwrap(),
Method::Patch => self.handle.custom_request("PATCH").unwrap(),
}
self.handle
.custom_request(method.to_string().as_str())
.unwrap()
}
/// Sets HTTP headers.

View File

@ -45,6 +45,13 @@ pub enum Method {
Options,
Trace,
Patch,
Link,
Unlink,
Purge,
Lock,
Unlock,
Propfind,
View,
}
#[derive(Clone, Debug, PartialEq, Eq)]
@ -97,6 +104,13 @@ impl fmt::Display for Method {
Method::Options => "OPTIONS",
Method::Trace => "TRACE",
Method::Patch => "PATCH",
Method::Link => "LINK",
Method::Unlink => "UNLINK",
Method::Purge => "PURGE",
Method::Lock => "LOCK",
Method::Unlock => "UNLOCK",
Method::Propfind => "PROPFIND",
Method::View => "VIEW",
};
write!(f, "{}", value)
}

View File

@ -126,12 +126,7 @@ impl Method {
vec!["-X".to_string(), "POST".to_string()]
}
}
Method::Put => vec!["-X".to_string(), "PUT".to_string()],
Method::Delete => vec!["-X".to_string(), "DELETE".to_string()],
Method::Connect => vec!["-X".to_string(), "CONNECT".to_string()],
Method::Options => vec!["-X".to_string(), "OPTIONS".to_string()],
Method::Trace => vec!["-X".to_string(), "TRACE".to_string()],
Method::Patch => vec!["-X".to_string(), "PATCH".to_string()],
_ => vec!["-X".to_string(), self.to_string()],
}
}
}

View File

@ -173,6 +173,13 @@ fn eval_method(method: &Method) -> http::Method {
Method::Options => http::Method::Options,
Method::Trace => http::Method::Trace,
Method::Patch => http::Method::Patch,
Method::Link => http::Method::Link,
Method::Unlink => http::Method::Unlink,
Method::Purge => http::Method::Purge,
Method::Lock => http::Method::Lock,
Method::Unlock => http::Method::Unlock,
Method::Propfind => http::Method::Propfind,
Method::View => http::Method::View,
}
}

View File

@ -138,6 +138,13 @@ pub enum Method {
Options,
Trace,
Patch,
Link,
Unlink,
Purge,
Lock,
Unlock,
Propfind,
View,
}
#[derive(Clone, Debug, PartialEq, Eq)]

View File

@ -30,6 +30,13 @@ impl fmt::Display for Method {
Method::Options => "OPTIONS",
Method::Trace => "TRACE",
Method::Patch => "PATCH",
Method::Link => "LINK",
Method::Unlink => "UNLINK",
Method::Purge => "PURGE",
Method::Lock => "LOCK",
Method::Unlock => "UNLOCK",
Method::Propfind => "PROPFIND",
Method::View => "VIEW",
};
write!(f, "{}", s)
}

View File

@ -68,9 +68,9 @@ impl Error for parser::Error {
match self.inner.clone() {
ParseError::Method { name }
=> format!("the HTTP method is not valid. {}", did_you_mean(
&["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH"],
&["GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE", "PATCH", "LINK", "UNLINK", "PURGE", "LOCK", "UNLOCK", "PROPFIND", "VIEW"],
name.as_str(),
"Available HTTP Methods are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE or PATCH",
"Valid values are GET, HEAD, POST, PUT, DELETE, CONNECT, OPTIONS, TRACE, PATCH, LINK, UNLINK, PURGE, LOCK, UNLOCK, PROPFIND or VIEW",
)),
ParseError::Version { .. } => "HTTP version must be HTTP, HTTP/1.0, HTTP/1.1 or HTTP/2".to_string(),
ParseError::Status { .. } => "HTTP status code is not valid".to_string(),
@ -79,9 +79,9 @@ impl Error for parser::Error {
ParseError::Space { .. } => "expecting a space".to_string(),
ParseError::RequestSectionName { name }
=> format!("the section is not valid. {}", did_you_mean(
&["QueryStringParams", "FormParams", "MultipartFormData", "Cookies"],
&["QueryStringParams", "FormParams", "MultipartFormData", "Cookies", "Options"],
name.as_str(),
"Valid values are QueryStringParams, FormParams, MultipartFormData or Cookies",
"Valid values are QueryStringParams, FormParams, MultipartFormData, Cookies or Options",
)),
ParseError::ResponseSectionName { name }
=> format!("the section is not valid. {}", did_you_mean(

View File

@ -135,7 +135,7 @@ fn method(reader: &mut Reader) -> ParseResult<'static, Method> {
}
let start = reader.state.clone();
let name = reader.read_while(|c| c.is_alphanumeric());
let available_methods = vec![
let available_methods = [
("GET", Method::Get),
("HEAD", Method::Head),
("POST", Method::Post),
@ -145,9 +145,16 @@ fn method(reader: &mut Reader) -> ParseResult<'static, Method> {
("OPTIONS", Method::Options),
("TRACE", Method::Trace),
("PATCH", Method::Patch),
("LINK", Method::Link),
("UNLINK", Method::Unlink),
("PURGE", Method::Purge),
("LOCK", Method::Lock),
("UNLOCK", Method::Unlock),
("PROPFIND", Method::Propfind),
("VIEW", Method::View),
];
for (s, method) in available_methods {
for (s, method) in available_methods.into_iter() {
if name == s {
return Ok(method);
}