Skip to content

Commit

Permalink
Merge pull request #139 from ltratt/handle_both_content_types
Browse files Browse the repository at this point in the history
Handle both JSON and urlencoded requests.
  • Loading branch information
vext01 authored Jul 22, 2024
2 parents 4f94c26 + c6c814d commit e348342
Show file tree
Hide file tree
Showing 6 changed files with 146 additions and 23 deletions.
41 changes: 32 additions & 9 deletions src/httpserver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,19 +116,42 @@ fn request(snare: &Arc<Snare>, mut stream: TcpStream) {
None => None,
};

if !body.starts_with("payload=".as_bytes()) {
snare.warn("Payload does not start with 'payload='");
http_400(stream);
return;
}
let json_str = match percent_decode(&body[8..]).decode_utf8() {
Ok(x) => x.to_string(),
Err(_) => {
snare.warn("JSON not valid UTF-8");
let json_str = match headers.get("content-type").map(|x| x.as_str()) {
Some("application/json") => match std::str::from_utf8(&body) {
Ok(x) => x.to_owned(),
Err(_) => {
snare.warn("JSON not valid UTF-8");
http_400(stream);
return;
}
},
Some("application/x-www-form-urlencoded") => {
if !body.starts_with("payload=".as_bytes()) {
snare.warn("Payload does not start with 'payload='");
http_400(stream);
return;
}
match percent_decode(&body[8..]).decode_utf8() {
Ok(x) => x.to_string(),
Err(_) => {
snare.warn("JSON not valid UTF-8");
http_400(stream);
return;
}
}
}
Some(x) => {
snare.warn(&format!("HTTP request: Unknown Content-Type '{x}'"));
http_400(stream);
return;
}
None => {
snare.warn("HTTP request: Content-Type header missing");
http_400(stream);
return;
}
};

let jv = match serde_json::from_str::<serde_json::Value>(&json_str) {
Ok(x) => x,
Err(e) => {
Expand Down
12 changes: 6 additions & 6 deletions tests/actions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,17 +49,17 @@ github {{
Ok(format!(
r#"POST /payload HTTP/1.1
Host: 127.0.0.1:{port}
Content-Length: 104
Content-Length: 96
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature-256: sha256=292e1ce3568fecd98589c71938e19afee9b04b7fe11886d5478d802416bbde66
X-Hub-Signature-256: sha256=d11297e14fe5286dd68fd58c5e23ea7fb45e60ceff51ec3eb3729400fcbcb4b2
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
X-GitHub-Event: issues
X-GitHub-Hook-ID: 292430182
X-GitHub-Hook-Installation-Target-ID: 79929171
X-GitHub-Hook-Installation-Target-Type: repository
payload={{
{{
"repository": {{
"owner": {{
"login": "testuser"
Expand Down Expand Up @@ -115,17 +115,17 @@ github {{
Ok(format!(
r#"POST /payload HTTP/1.1
Host: 127.0.0.1:{port}
Content-Length: 104
Content-Length: 96
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature-256: sha256=292e1ce3568fecd98589c71938e19afee9b04b7fe11886d5478d802416bbde66
X-Hub-Signature-256: sha256=d11297e14fe5286dd68fd58c5e23ea7fb45e60ceff51ec3eb3729400fcbcb4b2
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
X-GitHub-Event: issues
X-GitHub-Hook-ID: 292430182
X-GitHub-Hook-Installation-Target-ID: 79929171
X-GitHub-Hook-Installation-Target-Type: repository
payload={{
{{
"repository": {{
"owner": {{
"login": "testuser"
Expand Down
8 changes: 4 additions & 4 deletions tests/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,15 @@ github {{

fn req(port: u16, good_sha256: bool, event_type: &str) -> String {
let sha256 = if good_sha256 {
"292e1ce3568fecd98589c71938e19afee9b04b7fe11886d5478d802416bbde66"
"d11297e14fe5286dd68fd58c5e23ea7fb45e60ceff51ec3eb3729400fcbcb4b2"
} else {
"292e1ce3568fecd98589c71938e19afee9b04b7fe11886d5478d802416bbde67"
"d11297e14fe5286dd68fd58c5e23ea7fb45e60ceff51ec3eb3729400fcbcb4b3"
};

format!(
r#"POST /payload HTTP/1.1
Host: 127.0.0.1:{port}
Content-Length: 104
Content-Length: 96
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature-256: sha256={sha256}
User-Agent: GitHub-Hookshot/044aadd
Expand All @@ -51,7 +51,7 @@ X-GitHub-Hook-ID: 292430182
X-GitHub-Hook-Installation-Target-ID: 79929171
X-GitHub-Hook-Installation-Target-Type: repository
payload={{
{{
"repository": {{
"owner": {{
"login": "testuser"
Expand Down
100 changes: 100 additions & 0 deletions tests/basic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::error::Error;

mod common;
use common::run_success;

#[test]
fn content_type_json() -> Result<(), Box<dyn Error>> {
run_success(
r#"
listen = "127.0.0.1:0";
github {
match ".*" {
cmd = "true";
secret = "secretsecret";
}
}
"#,
&[(
move |port| {
Ok(format!(
r#"POST /payload HTTP/1.1
Host: 127.0.0.1:{port}
Content-Length: 96
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature-256: sha256=d11297e14fe5286dd68fd58c5e23ea7fb45e60ceff51ec3eb3729400fcbcb4b2
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
X-GitHub-Event: issues
X-GitHub-Hook-ID: 292430182
X-GitHub-Hook-Installation-Target-ID: 79929171
X-GitHub-Hook-Installation-Target-Type: repository
{{
"repository": {{
"owner": {{
"login": "testuser"
}},
"name": "testrepo"
}}
}}"#
))
},
move |response: String| {
if response.starts_with("HTTP/1.1 200 OK") {
Ok(())
} else {
Err(format!("Received HTTP response '{response}'").into())
}
},
)],
)
}

#[test]
fn content_type_url_encoded() -> Result<(), Box<dyn Error>> {
run_success(
r#"
listen = "127.0.0.1:0";
github {
match ".*" {
cmd = "true";
secret = "secretsecret";
}
}
"#,
&[(
move |port| {
Ok(format!(
r#"POST /payload HTTP/1.1
Host: 127.0.0.1:{port}
Content-Length: 104
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature-256: sha256=292e1ce3568fecd98589c71938e19afee9b04b7fe11886d5478d802416bbde66
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/x-www-form-urlencoded
X-GitHub-Event: issues
X-GitHub-Hook-ID: 292430182
X-GitHub-Hook-Installation-Target-ID: 79929171
X-GitHub-Hook-Installation-Target-Type: repository
payload={{
"repository": {{
"owner": {{
"login": "testuser"
}},
"name": "testrepo"
}}
}}"#
))
},
move |response: String| {
if response.starts_with("HTTP/1.1 200 OK") {
Ok(())
} else {
Err(format!("Received HTTP response '{response}'").into())
}
},
)],
)
}
2 changes: 1 addition & 1 deletion tests/common/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ fn snare_command(cfg: &str) -> Result<(Child, NamedTempFile), Box<dyn Error>> {
let tp = Builder::new().tempfile_in(env!("CARGO_TARGET_TMPDIR"))?;
cmd.env("SNARE_DEBUG_PORT_PATH", tp.path().to_str().unwrap());
cmd.stdout(Stdio::piped()).stderr(Stdio::piped());
cmd.args(["-d", "-c", tc.path().to_str().unwrap()]);
cmd.args(["-d", "-v", "-c", tc.path().to_str().unwrap()]);
let sn = cmd.spawn()?;
// We want to wait for snare to fully initialise: there is no way of doing that other than
// waiting and hoping.
Expand Down
6 changes: 3 additions & 3 deletions tests/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,17 @@ fn run_queue(
Ok(format!(
r#"POST /payload HTTP/1.1
Host: 127.0.0.1:{port}
Content-Length: 104
Content-Length: 96
X-GitHub-Delivery: 72d3162e-cc78-11e3-81ab-4c9367dc0958
X-Hub-Signature-256: sha256=292e1ce3568fecd98589c71938e19afee9b04b7fe11886d5478d802416bbde66
X-Hub-Signature-256: sha256=d11297e14fe5286dd68fd58c5e23ea7fb45e60ceff51ec3eb3729400fcbcb4b2
User-Agent: GitHub-Hookshot/044aadd
Content-Type: application/json
X-GitHub-Event: issues
X-GitHub-Hook-ID: 292430182
X-GitHub-Hook-Installation-Target-ID: 79929171
X-GitHub-Hook-Installation-Target-Type: repository
payload={{
{{
"repository": {{
"owner": {{
"login": "testuser"
Expand Down

0 comments on commit e348342

Please sign in to comment.