more organization and add some documentation to the awshttp module
This commit is contained in:
parent
05fcc5755e
commit
a732bc14db
330
src/awshttp.zig
330
src/awshttp.zig
|
@ -1,3 +1,12 @@
|
||||||
|
//! This module provides a low level http interface for working with AWS
|
||||||
|
//! It also provides an option to operate outside the AWS ecosystem through
|
||||||
|
//! the makeRequest call with a null signingOptions.
|
||||||
|
//!
|
||||||
|
//! Typical usage:
|
||||||
|
//! const client = awshttp.AwsHttp.init(allocator);
|
||||||
|
//! defer client.deinit()
|
||||||
|
//! const result = client.callApi (or client.makeRequest)
|
||||||
|
//! defer result.deinit();
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const c = @cImport({
|
const c = @cImport({
|
||||||
@cInclude("bitfield-workaround.h");
|
@cInclude("bitfield-workaround.h");
|
||||||
|
@ -66,6 +75,7 @@ pub const SigningOptions = struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
const HttpResult = struct {
|
const HttpResult = struct {
|
||||||
|
response_code: u16, // actually 3 digits can fit in u10
|
||||||
body: []const u8,
|
body: []const u8,
|
||||||
pub fn deinit(self: HttpResult) void {
|
pub fn deinit(self: HttpResult) void {
|
||||||
httplog.debug("http result deinit complete", .{});
|
httplog.debug("http result deinit complete", .{});
|
||||||
|
@ -218,6 +228,10 @@ pub const AwsHttp = struct {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// callApi allows the calling of AWS APIs through a higher-level interface.
|
||||||
|
/// It will calculate the appropriate endpoint and action parameters for the
|
||||||
|
/// service called, and will set up the signing options. The return
|
||||||
|
/// value is simply a raw HttpResult
|
||||||
pub fn callApi(self: Self, service: []const u8, version: []const u8, action: []const u8, options: Options) !HttpResult {
|
pub fn callApi(self: Self, service: []const u8, version: []const u8, action: []const u8, options: Options) !HttpResult {
|
||||||
const endpoint = try regionSubDomain(self.allocator, service, options.region, options.dualstack);
|
const endpoint = try regionSubDomain(self.allocator, service, options.region, options.dualstack);
|
||||||
defer endpoint.deinit();
|
defer endpoint.deinit();
|
||||||
|
@ -231,89 +245,24 @@ pub const AwsHttp = struct {
|
||||||
return try self.makeRequest(endpoint, "POST", "/", body, signing_options);
|
return try self.makeRequest(endpoint, "POST", "/", body, signing_options);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signRequest(self: Self, http_request: *c.aws_http_message, options: SigningOptions) !void {
|
/// makeRequest is a low level http/https function that can be used inside
|
||||||
const creds = try self.getCredentials();
|
/// or outside the context of AWS services. To use it outside AWS, simply
|
||||||
defer c.aws_credentials_release(creds);
|
/// pass a null value in for signing_options.
|
||||||
// print the access key. Creds are an opaque C type, so we
|
///
|
||||||
// use aws_credentials_get_access_key_id. That gets us an aws_byte_cursor,
|
/// Otherwise, it will simply take a URL endpoint (without path information),
|
||||||
// from which we create a new aws_string with the contents. We need
|
/// HTTP method (e.g. GET, POST, etc.), and request body.
|
||||||
// to convert to c_str with aws_string_c_str
|
///
|
||||||
const access_key = c.aws_string_new_from_cursor(c_allocator, &c.aws_credentials_get_access_key_id(creds));
|
/// At the moment this does not allow the controlling of headers
|
||||||
defer c.aws_mem_release(c_allocator, access_key);
|
/// This is likely to change. Current headers are:
|
||||||
// defer c_allocator.*.mem_release.?(c_allocator, access_key);
|
///
|
||||||
httplog.debug("Signing with access key: {s}", .{c.aws_string_c_str(access_key)});
|
/// Accept: application/json
|
||||||
|
/// User-Agent: zig-aws 1.0, Powered by the AWS Common Runtime.
|
||||||
const signable = c.aws_signable_new_http_request(c_allocator, http_request);
|
/// Content-Type: application/x-www-form-urlencoded
|
||||||
if (signable == null) {
|
/// Content-Length: (length of body)
|
||||||
httplog.warn("Could not create signable request", .{});
|
///
|
||||||
return AwsError.SignableError;
|
/// Return value is an HttpResult, which will need the caller to deinit().
|
||||||
}
|
/// HttpResult currently contains the body only. The addition of Headers
|
||||||
defer c.aws_signable_destroy(signable);
|
/// and return code would be a relatively minor change
|
||||||
|
|
||||||
const signing_region = try std.fmt.allocPrint(self.allocator, "{s}", .{options.region});
|
|
||||||
defer self.allocator.free(signing_region);
|
|
||||||
const signing_service = try std.fmt.allocPrint(self.allocator, "{s}", .{options.service});
|
|
||||||
defer self.allocator.free(signing_service);
|
|
||||||
const temp_signing_config = c.bitfield_workaround_aws_signing_config_aws{
|
|
||||||
.algorithm = .AWS_SIGNING_ALGORITHM_V4,
|
|
||||||
.config_type = .AWS_SIGNING_CONFIG_AWS,
|
|
||||||
.signature_type = .AWS_ST_HTTP_REQUEST_HEADERS,
|
|
||||||
.region = c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, signing_region)),
|
|
||||||
.service = c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, signing_service)),
|
|
||||||
.should_sign_header = null,
|
|
||||||
.should_sign_header_ud = null,
|
|
||||||
.flags = c.bitfield_workaround_aws_signing_config_aws_flags{
|
|
||||||
.use_double_uri_encode = 0,
|
|
||||||
.should_normalize_uri_path = 0,
|
|
||||||
.omit_session_token = 1,
|
|
||||||
},
|
|
||||||
.signed_body_value = c.aws_byte_cursor_from_c_str(""),
|
|
||||||
.signed_body_header = .AWS_SBHT_X_AMZ_CONTENT_SHA256, //or AWS_SBHT_NONE
|
|
||||||
.credentials = creds,
|
|
||||||
.credentials_provider = self.credentialsProvider,
|
|
||||||
.expiration_in_seconds = 0,
|
|
||||||
};
|
|
||||||
var signing_config = c.new_aws_signing_config(c_allocator, &temp_signing_config);
|
|
||||||
defer c.aws_mem_release(c_allocator, signing_config);
|
|
||||||
var signing_result = AwsAsyncCallbackResult(c.aws_http_message){ .result = http_request };
|
|
||||||
var sign_result_request = AsyncResult(AwsAsyncCallbackResult(c.aws_http_message)){ .result = &signing_result };
|
|
||||||
if (c.aws_sign_request_aws(c_allocator, signable, fullCast([*c]const c.aws_signing_config_base, signing_config), signComplete, &sign_result_request) != c.AWS_OP_SUCCESS) {
|
|
||||||
const error_code = c.aws_last_error();
|
|
||||||
httplog.alert("Could not initiate signing request: {s}:{s}", .{ c.aws_error_name(error_code), c.aws_error_str(error_code) });
|
|
||||||
return AwsError.SigningInitiationError;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for callback. Note that execution, including real work of signing
|
|
||||||
// the http request, will continue in signComplete (below),
|
|
||||||
// then continue beyond this line
|
|
||||||
waitOnCallback(c.aws_http_message, &sign_result_request);
|
|
||||||
if (sign_result_request.result.error_code != c.AWS_ERROR_SUCCESS) {
|
|
||||||
return AwsError.SignableError;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// It's my theory that the aws event loop has a trigger to corrupt the
|
|
||||||
/// signing result after this call completes. So the technique of assigning
|
|
||||||
/// now, using later will not work
|
|
||||||
fn signComplete(result: ?*c.aws_signing_result, error_code: c_int, user_data: ?*c_void) callconv(.C) void {
|
|
||||||
var async_result = userDataTo(AsyncResult(AwsAsyncCallbackResult(c.aws_http_message)), user_data);
|
|
||||||
var http_request = async_result.result.result;
|
|
||||||
async_result.sync.store(true, .SeqCst);
|
|
||||||
|
|
||||||
async_result.count += 1;
|
|
||||||
async_result.result.error_code = error_code;
|
|
||||||
|
|
||||||
if (result) |res| {
|
|
||||||
if (c.aws_apply_signing_result_to_http_request(http_request, c_allocator, result) != c.AWS_OP_SUCCESS) {
|
|
||||||
httplog.alert("Could not apply signing request to http request: {s}", .{c.aws_error_debug_str(c.aws_last_error())});
|
|
||||||
}
|
|
||||||
httplog.debug("signing result applied", .{});
|
|
||||||
} else {
|
|
||||||
httplog.alert("Did not receive signing result: {s}", .{c.aws_error_debug_str(c.aws_last_error())});
|
|
||||||
}
|
|
||||||
async_result.sync.store(false, .SeqCst);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn makeRequest(self: Self, endpoint: EndPoint, method: []const u8, path: []const u8, body: []const u8, signing_options: ?SigningOptions) !HttpResult {
|
pub fn makeRequest(self: Self, endpoint: EndPoint, method: []const u8, path: []const u8, body: []const u8, signing_options: ?SigningOptions) !HttpResult {
|
||||||
// TODO: Try to re-encapsulate this
|
// TODO: Try to re-encapsulate this
|
||||||
// var http_request = try createRequest(method, path, body);
|
// var http_request = try createRequest(method, path, body);
|
||||||
|
@ -321,9 +270,6 @@ pub const AwsHttp = struct {
|
||||||
// TODO: Likely this should be encapsulated more
|
// TODO: Likely this should be encapsulated more
|
||||||
var http_request = c.aws_http_message_new_request(c_allocator);
|
var http_request = c.aws_http_message_new_request(c_allocator);
|
||||||
defer c.aws_http_message_release(http_request);
|
defer c.aws_http_message_release(http_request);
|
||||||
// TODO: Verify if AWS cares about these headers (probably should be passing them...)
|
|
||||||
// Accept-Encoding: identity
|
|
||||||
// Content-Type: application/x-www-form-urlencoded
|
|
||||||
|
|
||||||
if (c.aws_http_message_set_request_method(http_request, c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, method))) != c.AWS_OP_SUCCESS)
|
if (c.aws_http_message_set_request_method(http_request, c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, method))) != c.AWS_OP_SUCCESS)
|
||||||
return AwsError.SetRequestMethodError;
|
return AwsError.SetRequestMethodError;
|
||||||
|
@ -453,8 +399,6 @@ pub const AwsHttp = struct {
|
||||||
.request = http_request,
|
.request = http_request,
|
||||||
};
|
};
|
||||||
|
|
||||||
// C code
|
|
||||||
// app_ctx->response_code_written = false;
|
|
||||||
const stream = c.aws_http_connection_make_request(context.connection, &request_options);
|
const stream = c.aws_http_connection_make_request(context.connection, &request_options);
|
||||||
if (stream == null) {
|
if (stream == null) {
|
||||||
httplog.alert("failed to create request.", .{});
|
httplog.alert("failed to create request.", .{});
|
||||||
|
@ -484,7 +428,12 @@ pub const AwsHttp = struct {
|
||||||
if (context.body) |b| {
|
if (context.body) |b| {
|
||||||
final_body = b;
|
final_body = b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Headers would need to be allocated/copied into HttpResult similar
|
||||||
|
// to RequestContext, so we'll leave this as a later excercise
|
||||||
|
// if it becomes necessary
|
||||||
const rc = HttpResult{
|
const rc = HttpResult{
|
||||||
|
.response_code = context.response_code.?,
|
||||||
.body = final_body,
|
.body = final_body,
|
||||||
};
|
};
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -495,9 +444,6 @@ pub const AwsHttp = struct {
|
||||||
fn createRequest(method: []const u8, path: []const u8, body: []const u8) !*c.aws_http_message {
|
fn createRequest(method: []const u8, path: []const u8, body: []const u8) !*c.aws_http_message {
|
||||||
// TODO: Likely this should be encapsulated more
|
// TODO: Likely this should be encapsulated more
|
||||||
var http_request = c.aws_http_message_new_request(c_allocator);
|
var http_request = c.aws_http_message_new_request(c_allocator);
|
||||||
// TODO: Verify if AWS cares about these headers (probably should be passing them...)
|
|
||||||
// Accept-Encoding: identity
|
|
||||||
// Content-Type: application/x-www-form-urlencoded
|
|
||||||
|
|
||||||
if (c.aws_http_message_set_request_method(http_request, c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, method))) != c.AWS_OP_SUCCESS)
|
if (c.aws_http_message_set_request_method(http_request, c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, method))) != c.AWS_OP_SUCCESS)
|
||||||
return AwsError.SetRequestMethodError;
|
return AwsError.SetRequestMethodError;
|
||||||
|
@ -511,6 +457,149 @@ pub const AwsHttp = struct {
|
||||||
c.aws_http_message_set_body_stream(http_request, request_body);
|
c.aws_http_message_set_body_stream(http_request, request_body);
|
||||||
return http_request.?;
|
return http_request.?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Re-encapsulate or delete this function. It is not currently
|
||||||
|
// used and will not be touched by the compiler
|
||||||
|
fn setupTls(self: Self, host: []const u8) !*c.aws_tls_connection_options {
|
||||||
|
if (tls_ctx_options == null) {
|
||||||
|
httplog.debug("Setting up tls options", .{});
|
||||||
|
var opts: c.aws_tls_ctx_options = .{
|
||||||
|
.allocator = c_allocator,
|
||||||
|
.minimum_tls_version = @intToEnum(c.aws_tls_versions, c.AWS_IO_TLS_VER_SYS_DEFAULTS),
|
||||||
|
.cipher_pref = @intToEnum(c.aws_tls_cipher_pref, c.AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT),
|
||||||
|
.ca_file = c.aws_byte_buf_from_c_str(""),
|
||||||
|
.ca_path = c.aws_string_new_from_c_str(c_allocator, ""),
|
||||||
|
.alpn_list = null,
|
||||||
|
.certificate = c.aws_byte_buf_from_c_str(""),
|
||||||
|
.private_key = c.aws_byte_buf_from_c_str(""),
|
||||||
|
.max_fragment_size = 0,
|
||||||
|
.verify_peer = true,
|
||||||
|
};
|
||||||
|
tls_ctx_options = &opts;
|
||||||
|
|
||||||
|
c.aws_tls_ctx_options_init_default_client(tls_ctx_options.?, c_allocator);
|
||||||
|
// h2;http/1.1
|
||||||
|
if (c.aws_tls_ctx_options_set_alpn_list(tls_ctx_options, "http/1.1") != c.AWS_OP_SUCCESS) {
|
||||||
|
httplog.alert("Failed to load alpn list with error {s}.", .{c.aws_error_debug_str(c.aws_last_error())});
|
||||||
|
return AwsError.AlpnError;
|
||||||
|
}
|
||||||
|
|
||||||
|
tls_ctx = c.aws_tls_client_ctx_new(c_allocator, tls_ctx_options.?);
|
||||||
|
|
||||||
|
if (tls_ctx == null) {
|
||||||
|
std.debug.panic("Failed to initialize TLS context with error {s}.", .{c.aws_error_debug_str(c.aws_last_error())});
|
||||||
|
}
|
||||||
|
httplog.debug("tls options setup applied", .{});
|
||||||
|
}
|
||||||
|
|
||||||
|
var tls_connection_options = c.aws_tls_connection_options{
|
||||||
|
.alpn_list = null,
|
||||||
|
.server_name = null,
|
||||||
|
.on_negotiation_result = null,
|
||||||
|
.on_data_read = null,
|
||||||
|
.on_error = null,
|
||||||
|
.user_data = null,
|
||||||
|
.ctx = null,
|
||||||
|
.advertise_alpn_message = false,
|
||||||
|
.timeout_ms = 0,
|
||||||
|
};
|
||||||
|
c.aws_tls_connection_options_init_from_ctx(&tls_connection_options, tls_ctx);
|
||||||
|
var host_var = host;
|
||||||
|
var host_cur = c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, host_var));
|
||||||
|
if (c.aws_tls_connection_options_set_server_name(&tls_connection_options, c_allocator, &host_cur) != c.AWS_OP_SUCCESS) {
|
||||||
|
httplog.alert("Failed to set servername with error {s}.", .{c.aws_error_debug_str(c.aws_last_error())});
|
||||||
|
return AwsError.TlsError;
|
||||||
|
}
|
||||||
|
return &tls_connection_options;
|
||||||
|
|
||||||
|
// if (app_ctx.uri.port) {
|
||||||
|
// port = app_ctx.uri.port;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn signRequest(self: Self, http_request: *c.aws_http_message, options: SigningOptions) !void {
|
||||||
|
const creds = try self.getCredentials();
|
||||||
|
defer c.aws_credentials_release(creds);
|
||||||
|
// print the access key. Creds are an opaque C type, so we
|
||||||
|
// use aws_credentials_get_access_key_id. That gets us an aws_byte_cursor,
|
||||||
|
// from which we create a new aws_string with the contents. We need
|
||||||
|
// to convert to c_str with aws_string_c_str
|
||||||
|
const access_key = c.aws_string_new_from_cursor(c_allocator, &c.aws_credentials_get_access_key_id(creds));
|
||||||
|
defer c.aws_mem_release(c_allocator, access_key);
|
||||||
|
// defer c_allocator.*.mem_release.?(c_allocator, access_key);
|
||||||
|
httplog.debug("Signing with access key: {s}", .{c.aws_string_c_str(access_key)});
|
||||||
|
|
||||||
|
const signable = c.aws_signable_new_http_request(c_allocator, http_request);
|
||||||
|
if (signable == null) {
|
||||||
|
httplog.warn("Could not create signable request", .{});
|
||||||
|
return AwsError.SignableError;
|
||||||
|
}
|
||||||
|
defer c.aws_signable_destroy(signable);
|
||||||
|
|
||||||
|
const signing_region = try std.fmt.allocPrint(self.allocator, "{s}", .{options.region});
|
||||||
|
defer self.allocator.free(signing_region);
|
||||||
|
const signing_service = try std.fmt.allocPrint(self.allocator, "{s}", .{options.service});
|
||||||
|
defer self.allocator.free(signing_service);
|
||||||
|
const temp_signing_config = c.bitfield_workaround_aws_signing_config_aws{
|
||||||
|
.algorithm = .AWS_SIGNING_ALGORITHM_V4,
|
||||||
|
.config_type = .AWS_SIGNING_CONFIG_AWS,
|
||||||
|
.signature_type = .AWS_ST_HTTP_REQUEST_HEADERS,
|
||||||
|
.region = c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, signing_region)),
|
||||||
|
.service = c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, signing_service)),
|
||||||
|
.should_sign_header = null,
|
||||||
|
.should_sign_header_ud = null,
|
||||||
|
.flags = c.bitfield_workaround_aws_signing_config_aws_flags{
|
||||||
|
.use_double_uri_encode = 0,
|
||||||
|
.should_normalize_uri_path = 0,
|
||||||
|
.omit_session_token = 1,
|
||||||
|
},
|
||||||
|
.signed_body_value = c.aws_byte_cursor_from_c_str(""),
|
||||||
|
.signed_body_header = .AWS_SBHT_X_AMZ_CONTENT_SHA256, //or AWS_SBHT_NONE
|
||||||
|
.credentials = creds,
|
||||||
|
.credentials_provider = self.credentialsProvider,
|
||||||
|
.expiration_in_seconds = 0,
|
||||||
|
};
|
||||||
|
var signing_config = c.new_aws_signing_config(c_allocator, &temp_signing_config);
|
||||||
|
defer c.aws_mem_release(c_allocator, signing_config);
|
||||||
|
var signing_result = AwsAsyncCallbackResult(c.aws_http_message){ .result = http_request };
|
||||||
|
var sign_result_request = AsyncResult(AwsAsyncCallbackResult(c.aws_http_message)){ .result = &signing_result };
|
||||||
|
if (c.aws_sign_request_aws(c_allocator, signable, fullCast([*c]const c.aws_signing_config_base, signing_config), signComplete, &sign_result_request) != c.AWS_OP_SUCCESS) {
|
||||||
|
const error_code = c.aws_last_error();
|
||||||
|
httplog.alert("Could not initiate signing request: {s}:{s}", .{ c.aws_error_name(error_code), c.aws_error_str(error_code) });
|
||||||
|
return AwsError.SigningInitiationError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait for callback. Note that execution, including real work of signing
|
||||||
|
// the http request, will continue in signComplete (below),
|
||||||
|
// then continue beyond this line
|
||||||
|
waitOnCallback(c.aws_http_message, &sign_result_request);
|
||||||
|
if (sign_result_request.result.error_code != c.AWS_ERROR_SUCCESS) {
|
||||||
|
return AwsError.SignableError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// It's my theory that the aws event loop has a trigger to corrupt the
|
||||||
|
/// signing result after this call completes. So the technique of assigning
|
||||||
|
/// now, using later will not work
|
||||||
|
fn signComplete(result: ?*c.aws_signing_result, error_code: c_int, user_data: ?*c_void) callconv(.C) void {
|
||||||
|
var async_result = userDataTo(AsyncResult(AwsAsyncCallbackResult(c.aws_http_message)), user_data);
|
||||||
|
var http_request = async_result.result.result;
|
||||||
|
async_result.sync.store(true, .SeqCst);
|
||||||
|
|
||||||
|
async_result.count += 1;
|
||||||
|
async_result.result.error_code = error_code;
|
||||||
|
|
||||||
|
if (result) |res| {
|
||||||
|
if (c.aws_apply_signing_result_to_http_request(http_request, c_allocator, result) != c.AWS_OP_SUCCESS) {
|
||||||
|
httplog.alert("Could not apply signing request to http request: {s}", .{c.aws_error_debug_str(c.aws_last_error())});
|
||||||
|
}
|
||||||
|
httplog.debug("signing result applied", .{});
|
||||||
|
} else {
|
||||||
|
httplog.alert("Did not receive signing result: {s}", .{c.aws_error_debug_str(c.aws_last_error())});
|
||||||
|
}
|
||||||
|
async_result.sync.store(false, .SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
fn addHeaders(self: Self, request: *c.aws_http_message, host: []const u8, body: []const u8) !void {
|
fn addHeaders(self: Self, request: *c.aws_http_message, host: []const u8, body: []const u8) !void {
|
||||||
const accept_header = c.aws_http_header{
|
const accept_header = c.aws_http_header{
|
||||||
.name = c.aws_byte_cursor_from_c_str("Accept"),
|
.name = c.aws_byte_cursor_from_c_str("Accept"),
|
||||||
|
@ -629,65 +718,6 @@ pub const AwsHttp = struct {
|
||||||
httplog.debug("request complete", .{});
|
httplog.debug("request complete", .{});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Re-encapsulate or delete this function. It is not currently
|
|
||||||
// used and will not be touched by the compiler
|
|
||||||
fn setupTls(self: Self, host: []const u8) !*c.aws_tls_connection_options {
|
|
||||||
if (tls_ctx_options == null) {
|
|
||||||
httplog.debug("Setting up tls options", .{});
|
|
||||||
var opts: c.aws_tls_ctx_options = .{
|
|
||||||
.allocator = c_allocator,
|
|
||||||
.minimum_tls_version = @intToEnum(c.aws_tls_versions, c.AWS_IO_TLS_VER_SYS_DEFAULTS),
|
|
||||||
.cipher_pref = @intToEnum(c.aws_tls_cipher_pref, c.AWS_IO_TLS_CIPHER_PREF_SYSTEM_DEFAULT),
|
|
||||||
.ca_file = c.aws_byte_buf_from_c_str(""),
|
|
||||||
.ca_path = c.aws_string_new_from_c_str(c_allocator, ""),
|
|
||||||
.alpn_list = null,
|
|
||||||
.certificate = c.aws_byte_buf_from_c_str(""),
|
|
||||||
.private_key = c.aws_byte_buf_from_c_str(""),
|
|
||||||
.max_fragment_size = 0,
|
|
||||||
.verify_peer = true,
|
|
||||||
};
|
|
||||||
tls_ctx_options = &opts;
|
|
||||||
|
|
||||||
c.aws_tls_ctx_options_init_default_client(tls_ctx_options.?, c_allocator);
|
|
||||||
// h2;http/1.1
|
|
||||||
if (c.aws_tls_ctx_options_set_alpn_list(tls_ctx_options, "http/1.1") != c.AWS_OP_SUCCESS) {
|
|
||||||
httplog.alert("Failed to load alpn list with error {s}.", .{c.aws_error_debug_str(c.aws_last_error())});
|
|
||||||
return AwsError.AlpnError;
|
|
||||||
}
|
|
||||||
|
|
||||||
tls_ctx = c.aws_tls_client_ctx_new(c_allocator, tls_ctx_options.?);
|
|
||||||
|
|
||||||
if (tls_ctx == null) {
|
|
||||||
std.debug.panic("Failed to initialize TLS context with error {s}.", .{c.aws_error_debug_str(c.aws_last_error())});
|
|
||||||
}
|
|
||||||
httplog.debug("tls options setup applied", .{});
|
|
||||||
}
|
|
||||||
|
|
||||||
var tls_connection_options = c.aws_tls_connection_options{
|
|
||||||
.alpn_list = null,
|
|
||||||
.server_name = null,
|
|
||||||
.on_negotiation_result = null,
|
|
||||||
.on_data_read = null,
|
|
||||||
.on_error = null,
|
|
||||||
.user_data = null,
|
|
||||||
.ctx = null,
|
|
||||||
.advertise_alpn_message = false,
|
|
||||||
.timeout_ms = 0,
|
|
||||||
};
|
|
||||||
c.aws_tls_connection_options_init_from_ctx(&tls_connection_options, tls_ctx);
|
|
||||||
var host_var = host;
|
|
||||||
var host_cur = c.aws_byte_cursor_from_c_str(@ptrCast([*c]const u8, host_var));
|
|
||||||
if (c.aws_tls_connection_options_set_server_name(&tls_connection_options, c_allocator, &host_cur) != c.AWS_OP_SUCCESS) {
|
|
||||||
httplog.alert("Failed to set servername with error {s}.", .{c.aws_error_debug_str(c.aws_last_error())});
|
|
||||||
return AwsError.TlsError;
|
|
||||||
}
|
|
||||||
return &tls_connection_options;
|
|
||||||
|
|
||||||
// if (app_ctx.uri.port) {
|
|
||||||
// port = app_ctx.uri.port;
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn getCredentials(self: Self) !*c.aws_credentials {
|
fn getCredentials(self: Self) !*c.aws_credentials {
|
||||||
var credential_result = AwsAsyncCallbackResult(c.aws_credentials){};
|
var credential_result = AwsAsyncCallbackResult(c.aws_credentials){};
|
||||||
var callback_results = AsyncResult(AwsAsyncCallbackResult(c.aws_credentials)){ .result = &credential_result };
|
var callback_results = AsyncResult(AwsAsyncCallbackResult(c.aws_credentials)){ .result = &credential_result };
|
||||||
|
|
Loading…
Reference in New Issue
Block a user