diff --git a/README.md b/README.md index 006025a..27bb3e7 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,8 @@ docker run -it --platform linux/amd64 -p 9000:8080 --entrypoint /bin/bash oj-rus # to send command: curl "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}' + +# to get format for ^: https://github.com/brefphp/local-api-gateway/blob/main/src/apiGateway.ts ``` To upload to ECR @@ -86,11 +88,6 @@ Should benchmark this to determine how off the timings are / whether we can just misc todos ``` -// timeout: warning: disabling core dumps failed: Operation not permitted -// Command exited with non-zero status 137 -// UGH - -// also, internal server error when output too large // want smth like /* diff --git a/src/execute.rs b/src/execute.rs index 3e5a092..b6a8b62 100644 --- a/src/execute.rs +++ b/src/execute.rs @@ -1,4 +1,5 @@ use std::{ + cmp::min, fs::{self, File}, io::Write, path::Path, @@ -7,13 +8,14 @@ use std::{ use anyhow::{anyhow, Result}; use axum::Json; +use regex::Replacer; use serde::{Deserialize, Serialize}; use tempfile::{tempdir, NamedTempFile}; use crate::{ error::AppError, run_command::{run_command, CommandOptions}, - types::{Executable}, + types::Executable, }; use base64::{prelude::BASE64_STANDARD, Engine}; @@ -82,6 +84,45 @@ fn extract_zip(dir: &Path, base64_zip: &str) -> Result<()> { } } +fn truncate_response(mut response: ExecuteResponse) -> ExecuteResponse { + const MAX_LEN: usize = 5_800_000; + + let mut stdout = response.stdout; + let mut stderr = response.stderr; + let mut file_output = response.file_output; + + let mut file_output_len = 0; + + if file_output.is_some() { + let mut actual_file_output = file_output.unwrap(); + file_output_len = min(MAX_LEN / 3, actual_file_output.len()); + actual_file_output.truncate(file_output_len); + actual_file_output += "\n[Truncated]"; + file_output = Some(actual_file_output); + } + + let stderr_len = min((MAX_LEN - file_output_len) / 2, stderr.len()); + let stdout_len = min(MAX_LEN - stderr_len - file_output_len, stdout.len()); + + if stderr.len() > stderr_len { + // Note: This could panic if printing multi-byte characters! + stderr.truncate(stderr_len); + stderr += "\n[Truncated]"; + } + + if stdout.len() > stdout_len { + // Note: This could panic if printing multi-byte characters! + stdout.truncate(stdout_len); + stdout += "\n[Truncated]"; + } + + response.stdout = stdout; + response.stderr = stderr; + response.file_output = file_output; + + response +} + pub fn execute(payload: ExecuteRequest) -> Result { let tmp_dir = tempdir()?; @@ -102,7 +143,11 @@ pub fn execute(payload: ExecuteRequest) -> Result { timeout_ms: payload.options.timeout_ms, }; - let command_output = run_command(&payload.executable.run_command, tmp_dir.path(), command_options)?; + let command_output = run_command( + &payload.executable.run_command, + tmp_dir.path(), + command_options, + )?; let verdict = match command_output.exit_code { 124 => Verdict::TimeLimitExceeded, @@ -121,7 +166,7 @@ pub fn execute(payload: ExecuteRequest) -> Result { None }; - Ok(ExecuteResponse { + Ok(truncate_response(ExecuteResponse { stdout: command_output.stdout, file_output, stderr: command_output.stderr, @@ -130,7 +175,7 @@ pub fn execute(payload: ExecuteRequest) -> Result { exit_code: command_output.exit_code, exit_signal: command_output.exit_signal, verdict, - }) + })) } pub async fn execute_handler( diff --git a/src/run_command.rs b/src/run_command.rs index 90b979a..b410ebf 100644 --- a/src/run_command.rs +++ b/src/run_command.rs @@ -94,7 +94,7 @@ pub fn run_command( // use `brew install timeout` to install linux timeout on mac os "gtime -v timeout" } else { - "ulimit -c 0 && ulimit -s unlimited && /usr/bin/time -v /usr/bin/timeout" + "ulimit -s unlimited && /usr/bin/time -v /usr/bin/timeout" }, options.timeout_ms / 1000 ))