summaryrefslogtreecommitdiff
path: root/c/wasi-http/0.2.0/env-var/component.c
blob: 1fff24588c7faf03695108e72f1b6a30ec608041 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* SPDX-License-Identifier: Apache-2.0 */

/*
 * component.c - Example of writing a wasi-http Wasm component
 *
 * Copyright (C) Andrew Clayton
 * Copyright (C) F5, Inc.
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

#include "proxy.h"

#define ex(...) \
	do { \
		printf(__VA_ARGS__); \
		exit(EXIT_FAILURE); \
	} while (0);

void exports_wasi_http_incoming_handler_handle(
	exports_wasi_http_incoming_handler_own_incoming_request_t request,
	exports_wasi_http_incoming_handler_own_response_outparam_t response_out)
{
	bool ok;
	FILE *out;
	size_t size;
	char *out_ptr;
	char clen[32];
	wasi_http_types_own_outgoing_response_t resp;
	wasi_http_types_borrow_outgoing_response_t b_resp;
	wasi_http_types_own_fields_t fields;
	wasi_http_types_borrow_fields_t b_fields;
	wasi_http_types_result_own_outgoing_response_error_code_t rerr = { };
	wasi_http_types_own_outgoing_body_t body;
	wasi_http_types_borrow_outgoing_body_t b_body;
	wasi_io_streams_own_output_stream_t out_stream;
	wasi_io_streams_borrow_output_stream_t b_out_stream;
	proxy_list_u8_t stream_data;
	wasi_io_streams_stream_error_t stream_err;
	wasi_http_types_header_error_t hdr_err;
	wasi_http_types_field_key_t key;
	wasi_http_types_field_value_t value;
	proxy_list_tuple2_string_string_t env;

	(void)request;

	out = open_memstream(&out_ptr, &size);

#define BUF_ADD(fmt, ...) \
	fprintf(out, fmt, ##__VA_ARGS__);

	BUF_ADD("*** Environment Variables ***\n\n");

	wasi_cli_environment_get_environment(&env);
	for (size_t i = 0; i < env.len; i++)
		BUF_ADD("%.*s=%.*s\n",
		       (int)env.ptr[i].f0.len, env.ptr[i].f0.ptr,
		       (int)env.ptr[i].f1.len, env.ptr[i].f1.ptr);

	fclose(out);

	fields = wasi_http_types_constructor_fields();
	b_fields = wasi_http_types_borrow_fields(fields);

	proxy_string_set((proxy_string_t *)&key, "Content-Type");
	proxy_string_set((proxy_string_t *)&value, "text/plain");

	proxy_string_set((proxy_string_t *)&key, "Content-Length");
	sprintf(clen, "%zu", size);
	proxy_string_set((proxy_string_t *)&value, clen);

	ok = wasi_http_types_method_fields_append(b_fields, &key, &value,
						  &hdr_err);
	if (!ok)
		ex("wasi_http_types_method_fields_append() failed\n");

	resp = wasi_http_types_constructor_outgoing_response(fields);
	rerr.val.ok = resp;

	b_resp = wasi_http_types_borrow_outgoing_response(resp);
	ok = wasi_http_types_method_outgoing_response_body(b_resp, &body);
	if (!ok)
		ex("wasi_http_types_method_outgoing_response_body() failed\n");
	b_body = wasi_http_types_borrow_outgoing_body(body);

	ok = wasi_http_types_method_outgoing_body_write(b_body, &out_stream);
	if (!ok)
		ex("wasi_http_types_method_outgoing_body_write() failed\n");
	b_out_stream = wasi_io_streams_borrow_output_stream(out_stream);

	stream_data.len = size;
	stream_data.ptr = (uint8_t *)out_ptr;
	ok = wasi_io_streams_method_output_stream_write(b_out_stream,
							&stream_data,
							&stream_err);
	if (!ok)
		ex("wasi_io_streams_method_output_stream_blocking_write_and_flush() failed\n");

	wasi_http_types_static_response_outparam_set(response_out, &rerr);

	free(out_ptr);
}