Skip to content

Commit

Permalink
codegen extracts http body
Browse files Browse the repository at this point in the history
  • Loading branch information
Autoparallel committed Sep 10, 2024
1 parent a05c41b commit 4645d59
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 8 deletions.
20 changes: 13 additions & 7 deletions circuits/test/http/codegen.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ describe("HTTP :: Codegen :: Request", async () => {
const lockData = await readLockFile<Request>(`${lockfile}.json`);
console.log("lockData: ", JSON.stringify(lockData));

const input = await readHTTPInputFile(`${inputfile}`).input
const input = await readHTTPInputFile(`${inputfile}`).input;

const headers = getHeaders(lockData);
const params = [input.length, lockData.method.length, lockData.target.length, lockData.version.length];
Expand Down Expand Up @@ -154,7 +154,7 @@ describe("HTTP :: Codegen :: Request", async () => {
});

describe("HTTP :: Codegen :: Response", async () => {
let circuit: WitnessTester<["data", "version", "status", "message", "header1", "value1", "header2", "value2"], []>;
let circuit: WitnessTester<["data", "version", "status", "message", "header1", "value1", "header2", "value2"], ["body"]>;

it("(valid) GET:", async () => {
let lockfile = "response.lock";
Expand All @@ -166,10 +166,12 @@ describe("HTTP :: Codegen :: Response", async () => {
const lockData = await readLockFile<Response>(`${lockfile}.json`);
console.log("lockData: ", JSON.stringify(lockData));

const input = await readHTTPInputFile(`${inputfile}`).input
const http = await readHTTPInputFile(`${inputfile}`);
const input = http.input;

const headers = getHeaders(lockData);
const params = [input.length, lockData.version.length, lockData.status.length, lockData.message.length];

const params = [input.length, parseInt(http.headers["Content-Length"]), lockData.version.length, lockData.status.length, lockData.message.length];
headers.forEach(header => {
params.push(header[0].length);
params.push(header[1].length);
Expand All @@ -195,7 +197,9 @@ describe("HTTP :: Codegen :: Response", async () => {
circuitInput[`header${index + 1}`] = toByte(header[0]);
circuitInput[`value${index + 1}`] = toByte(header[1]);
});
await circuit.expectPass(circuitInput, {});


await circuit.expectPass(circuitInput, { body: http.bodyBytes });
});

it("(invalid) GET:", async () => {
Expand All @@ -207,10 +211,12 @@ describe("HTTP :: Codegen :: Response", async () => {

const lockData = await readLockFile<Response>(`${lockfile}.json`);

const input = await readHTTPInputFile(`${inputfile}`).input
const http = await readHTTPInputFile(`${inputfile}`);
const input = http.input;

const headers = getHeaders(lockData);
const params = [input.length, lockData.version.length, lockData.status.length, lockData.message.length];

const params = [input.length, parseInt(http.headers["Content-Length"]), lockData.version.length, lockData.status.length, lockData.message.length];
headers.forEach(header => {
params.push(header[0].length);
params.push(header[1].length);
Expand Down
53 changes: 52 additions & 1 deletion src/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ fn build_http_circuit(
}
HttpData::Response(_) => {
circuit_buffer +=
"template LockHTTPResponse(DATA_BYTES, versionLen, statusLen, messageLen";
"template LockHTTPResponse(DATA_BYTES, maxContentLength, versionLen, statusLen, messageLen";
}
}

Expand Down Expand Up @@ -155,6 +155,19 @@ fn build_http_circuit(
}
}

// Create an output if circuit is for `Response`
{
if let HttpData::Response(_) = data {
circuit_buffer += r#"
// Set up mask bits for where the body of response lies
signal output body[maxContentLength];
signal bodyMask[DATA_BYTES];
bodyMask[0] <== 0;
"#;
}
}

// Setup for parsing the start line
{
match data {
Expand Down Expand Up @@ -233,6 +246,16 @@ fn build_http_circuit(
"#;
}

// If parsing a `Response`, create a mask of the body bytes
{
if let HttpData::Response(_) = data {
circuit_buffer += r#"
// Mask if parser is in the body of response
bodyMask[data_idx] <== data[data_idx] * State[data_idx].next_parsing_body;
"#;
}
}

// Start line matches
{
match data {
Expand Down Expand Up @@ -320,6 +343,34 @@ fn build_http_circuit(
"#;
}

// Get the output body bytes
{
if let HttpData::Response(_) = data {
circuit_buffer += r#"
signal bodyStartingIndex[DATA_BYTES];
signal isZeroMask[DATA_BYTES];
signal isPrevStartingIndex[DATA_BYTES];
bodyStartingIndex[0] <== 0;
isZeroMask[0] <== IsZero()(bodyMask[0]);
for (var i=1 ; i < DATA_BYTES; i++) {
isZeroMask[i] <== IsZero()(bodyMask[i]);
isPrevStartingIndex[i] <== IsZero()(bodyStartingIndex[i-1]);
bodyStartingIndex[i] <== bodyStartingIndex[i-1] + i * (1-isZeroMask[i]) * isPrevStartingIndex[i];
}
body <== SelectSubArray(DATA_BYTES, maxContentLength)(bodyMask, bodyStartingIndex[DATA_BYTES-1]+1, DATA_BYTES - bodyStartingIndex[DATA_BYTES-1]);
"#;
}
}

if debug {
circuit_buffer += r#"
for(var i = 0; i < maxContentLength; i++) {
log("body[", i, "] = ", body[i]);
}
"#;
}

// Verify all start line has matched
{
match data {
Expand Down

0 comments on commit 4645d59

Please sign in to comment.