HTTP message API (#19)

* HTTP message API

* Added MacOS CI

* Grabbed fixes for mac from aws-crt-ffi
This commit is contained in:
Justin Boswell
2021-03-25 13:14:07 -04:00
committed by GitHub
parent 974fe3d74a
commit 9c9422c21f
14 changed files with 421 additions and 69 deletions
+11 -8
View File
@@ -81,11 +81,14 @@ jobs:
# python -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder.pyz')" # python -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder.pyz')"
# python builder.pyz build -p ${{ env.PACKAGE_NAME }} downstream # python builder.pyz build -p ${{ env.PACKAGE_NAME }} downstream
# osx: macos:
# runs-on: macos-latest runs-on: macos-${{ matrix.version }}
# steps: strategy:
# - name: Build ${{ env.PACKAGE_NAME }} + consumers matrix:
# run: | version: [10.15]
# python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')" steps:
# chmod a+x builder - name: Build PHP 8 extension and test
# ./builder build -p ${{ env.PACKAGE_NAME }} --spec=downstream run: |
python3 -c "from urllib.request import urlretrieve; urlretrieve('${{ env.BUILDER_HOST }}/${{ env.BUILDER_SOURCE }}/${{ env.BUILDER_VERSION }}/builder.pyz?run=${{ env.RUN }}', 'builder')"
chmod a+x builder
./builder build -p ${{ env.PACKAGE_NAME }} --spec=downstream
+7 -1
View File
@@ -8,8 +8,14 @@ PHP_ARG_WITH(awscrt)
if test "$PHP_AWSCRT" != "no"; then if test "$PHP_AWSCRT" != "no"; then
# force lib paths to be absolute, or PHP will mangle them # force lib paths to be absolute, or PHP will mangle them
cwd=`pwd` cwd=`pwd`
# Enable s2n and libcrypto for non-darwin UNIX
if uname -a | grep -i darwin > /dev/null 2>&1; then
platform_tls_libs=""
else
platform_tls_libs="-ls2n -l:libcrypto.a"
fi
CRT_LIBPATHS="-L${cwd}/build/install/lib -L${cwd}/build/install/lib64" CRT_LIBPATHS="-L${cwd}/build/install/lib -L${cwd}/build/install/lib64"
CRT_LIBS="-laws-crt-ffi -laws-c-auth -laws-c-http -laws-c-io -laws-c-cal -laws-c-compression -laws-c-common -ls2n -l:libcrypto.a" CRT_LIBS="-laws-crt-ffi -laws-c-auth -laws-c-http -laws-c-io -laws-c-cal -laws-c-compression -laws-c-common ${platform_tls_libs}"
PHP_ADD_INCLUDE(${cwd}/build/install/include) PHP_ADD_INCLUDE(${cwd}/build/install/include)
PHP_EVAL_LIBLINE([$CRT_LIBPATHS $CRT_LIBS], AWSCRT_SHARED_LIBADD) PHP_EVAL_LIBLINE([$CRT_LIBPATHS $CRT_LIBS], AWSCRT_SHARED_LIBADD)
+6
View File
@@ -38,6 +38,12 @@ function aws_crt_input_stream_eof(int $stream): bool {}
function aws_crt_input_stream_get_length(int $stream): int {} function aws_crt_input_stream_get_length(int $stream): int {}
function aws_crt_http_message_new_from_blob(string $blob): int {}
function aws_crt_http_message_to_blob(int $message): string {}
function aws_crt_http_message_release(int $message): void {}
function aws_crt_credentials_options_new(): object {} function aws_crt_credentials_options_new(): object {}
function aws_crt_credentials_options_release(object $options): void {} function aws_crt_credentials_options_release(object $options): void {}
+19 -1
View File
@@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead. /* This is a generated file, edit the .stub.php file instead.
* Stub hash: 5549e1214a9a419075f5cb561adb2d7a340c5916 */ * Stub hash: bd274f6b280b27aa5fb7d3be2ce85ad065936943 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_aws_crt_last_error, 0, 0, IS_LONG, 0) ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_aws_crt_last_error, 0, 0, IS_LONG, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
@@ -68,6 +68,18 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_aws_crt_input_stream_get_length,
ZEND_ARG_TYPE_INFO(0, stream, IS_LONG, 0) ZEND_ARG_TYPE_INFO(0, stream, IS_LONG, 0)
ZEND_END_ARG_INFO() ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_aws_crt_http_message_new_from_blob, 0, 1, IS_LONG, 0)
ZEND_ARG_TYPE_INFO(0, blob, IS_STRING, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_aws_crt_http_message_to_blob, 0, 1, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, message, IS_LONG, 0)
ZEND_END_ARG_INFO()
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_aws_crt_http_message_release, 0, 1, IS_VOID, 0)
ZEND_ARG_TYPE_INFO(0, message, IS_LONG, 0)
ZEND_END_ARG_INFO()
#define arginfo_aws_crt_credentials_options_new arginfo_aws_crt_input_stream_options_new #define arginfo_aws_crt_credentials_options_new arginfo_aws_crt_input_stream_options_new
#define arginfo_aws_crt_credentials_options_release arginfo_aws_crt_input_stream_options_release #define arginfo_aws_crt_credentials_options_release arginfo_aws_crt_input_stream_options_release
@@ -133,6 +145,9 @@ ZEND_FUNCTION(aws_crt_input_stream_seek);
ZEND_FUNCTION(aws_crt_input_stream_read); ZEND_FUNCTION(aws_crt_input_stream_read);
ZEND_FUNCTION(aws_crt_input_stream_eof); ZEND_FUNCTION(aws_crt_input_stream_eof);
ZEND_FUNCTION(aws_crt_input_stream_get_length); ZEND_FUNCTION(aws_crt_input_stream_get_length);
ZEND_FUNCTION(aws_crt_http_message_new_from_blob);
ZEND_FUNCTION(aws_crt_http_message_to_blob);
ZEND_FUNCTION(aws_crt_http_message_release);
ZEND_FUNCTION(aws_crt_credentials_options_new); ZEND_FUNCTION(aws_crt_credentials_options_new);
ZEND_FUNCTION(aws_crt_credentials_options_release); ZEND_FUNCTION(aws_crt_credentials_options_release);
ZEND_FUNCTION(aws_crt_credentials_options_set_access_key_id); ZEND_FUNCTION(aws_crt_credentials_options_set_access_key_id);
@@ -169,6 +184,9 @@ static const zend_function_entry ext_functions[] = {
ZEND_FE(aws_crt_input_stream_read, arginfo_aws_crt_input_stream_read) ZEND_FE(aws_crt_input_stream_read, arginfo_aws_crt_input_stream_read)
ZEND_FE(aws_crt_input_stream_eof, arginfo_aws_crt_input_stream_eof) ZEND_FE(aws_crt_input_stream_eof, arginfo_aws_crt_input_stream_eof)
ZEND_FE(aws_crt_input_stream_get_length, arginfo_aws_crt_input_stream_get_length) ZEND_FE(aws_crt_input_stream_get_length, arginfo_aws_crt_input_stream_get_length)
ZEND_FE(aws_crt_http_message_new_from_blob, arginfo_aws_crt_http_message_new_from_blob)
ZEND_FE(aws_crt_http_message_to_blob, arginfo_aws_crt_http_message_to_blob)
ZEND_FE(aws_crt_http_message_release, arginfo_aws_crt_http_message_release)
ZEND_FE(aws_crt_credentials_options_new, arginfo_aws_crt_credentials_options_new) ZEND_FE(aws_crt_credentials_options_new, arginfo_aws_crt_credentials_options_new)
ZEND_FE(aws_crt_credentials_options_release, arginfo_aws_crt_credentials_options_release) ZEND_FE(aws_crt_credentials_options_release, arginfo_aws_crt_credentials_options_release)
ZEND_FE(aws_crt_credentials_options_set_access_key_id, arginfo_aws_crt_credentials_options_set_access_key_id) ZEND_FE(aws_crt_credentials_options_set_access_key_id, arginfo_aws_crt_credentials_options_set_access_key_id)
+73 -39
View File
@@ -61,7 +61,7 @@ PHP_FUNCTION(aws_crt_last_error) {
PHP_FUNCTION(aws_crt_error_str) { PHP_FUNCTION(aws_crt_error_str) {
zend_ulong error_code = 0; zend_ulong error_code = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error_code) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &error_code) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -72,7 +72,7 @@ PHP_FUNCTION(aws_crt_error_str) {
PHP_FUNCTION(aws_crt_error_name) { PHP_FUNCTION(aws_crt_error_name) {
zend_ulong error_code = 0; zend_ulong error_code = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error_code) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &error_code) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -83,7 +83,7 @@ PHP_FUNCTION(aws_crt_error_name) {
PHP_FUNCTION(aws_crt_error_debug_str) { PHP_FUNCTION(aws_crt_error_debug_str) {
zend_ulong error_code = 0; zend_ulong error_code = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &error_code) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &error_code) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -98,7 +98,7 @@ PHP_FUNCTION(aws_crt_event_loop_group_options_new) {
PHP_FUNCTION(aws_crt_event_loop_group_options_release) { PHP_FUNCTION(aws_crt_event_loop_group_options_release) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
return; return;
} }
@@ -110,7 +110,7 @@ PHP_FUNCTION(aws_crt_event_loop_group_options_set_max_threads) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
zend_ulong num_threads = 0; zend_ulong num_threads = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &php_options, &num_threads) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &php_options, &num_threads) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -121,7 +121,7 @@ PHP_FUNCTION(aws_crt_event_loop_group_options_set_max_threads) {
PHP_FUNCTION(aws_crt_event_loop_group_new) { PHP_FUNCTION(aws_crt_event_loop_group_new) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -133,7 +133,7 @@ PHP_FUNCTION(aws_crt_event_loop_group_new) {
PHP_FUNCTION(aws_crt_event_loop_group_release) { PHP_FUNCTION(aws_crt_event_loop_group_release) {
zend_ulong php_elg = 0; zend_ulong php_elg = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_elg) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_elg) == FAILURE) {
return; return;
} }
@@ -153,7 +153,7 @@ PHP_FUNCTION(aws_crt_input_stream_options_new) {
PHP_FUNCTION(aws_crt_input_stream_options_release) { PHP_FUNCTION(aws_crt_input_stream_options_release) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
return; return;
} }
@@ -170,7 +170,7 @@ PHP_FUNCTION(aws_crt_input_stream_options_set_user_data) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
zval *user_data = NULL; zval *user_data = NULL;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lz", &php_options, &user_data) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "lz", &php_options, &user_data) == FAILURE) {
return; return;
} }
@@ -187,7 +187,7 @@ static int s_php_stream_seek(void *user_data, int64_t offset, aws_crt_input_stre
static int s_php_stream_read(void *user_data, uint8_t *dest, size_t dest_length) { static int s_php_stream_read(void *user_data, uint8_t *dest, size_t dest_length) {
php_stream *stream = user_data; php_stream *stream = user_data;
return php_stream_read(stream, dest, dest_length) != 0; return php_stream_read(stream, (char *)dest, dest_length) != 0;
} }
static int s_php_stream_get_length(void *user_data, int64_t *out_length) { static int s_php_stream_get_length(void *user_data, int64_t *out_length) {
@@ -204,7 +204,8 @@ static int s_php_stream_get_status(void *user_data, aws_crt_input_stream_status
out_status->is_valid = stream != NULL; out_status->is_valid = stream != NULL;
/* We would like to use php_stream_eof here, but certain streams (notably php://memory) /* We would like to use php_stream_eof here, but certain streams (notably php://memory)
* are not actually capable of EOF, so we get to do it the hard way */ * are not actually capable of EOF, so we get to do it the hard way */
size_t length = 0, pos = 0; int64_t length = 0;
int64_t pos = 0;
s_php_stream_get_length(stream, &length); s_php_stream_get_length(stream, &length);
pos = php_stream_tell(stream); pos = php_stream_tell(stream);
out_status->is_end_of_stream = pos == length; out_status->is_end_of_stream = pos == length;
@@ -219,7 +220,7 @@ static void s_php_stream_destroy(void *user_data) {
PHP_FUNCTION(aws_crt_input_stream_new) { PHP_FUNCTION(aws_crt_input_stream_new) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -236,7 +237,7 @@ PHP_FUNCTION(aws_crt_input_stream_new) {
PHP_FUNCTION(aws_crt_input_stream_release) { PHP_FUNCTION(aws_crt_input_stream_release) {
zend_ulong php_stream = 0; zend_ulong php_stream = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_stream) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_stream) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -249,7 +250,7 @@ PHP_FUNCTION(aws_crt_input_stream_seek) {
zend_ulong offset = 0; zend_ulong offset = 0;
zend_ulong basis = 0; zend_ulong basis = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lll", &php_stream, &offset, &basis) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "lll", &php_stream, &offset, &basis) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -261,21 +262,21 @@ PHP_FUNCTION(aws_crt_input_stream_read) {
zend_ulong php_stream = 0; zend_ulong php_stream = 0;
zend_ulong length = 0; zend_ulong length = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &php_stream, &length) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &php_stream, &length) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
aws_crt_input_stream *stream = (void *)php_stream; aws_crt_input_stream *stream = (void *)php_stream;
uint8_t *buf = emalloc(length); uint8_t *buf = emalloc(length);
int ret = aws_crt_input_stream_read(stream, buf, length); int ret = aws_crt_input_stream_read(stream, buf, length);
AWS_RETURN_STRINGL(buf, length); AWS_RETURN_STRINGL((const char *)buf, length);
efree(buf); efree(buf);
} }
PHP_FUNCTION(aws_crt_input_stream_eof) { PHP_FUNCTION(aws_crt_input_stream_eof) {
zend_ulong php_stream = 0; zend_ulong php_stream = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_stream) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_stream) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -288,16 +289,54 @@ PHP_FUNCTION(aws_crt_input_stream_eof) {
PHP_FUNCTION(aws_crt_input_stream_get_length) { PHP_FUNCTION(aws_crt_input_stream_get_length) {
zend_ulong php_stream = 0; zend_ulong php_stream = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_stream) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_stream) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
aws_crt_input_stream *stream = (void *)php_stream; aws_crt_input_stream *stream = (void *)php_stream;
size_t length = 0; int64_t length = 0;
aws_crt_input_stream_get_length(stream, &length); aws_crt_input_stream_get_length(stream, &length);
RETURN_LONG(length); RETURN_LONG(length);
} }
PHP_FUNCTION(aws_crt_http_message_new_from_blob) {
const char *blob = NULL;
size_t blob_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "s", &blob, &blob_len) == FAILURE) {
RETURN_NULL();
}
aws_crt_http_message *message = aws_crt_http_message_new_from_blob((uint8_t *)blob, blob_len);
RETURN_LONG((zend_ulong)message);
}
PHP_FUNCTION(aws_crt_http_message_to_blob) {
zend_ulong php_msg = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_msg) == FAILURE) {
RETURN_NULL();
}
aws_crt_http_message *message = (void *)php_msg;
uint8_t *blob = NULL;
size_t blob_len = 0;
aws_crt_http_message_to_blob(message, &blob, &blob_len);
AWS_RETURN_STRINGL((const char *)blob, blob_len);
aws_crt_mem_release(blob);
}
PHP_FUNCTION(aws_crt_http_message_release) {
zend_ulong php_msg = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_msg) == FAILURE) {
RETURN_NULL();
}
aws_crt_http_message *message = (void *)php_msg;
aws_crt_http_message_release(message);
}
PHP_FUNCTION(aws_crt_credentials_options_new) { PHP_FUNCTION(aws_crt_credentials_options_new) {
aws_crt_credentials_options *options = aws_crt_credentials_options_new(); aws_crt_credentials_options *options = aws_crt_credentials_options_new();
RETURN_LONG((zend_ulong)options); RETURN_LONG((zend_ulong)options);
@@ -306,7 +345,7 @@ PHP_FUNCTION(aws_crt_credentials_options_new) {
PHP_FUNCTION(aws_crt_credentials_options_release) { PHP_FUNCTION(aws_crt_credentials_options_release) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -319,8 +358,7 @@ PHP_FUNCTION(aws_crt_credentials_options_set_access_key_id) {
const char *access_key_id = NULL; const char *access_key_id = NULL;
size_t access_key_id_len = 0; size_t access_key_id_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &php_options, &access_key_id, &access_key_id_len) == if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &php_options, &access_key_id, &access_key_id_len) == FAILURE) {
FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -333,8 +371,8 @@ PHP_FUNCTION(aws_crt_credentials_options_set_secret_access_key) {
const char *secret_access_key = NULL; const char *secret_access_key = NULL;
size_t secret_access_key_len = 0; size_t secret_access_key_len = 0;
if (zend_parse_parameters( if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &php_options, &secret_access_key, &secret_access_key_len) ==
ZEND_NUM_ARGS() TSRMLS_CC, "ls", &php_options, &secret_access_key, &secret_access_key_len) == FAILURE) { FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -347,8 +385,7 @@ PHP_FUNCTION(aws_crt_credentials_options_set_session_token) {
const char *session_token = NULL; const char *session_token = NULL;
size_t session_token_len = 0; size_t session_token_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &php_options, &session_token, &session_token_len) == if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &php_options, &session_token, &session_token_len) == FAILURE) {
FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -359,8 +396,7 @@ PHP_FUNCTION(aws_crt_credentials_options_set_session_token) {
PHP_FUNCTION(aws_crt_credentials_options_set_expiration_timepoint_seconds) { PHP_FUNCTION(aws_crt_credentials_options_set_expiration_timepoint_seconds) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
zend_ulong expiration_timepoint_seconds = 0; zend_ulong expiration_timepoint_seconds = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ll", &php_options, &expiration_timepoint_seconds) == if (zend_parse_parameters(ZEND_NUM_ARGS(), "ll", &php_options, &expiration_timepoint_seconds) == FAILURE) {
FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -371,7 +407,7 @@ PHP_FUNCTION(aws_crt_credentials_options_set_expiration_timepoint_seconds) {
PHP_FUNCTION(aws_crt_credentials_new) { PHP_FUNCTION(aws_crt_credentials_new) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -383,7 +419,7 @@ PHP_FUNCTION(aws_crt_credentials_new) {
PHP_FUNCTION(aws_crt_credentials_release) { PHP_FUNCTION(aws_crt_credentials_release) {
zend_ulong php_credentials = 0; zend_ulong php_credentials = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_credentials) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_credentials) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -394,7 +430,7 @@ PHP_FUNCTION(aws_crt_credentials_release) {
PHP_FUNCTION(aws_crt_credentials_provider_release) { PHP_FUNCTION(aws_crt_credentials_provider_release) {
zend_ulong php_creds_provider = 0; zend_ulong php_creds_provider = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_creds_provider) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_creds_provider) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -410,7 +446,7 @@ PHP_FUNCTION(aws_crt_credentials_provider_static_options_new) {
PHP_FUNCTION(aws_crt_credentials_provider_static_options_release) { PHP_FUNCTION(aws_crt_credentials_provider_static_options_release) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -423,8 +459,7 @@ PHP_FUNCTION(aws_crt_credentials_provider_static_options_set_access_key_id) {
const char *access_key_id = NULL; const char *access_key_id = NULL;
size_t access_key_id_len = 0; size_t access_key_id_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &php_options, &access_key_id, &access_key_id_len) == if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &php_options, &access_key_id, &access_key_id_len) == FAILURE) {
FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -437,8 +472,8 @@ PHP_FUNCTION(aws_crt_credentials_provider_static_options_set_secret_access_key)
const char *secret_access_key = NULL; const char *secret_access_key = NULL;
size_t secret_access_key_len = 0; size_t secret_access_key_len = 0;
if (zend_parse_parameters( if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &php_options, &secret_access_key, &secret_access_key_len) ==
ZEND_NUM_ARGS() TSRMLS_CC, "ls", &php_options, &secret_access_key, &secret_access_key_len) == FAILURE) { FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -452,8 +487,7 @@ PHP_FUNCTION(aws_crt_credentials_provider_static_options_set_session_token) {
const char *session_token = NULL; const char *session_token = NULL;
size_t session_token_len = 0; size_t session_token_len = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ls", &php_options, &session_token, &session_token_len) == if (zend_parse_parameters(ZEND_NUM_ARGS(), "ls", &php_options, &session_token, &session_token_len) == FAILURE) {
FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
@@ -464,7 +498,7 @@ PHP_FUNCTION(aws_crt_credentials_provider_static_options_set_session_token) {
PHP_FUNCTION(aws_crt_credentials_provider_static_new) { PHP_FUNCTION(aws_crt_credentials_provider_static_new) {
zend_ulong php_options = 0; zend_ulong php_options = 0;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &php_options) == FAILURE) { if (zend_parse_parameters(ZEND_NUM_ARGS(), "l", &php_options) == FAILURE) {
RETURN_NULL(); RETURN_NULL();
} }
+1 -1
View File
@@ -19,7 +19,7 @@
# error "PHP >= 5.6 is required" # error "PHP >= 5.6 is required"
#endif #endif
#define AWS_PHP_AT_LEAST_7 defined(ZEND_EXTENSION_API_NO_7_0_X) || (ZEND_EXTENSION_API_NO >= 320151012) #define AWS_PHP_AT_LEAST_7 (ZEND_EXTENSION_API_NO >= 320151012)
ZEND_BEGIN_MODULE_GLOBALS(awscrt) ZEND_BEGIN_MODULE_GLOBALS(awscrt)
long log_level; long log_level;
+8
View File
@@ -203,4 +203,12 @@ final class CRT {
function input_stream_get_length($stream) { function input_stream_get_length($stream) {
return self::$impl->aws_crt_input_stream_get_length($stream); return self::$impl->aws_crt_input_stream_get_length($stream);
} }
function http_message_new_from_blob($blob) {
return self::$impl->aws_crt_http_message_new_from_blob($blob);
}
function http_message_release($message) {
self::$impl->aws_crt_http_message_release($message);
}
} }
+47
View File
@@ -0,0 +1,47 @@
<?php
namespace AWS\CRT\HTTP;
use AWS\CRT\Internal\Encoding;
final class Headers {
private $headers;
public function __construct($headers = []) {
$this->headers = $headers;
}
public static function marshall($headers) {
$buf = "";
foreach ($headers->headers as $header => $value) {
$buf .= Encoding::encodeString($header);
$buf .= Encoding::encodeString($value);
}
return $buf;
}
public static function unmarshall($buf) {
$strings = Encoding::readStrings($buf);
$headers = [];
for ($idx = 0; $idx < count($strings);) {
$headers[$strings[$idx++]] = $strings[$idx++];
}
return new Headers($headers);
}
public function count() {
return count($this->headers);
}
public function get($header) {
return isset($this->headers[$header]) ? $this->headers[$header] : null;
}
public function set($header, $value) {
$this->headers[$header] = $value;
}
public function toArray() {
return array_merge($this->headers);
}
}
+73 -18
View File
@@ -2,32 +2,87 @@
namespace AWS\CRT\HTTP; namespace AWS\CRT\HTTP;
abstract class Message { use AWS\CRT\NativeResource;
private $path = "";
private $query = [];
private $headers = [];
public function __construct($path, $query = [], $headers = []) { use AWS\CRT\Internal\Encoding;
abstract class Message extends NativeResource {
private $method;
private $path;
private $query;
private $headers;
public function __construct($method, $path, $query = [], $headers = null) {
$this->method = $method;
$this->path = $path; $this->path = $path;
$this->query = $query; $this->query = $query;
$this->headers = $headers; $this->headers = !is_null($headers) ? $headers : new Headers();
$this->acquire(self::$crt->http_message_new_from_blob(self::marshall($this)));
} }
}
class Request extends Message { public function __destruct() {
private $body_stream = null; self::$crt->http_message_release($this->release());
parent::__destruct();
}
protected static function marshall($msg) {
$buf = "";
$buf .= Encoding::encodeString($msg->method);
$buf .= Encoding::encodeString($msg->pathAndQuery());
$buf .= Headers::marshall($msg->headers);
return $buf;
}
protected static function _unmarshall($buf, $class=Message::class) {
$method = Encoding::readString($buf);
$path_and_query = Encoding::readString($buf);
$parts = explode("?", $path_and_query, 2);
$path = isset($parts[0]) ? $parts[0] : "";
$query = isset($parts[1]) ? $parts[1] : "";
$headers = Headers::unmarshall($buf);
public function __construct($path, $query = [], $headers = [], $body_stream = null) { // Turn query params back into a dictionary
parent::__construct($path, $query, $headers); if (strlen($query)) {
$this->body_stream = $body_stream; $query = rawurldecode($query);
$query = explode("&", $query);
$query = array_reduce($query, function($params, $pair) {
list($param, $value) = explode("=", $pair, 2);
$params[$param] = $value;
return $params;
}, []);
} else {
$query = [];
} }
}
class Response extends Message { return new $class($method, $path, $query, $headers);
private $status_code; }
public function pathAndQuery() {
$path = $this->path;
$queries = [];
foreach ($this->query as $param => $value) {
$queries []= urlencode($param) . "=" . urlencode($value);
}
$query = implode("&", $queries);
if (strlen($query)) {
$path = implode("?", [$path, $query]);
}
return $path;
}
public function method() {
return $this->method;
}
public function path() {
return $this->path;
}
public function query() {
return $this->query;
}
public function __construct($path, $headers, $status_code) { public function headers() {
parent::__construct($path, [], $headers); return $this->headers;
$this->status_code = $status_code;
} }
} }
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace AWS\CRT\HTTP;
class Request extends Message {
private $body_stream = null;
public function __construct($method, $path, $query = [], $headers = null, $body_stream = null) {
parent::__construct($method, $path, $query, $headers);
$this->body_stream = $body_stream;
}
public static function marshall($request) {
return parent::marshall($request);
}
public static function unmarshall($buf) {
return parent::_unmarshall($buf, Request::class);
}
public function body_stream() {
return $this->body_stream;
}
}
+24
View File
@@ -0,0 +1,24 @@
<?php
namespace AWS\CRT\HTTP;
class Response extends Message {
private $status_code;
public function __construct($method, $path, $query, $headers, $status_code) {
parent::__construct($method, $path, $query, $headers);
$this->status_code = $status_code;
}
public static function marshall($response) {
return parent::marshall($response);
}
public static function unmarshall($buf) {
return parent::_unmarshall($buf, Response::class);
}
public function status_code() {
return $this->status_code;
}
}
+31
View File
@@ -0,0 +1,31 @@
<?php
namespace AWS\CRT\Internal;
final class Encoding {
public static function readString(&$buffer) {
list($len, $str) = self::decodeString($buffer);
// Advance by sizeof(length) + strlen(str)
$buffer = substr($buffer, 4 + $len);
return $str;
}
public static function readStrings($buffer) {
$strings = [];
while (strlen($buffer)) {
$strings []= self::readString($buffer);
}
return $strings;
}
public static function decodeString($buffer) {
$len = unpack("N", $buffer)[1];
$buffer = substr($buffer, 4);
$str = unpack("a${len}", $buffer)[1];
return [$len, $str];
}
public static function encodeString($str) {
return pack("Na*", strlen($str), $str);
}
}
+96
View File
@@ -0,0 +1,96 @@
<?php
use AWS\CRT\HTTP\Message;
use AWS\CRT\HTTP\Headers;
use AWS\CRT\HTTP\Request;
use AWS\CRT\HTTP\Response;
require_once('common.inc');
final class HttpMessageTest extends CrtTestCase {
public function testHeaders() {
$headers = new Headers();
$this->assertSame(0, $headers->count());
}
public function testHeadersMarshalling() {
$headers_array = [
"host" => "s3.amazonaws.com",
"test" => "this is a test header value"
];
$headers = new Headers($headers_array);
$this->assertSame(2, $headers->count());
$this->assertSame($headers_array['host'], $headers->get('host'));
$this->assertSame($headers_array['test'], $headers->get('test'));
$buffer = Headers::marshall($headers);
$headers_copy = Headers::unmarshall($buffer);
$this->assertSame(2, $headers_copy->count());
$this->assertSame($headers_array['host'], $headers_copy->get('host'));
$this->assertSame($headers_array['test'], $headers_copy->get('test'));
}
private function assertMessagesMatch($a, $b) {
$this->assertSame($a->method(), $b->method());
$this->assertSame($a->path(), $b->path());
$this->assertSame($a->query(), $b->query());
$this->assertSame($a->headers()->toArray(), $b->headers()->toArray());
}
public function testRequestMarshalling() {
$headers_array = [
"host" => "s3.amazonaws.com",
"test" => "this is a test header value"
];
$headers = new Headers($headers_array);
$method = "GET";
$path = "/index.php";
$query = [];
$msg = new Request($method, $path, $query, $headers);
$msg_buf = Request::marshall($msg);
$msg_copy = Request::unmarshall($msg_buf);
$this->assertMessagesMatch($msg, $msg_copy);
}
public function testRequestMarshallingWithQueryParams() {
$headers_array = [
"host" => "s3.amazonaws.com",
"test" => "this is a test header value"
];
$headers = new Headers($headers_array);
$method = "GET";
$path = "/index.php";
$query = [
'request' => '1',
'test' => 'true',
'answer' => '42',
'foo' => 'bar',
];
$msg = new Request($method, $path, $query, $headers);
$msg_buf = Request::marshall($msg);
$msg_copy = Request::unmarshall($msg_buf);
$this->assertMessagesMatch($msg, $msg_copy);
}
public function testResponseMarshalling() {
$headers_array = [
"content-length" => "42",
"test" => "this is a test header value"
];
$headers = new Headers($headers_array);
$method = "GET";
$path = "/index.php";
$query = [
'response' => '1'
];
$msg = new Response($method, $path, $query, $headers, 400);
$msg_buf = Request::marshall($msg);
$msg_copy = Request::unmarshall($msg_buf);
$this->assertMessagesMatch($msg, $msg_copy);
}
}