@@ -123,6 +123,26 @@ post_runtime_response() {
123123 esac
124124}
125125
126+ post_streaming_response () {
127+ url=$1
128+ payload=$2
129+ http_code=$( curl -sS -o /dev/null -w ' %{http_code}' -X POST \
130+ -H " Lambda-Runtime-Function-Response-Mode: streaming" \
131+ -H " Trailer: Lambda-Runtime-Function-Error-Type, Lambda-Runtime-Function-Error-Body" \
132+ --data-binary @- " $url " < " $payload " )
133+ curl_status=$?
134+ if [ " $curl_status " -ne 0 ]; then
135+ http_code=000
136+ fi
137+ case " $http_code " in
138+ 2?? ) return 0 ;;
139+ * )
140+ log " Failed to post runtime streaming response to $url (HTTP $http_code )"
141+ return 1
142+ ;;
143+ esac
144+ }
145+
126146post_init_error () {
127147 message=$1
128148 error_type=$2
@@ -171,6 +191,55 @@ post_response() {
171191 " $response_file "
172192}
173193
194+ stream_response () {
195+ request_id=$1
196+ stderr_file=$2
197+ shift 2
198+
199+ response_pipe=$( make_temp_file) || {
200+ log " Failed to create response pipe"
201+ return 1
202+ }
203+ rm -f " $response_pipe "
204+ if ! mkfifo " $response_pipe " ; then
205+ log " Failed to create response pipe"
206+ return 1
207+ fi
208+
209+ post_streaming_response \
210+ " http://${runtime_api} /2018-06-01/runtime/invocation/${request_id} /response" \
211+ " $response_pipe " &
212+ post_pid=$!
213+
214+ if run_with_stderr_capture " $stderr_file " " $@ " > " $response_pipe " ; then
215+ handler_exit=0
216+ else
217+ handler_exit=$?
218+ fi
219+
220+ if wait " $post_pid " ; then
221+ post_status=0
222+ else
223+ post_status=$?
224+ fi
225+
226+ rm -f " $response_pipe "
227+
228+ if [ " $handler_exit " -eq 0 ]; then
229+ if [ " $post_status " -eq 0 ]; then
230+ return 0
231+ fi
232+ return 1
233+ fi
234+
235+ log " Handler exited with status ${handler_exit} "
236+ set_error_from_stderr " $stderr_file " " $handler_exit "
237+ if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
238+ return 1
239+ fi
240+ return 0
241+ }
242+
174243# Capture handler stderr while streaming it to the runtime logs.
175244run_with_stderr_capture () {
176245 stderr_file=$1
@@ -331,6 +400,7 @@ while :; do
331400 trace_id=$( header_value " $headers " " Lambda-Runtime-Trace-Id" )
332401 client_context=$( header_value " $headers " " Lambda-Runtime-Client-Context" )
333402 cognito_identity=$( header_value " $headers " " Lambda-Runtime-Cognito-Identity" )
403+ response_mode=$( header_value " $headers " " Lambda-Runtime-Function-Response-Mode" )
334404
335405 set_invocation_env " LAMBDA_RUNTIME_AWS_REQUEST_ID" " $request_id "
336406 set_invocation_env " LAMBDA_RUNTIME_DEADLINE_MS" " $deadline_ms "
@@ -344,48 +414,69 @@ while :; do
344414 stderr_file=$( mktemp)
345415 if [ " $handler_mode " = " function" ]; then
346416 event_data=$( cat " $body " )
347- if run_with_stderr_capture " $stderr_file " " $handler_func " " $event_data " > " $response " ; then
348- if ! post_response " $request_id " " $response " ; then
417+ if [ " $response_mode " = " streaming " ] ; then
418+ if ! stream_response " $request_id " " $stderr_file " " $handler_func " " $event_data " ; then
349419 rm -f " $headers " " $body " " $response " " $stderr_file "
350420 exit 1
351421 fi
352422 else
353- handler_exit=$?
354- log " Handler exited with status ${handler_exit} "
355- set_error_from_stderr " $stderr_file " " $handler_exit "
356- if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
357- rm -f " $headers " " $body " " $response " " $stderr_file "
358- exit 1
423+ if run_with_stderr_capture " $stderr_file " " $handler_func " " $event_data " > " $response " ; then
424+ if ! post_response " $request_id " " $response " ; then
425+ rm -f " $headers " " $body " " $response " " $stderr_file "
426+ exit 1
427+ fi
428+ else
429+ handler_exit=$?
430+ log " Handler exited with status ${handler_exit} "
431+ set_error_from_stderr " $stderr_file " " $handler_exit "
432+ if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
433+ rm -f " $headers " " $body " " $response " " $stderr_file "
434+ exit 1
435+ fi
359436 fi
360437 fi
361438 elif [ " $handler_mode " = " executable" ]; then
362- if run_with_stderr_capture " $stderr_file " " $handler_path " < " $body " > " $response " ; then
363- if ! post_response " $request_id " " $response " ; then
439+ if [ " $response_mode " = " streaming " ] ; then
440+ if ! stream_response " $request_id " " $stderr_file " " $handler_path " < " $body " ; then
364441 rm -f " $headers " " $body " " $response " " $stderr_file "
365442 exit 1
366443 fi
367444 else
368- handler_exit=$?
369- log " Handler exited with status ${handler_exit} "
370- set_error_from_stderr " $stderr_file " " $handler_exit "
371- if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
372- rm -f " $headers " " $body " " $response " " $stderr_file "
373- exit 1
445+ if run_with_stderr_capture " $stderr_file " " $handler_path " < " $body " > " $response " ; then
446+ if ! post_response " $request_id " " $response " ; then
447+ rm -f " $headers " " $body " " $response " " $stderr_file "
448+ exit 1
449+ fi
450+ else
451+ handler_exit=$?
452+ log " Handler exited with status ${handler_exit} "
453+ set_error_from_stderr " $stderr_file " " $handler_exit "
454+ if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
455+ rm -f " $headers " " $body " " $response " " $stderr_file "
456+ exit 1
457+ fi
374458 fi
375459 fi
376460 else
377- if run_with_stderr_capture " $stderr_file " sh " $handler_path " < " $body " > " $response " ; then
378- if ! post_response " $request_id " " $response " ; then
461+ if [ " $response_mode " = " streaming " ] ; then
462+ if ! stream_response " $request_id " " $stderr_file " sh " $handler_path " < " $body " ; then
379463 rm -f " $headers " " $body " " $response " " $stderr_file "
380464 exit 1
381465 fi
382466 else
383- handler_exit=$?
384- log " Handler exited with status ${handler_exit} "
385- set_error_from_stderr " $stderr_file " " $handler_exit "
386- if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
387- rm -f " $headers " " $body " " $response " " $stderr_file "
388- exit 1
467+ if run_with_stderr_capture " $stderr_file " sh " $handler_path " < " $body " > " $response " ; then
468+ if ! post_response " $request_id " " $response " ; then
469+ rm -f " $headers " " $body " " $response " " $stderr_file "
470+ exit 1
471+ fi
472+ else
473+ handler_exit=$?
474+ log " Handler exited with status ${handler_exit} "
475+ set_error_from_stderr " $stderr_file " " $handler_exit "
476+ if ! post_invoke_error " $request_id " " $error_message " " $error_type " " $stack_trace " ; then
477+ rm -f " $headers " " $body " " $response " " $stderr_file "
478+ exit 1
479+ fi
389480 fi
390481 fi
391482 fi
0 commit comments