lnk commit front code
This commit is contained in:
187
include/oss_sdk/aos_buf.c
Normal file
187
include/oss_sdk/aos_buf.c
Normal file
@@ -0,0 +1,187 @@
|
||||
#include "aos_buf.h"
|
||||
#include "aos_log.h"
|
||||
#include <apr_file_io.h>
|
||||
|
||||
aos_buf_t *aos_create_buf(aos_pool_t *p, int size)
|
||||
{
|
||||
aos_buf_t* b;
|
||||
|
||||
b = aos_palloc(p, sizeof(aos_buf_t) + size);
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b->pos = (uint8_t *)b + sizeof(aos_buf_t);
|
||||
b->start = b->pos;
|
||||
b->last = b->start;
|
||||
b->end = b->last + size;
|
||||
aos_list_init(&b->node);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
aos_buf_t *aos_buf_pack(aos_pool_t *p, const void *data, int size)
|
||||
{
|
||||
aos_buf_t* b;
|
||||
|
||||
b = aos_palloc(p, sizeof(aos_buf_t));
|
||||
if (b == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
b->pos = (uint8_t *)data;
|
||||
b->start = b->pos;
|
||||
b->last = b->start + size;
|
||||
b->end = b->last;
|
||||
aos_list_init(&b->node);
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
int64_t aos_buf_list_len(aos_list_t *list)
|
||||
{
|
||||
aos_buf_t *b;
|
||||
int64_t len = 0;
|
||||
|
||||
aos_list_for_each_entry(aos_buf_t, b, list, node) {
|
||||
len += aos_buf_size(b);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
char *aos_buf_list_content(aos_pool_t *p, aos_list_t *list)
|
||||
{
|
||||
int64_t body_len;
|
||||
char *buf;
|
||||
int64_t pos = 0;
|
||||
int64_t size = 0;
|
||||
aos_buf_t *content;
|
||||
|
||||
body_len = aos_buf_list_len(list);
|
||||
buf = aos_pcalloc(p, (size_t)(body_len + 1));
|
||||
buf[body_len] = '\0';
|
||||
aos_list_for_each_entry(aos_buf_t, content, list, node) {
|
||||
size = aos_buf_size(content);
|
||||
memcpy(buf + pos, content->pos, (size_t)(size));
|
||||
pos += size;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
aos_file_buf_t *aos_create_file_buf(aos_pool_t *p)
|
||||
{
|
||||
return (aos_file_buf_t*)aos_pcalloc(p, sizeof(aos_file_buf_t));
|
||||
}
|
||||
|
||||
int aos_open_file_for_read(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||||
{
|
||||
int s;
|
||||
char buf[256];
|
||||
apr_finfo_t finfo;
|
||||
|
||||
if ((s = apr_file_open(&fb->file, path, APR_READ, APR_UREAD | APR_GREAD, p)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
assert(fb->file == NULL);
|
||||
return AOSE_OPEN_FILE_ERROR;
|
||||
}
|
||||
|
||||
if ((s = apr_file_info_get(&finfo, APR_FINFO_NORM, fb->file)) != APR_SUCCESS) {
|
||||
apr_file_close(fb->file);
|
||||
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
return AOSE_FILE_INFO_ERROR;
|
||||
}
|
||||
fb->file_pos = 0;
|
||||
fb->file_last = finfo.size;
|
||||
fb->owner = 1;
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int aos_open_file_for_all_read(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||||
{
|
||||
return aos_open_file_for_read(p, path, fb);
|
||||
}
|
||||
|
||||
int aos_open_file_for_range_read(aos_pool_t *p, const char *path,
|
||||
int64_t file_pos, int64_t file_last, aos_file_buf_t *fb)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = aos_open_file_for_read(p, path, fb);
|
||||
if (s == AOSE_OK) {
|
||||
if (file_pos > fb->file_pos) {
|
||||
if (file_pos > fb->file_last) {
|
||||
aos_warn_log("read range beyond file size, read start:%" APR_INT64_T_FMT ", file size:%" APR_INT64_T_FMT "\n",
|
||||
file_pos, fb->file_last);
|
||||
file_pos = fb->file_last;
|
||||
}
|
||||
fb->file_pos = file_pos;
|
||||
}
|
||||
if (file_last < fb->file_last) {
|
||||
fb->file_last = file_last;
|
||||
}
|
||||
apr_file_seek(fb->file, APR_SET, (apr_off_t *)&fb->file_pos);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int aos_open_file_for_write(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||||
{
|
||||
int s;
|
||||
char buf[256];
|
||||
|
||||
if ((s = apr_file_open(&fb->file, path, APR_CREATE | APR_WRITE | APR_TRUNCATE,
|
||||
APR_UREAD | APR_UWRITE | APR_GREAD, p)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
assert(fb->file == NULL);
|
||||
return AOSE_OPEN_FILE_ERROR;
|
||||
}
|
||||
fb->owner = 1;
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int aos_open_file_for_write_notrunc(aos_pool_t *p, const char *path, aos_file_buf_t *fb)
|
||||
{
|
||||
int s;
|
||||
char buf[256];
|
||||
|
||||
if ((s = apr_file_open(&fb->file, path, APR_CREATE | APR_WRITE,
|
||||
APR_UREAD | APR_UWRITE | APR_GREAD, p)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_file_open failure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
assert(fb->file == NULL);
|
||||
return AOSE_OPEN_FILE_ERROR;
|
||||
}
|
||||
fb->owner = 1;
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
void aos_buf_append_string(aos_pool_t *p, aos_buf_t *b, const char *str, int len)
|
||||
{
|
||||
int size;
|
||||
int nsize;
|
||||
int remain;
|
||||
char *buf;
|
||||
|
||||
if (len <= 0) return;
|
||||
|
||||
remain = b->end - b->last;
|
||||
|
||||
if (remain > len + 128) {
|
||||
memcpy(b->last, str, len);
|
||||
b->last += len;
|
||||
} else {
|
||||
size = aos_buf_size(b);
|
||||
nsize = (size + len) * 2;
|
||||
buf = aos_palloc(p, nsize);
|
||||
memcpy(buf, b->pos, size);
|
||||
memcpy(buf+size, str, len);
|
||||
b->start = (uint8_t *)buf;
|
||||
b->end = (uint8_t *)buf + nsize;
|
||||
b->pos = (uint8_t *)buf;
|
||||
b->last = (uint8_t *)buf + size + len;
|
||||
}
|
||||
}
|
||||
67
include/oss_sdk/aos_buf.h
Normal file
67
include/oss_sdk/aos_buf.h
Normal file
@@ -0,0 +1,67 @@
|
||||
#ifndef LIBAOS_BUF_H
|
||||
#define LIBAOS_BUF_H
|
||||
|
||||
#include "aos_define.h"
|
||||
#include "aos_list.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
uint8_t *pos;
|
||||
uint8_t *last;
|
||||
uint8_t *start;
|
||||
uint8_t *end;
|
||||
} aos_buf_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
int64_t file_pos;
|
||||
int64_t file_last;
|
||||
apr_file_t *file;
|
||||
uint32_t owner:1;
|
||||
} aos_file_buf_t;
|
||||
|
||||
aos_buf_t *aos_create_buf(aos_pool_t *p, int size);
|
||||
#define aos_buf_size(b) (b->last - b->pos)
|
||||
|
||||
aos_file_buf_t *aos_create_file_buf(aos_pool_t *p);
|
||||
|
||||
aos_buf_t *aos_buf_pack(aos_pool_t *p, const void *data, int size);
|
||||
|
||||
int64_t aos_buf_list_len(aos_list_t *list);
|
||||
|
||||
char *aos_buf_list_content(aos_pool_t *p, aos_list_t *list);
|
||||
|
||||
void aos_buf_append_string(aos_pool_t *p, aos_buf_t *b, const char *str, int len);
|
||||
|
||||
/**
|
||||
* @param fb file_pos, file_last equal file_size.
|
||||
* @return AOSE_OK success, other failure.
|
||||
*/
|
||||
int aos_open_file_for_read(aos_pool_t *p, const char *path, aos_file_buf_t *fb);
|
||||
|
||||
int aos_open_file_for_all_read(aos_pool_t *p, const char *path, aos_file_buf_t *fb);
|
||||
|
||||
int aos_open_file_for_range_read(aos_pool_t *p, const char *path,
|
||||
int64_t file_pos, int64_t file_last,
|
||||
aos_file_buf_t *fb);
|
||||
|
||||
/**
|
||||
* create the file if not there, truncate if file exists.
|
||||
* @param fb not check file_pos, file_last.
|
||||
* @return AOSE_OK success, other failure.
|
||||
*/
|
||||
int aos_open_file_for_write(aos_pool_t *p, const char *path, aos_file_buf_t *fb);
|
||||
|
||||
/**
|
||||
* create the file if not there.
|
||||
* @param fb not check file_pos, file_last.
|
||||
* @return AOSE_OK success, other failure.
|
||||
*/
|
||||
int aos_open_file_for_write_notrunc(aos_pool_t *p, const char *path, aos_file_buf_t *fb);
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
|
||||
288
include/oss_sdk/aos_crc64.c
Normal file
288
include/oss_sdk/aos_crc64.c
Normal file
@@ -0,0 +1,288 @@
|
||||
/* aos_crc64.c -- compute CRC-64
|
||||
* Copyright (C) 2013 Mark Adler
|
||||
* Version 1.4 16 Dec 2013 Mark Adler
|
||||
*/
|
||||
|
||||
/*
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the author be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
Mark Adler
|
||||
madler@alumni.caltech.edu
|
||||
*/
|
||||
|
||||
/* Compute CRC-64 in the manner of xz, using the ECMA-182 polynomial,
|
||||
bit-reversed, with one's complement pre and post processing. Provide a
|
||||
means to combine separately computed CRC-64's. */
|
||||
|
||||
/* Version history:
|
||||
1.0 13 Dec 2013 First version
|
||||
1.1 13 Dec 2013 Fix comments in test code
|
||||
1.2 14 Dec 2013 Determine endianess at run time
|
||||
1.3 15 Dec 2013 Add eight-byte processing for big endian as well
|
||||
Make use of the pthread library optional
|
||||
1.4 16 Dec 2013 Make once variable volatile for limited thread protection
|
||||
*/
|
||||
|
||||
#include "aos_crc64.h"
|
||||
|
||||
/* 64-bit CRC polynomial with these coefficients, but reversed:
|
||||
64, 62, 57, 55, 54, 53, 52, 47, 46, 45, 40, 39, 38, 37, 35, 33, 32,
|
||||
31, 29, 27, 24, 23, 22, 21, 19, 17, 13, 12, 10, 9, 7, 4, 1, 0 */
|
||||
#define POLY UINT64_C(0xc96c5795d7870f42)
|
||||
|
||||
/* Tables for CRC calculation -- filled in by initialization functions that are
|
||||
called once. These could be replaced by constant tables generated in the
|
||||
same way. There are two tables, one for each endianess. Since these are
|
||||
static, i.e. local, one should be compiled out of existence if the compiler
|
||||
can evaluate the endianess check in crc64() at compile time. */
|
||||
static uint64_t crc64_little_table[8][256];
|
||||
static uint64_t crc64_big_table[8][256];
|
||||
|
||||
/* Fill in the CRC-64 constants table. */
|
||||
static void crc64_init(uint64_t table[][256])
|
||||
{
|
||||
unsigned n, k;
|
||||
uint64_t crc;
|
||||
|
||||
/* generate CRC-64's for all single byte sequences */
|
||||
for (n = 0; n < 256; n++) {
|
||||
crc = n;
|
||||
for (k = 0; k < 8; k++)
|
||||
crc = crc & 1 ? POLY ^ (crc >> 1) : crc >> 1;
|
||||
table[0][n] = crc;
|
||||
}
|
||||
|
||||
/* generate CRC-64's for those followed by 1 to 7 zeros */
|
||||
for (n = 0; n < 256; n++) {
|
||||
crc = table[0][n];
|
||||
for (k = 1; k < 8; k++) {
|
||||
crc = table[0][crc & 0xff] ^ (crc >> 8);
|
||||
table[k][n] = crc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is called once to initialize the CRC-64 table for use on a
|
||||
little-endian architecture. */
|
||||
static void crc64_little_init(void)
|
||||
{
|
||||
crc64_init(crc64_little_table);
|
||||
}
|
||||
|
||||
/* Reverse the bytes in a 64-bit word. */
|
||||
static APR_INLINE uint64_t rev8(uint64_t a)
|
||||
{
|
||||
uint64_t m;
|
||||
|
||||
m = UINT64_C(0xff00ff00ff00ff);
|
||||
a = ((a >> 8) & m) | (a & m) << 8;
|
||||
m = UINT64_C(0xffff0000ffff);
|
||||
a = ((a >> 16) & m) | (a & m) << 16;
|
||||
return a >> 32 | a << 32;
|
||||
}
|
||||
|
||||
/* This function is called once to initialize the CRC-64 table for use on a
|
||||
big-endian architecture. */
|
||||
static void crc64_big_init(void)
|
||||
{
|
||||
unsigned k, n;
|
||||
|
||||
crc64_init(crc64_big_table);
|
||||
for (k = 0; k < 8; k++)
|
||||
for (n = 0; n < 256; n++)
|
||||
crc64_big_table[k][n] = rev8(crc64_big_table[k][n]);
|
||||
}
|
||||
|
||||
/* Run the init() function exactly once. If pthread.h is not included, then
|
||||
this macro will use a simple static state variable for the purpose, which is
|
||||
not thread-safe. The init function must be of the type void init(void). */
|
||||
#ifdef PTHREAD_ONCE_INIT
|
||||
# define ONCE(init) \
|
||||
do { \
|
||||
static pthread_once_t once = PTHREAD_ONCE_INIT; \
|
||||
pthread_once(&once, init); \
|
||||
} while (0)
|
||||
#else
|
||||
# define ONCE(init) \
|
||||
do { \
|
||||
static volatile int once = 1; \
|
||||
if (once) { \
|
||||
if (once++ == 1) { \
|
||||
init(); \
|
||||
once = 0; \
|
||||
} \
|
||||
else \
|
||||
while (once) \
|
||||
; \
|
||||
} \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
/* Calculate a CRC-64 eight bytes at a time on a little-endian architecture. */
|
||||
static APR_INLINE uint64_t crc64_little(uint64_t crc, void *buf, size_t len)
|
||||
{
|
||||
unsigned char *next = buf;
|
||||
|
||||
ONCE(crc64_little_init);
|
||||
crc = ~crc;
|
||||
while (len && ((uintptr_t)next & 7) != 0) {
|
||||
crc = crc64_little_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
|
||||
len--;
|
||||
}
|
||||
while (len >= 8) {
|
||||
crc ^= *(uint64_t *)next;
|
||||
crc = crc64_little_table[7][crc & 0xff] ^
|
||||
crc64_little_table[6][(crc >> 8) & 0xff] ^
|
||||
crc64_little_table[5][(crc >> 16) & 0xff] ^
|
||||
crc64_little_table[4][(crc >> 24) & 0xff] ^
|
||||
crc64_little_table[3][(crc >> 32) & 0xff] ^
|
||||
crc64_little_table[2][(crc >> 40) & 0xff] ^
|
||||
crc64_little_table[1][(crc >> 48) & 0xff] ^
|
||||
crc64_little_table[0][crc >> 56];
|
||||
next += 8;
|
||||
len -= 8;
|
||||
}
|
||||
while (len) {
|
||||
crc = crc64_little_table[0][(crc ^ *next++) & 0xff] ^ (crc >> 8);
|
||||
len--;
|
||||
}
|
||||
return ~crc;
|
||||
}
|
||||
|
||||
/* Calculate a CRC-64 eight bytes at a time on a big-endian architecture. */
|
||||
static APR_INLINE uint64_t crc64_big(uint64_t crc, void *buf, size_t len)
|
||||
{
|
||||
unsigned char *next = buf;
|
||||
|
||||
ONCE(crc64_big_init);
|
||||
crc = ~rev8(crc);
|
||||
while (len && ((uintptr_t)next & 7) != 0) {
|
||||
crc = crc64_big_table[0][(crc >> 56) ^ *next++] ^ (crc << 8);
|
||||
len--;
|
||||
}
|
||||
while (len >= 8) {
|
||||
crc ^= *(uint64_t *)next;
|
||||
crc = crc64_big_table[0][crc & 0xff] ^
|
||||
crc64_big_table[1][(crc >> 8) & 0xff] ^
|
||||
crc64_big_table[2][(crc >> 16) & 0xff] ^
|
||||
crc64_big_table[3][(crc >> 24) & 0xff] ^
|
||||
crc64_big_table[4][(crc >> 32) & 0xff] ^
|
||||
crc64_big_table[5][(crc >> 40) & 0xff] ^
|
||||
crc64_big_table[6][(crc >> 48) & 0xff] ^
|
||||
crc64_big_table[7][crc >> 56];
|
||||
next += 8;
|
||||
len -= 8;
|
||||
}
|
||||
while (len) {
|
||||
crc = crc64_big_table[0][(crc >> 56) ^ *next++] ^ (crc << 8);
|
||||
len--;
|
||||
}
|
||||
return ~rev8(crc);
|
||||
}
|
||||
|
||||
/* Return the CRC-64 of buf[0..len-1] with initial crc, processing eight bytes
|
||||
at a time. This selects one of two routines depending on the endianess of
|
||||
the architecture. A good optimizing compiler will determine the endianess
|
||||
at compile time if it can, and get rid of the unused code and table. If the
|
||||
endianess can be changed at run time, then this code will handle that as
|
||||
well, initializing and using two tables, if called upon to do so. */
|
||||
uint64_t aos_crc64(uint64_t crc, void *buf, size_t len)
|
||||
{
|
||||
uint64_t n = 1;
|
||||
|
||||
return *(char *)&n ? crc64_little(crc, buf, len) :
|
||||
crc64_big(crc, buf, len);
|
||||
}
|
||||
|
||||
#define GF2_DIM 64 /* dimension of GF(2) vectors (length of CRC) */
|
||||
|
||||
static uint64_t gf2_matrix_times(uint64_t *mat, uint64_t vec)
|
||||
{
|
||||
uint64_t sum;
|
||||
|
||||
sum = 0;
|
||||
while (vec) {
|
||||
if (vec & 1)
|
||||
sum ^= *mat;
|
||||
vec >>= 1;
|
||||
mat++;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
static void gf2_matrix_square(uint64_t *square, uint64_t *mat)
|
||||
{
|
||||
unsigned n;
|
||||
|
||||
for (n = 0; n < GF2_DIM; n++)
|
||||
square[n] = gf2_matrix_times(mat, mat[n]);
|
||||
}
|
||||
|
||||
/* Return the CRC-64 of two sequential blocks, where crc1 is the CRC-64 of the
|
||||
first block, crc2 is the CRC-64 of the second block, and len2 is the length
|
||||
of the second block. */
|
||||
uint64_t aos_crc64_combine(uint64_t crc1, uint64_t crc2, uintmax_t len2)
|
||||
{
|
||||
unsigned n;
|
||||
uint64_t row;
|
||||
uint64_t even[GF2_DIM]; /* even-power-of-two zeros operator */
|
||||
uint64_t odd[GF2_DIM]; /* odd-power-of-two zeros operator */
|
||||
|
||||
/* degenerate case */
|
||||
if (len2 == 0)
|
||||
return crc1;
|
||||
|
||||
/* put operator for one zero bit in odd */
|
||||
odd[0] = POLY; /* CRC-64 polynomial */
|
||||
row = 1;
|
||||
for (n = 1; n < GF2_DIM; n++) {
|
||||
odd[n] = row;
|
||||
row <<= 1;
|
||||
}
|
||||
|
||||
/* put operator for two zero bits in even */
|
||||
gf2_matrix_square(even, odd);
|
||||
|
||||
/* put operator for four zero bits in odd */
|
||||
gf2_matrix_square(odd, even);
|
||||
|
||||
/* apply len2 zeros to crc1 (first square will put the operator for one
|
||||
zero byte, eight zero bits, in even) */
|
||||
do {
|
||||
/* apply zeros operator for this bit of len2 */
|
||||
gf2_matrix_square(even, odd);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(even, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
if (len2 == 0)
|
||||
break;
|
||||
|
||||
/* another iteration of the loop with odd and even swapped */
|
||||
gf2_matrix_square(odd, even);
|
||||
if (len2 & 1)
|
||||
crc1 = gf2_matrix_times(odd, crc1);
|
||||
len2 >>= 1;
|
||||
|
||||
/* if no more bits set, then done */
|
||||
} while (len2 != 0);
|
||||
|
||||
/* return combined crc */
|
||||
crc1 ^= crc2;
|
||||
return crc1;
|
||||
}
|
||||
13
include/oss_sdk/aos_crc64.h
Normal file
13
include/oss_sdk/aos_crc64.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef LIBAOS_CRC_H
|
||||
#define LIBAOS_CRC_H
|
||||
|
||||
#include "aos_define.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
uint64_t aos_crc64(uint64_t crc, void *buf, size_t len);
|
||||
uint64_t aos_crc64_combine(uint64_t crc1, uint64_t crc2, uintmax_t len2);
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
152
include/oss_sdk/aos_define.h
Normal file
152
include/oss_sdk/aos_define.h
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef LIBAOS_DEFINE_H
|
||||
#define LIBAOS_DEFINE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include <apr_time.h>
|
||||
#include <apr_strings.h>
|
||||
#include <apr_pools.h>
|
||||
#include <apr_tables.h>
|
||||
#include <apr_file_io.h>
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define AOS_CPP_START extern "C" {
|
||||
# define AOS_CPP_END }
|
||||
#else
|
||||
# define AOS_CPP_START
|
||||
# define AOS_CPP_END
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
HTTP_GET,
|
||||
HTTP_HEAD,
|
||||
HTTP_PUT,
|
||||
HTTP_POST,
|
||||
HTTP_DELETE
|
||||
} http_method_e;
|
||||
|
||||
typedef enum {
|
||||
AOSE_OK = 0,
|
||||
AOSE_OUT_MEMORY = -1000,
|
||||
AOSE_OVER_MEMORY = -999,
|
||||
AOSE_FAILED_CONNECT = -998,
|
||||
AOSE_ABORT_CALLBACK = -997,
|
||||
AOSE_INTERNAL_ERROR = -996,
|
||||
AOSE_REQUEST_TIMEOUT = -995,
|
||||
AOSE_INVALID_ARGUMENT = -994,
|
||||
AOSE_INVALID_OPERATION = -993,
|
||||
AOSE_CONNECTION_FAILED = -992,
|
||||
AOSE_FAILED_INITIALIZE = -991,
|
||||
AOSE_NAME_LOOKUP_ERROR = -990,
|
||||
AOSE_FAILED_VERIFICATION = -989,
|
||||
AOSE_WRITE_BODY_ERROR = -988,
|
||||
AOSE_READ_BODY_ERROR = -987,
|
||||
AOSE_SERVICE_ERROR = -986,
|
||||
AOSE_OPEN_FILE_ERROR = -985,
|
||||
AOSE_FILE_SEEK_ERROR = -984,
|
||||
AOSE_FILE_INFO_ERROR = -983,
|
||||
AOSE_FILE_READ_ERROR = -982,
|
||||
AOSE_FILE_WRITE_ERROR = -981,
|
||||
AOSE_XML_PARSE_ERROR = -980,
|
||||
AOSE_UTF8_ENCODE_ERROR = -979,
|
||||
AOSE_CRC_INCONSISTENT_ERROR = -978,
|
||||
AOSE_FILE_FLUSH_ERROR = -977,
|
||||
AOSE_FILE_TRUNC_ERROR = -976,
|
||||
AOSE_UNKNOWN_ERROR = -100
|
||||
} aos_error_code_e;
|
||||
|
||||
typedef apr_pool_t aos_pool_t;
|
||||
typedef apr_table_t aos_table_t;
|
||||
typedef apr_table_entry_t aos_table_entry_t;
|
||||
typedef apr_array_header_t aos_array_header_t;
|
||||
|
||||
#define aos_table_elts(t) apr_table_elts(t)
|
||||
#define aos_is_empty_table(t) apr_is_empty_table(t)
|
||||
#define aos_table_make(p, n) apr_table_make(p, n)
|
||||
#define aos_table_add_int(t, key, value) do { \
|
||||
char value_str[64]; \
|
||||
apr_snprintf(value_str, sizeof(value_str), "%d", value);\
|
||||
apr_table_add(t, key, value_str); \
|
||||
} while(0)
|
||||
|
||||
#define aos_table_add_int64(t, key, value) do { \
|
||||
char value_str[64]; \
|
||||
apr_snprintf(value_str, sizeof(value_str), "%" APR_INT64_T_FMT, value);\
|
||||
apr_table_add(t, key, value_str); \
|
||||
} while(0)
|
||||
|
||||
#define aos_table_set_int64(t, key, value) do { \
|
||||
char value_str[64]; \
|
||||
apr_snprintf(value_str, sizeof(value_str), "%" APR_INT64_T_FMT, value);\
|
||||
apr_table_set(t, key, value_str); \
|
||||
} while(0)
|
||||
|
||||
#define aos_pool_create(n, p) apr_pool_create(n, p)
|
||||
#define aos_pool_destroy(p) apr_pool_destroy(p)
|
||||
#define aos_palloc(p, s) apr_palloc(p, s)
|
||||
#define aos_pcalloc(p, s) apr_pcalloc(p, s)
|
||||
|
||||
#define AOS_INIT_WINSOCK 1
|
||||
#define AOS_MD5_STRING_LEN 32
|
||||
#define AOS_MAX_URI_LEN 2048
|
||||
#define AOS_MAX_HEADER_LEN 8192
|
||||
#define AOS_MAX_QUERY_ARG_LEN 1024
|
||||
#define AOS_MAX_GMT_TIME_LEN 128
|
||||
|
||||
#define AOS_MAX_XML_NODE_VALUE_LEN 1024
|
||||
#define AOS_MAX_INT64_STRING_LEN 64
|
||||
#define AOS_MAX_UINT64_STRING_LEN 64
|
||||
|
||||
#define AOS_CONNECT_TIMEOUT 10
|
||||
#define AOS_DNS_CACHE_TIMOUT 60
|
||||
#define AOS_MIN_SPEED_LIMIT 1024
|
||||
#define AOS_MIN_SPEED_TIME 15
|
||||
#define AOS_MAX_MEMORY_SIZE 1024*1024*1024L
|
||||
#define AOS_MAX_PART_SIZE 512*1024*1024L
|
||||
#define AOS_DEFAULT_PART_SIZE 1024*1024L
|
||||
|
||||
#define AOS_REQUEST_STACK_SIZE 32
|
||||
|
||||
#define aos_abs(value) (((value) >= 0) ? (value) : - (value))
|
||||
#define aos_max(val1, val2) (((val1) < (val2)) ? (val2) : (val1))
|
||||
#define aos_min(val1, val2) (((val1) > (val2)) ? (val2) : (val1))
|
||||
|
||||
#define LF (char) 10
|
||||
#define CR (char) 13
|
||||
#define CRLF "\x0d\x0a"
|
||||
|
||||
#define AOS_VERSION "3.5.0"
|
||||
#define AOS_VER "aliyun-sdk-c/" AOS_VERSION
|
||||
|
||||
#define AOS_HTTP_PREFIX "http://"
|
||||
#define AOS_HTTPS_PREFIX "https://"
|
||||
#define AOS_RTMP_PREFIX "rtmp://"
|
||||
|
||||
#define AOS_TEMP_FILE_SUFFIX ".tmp"
|
||||
|
||||
#define AOS_FALSE 0
|
||||
#define AOS_TRUE 1
|
||||
|
||||
# ifndef WIN32
|
||||
# ifndef __LONG_LONG_MAX__
|
||||
# define __LONG_LONG_MAX__ 9223372036854775807LL
|
||||
# endif
|
||||
# ifndef LLONG_MIN
|
||||
# define LLONG_MIN (-LLONG_MAX-1)
|
||||
# endif
|
||||
# ifndef LLONG_MAX
|
||||
# define LLONG_MAX __LONG_LONG_MAX__
|
||||
# endif
|
||||
# ifndef ULLONG_MAX
|
||||
# define ULLONG_MAX (LLONG_MAX * 2ULL + 1)
|
||||
# endif
|
||||
# endif
|
||||
|
||||
#endif
|
||||
50
include/oss_sdk/aos_fstack.c
Normal file
50
include/oss_sdk/aos_fstack.c
Normal file
@@ -0,0 +1,50 @@
|
||||
#include "aos_fstack.h"
|
||||
|
||||
aos_array_header_t *aos_fstack_create(aos_pool_t *p, int size)
|
||||
{
|
||||
return apr_array_make(p, size, sizeof(aos_fstack_item_t));
|
||||
}
|
||||
|
||||
void aos_fstack_push(aos_array_header_t *fstack, void *data, aos_func_u func, int order)
|
||||
{
|
||||
aos_fstack_item_t *item;
|
||||
|
||||
item = (aos_fstack_item_t*)apr_array_push(fstack);
|
||||
item->data = data;
|
||||
item->func = func;
|
||||
item->order = order;
|
||||
}
|
||||
|
||||
aos_fstack_item_t *aos_fstack_pop(aos_array_header_t *fstack)
|
||||
{
|
||||
aos_fstack_item_t *item;
|
||||
|
||||
item = (aos_fstack_item_t*)apr_array_pop(fstack);
|
||||
if (item == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (item->order) {
|
||||
case 1:
|
||||
item->func.func1(item->data);
|
||||
break;
|
||||
case 2:
|
||||
item->func.func2();
|
||||
break;
|
||||
case 3:
|
||||
item->func.func3(item->data);
|
||||
break;
|
||||
case 4:
|
||||
item->func.func4();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
void aos_fstack_destory(aos_array_header_t *fstack)
|
||||
{
|
||||
while (aos_fstack_pop(fstack) != NULL);
|
||||
}
|
||||
36
include/oss_sdk/aos_fstack.h
Normal file
36
include/oss_sdk/aos_fstack.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef LIBAOS_FSTACK_H
|
||||
#define LIBAOS_FSTACK_H
|
||||
|
||||
#include "aos_define.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
typedef void (*aos_func1_pt)(void*);
|
||||
typedef void (*aos_func2_pt)();
|
||||
typedef int (*aos_func3_pt)(void*);
|
||||
typedef int (*aos_func4_pt)();
|
||||
|
||||
typedef union aos_func_u {
|
||||
aos_func1_pt func1;
|
||||
aos_func2_pt func2;
|
||||
aos_func3_pt func3;
|
||||
aos_func4_pt func4;
|
||||
} aos_func_u;
|
||||
|
||||
typedef struct aos_fstack_item_t {
|
||||
void *data;
|
||||
aos_func_u func;
|
||||
int order;
|
||||
} aos_fstack_item_t;
|
||||
|
||||
aos_array_header_t *aos_fstack_create(aos_pool_t *p, int size);
|
||||
|
||||
aos_fstack_item_t *aos_fstack_pop(aos_array_header_t *fstack);
|
||||
|
||||
void aos_fstack_destory(aos_array_header_t *fstack);
|
||||
|
||||
void aos_fstack_push(aos_array_header_t *fstack, void *data, aos_func_u func, int order);
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
332
include/oss_sdk/aos_http_io.c
Normal file
332
include/oss_sdk/aos_http_io.c
Normal file
@@ -0,0 +1,332 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_http_io.h"
|
||||
#include "aos_define.h"
|
||||
#include <apr_thread_mutex.h>
|
||||
#include <apr_file_io.h>
|
||||
|
||||
aos_pool_t *aos_global_pool = NULL;
|
||||
apr_file_t *aos_stderr_file = NULL;
|
||||
|
||||
aos_http_request_options_t *aos_default_http_request_options = NULL;
|
||||
aos_http_transport_options_t *aos_default_http_transport_options = NULL;
|
||||
|
||||
aos_http_transport_create_pt aos_http_transport_create = aos_curl_http_transport_create;
|
||||
aos_http_transport_perform_pt aos_http_transport_perform = aos_curl_http_transport_perform;
|
||||
|
||||
static apr_thread_mutex_t* requestStackMutexG = NULL;
|
||||
static CURL *requestStackG[AOS_REQUEST_STACK_SIZE];
|
||||
static int requestStackCountG;
|
||||
static char aos_user_agent[256];
|
||||
|
||||
|
||||
static aos_http_transport_options_t *aos_http_transport_options_create(aos_pool_t *p);
|
||||
|
||||
CURL *aos_request_get()
|
||||
{
|
||||
CURL *request = NULL;
|
||||
|
||||
apr_thread_mutex_lock(requestStackMutexG);
|
||||
if (requestStackCountG > 0) {
|
||||
request = requestStackG[--requestStackCountG];
|
||||
}
|
||||
apr_thread_mutex_unlock(requestStackMutexG);
|
||||
|
||||
// If we got one, deinitialize it for re-use
|
||||
if (request) {
|
||||
curl_easy_reset(request);
|
||||
}
|
||||
else {
|
||||
request = curl_easy_init();
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
void request_release(CURL *request)
|
||||
{
|
||||
apr_thread_mutex_lock(requestStackMutexG);
|
||||
|
||||
// If the request stack is full, destroy this one
|
||||
// else put this one at the front of the request stack; we do this because
|
||||
// we want the most-recently-used curl handle to be re-used on the next
|
||||
// request, to maximize our chances of re-using a TCP connection before it
|
||||
// times out
|
||||
if (requestStackCountG == AOS_REQUEST_STACK_SIZE) {
|
||||
apr_thread_mutex_unlock(requestStackMutexG);
|
||||
curl_easy_cleanup(request);
|
||||
}
|
||||
else {
|
||||
requestStackG[requestStackCountG++] = request;
|
||||
apr_thread_mutex_unlock(requestStackMutexG);
|
||||
}
|
||||
}
|
||||
|
||||
void aos_set_default_request_options(aos_http_request_options_t *op)
|
||||
{
|
||||
aos_default_http_request_options = op;
|
||||
}
|
||||
|
||||
void aos_set_default_transport_options(aos_http_transport_options_t *op)
|
||||
{
|
||||
aos_default_http_transport_options = op;
|
||||
}
|
||||
|
||||
aos_http_request_options_t *aos_http_request_options_create(aos_pool_t *p)
|
||||
{
|
||||
aos_http_request_options_t *options;
|
||||
|
||||
options = (aos_http_request_options_t *)aos_pcalloc(p, sizeof(aos_http_request_options_t));
|
||||
options->speed_limit = AOS_MIN_SPEED_LIMIT;
|
||||
options->speed_time = AOS_MIN_SPEED_TIME;
|
||||
options->connect_timeout = AOS_CONNECT_TIMEOUT;
|
||||
options->dns_cache_timeout = AOS_DNS_CACHE_TIMOUT;
|
||||
options->max_memory_size = AOS_MAX_MEMORY_SIZE;
|
||||
options->enable_crc = AOS_TRUE;
|
||||
options->proxy_auth = NULL;
|
||||
options->proxy_host = NULL;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
aos_http_transport_options_t *aos_http_transport_options_create(aos_pool_t *p)
|
||||
{
|
||||
return (aos_http_transport_options_t *)aos_pcalloc(p, sizeof(aos_http_transport_options_t));
|
||||
}
|
||||
|
||||
aos_http_controller_t *aos_http_controller_create(aos_pool_t *p, int owner)
|
||||
{
|
||||
int s;
|
||||
aos_http_controller_t *ctl;
|
||||
|
||||
if(p == NULL) {
|
||||
if ((s = aos_pool_create(&p, NULL)) != APR_SUCCESS) {
|
||||
aos_fatal_log("aos_pool_create failure.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ctl = (aos_http_controller_t *)aos_pcalloc(p, sizeof(aos_http_controller_ex_t));
|
||||
ctl->pool = p;
|
||||
ctl->owner = owner;
|
||||
ctl->options = aos_default_http_request_options;
|
||||
|
||||
return ctl;
|
||||
}
|
||||
|
||||
aos_http_request_t *aos_http_request_create(aos_pool_t *p)
|
||||
{
|
||||
aos_http_request_t *req;
|
||||
|
||||
req = (aos_http_request_t *)aos_pcalloc(p, sizeof(aos_http_request_t));
|
||||
req->method = HTTP_GET;
|
||||
req->headers = aos_table_make(p, 5);
|
||||
req->query_params = aos_table_make(p, 3);
|
||||
aos_list_init(&req->body);
|
||||
req->type = BODY_IN_MEMORY;
|
||||
req->body_len = 0;
|
||||
req->pool = p;
|
||||
req->read_body = aos_read_http_body_memory;
|
||||
|
||||
return req;
|
||||
}
|
||||
|
||||
aos_http_response_t *aos_http_response_create(aos_pool_t *p)
|
||||
{
|
||||
aos_http_response_t *resp;
|
||||
|
||||
resp = (aos_http_response_t *)aos_pcalloc(p, sizeof(aos_http_response_t));
|
||||
resp->status = -1;
|
||||
resp->headers = aos_table_make(p, 10);
|
||||
aos_list_init(&resp->body);
|
||||
resp->type = BODY_IN_MEMORY;
|
||||
resp->body_len = 0;
|
||||
resp->pool = p;
|
||||
resp->write_body = aos_write_http_body_memory;
|
||||
|
||||
return resp;
|
||||
}
|
||||
|
||||
int aos_read_http_body_memory(aos_http_request_t *req, char *buffer, int len)
|
||||
{
|
||||
int wsize;
|
||||
int bytes = 0;
|
||||
aos_buf_t *b;
|
||||
aos_buf_t *n;
|
||||
|
||||
aos_list_for_each_entry_safe(aos_buf_t, b, n, &req->body, node) {
|
||||
wsize = aos_buf_size(b);
|
||||
if (wsize == 0) {
|
||||
aos_list_del(&b->node);
|
||||
continue;
|
||||
}
|
||||
wsize = aos_min(len - bytes, wsize);
|
||||
if (wsize == 0) {
|
||||
break;
|
||||
}
|
||||
memcpy(buffer + bytes, b->pos, wsize);
|
||||
b->pos += wsize;
|
||||
bytes += wsize;
|
||||
if (b->pos == b->last) {
|
||||
aos_list_del(&b->node);
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
int aos_read_http_body_file(aos_http_request_t *req, char *buffer, int len)
|
||||
{
|
||||
int s;
|
||||
char buf[256];
|
||||
apr_size_t nbytes = len;
|
||||
apr_size_t bytes_left;
|
||||
|
||||
if (req->file_buf == NULL || req->file_buf->file == NULL) {
|
||||
aos_error_log("request body arg invalid file_buf NULL.");
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
if (req->file_buf->file_pos >= req->file_buf->file_last) {
|
||||
aos_debug_log("file read finish.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
bytes_left = (apr_size_t)(req->file_buf->file_last - req->file_buf->file_pos);
|
||||
if (nbytes > bytes_left) {
|
||||
nbytes = bytes_left;
|
||||
}
|
||||
|
||||
if ((s = apr_file_read(req->file_buf->file, buffer, &nbytes)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_file_read filure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
return AOSE_FILE_READ_ERROR;
|
||||
}
|
||||
req->file_buf->file_pos += nbytes;
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
int aos_write_http_body_memory(aos_http_response_t *resp, const char *buffer, int len)
|
||||
{
|
||||
aos_buf_t *b;
|
||||
|
||||
b = aos_create_buf(resp->pool, len);
|
||||
memcpy(b->pos, buffer, len);
|
||||
b->last += len;
|
||||
aos_list_add_tail(&b->node, &resp->body);
|
||||
resp->body_len += len;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int aos_write_http_body_file(aos_http_response_t *resp, const char *buffer, int len)
|
||||
{
|
||||
int elen;
|
||||
int s;
|
||||
char buf[256];
|
||||
apr_size_t nbytes = len;
|
||||
|
||||
if (resp->file_buf == NULL) {
|
||||
resp->file_buf = aos_create_file_buf(resp->pool);
|
||||
}
|
||||
|
||||
if (resp->file_buf->file == NULL) {
|
||||
if (resp->file_path == NULL) {
|
||||
aos_error_log("resp body file arg NULL.");
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
aos_trace_log("open file %s.", resp->file_path);
|
||||
if ((elen = aos_open_file_for_write(resp->pool, resp->file_path, resp->file_buf)) != AOSE_OK) {
|
||||
return elen;
|
||||
}
|
||||
}
|
||||
|
||||
assert(resp->file_buf->file != NULL);
|
||||
if ((s = apr_file_write(resp->file_buf->file, buffer, &nbytes)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_file_write fialure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
return AOSE_FILE_WRITE_ERROR;
|
||||
}
|
||||
|
||||
resp->file_buf->file_last += nbytes;
|
||||
resp->body_len += nbytes;
|
||||
|
||||
return nbytes;
|
||||
}
|
||||
|
||||
int aos_http_io_initialize(const char *user_agent_info, int flags)
|
||||
{
|
||||
CURLcode ecode;
|
||||
int s;
|
||||
char buf[256];
|
||||
aos_http_request_options_t *req_options;
|
||||
aos_http_transport_options_t *trans_options;
|
||||
|
||||
if ((ecode = curl_global_init(CURL_GLOBAL_ALL &
|
||||
~((flags & AOS_INIT_WINSOCK) ? 0: CURL_GLOBAL_WIN32))) != CURLE_OK)
|
||||
{
|
||||
aos_error_log("curl_global_init failure, code:%d %s.\n", ecode, curl_easy_strerror(ecode));
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((s = apr_initialize()) != APR_SUCCESS) {
|
||||
aos_error_log("apr_initialize failue.\n");
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if (!user_agent_info || !*user_agent_info) {
|
||||
user_agent_info = "Unknown";
|
||||
}
|
||||
|
||||
if ((s = aos_pool_create(&aos_global_pool, NULL)) != APR_SUCCESS) {
|
||||
aos_error_log("aos_pool_create failure, code:%d %s.\n", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((s = apr_thread_mutex_create(&requestStackMutexG, APR_THREAD_MUTEX_DEFAULT, aos_global_pool)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_thread_mutex_create failure, code:%d %s.\n", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
requestStackCountG = 0;
|
||||
|
||||
apr_snprintf(aos_user_agent, sizeof(aos_user_agent)-1, "%s(Compatible %s)",
|
||||
AOS_VER, user_agent_info);
|
||||
|
||||
req_options = aos_http_request_options_create(aos_global_pool);
|
||||
trans_options = aos_http_transport_options_create(aos_global_pool);
|
||||
trans_options->user_agent = aos_user_agent;
|
||||
|
||||
aos_set_default_request_options(req_options);
|
||||
aos_set_default_transport_options(trans_options);
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
void aos_http_io_deinitialize()
|
||||
{
|
||||
apr_thread_mutex_destroy(requestStackMutexG);
|
||||
|
||||
while (requestStackCountG--) {
|
||||
curl_easy_cleanup(requestStackG[requestStackCountG]);
|
||||
}
|
||||
|
||||
if (aos_stderr_file != NULL) {
|
||||
apr_file_close(aos_stderr_file);
|
||||
aos_stderr_file = NULL;
|
||||
}
|
||||
if (aos_global_pool != NULL) {
|
||||
aos_pool_destroy(aos_global_pool);
|
||||
aos_global_pool = NULL;
|
||||
}
|
||||
apr_terminate();
|
||||
}
|
||||
|
||||
int aos_http_send_request(aos_http_controller_t *ctl, aos_http_request_t *req, aos_http_response_t *resp)
|
||||
{
|
||||
aos_http_transport_t *t;
|
||||
|
||||
t = aos_http_transport_create(ctl->pool);
|
||||
t->req = req;
|
||||
t->resp = resp;
|
||||
t->controller = (aos_http_controller_ex_t *)ctl;
|
||||
|
||||
return aos_http_transport_perform(t);
|
||||
}
|
||||
|
||||
55
include/oss_sdk/aos_http_io.h
Normal file
55
include/oss_sdk/aos_http_io.h
Normal file
@@ -0,0 +1,55 @@
|
||||
#ifndef LIBAOS_HTTP_IO_H
|
||||
#define LIBAOS_HTTP_IO_H
|
||||
|
||||
#include "aos_transport.h"
|
||||
#include "oss_define.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
aos_http_controller_t *aos_http_controller_create(aos_pool_t *p, int owner);
|
||||
|
||||
/* http io error message*/
|
||||
static APR_INLINE const char *aos_http_controller_get_reason(aos_http_controller_t *ctl)
|
||||
{
|
||||
aos_http_controller_ex_t *ctle = (aos_http_controller_ex_t *)ctl;
|
||||
return ctle->reason;
|
||||
}
|
||||
|
||||
CURL *aos_request_get();
|
||||
void request_release(CURL *request);
|
||||
|
||||
int aos_http_io_initialize(const char *user_agent_info, int flag);
|
||||
void aos_http_io_deinitialize();
|
||||
|
||||
int aos_http_send_request(aos_http_controller_t *ctl, aos_http_request_t *req, aos_http_response_t *resp);
|
||||
|
||||
void aos_set_default_request_options(aos_http_request_options_t *op);
|
||||
void aos_set_default_transport_options(aos_http_transport_options_t *op);
|
||||
|
||||
aos_http_request_options_t *aos_http_request_options_create(aos_pool_t *p);
|
||||
|
||||
aos_http_request_t *aos_http_request_create(aos_pool_t *p);
|
||||
aos_http_response_t *aos_http_response_create(aos_pool_t *p);
|
||||
|
||||
int aos_read_http_body_memory(aos_http_request_t *req, char *buffer, int len);
|
||||
int aos_write_http_body_memory(aos_http_response_t *resp, const char *buffer, int len);
|
||||
|
||||
int aos_read_http_body_file(aos_http_request_t *req, char *buffer, int len);
|
||||
int aos_write_http_body_file(aos_http_response_t *resp, const char *buffer, int len);
|
||||
|
||||
typedef aos_http_transport_t *(*aos_http_transport_create_pt)(aos_pool_t *p);
|
||||
typedef int (*aos_http_transport_perform_pt)(aos_http_transport_t *t);
|
||||
|
||||
extern aos_pool_t *aos_global_pool;
|
||||
extern apr_file_t *aos_stderr_file;
|
||||
|
||||
extern aos_http_request_options_t *aos_default_http_request_options;
|
||||
extern aos_http_transport_options_t *aos_default_http_transport_options;
|
||||
|
||||
extern aos_http_transport_create_pt aos_http_transport_create;
|
||||
extern aos_http_transport_perform_pt aos_http_transport_perform;
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
|
||||
101
include/oss_sdk/aos_list.h
Normal file
101
include/oss_sdk/aos_list.h
Normal file
@@ -0,0 +1,101 @@
|
||||
#ifndef LIBAOS_LIST_H
|
||||
#define LIBAOS_LIST_H
|
||||
|
||||
#include <apr_general.h>
|
||||
|
||||
// from kernel list
|
||||
typedef struct aos_list_s aos_list_t;
|
||||
|
||||
struct aos_list_s {
|
||||
aos_list_t *next, *prev;
|
||||
};
|
||||
|
||||
#define aos_list_head_init(name) {&(name), &(name)}
|
||||
|
||||
#define aos_list_init(ptr) do { \
|
||||
(ptr)->next = (ptr); \
|
||||
(ptr)->prev = (ptr); \
|
||||
} while (0)
|
||||
|
||||
static APR_INLINE void __aos_list_add(aos_list_t *list, aos_list_t *prev, aos_list_t *next)
|
||||
{
|
||||
next->prev = list;
|
||||
list->next = next;
|
||||
list->prev = prev;
|
||||
prev->next = list;
|
||||
}
|
||||
|
||||
// list head to add it before
|
||||
static APR_INLINE void aos_list_add_tail(aos_list_t *list, aos_list_t *head)
|
||||
{
|
||||
__aos_list_add(list, head->prev, head);
|
||||
}
|
||||
|
||||
static APR_INLINE void __aos_list_del(aos_list_t *prev, aos_list_t *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
// deletes entry from list
|
||||
static APR_INLINE void aos_list_del(aos_list_t *entry)
|
||||
{
|
||||
__aos_list_del(entry->prev, entry->next);
|
||||
aos_list_init(entry);
|
||||
}
|
||||
|
||||
// tests whether a list is empty
|
||||
static APR_INLINE int aos_list_empty(const aos_list_t *head)
|
||||
{
|
||||
return (head->next == head);
|
||||
}
|
||||
|
||||
// move list to new_list
|
||||
static APR_INLINE void aos_list_movelist(aos_list_t *list, aos_list_t *new_list)
|
||||
{
|
||||
if (!aos_list_empty(list)) {
|
||||
new_list->prev = list->prev;
|
||||
new_list->next = list->next;
|
||||
new_list->prev->next = new_list;
|
||||
new_list->next->prev = new_list;
|
||||
aos_list_init(list);
|
||||
} else {
|
||||
aos_list_init(new_list);
|
||||
}
|
||||
}
|
||||
|
||||
// get last
|
||||
#define aos_list_get_last(list, type, member) \
|
||||
aos_list_empty(list) ? NULL : aos_list_entry((list)->prev, type, member)
|
||||
|
||||
// get first
|
||||
#define aos_list_get_first(list, type, member) \
|
||||
aos_list_empty(list) ? NULL : aos_list_entry((list)->next, type, member)
|
||||
|
||||
#define aos_list_entry(ptr, type, member) \
|
||||
(type *)( (char *)ptr - APR_OFFSETOF(type, member) )
|
||||
|
||||
// traversing
|
||||
#define aos_list_for_each_entry(postp, pos, head, member) \
|
||||
for (pos = aos_list_entry((head)->next, postp, member); \
|
||||
&pos->member != (head); \
|
||||
pos = aos_list_entry(pos->member.next, postp, member))
|
||||
|
||||
#define aos_list_for_each_entry_reverse(postp, pos, head, member) \
|
||||
for (pos = aos_list_entry((head)->prev, postp, member); \
|
||||
&pos->member != (head); \
|
||||
pos = aos_list_entry(pos->member.prev, postp, member))
|
||||
|
||||
#define aos_list_for_each_entry_safe(postp, pos, n, head, member) \
|
||||
for (pos = aos_list_entry((head)->next, postp, member), \
|
||||
n = aos_list_entry(pos->member.next, postp, member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = aos_list_entry(n->member.next, postp, member))
|
||||
|
||||
#define aos_list_for_each_entry_safe_reverse(postp, pos, n, head, member) \
|
||||
for (pos = aos_list_entry((head)->prev, postp, member), \
|
||||
n = aos_list_entry(pos->member.prev, postp, member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = aos_list_entry(n->member.prev, postp, member))
|
||||
|
||||
#endif
|
||||
73
include/oss_sdk/aos_log.c
Normal file
73
include/oss_sdk/aos_log.c
Normal file
@@ -0,0 +1,73 @@
|
||||
#include "aos_log.h"
|
||||
#include "apr_portable.h"
|
||||
|
||||
aos_log_print_pt aos_log_print = aos_log_print_default;
|
||||
aos_log_format_pt aos_log_format = aos_log_format_default;
|
||||
aos_log_level_e aos_log_level = AOS_LOG_WARN;
|
||||
|
||||
extern apr_file_t *aos_stderr_file;
|
||||
|
||||
void aos_log_set_print(aos_log_print_pt p)
|
||||
{
|
||||
aos_log_print = p;
|
||||
}
|
||||
|
||||
void aos_log_set_format(aos_log_format_pt p)
|
||||
{
|
||||
aos_log_format = p;
|
||||
}
|
||||
|
||||
void aos_log_set_level(aos_log_level_e level)
|
||||
{
|
||||
aos_log_level = level;
|
||||
}
|
||||
|
||||
void aos_log_set_output(apr_file_t *output)
|
||||
{
|
||||
aos_stderr_file = output;
|
||||
}
|
||||
|
||||
void aos_log_print_default(const char *message, int len)
|
||||
{
|
||||
if (aos_stderr_file == NULL) {
|
||||
fprintf(stderr, "%s", message);
|
||||
} else {
|
||||
apr_size_t bnytes = len;
|
||||
apr_file_write(aos_stderr_file, message, &bnytes);
|
||||
}
|
||||
}
|
||||
|
||||
void aos_log_format_default(int level,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *function,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
int len;
|
||||
apr_time_t t;
|
||||
int s;
|
||||
apr_time_exp_t tm;
|
||||
va_list args;
|
||||
char buffer[4096];
|
||||
|
||||
t = apr_time_now();
|
||||
if ((s = apr_time_exp_lt(&tm, t)) != APR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
len = apr_snprintf(buffer, 4090, "[%04d-%02d-%02d %02d:%02d:%02d.%03d] %" APR_INT64_T_FMT " %s:%d ",
|
||||
tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
|
||||
tm.tm_hour, tm.tm_min, tm.tm_sec, tm.tm_usec/1000,
|
||||
(int64_t)apr_os_thread_current(), file, line);
|
||||
|
||||
va_start(args, fmt);
|
||||
len += vsnprintf(buffer + len, 4090 - len, fmt, args);
|
||||
va_end(args);
|
||||
|
||||
while (buffer[len -1] == '\n') len--;
|
||||
buffer[len++] = '\n';
|
||||
buffer[len] = '\0';
|
||||
|
||||
aos_log_print(buffer, len);
|
||||
}
|
||||
|
||||
78
include/oss_sdk/aos_log.h
Normal file
78
include/oss_sdk/aos_log.h
Normal file
@@ -0,0 +1,78 @@
|
||||
#ifndef LIBAOS_LOG_H
|
||||
#define LIBAOS_LOG_H
|
||||
|
||||
#include "aos_define.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
typedef void (*aos_log_print_pt)(const char *message, int len);
|
||||
|
||||
typedef void (*aos_log_format_pt)(int level,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *function,
|
||||
const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 5, 6)));
|
||||
|
||||
void aos_log_set_print(aos_log_print_pt p);
|
||||
void aos_log_set_format(aos_log_format_pt p);
|
||||
|
||||
typedef enum {
|
||||
AOS_LOG_OFF = 1,
|
||||
AOS_LOG_FATAL,
|
||||
AOS_LOG_ERROR,
|
||||
AOS_LOG_WARN,
|
||||
AOS_LOG_INFO,
|
||||
AOS_LOG_DEBUG,
|
||||
AOS_LOG_TRACE,
|
||||
AOS_LOG_ALL
|
||||
} aos_log_level_e;
|
||||
|
||||
#ifdef WIN32
|
||||
#define aos_fatal_log(format, ...) if(aos_log_level>=AOS_LOG_FATAL) \
|
||||
aos_log_format(AOS_LOG_FATAL, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
|
||||
#define aos_error_log(format, ...) if(aos_log_level>=AOS_LOG_ERROR) \
|
||||
aos_log_format(AOS_LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
|
||||
#define aos_warn_log(format, ...) if(aos_log_level>=AOS_LOG_WARN) \
|
||||
aos_log_format(AOS_LOG_WARN, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
|
||||
#define aos_info_log(format, ...) if(aos_log_level>=AOS_LOG_INFO) \
|
||||
aos_log_format(AOS_LOG_INFO, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
|
||||
#define aos_debug_log(format, ...) if(aos_log_level>=AOS_LOG_DEBUG) \
|
||||
aos_log_format(AOS_LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
|
||||
#define aos_trace_log(format, ...) if(aos_log_level>=AOS_LOG_TRACE) \
|
||||
aos_log_format(AOS_LOG_TRACE, __FILE__, __LINE__, __FUNCTION__, format, ##__VA_ARGS__)
|
||||
#else
|
||||
#define aos_fatal_log(format, args...) if(aos_log_level>=AOS_LOG_FATAL) \
|
||||
aos_log_format(AOS_LOG_FATAL, __FILE__, __LINE__, __FUNCTION__, format, ## args)
|
||||
#define aos_error_log(format, args...) if(aos_log_level>=AOS_LOG_ERROR) \
|
||||
aos_log_format(AOS_LOG_ERROR, __FILE__, __LINE__, __FUNCTION__, format, ## args)
|
||||
#define aos_warn_log(format, args...) if(aos_log_level>=AOS_LOG_WARN) \
|
||||
aos_log_format(AOS_LOG_WARN, __FILE__, __LINE__, __FUNCTION__, format, ## args)
|
||||
#define aos_info_log(format, args...) if(aos_log_level>=AOS_LOG_INFO) \
|
||||
aos_log_format(AOS_LOG_INFO, __FILE__, __LINE__, __FUNCTION__, format, ## args)
|
||||
#define aos_debug_log(format, args...) if(aos_log_level>=AOS_LOG_DEBUG) \
|
||||
aos_log_format(AOS_LOG_DEBUG, __FILE__, __LINE__, __FUNCTION__, format, ## args)
|
||||
#define aos_trace_log(format, args...) if(aos_log_level>=AOS_LOG_TRACE) \
|
||||
aos_log_format(AOS_LOG_TRACE, __FILE__, __LINE__, __FUNCTION__, format, ## args)
|
||||
#endif
|
||||
|
||||
void aos_log_set_level(aos_log_level_e level);
|
||||
|
||||
void aos_log_set_output(apr_file_t *output);
|
||||
|
||||
void aos_log_print_default(const char *message, int len);
|
||||
|
||||
void aos_log_format_default(int level,
|
||||
const char *file,
|
||||
int line,
|
||||
const char *function,
|
||||
const char *fmt, ...)
|
||||
__attribute__ ((__format__ (__printf__, 5, 6)));
|
||||
|
||||
extern aos_log_level_e aos_log_level;
|
||||
extern aos_log_format_pt aos_log_format;
|
||||
extern aos_log_format_pt aos_log_format;
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
108
include/oss_sdk/aos_status.c
Normal file
108
include/oss_sdk/aos_status.c
Normal file
@@ -0,0 +1,108 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_status.h"
|
||||
|
||||
const char AOS_XML_PARSE_ERROR_CODE[] = "ParseXmlError";
|
||||
const char AOS_OPEN_FILE_ERROR_CODE[] = "OpenFileFail";
|
||||
const char AOS_WRITE_FILE_ERROR_CODE[] = "WriteFileFail";
|
||||
const char AOS_RENAME_FILE_ERROR_CODE[] = "RenameFileFail";
|
||||
const char AOS_HTTP_IO_ERROR_CODE[] = "HttpIoError";
|
||||
const char AOS_UNKNOWN_ERROR_CODE[] = "UnknownError";
|
||||
const char AOS_CLIENT_ERROR_CODE[] = "ClientError";
|
||||
const char AOS_SERVER_ERROR_CODE[] = "ServerError";
|
||||
const char AOS_UTF8_ENCODE_ERROR_CODE[] = "Utf8EncodeFail";
|
||||
const char AOS_URL_ENCODE_ERROR_CODE[] = "UrlEncodeFail";
|
||||
const char AOS_INCONSISTENT_ERROR_CODE[] = "InconsistentError";
|
||||
const char AOS_CREATE_QUEUE_ERROR_CODE[] = "CreateQueueFail";
|
||||
const char AOS_CREATE_THREAD_POOL_ERROR_CODE[] = "CreateThreadPoolFail";
|
||||
|
||||
aos_status_t *aos_status_create(aos_pool_t *p)
|
||||
{
|
||||
return (aos_status_t *)aos_pcalloc(p, sizeof(aos_status_t));
|
||||
}
|
||||
|
||||
aos_status_t *aos_status_dup(aos_pool_t *p, aos_status_t *src)
|
||||
{
|
||||
aos_status_t *dst = aos_status_create(p);
|
||||
dst->code = src->code;
|
||||
dst->error_code = apr_pstrdup(p, src->error_code);
|
||||
dst->error_msg = apr_pstrdup(p, src->error_msg);
|
||||
return dst;
|
||||
}
|
||||
|
||||
int aos_should_retry(aos_status_t *s) {
|
||||
int aos_error_code = 0;
|
||||
|
||||
// HTTP Error
|
||||
if (s == NULL || s->code / 100 == 2) {
|
||||
return AOS_FALSE;
|
||||
}
|
||||
|
||||
// OSS Error
|
||||
if (s->code / 100 == 5) {
|
||||
return AOS_TRUE;
|
||||
}
|
||||
|
||||
// Curl Error
|
||||
if (s->code != AOSE_OK) {
|
||||
if (s->code == AOSE_CONNECTION_FAILED || s->code == AOSE_REQUEST_TIMEOUT ||
|
||||
s->code == AOSE_FAILED_CONNECT || s->code == AOSE_SERVICE_ERROR) {
|
||||
return AOS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return AOS_FALSE;
|
||||
}
|
||||
|
||||
aos_status_t *aos_status_parse_from_body(aos_pool_t *p, aos_list_t *bc, int code, aos_status_t *s)
|
||||
{
|
||||
int res;
|
||||
mxml_node_t *root, *node;
|
||||
mxml_node_t *code_node, *message_node;
|
||||
char *node_content;
|
||||
|
||||
if (s == NULL) {
|
||||
s = aos_status_create(p);
|
||||
}
|
||||
s->code = code;
|
||||
|
||||
if (aos_http_is_ok(code)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
if (aos_list_empty(bc)) {
|
||||
s->error_code = (char *)AOS_UNKNOWN_ERROR_CODE;
|
||||
return s;
|
||||
}
|
||||
|
||||
if ((res = aos_parse_xml_body(bc, &root)) != AOSE_OK) {
|
||||
s->error_code = (char *)AOS_UNKNOWN_ERROR_CODE;
|
||||
return s;
|
||||
}
|
||||
|
||||
node = mxmlFindElement(root, root, "Error",NULL, NULL,MXML_DESCEND);
|
||||
if (NULL == node) {
|
||||
char *xml_content = aos_buf_list_content(p, bc);
|
||||
aos_error_log("Xml format invalid, root node name is not Error.\n");
|
||||
aos_error_log("Xml Content:%s\n", xml_content);
|
||||
s->error_code = (char *)AOS_UNKNOWN_ERROR_CODE;
|
||||
mxmlDelete(root);
|
||||
return s;
|
||||
}
|
||||
|
||||
code_node = mxmlFindElement(node, root, "Code",NULL, NULL,MXML_DESCEND);
|
||||
if (NULL != code_node) {
|
||||
node_content = code_node->child->value.opaque;
|
||||
s->error_code = apr_pstrdup(p, (char *)node_content);
|
||||
}
|
||||
|
||||
message_node = mxmlFindElement(node, root, "Message",NULL, NULL,MXML_DESCEND);
|
||||
if (NULL != message_node) {
|
||||
node_content = message_node->child->value.opaque;
|
||||
s->error_msg = apr_pstrdup(p, (char *)node_content);
|
||||
}
|
||||
|
||||
mxmlDelete(root);
|
||||
|
||||
return s;
|
||||
}
|
||||
60
include/oss_sdk/aos_status.h
Normal file
60
include/oss_sdk/aos_status.h
Normal file
@@ -0,0 +1,60 @@
|
||||
#ifndef LIBAOS_STATUS_H
|
||||
#define LIBAOS_STATUS_H
|
||||
|
||||
#include "aos_define.h"
|
||||
#include "aos_list.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
typedef struct aos_status_s aos_status_t;
|
||||
|
||||
struct aos_status_s {
|
||||
int code; // > 0 http code
|
||||
char *error_code; // can't modify
|
||||
char *error_msg; // can't modify
|
||||
char *req_id; // can't modify
|
||||
};
|
||||
|
||||
static APR_INLINE int aos_status_is_ok(aos_status_t *s)
|
||||
{
|
||||
return s->code > 0 && s->code / 100 == 2;
|
||||
}
|
||||
|
||||
static APR_INLINE int aos_http_is_ok(int st)
|
||||
{
|
||||
return st / 100 == 2;
|
||||
}
|
||||
|
||||
#define aos_status_set(s, c, ec, es) \
|
||||
(s)->code = c; (s)->error_code = (char *)ec; (s)->error_msg = (char *)es
|
||||
|
||||
/**
|
||||
* @brief determine whether the request should be retried
|
||||
* @param[in] s the return status of api, such as oss_put_object_from_buffer
|
||||
* @return int AOS_FALSE indicates no retries, AOS_TRUE retry
|
||||
*/
|
||||
int aos_should_retry(aos_status_t *s);
|
||||
|
||||
aos_status_t *aos_status_create(aos_pool_t *p);
|
||||
|
||||
aos_status_t *aos_status_dup(aos_pool_t *p, aos_status_t *src);
|
||||
|
||||
aos_status_t *aos_status_parse_from_body(aos_pool_t *p, aos_list_t *bc, int code, aos_status_t *s);
|
||||
|
||||
extern const char AOS_XML_PARSE_ERROR_CODE[];
|
||||
extern const char AOS_OPEN_FILE_ERROR_CODE[];
|
||||
extern const char AOS_WRITE_FILE_ERROR_CODE[];
|
||||
extern const char AOS_RENAME_FILE_ERROR_CODE[];
|
||||
extern const char AOS_HTTP_IO_ERROR_CODE[];
|
||||
extern const char AOS_UNKNOWN_ERROR_CODE[];
|
||||
extern const char AOS_CLIENT_ERROR_CODE[];
|
||||
extern const char AOS_SERVER_ERROR_CODE[];
|
||||
extern const char AOS_UTF8_ENCODE_ERROR_CODE[];
|
||||
extern const char AOS_URL_ENCODE_ERROR_CODE[];
|
||||
extern const char AOS_INCONSISTENT_ERROR_CODE[];
|
||||
extern const char AOS_CREATE_QUEUE_ERROR_CODE[];
|
||||
extern const char AOS_CREATE_THREAD_POOL_ERROR_CODE[];
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
54
include/oss_sdk/aos_string.c
Normal file
54
include/oss_sdk/aos_string.c
Normal file
@@ -0,0 +1,54 @@
|
||||
#include "aos_string.h"
|
||||
|
||||
typedef int (*aos_is_char_pt)(char c);
|
||||
|
||||
static void aos_strip_str_func(aos_string_t *str, aos_is_char_pt func);
|
||||
|
||||
char *aos_pstrdup(aos_pool_t *p, const aos_string_t *s)
|
||||
{
|
||||
return apr_pstrndup(p, s->data, s->len);
|
||||
}
|
||||
|
||||
static void aos_strip_str_func(aos_string_t *str, aos_is_char_pt func)
|
||||
{
|
||||
char *data = str->data;
|
||||
int len = str->len;
|
||||
int offset = 0;
|
||||
|
||||
if (len == 0) return;
|
||||
|
||||
while (len > 0 && func(data[len - 1])) {
|
||||
--len;
|
||||
}
|
||||
|
||||
for (; offset < len && func(data[offset]); ++offset) {
|
||||
// empty;
|
||||
}
|
||||
|
||||
str->data = data + offset;
|
||||
str->len = len - offset;
|
||||
}
|
||||
|
||||
void aos_unquote_str(aos_string_t *str)
|
||||
{
|
||||
aos_strip_str_func(str, aos_is_quote);
|
||||
}
|
||||
|
||||
void aos_strip_space(aos_string_t *str)
|
||||
{
|
||||
aos_strip_str_func(str, aos_is_space);
|
||||
}
|
||||
|
||||
void aos_trip_space_and_cntrl(aos_string_t *str)
|
||||
{
|
||||
aos_strip_str_func(str, aos_is_space_or_cntrl);
|
||||
}
|
||||
|
||||
int aos_ends_with(const aos_string_t *str, const aos_string_t *suffix)
|
||||
{
|
||||
if (!str || !suffix) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (str->len >= suffix->len) && strncmp(str->data + str->len - suffix->len, suffix->data, suffix->len) == 0;
|
||||
}
|
||||
75
include/oss_sdk/aos_string.h
Normal file
75
include/oss_sdk/aos_string.h
Normal file
@@ -0,0 +1,75 @@
|
||||
#ifndef LIBAOS_STRING_H
|
||||
#define LIBAOS_STRING_H
|
||||
|
||||
#include "aos_define.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
typedef struct {
|
||||
int len;
|
||||
char *data;
|
||||
} aos_string_t;
|
||||
|
||||
#define aos_string(str) { sizeof(str) - 1, (char *) str }
|
||||
#define aos_null_string { 0, NULL }
|
||||
#define aos_str_set(str, text) \
|
||||
(str)->len = strlen(text); (str)->data = (char *) text
|
||||
#define aos_str_null(str) (str)->len = 0; (str)->data = NULL
|
||||
|
||||
#define aos_tolower(c) (char) ((c >= 'A' && c <= 'Z') ? (c | 0x20) : c)
|
||||
#define aos_toupper(c) (char) ((c >= 'a' && c <= 'z') ? (c & ~0x20) : c)
|
||||
|
||||
static APR_INLINE void aos_string_tolower(aos_string_t *str)
|
||||
{
|
||||
int i = 0;
|
||||
while (i < str->len) {
|
||||
str->data[i] = aos_tolower(str->data[i]);
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static APR_INLINE char *aos_strlchr(char *p, char *last, char c)
|
||||
{
|
||||
while (p < last) {
|
||||
if (*p == c) {
|
||||
return p;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static APR_INLINE int aos_is_quote(char c)
|
||||
{
|
||||
return c == '\"';
|
||||
}
|
||||
|
||||
static APR_INLINE int aos_is_space(char c)
|
||||
{
|
||||
return ((c == ' ') || (c == '\t'));
|
||||
}
|
||||
|
||||
static APR_INLINE int aos_is_space_or_cntrl(char c)
|
||||
{
|
||||
return c <= ' ';
|
||||
}
|
||||
|
||||
static APR_INLINE int aos_is_null_string(aos_string_t *str)
|
||||
{
|
||||
if (str == NULL || str->data == NULL || str->len == 0) {
|
||||
return AOS_TRUE;
|
||||
}
|
||||
return AOS_FALSE;
|
||||
}
|
||||
|
||||
void aos_strip_space(aos_string_t *str);
|
||||
void aos_trip_space_and_cntrl(aos_string_t *str);
|
||||
void aos_unquote_str(aos_string_t *str);
|
||||
|
||||
char *aos_pstrdup(aos_pool_t *p, const aos_string_t *s);
|
||||
|
||||
int aos_ends_with(const aos_string_t *str, const aos_string_t *suffix);
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
463
include/oss_sdk/aos_transport.c
Normal file
463
include/oss_sdk/aos_transport.c
Normal file
@@ -0,0 +1,463 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_http_io.h"
|
||||
#include "aos_transport.h"
|
||||
#include "aos_crc64.h"
|
||||
|
||||
static int aos_curl_code_to_status(CURLcode code);
|
||||
static void aos_init_curl_headers(aos_curl_http_transport_t *t);
|
||||
static void aos_transport_cleanup(aos_http_transport_t *t);
|
||||
static int aos_init_curl_url(aos_curl_http_transport_t *t);
|
||||
static void aos_curl_transport_headers_done(aos_curl_http_transport_t *t);
|
||||
static int aos_curl_transport_setup(aos_curl_http_transport_t *t);
|
||||
static void aos_curl_transport_finish(aos_curl_http_transport_t *t);
|
||||
static void aos_move_transport_state(aos_curl_http_transport_t *t, aos_transport_state_e s);
|
||||
|
||||
static size_t aos_curl_default_header_callback(char *buffer, size_t size, size_t nitems, void *userdata);
|
||||
static size_t aos_curl_default_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata);
|
||||
static size_t aos_curl_default_read_callback(char *buffer, size_t size, size_t nitems, void *instream);
|
||||
|
||||
static void aos_init_curl_headers(aos_curl_http_transport_t *t)
|
||||
{
|
||||
int pos;
|
||||
char *header;
|
||||
const aos_array_header_t *tarr;
|
||||
const aos_table_entry_t *telts;
|
||||
union aos_func_u func;
|
||||
|
||||
if (t->req->method == HTTP_PUT || t->req->method == HTTP_POST) {
|
||||
header = apr_psprintf(t->pool, "Content-Length: %" APR_INT64_T_FMT, t->req->body_len);
|
||||
t->headers = curl_slist_append(t->headers, header);
|
||||
}
|
||||
|
||||
tarr = aos_table_elts(t->req->headers);
|
||||
telts = (aos_table_entry_t*)tarr->elts;
|
||||
for (pos = 0; pos < tarr->nelts; ++pos) {
|
||||
header = apr_psprintf(t->pool, "%s: %s", telts[pos].key, telts[pos].val);
|
||||
t->headers = curl_slist_append(t->headers, header);
|
||||
}
|
||||
|
||||
func.func1 = (aos_func1_pt)curl_slist_free_all;
|
||||
aos_fstack_push(t->cleanup, t->headers, func, 1);
|
||||
}
|
||||
|
||||
static int aos_init_curl_url(aos_curl_http_transport_t *t)
|
||||
{
|
||||
int rs;
|
||||
const char *proto;
|
||||
aos_string_t querystr;
|
||||
char uristr[3*AOS_MAX_URI_LEN+1];
|
||||
|
||||
uristr[0] = '\0';
|
||||
aos_str_null(&querystr);
|
||||
|
||||
if ((rs = aos_url_encode(uristr, t->req->uri, AOS_MAX_URI_LEN)) != AOSE_OK) {
|
||||
t->controller->error_code = rs;
|
||||
t->controller->reason = "uri invalid argument.";
|
||||
return rs;
|
||||
}
|
||||
|
||||
if ((rs = aos_query_params_to_string(t->pool, t->req->query_params, &querystr)) != AOSE_OK) {
|
||||
t->controller->error_code = rs;
|
||||
t->controller->reason = "query params invalid argument.";
|
||||
return rs;
|
||||
}
|
||||
|
||||
proto = strlen(t->req->proto) != 0 ? t->req->proto : AOS_HTTP_PREFIX;
|
||||
if (querystr.len == 0) {
|
||||
t->url = apr_psprintf(t->pool, "%s%s/%s",
|
||||
proto,
|
||||
t->req->host,
|
||||
uristr);
|
||||
} else {
|
||||
t->url = apr_psprintf(t->pool, "%s%s/%s%.*s",
|
||||
proto,
|
||||
t->req->host,
|
||||
uristr,
|
||||
querystr.len,
|
||||
querystr.data);
|
||||
}
|
||||
aos_debug_log("url:%s.", t->url);
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
static void aos_transport_cleanup(aos_http_transport_t *t)
|
||||
{
|
||||
int s;
|
||||
char buf[256];
|
||||
|
||||
if (t->req->file_buf != NULL && t->req->file_buf->owner) {
|
||||
aos_trace_log("close request body file.");
|
||||
if ((s = apr_file_close(t->req->file_buf->file)) != APR_SUCCESS) {
|
||||
aos_warn_log("apr_file_close failure, %s.", apr_strerror(s, buf, sizeof(buf)));
|
||||
}
|
||||
t->req->file_buf = NULL;
|
||||
}
|
||||
|
||||
if (t->resp->file_buf != NULL && t->resp->file_buf->owner) {
|
||||
aos_trace_log("close response body file.");
|
||||
if ((s = apr_file_close(t->resp->file_buf->file)) != APR_SUCCESS) {
|
||||
aos_warn_log("apr_file_close failure, %s.", apr_strerror(s, buf, sizeof(buf)));
|
||||
}
|
||||
t->resp->file_buf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
aos_http_transport_t *aos_curl_http_transport_create(aos_pool_t *p)
|
||||
{
|
||||
aos_func_u func;
|
||||
aos_curl_http_transport_t *t;
|
||||
|
||||
t = (aos_curl_http_transport_t *)aos_pcalloc(p, sizeof(aos_curl_http_transport_t));
|
||||
|
||||
t->pool = p;
|
||||
t->options = aos_default_http_transport_options;
|
||||
t->cleanup = aos_fstack_create(p, 5);
|
||||
|
||||
func.func1 = (aos_func1_pt)aos_transport_cleanup;
|
||||
aos_fstack_push(t->cleanup, t, func, 1);
|
||||
|
||||
t->curl = aos_request_get();
|
||||
func.func1 = (aos_func1_pt)request_release;
|
||||
aos_fstack_push(t->cleanup, t->curl, func, 1);
|
||||
|
||||
t->header_callback = aos_curl_default_header_callback;
|
||||
t->read_callback = aos_curl_default_read_callback;
|
||||
t->write_callback = aos_curl_default_write_callback;
|
||||
|
||||
return (aos_http_transport_t *)t;
|
||||
}
|
||||
|
||||
static void aos_move_transport_state(aos_curl_http_transport_t *t, aos_transport_state_e s)
|
||||
{
|
||||
if (t->state < s) {
|
||||
t->state = s;
|
||||
}
|
||||
}
|
||||
|
||||
void aos_curl_response_headers_parse(aos_pool_t *p, aos_table_t *headers, char *buffer, int len)
|
||||
{
|
||||
char *pos;
|
||||
aos_string_t str;
|
||||
aos_string_t key;
|
||||
aos_string_t value;
|
||||
|
||||
str.data = buffer;
|
||||
str.len = len;
|
||||
|
||||
aos_trip_space_and_cntrl(&str);
|
||||
|
||||
pos = aos_strlchr(str.data, str.data + str.len, ':');
|
||||
if (pos == NULL) {
|
||||
return;
|
||||
}
|
||||
key.data = str.data;
|
||||
key.len = pos - str.data;
|
||||
|
||||
pos += 1;
|
||||
value.len = str.data + str.len - pos;
|
||||
value.data = pos;
|
||||
aos_strip_space(&value);
|
||||
|
||||
apr_table_addn(headers, aos_pstrdup(p, &key), aos_pstrdup(p, &value));
|
||||
}
|
||||
|
||||
size_t aos_curl_default_header_callback(char *buffer, size_t size, size_t nitems, void *userdata)
|
||||
{
|
||||
int len;
|
||||
aos_curl_http_transport_t *t;
|
||||
|
||||
t = (aos_curl_http_transport_t *)(userdata);
|
||||
len = size * nitems;
|
||||
|
||||
if (t->controller->first_byte_time == 0) {
|
||||
t->controller->first_byte_time = apr_time_now();
|
||||
}
|
||||
|
||||
aos_curl_response_headers_parse(t->pool, t->resp->headers, buffer, len);
|
||||
|
||||
aos_move_transport_state(t, TRANS_STATE_HEADER);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static void aos_curl_transport_headers_done(aos_curl_http_transport_t *t)
|
||||
{
|
||||
long http_code;
|
||||
CURLcode code;
|
||||
const char *value;
|
||||
|
||||
if (t->controller->error_code != AOSE_OK) {
|
||||
aos_debug_log("has error %d.", t->controller->error_code);
|
||||
return;
|
||||
}
|
||||
|
||||
if (t->resp->status > 0) {
|
||||
aos_trace_log("http response status %d.", t->resp->status);
|
||||
return;
|
||||
}
|
||||
|
||||
t->resp->status = 0;
|
||||
if ((code = curl_easy_getinfo(t->curl, CURLINFO_RESPONSE_CODE, &http_code)) != CURLE_OK) {
|
||||
t->controller->reason = apr_pstrdup(t->pool, curl_easy_strerror(code));
|
||||
t->controller->error_code = AOSE_INTERNAL_ERROR;
|
||||
return;
|
||||
} else {
|
||||
t->resp->status = http_code;
|
||||
}
|
||||
|
||||
value = apr_table_get(t->resp->headers, "Content-Length");
|
||||
if (value != NULL) {
|
||||
t->resp->content_length = aos_atoi64(value);
|
||||
}
|
||||
}
|
||||
|
||||
size_t aos_curl_default_write_callback(char *ptr, size_t size, size_t nmemb, void *userdata)
|
||||
{
|
||||
int len;
|
||||
int bytes;
|
||||
aos_curl_http_transport_t *t;
|
||||
|
||||
t = (aos_curl_http_transport_t *)(userdata);
|
||||
len = size * nmemb;
|
||||
|
||||
if (t->controller->first_byte_time == 0) {
|
||||
t->controller->first_byte_time = apr_time_now();
|
||||
}
|
||||
|
||||
aos_curl_transport_headers_done(t);
|
||||
|
||||
if (t->controller->error_code != AOSE_OK) {
|
||||
aos_debug_log("write callback abort");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// On HTTP error, we expect to parse an HTTP error response
|
||||
if (t->resp->status < 200 || t->resp->status > 299) {
|
||||
bytes = aos_write_http_body_memory(t->resp, ptr, len);
|
||||
assert(bytes == len);
|
||||
aos_move_transport_state(t, TRANS_STATE_BODY_IN);
|
||||
return bytes;
|
||||
}
|
||||
|
||||
if (t->resp->type == BODY_IN_MEMORY && t->resp->body_len >= (int64_t)t->controller->options->max_memory_size) {
|
||||
t->controller->reason = apr_psprintf(t->pool,
|
||||
"receive body too big, current body size: %" APR_INT64_T_FMT ", max memory size: %" APR_INT64_T_FMT,
|
||||
t->resp->body_len, t->controller->options->max_memory_size);
|
||||
t->controller->error_code = AOSE_OVER_MEMORY;
|
||||
aos_error_log("error reason:%s, ", t->controller->reason);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((bytes = t->resp->write_body(t->resp, ptr, len)) < 0) {
|
||||
aos_debug_log("write body failure, %d.", bytes);
|
||||
t->controller->error_code = AOSE_WRITE_BODY_ERROR;
|
||||
t->controller->reason = "write body failure.";
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (bytes >= 0) {
|
||||
// progress callback
|
||||
if (NULL != t->resp->progress_callback) {
|
||||
t->resp->progress_callback(t->resp->body_len, t->resp->content_length);
|
||||
}
|
||||
|
||||
// crc
|
||||
if (t->controller->options->enable_crc) {
|
||||
t->resp->crc64 = aos_crc64(t->resp->crc64, ptr, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
aos_move_transport_state(t, TRANS_STATE_BODY_IN);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
size_t aos_curl_default_read_callback(char *buffer, size_t size, size_t nitems, void *instream)
|
||||
{
|
||||
int len;
|
||||
int bytes;
|
||||
aos_curl_http_transport_t *t;
|
||||
|
||||
t = (aos_curl_http_transport_t *)(instream);
|
||||
len = size * nitems;
|
||||
|
||||
if (t->controller->error_code != AOSE_OK) {
|
||||
aos_debug_log("abort read callback.");
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
|
||||
if ((bytes = t->req->read_body(t->req, buffer, len)) < 0) {
|
||||
aos_debug_log("read body failure, %d.", bytes);
|
||||
t->controller->error_code = AOSE_READ_BODY_ERROR;
|
||||
t->controller->reason = "read body failure.";
|
||||
return CURL_READFUNC_ABORT;
|
||||
}
|
||||
|
||||
if (bytes >= 0) {
|
||||
// progress callback
|
||||
t->req->consumed_bytes += bytes;
|
||||
if (NULL != t->req->progress_callback) {
|
||||
t->req->progress_callback(t->req->consumed_bytes, t->req->body_len);
|
||||
}
|
||||
|
||||
// crc
|
||||
if (t->controller->options->enable_crc) {
|
||||
t->req->crc64 = aos_crc64(t->req->crc64, buffer, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
aos_move_transport_state(t, TRANS_STATE_BODY_OUT);
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static int aos_curl_code_to_status(CURLcode code)
|
||||
{
|
||||
switch (code) {
|
||||
case CURLE_OUT_OF_MEMORY:
|
||||
return AOSE_OUT_MEMORY;
|
||||
case CURLE_COULDNT_RESOLVE_PROXY:
|
||||
case CURLE_COULDNT_RESOLVE_HOST:
|
||||
return AOSE_NAME_LOOKUP_ERROR;
|
||||
case CURLE_COULDNT_CONNECT:
|
||||
return AOSE_FAILED_CONNECT;
|
||||
case CURLE_WRITE_ERROR:
|
||||
case CURLE_OPERATION_TIMEDOUT:
|
||||
return AOSE_CONNECTION_FAILED;
|
||||
case CURLE_PARTIAL_FILE:
|
||||
return AOSE_OK;
|
||||
case CURLE_SSL_CACERT:
|
||||
return AOSE_FAILED_VERIFICATION;
|
||||
default:
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
static void aos_curl_transport_finish(aos_curl_http_transport_t *t)
|
||||
{
|
||||
aos_curl_transport_headers_done(t);
|
||||
|
||||
if (t->cleanup != NULL) {
|
||||
aos_fstack_destory(t->cleanup);
|
||||
t->cleanup = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int aos_curl_transport_setup(aos_curl_http_transport_t *t)
|
||||
{
|
||||
CURLcode code;
|
||||
|
||||
#define curl_easy_setopt_safe(opt, val) \
|
||||
if ((code = curl_easy_setopt(t->curl, opt, val)) != CURLE_OK) { \
|
||||
t->controller->reason = apr_pstrdup(t->pool, curl_easy_strerror(code)); \
|
||||
t->controller->error_code = AOSE_FAILED_INITIALIZE; \
|
||||
aos_error_log("curl_easy_setopt failed, code:%d %s.", code, t->controller->reason); \
|
||||
return AOSE_FAILED_INITIALIZE; \
|
||||
}
|
||||
|
||||
curl_easy_setopt_safe(CURLOPT_PRIVATE, t);
|
||||
|
||||
curl_easy_setopt_safe(CURLOPT_HEADERDATA, t);
|
||||
curl_easy_setopt_safe(CURLOPT_HEADERFUNCTION, t->header_callback);
|
||||
|
||||
curl_easy_setopt_safe(CURLOPT_READDATA, t);
|
||||
curl_easy_setopt_safe(CURLOPT_READFUNCTION, t->read_callback);
|
||||
|
||||
curl_easy_setopt_safe(CURLOPT_WRITEDATA, t);
|
||||
curl_easy_setopt_safe(CURLOPT_WRITEFUNCTION, t->write_callback);
|
||||
|
||||
curl_easy_setopt_safe(CURLOPT_FILETIME, 1);
|
||||
curl_easy_setopt_safe(CURLOPT_NOSIGNAL, 1);
|
||||
curl_easy_setopt_safe(CURLOPT_NOPROGRESS, 1);
|
||||
curl_easy_setopt_safe(CURLOPT_TCP_NODELAY, 1);
|
||||
curl_easy_setopt_safe(CURLOPT_NETRC, CURL_NETRC_IGNORED);
|
||||
|
||||
// transport options
|
||||
curl_easy_setopt_safe(CURLOPT_SSL_VERIFYPEER, 0);
|
||||
curl_easy_setopt_safe(CURLOPT_USERAGENT, t->options->user_agent);
|
||||
|
||||
// request options
|
||||
curl_easy_setopt_safe(CURLOPT_DNS_CACHE_TIMEOUT, t->controller->options->dns_cache_timeout);
|
||||
curl_easy_setopt_safe(CURLOPT_CONNECTTIMEOUT, t->controller->options->connect_timeout);
|
||||
curl_easy_setopt_safe(CURLOPT_LOW_SPEED_LIMIT, t->controller->options->speed_limit);
|
||||
curl_easy_setopt_safe(CURLOPT_LOW_SPEED_TIME, t->controller->options->speed_time);
|
||||
|
||||
aos_init_curl_headers(t);
|
||||
curl_easy_setopt_safe(CURLOPT_HTTPHEADER, t->headers);
|
||||
|
||||
if (t->controller->options->proxy_host != NULL) {
|
||||
// proxy
|
||||
curl_easy_setopt_safe(CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
|
||||
curl_easy_setopt_safe(CURLOPT_PROXY, t->controller->options->proxy_host);
|
||||
// authorize
|
||||
if (t->controller->options->proxy_auth != NULL) {
|
||||
curl_easy_setopt_safe(CURLOPT_PROXYAUTH, CURLAUTH_BASIC);
|
||||
curl_easy_setopt_safe(CURLOPT_PROXYUSERPWD, t->controller->options->proxy_auth);
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL == t->req->signed_url) {
|
||||
if (aos_init_curl_url(t) != AOSE_OK) {
|
||||
return t->controller->error_code;
|
||||
}
|
||||
}
|
||||
else {
|
||||
t->url = t->req->signed_url;
|
||||
}
|
||||
curl_easy_setopt_safe(CURLOPT_URL, t->url);
|
||||
|
||||
switch (t->req->method) {
|
||||
case HTTP_HEAD:
|
||||
curl_easy_setopt_safe(CURLOPT_NOBODY, 1);
|
||||
break;
|
||||
case HTTP_PUT:
|
||||
curl_easy_setopt_safe(CURLOPT_UPLOAD, 1);
|
||||
break;
|
||||
case HTTP_POST:
|
||||
curl_easy_setopt_safe(CURLOPT_POST, 1);
|
||||
break;
|
||||
case HTTP_DELETE:
|
||||
curl_easy_setopt_safe(CURLOPT_CUSTOMREQUEST, "DELETE");
|
||||
break;
|
||||
default: // HTTP_GET
|
||||
break;
|
||||
}
|
||||
|
||||
#undef curl_easy_setopt_safe
|
||||
|
||||
t->state = TRANS_STATE_INIT;
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int aos_curl_http_transport_perform(aos_http_transport_t *t_)
|
||||
{
|
||||
int ecode;
|
||||
CURLcode code;
|
||||
aos_curl_http_transport_t *t = (aos_curl_http_transport_t *)(t_);
|
||||
ecode = aos_curl_transport_setup(t);
|
||||
if (ecode != AOSE_OK) {
|
||||
return ecode;
|
||||
}
|
||||
|
||||
t->controller->start_time = apr_time_now();
|
||||
code = curl_easy_perform(t->curl);
|
||||
t->controller->finish_time = apr_time_now();
|
||||
aos_move_transport_state(t, TRANS_STATE_DONE);
|
||||
|
||||
if ((code != CURLE_OK) && (t->controller->error_code == AOSE_OK)) {
|
||||
ecode = aos_curl_code_to_status(code);
|
||||
if (ecode != AOSE_OK) {
|
||||
t->controller->error_code = ecode;
|
||||
t->controller->reason = apr_pstrdup(t->pool, curl_easy_strerror(code));
|
||||
aos_error_log("transport failure curl code:%d error:%s", code, t->controller->reason);
|
||||
}
|
||||
}
|
||||
|
||||
aos_curl_transport_finish(t);
|
||||
|
||||
return t->controller->error_code;
|
||||
}
|
||||
152
include/oss_sdk/aos_transport.h
Normal file
152
include/oss_sdk/aos_transport.h
Normal file
@@ -0,0 +1,152 @@
|
||||
#ifndef LIBAOS_TRANSPORT_H
|
||||
#define LIBAOS_TRANSPORT_H
|
||||
|
||||
#include "aos_define.h"
|
||||
#include "aos_buf.h"
|
||||
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
typedef struct aos_http_request_s aos_http_request_t;
|
||||
typedef struct aos_http_response_s aos_http_response_t;
|
||||
typedef struct aos_http_transport_s aos_http_transport_t;
|
||||
typedef struct aos_http_controller_s aos_http_controller_t;
|
||||
|
||||
typedef struct aos_http_request_options_s aos_http_request_options_t;
|
||||
typedef struct aos_http_transport_options_s aos_http_transport_options_t;
|
||||
typedef struct aos_curl_http_transport_s aos_curl_http_transport_t;
|
||||
|
||||
typedef int (*aos_read_http_body_pt)(aos_http_request_t *req, char *buffer, int len);
|
||||
typedef int (*aos_write_http_body_pt)(aos_http_response_t *resp, const char *buffer, int len);
|
||||
|
||||
typedef void (*oss_progress_callback)(int64_t consumed_bytes, int64_t total_bytes);
|
||||
|
||||
void aos_curl_response_headers_parse(aos_pool_t *p, aos_table_t *headers, char *buffer, int len);
|
||||
aos_http_transport_t *aos_curl_http_transport_create(aos_pool_t *p);
|
||||
int aos_curl_http_transport_perform(aos_http_transport_t *t);
|
||||
|
||||
struct aos_http_request_options_s {
|
||||
int speed_limit;
|
||||
int speed_time;
|
||||
int dns_cache_timeout;
|
||||
int connect_timeout;
|
||||
int64_t max_memory_size;
|
||||
int enable_crc;
|
||||
char *proxy_host;
|
||||
char *proxy_auth;
|
||||
};
|
||||
|
||||
struct aos_http_transport_options_s {
|
||||
char *user_agent;
|
||||
char *cacerts_path;
|
||||
uint32_t ssl_verification_disabled:1;
|
||||
};
|
||||
|
||||
#define AOS_HTTP_BASE_CONTROLLER_DEFINE \
|
||||
aos_http_request_options_t *options; \
|
||||
aos_pool_t *pool; \
|
||||
int64_t start_time; \
|
||||
int64_t first_byte_time; \
|
||||
int64_t finish_time; \
|
||||
uint32_t owner:1; \
|
||||
void *user_data;
|
||||
|
||||
struct aos_http_controller_s {
|
||||
AOS_HTTP_BASE_CONTROLLER_DEFINE
|
||||
};
|
||||
|
||||
typedef struct aos_http_controller_ex_s {
|
||||
AOS_HTTP_BASE_CONTROLLER_DEFINE
|
||||
// private
|
||||
int error_code;
|
||||
char *reason; // can't modify
|
||||
} aos_http_controller_ex_t;
|
||||
|
||||
typedef enum {
|
||||
BODY_IN_MEMORY = 0,
|
||||
BODY_IN_FILE,
|
||||
BODY_IN_CALLBACK
|
||||
} aos_http_body_type_e;
|
||||
|
||||
struct aos_http_request_s {
|
||||
char *host;
|
||||
char *proto;
|
||||
char *signed_url;
|
||||
|
||||
http_method_e method;
|
||||
char *uri;
|
||||
char *resource;
|
||||
aos_table_t *headers;
|
||||
aos_table_t *query_params;
|
||||
|
||||
aos_list_t body;
|
||||
int64_t body_len;
|
||||
char *file_path;
|
||||
aos_file_buf_t *file_buf;
|
||||
|
||||
aos_pool_t *pool;
|
||||
void *user_data;
|
||||
aos_read_http_body_pt read_body;
|
||||
|
||||
aos_http_body_type_e type;
|
||||
|
||||
oss_progress_callback progress_callback;
|
||||
uint64_t crc64;
|
||||
int64_t consumed_bytes;
|
||||
};
|
||||
|
||||
struct aos_http_response_s {
|
||||
int status;
|
||||
aos_table_t *headers;
|
||||
|
||||
aos_list_t body;
|
||||
int64_t body_len;
|
||||
char *file_path;
|
||||
aos_file_buf_t* file_buf;
|
||||
int64_t content_length;
|
||||
|
||||
aos_pool_t *pool;
|
||||
void *user_data;
|
||||
aos_write_http_body_pt write_body;
|
||||
|
||||
aos_http_body_type_e type;
|
||||
|
||||
oss_progress_callback progress_callback;
|
||||
uint64_t crc64;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
TRANS_STATE_INIT,
|
||||
TRANS_STATE_HEADER,
|
||||
TRANS_STATE_BODY_IN,
|
||||
TRANS_STATE_BODY_OUT,
|
||||
TRANS_STATE_ABORT,
|
||||
TRANS_STATE_DONE
|
||||
} aos_transport_state_e;
|
||||
|
||||
#define AOS_HTTP_BASE_TRANSPORT_DEFINE \
|
||||
aos_http_request_t *req; \
|
||||
aos_http_response_t *resp; \
|
||||
aos_pool_t *pool; \
|
||||
aos_transport_state_e state; \
|
||||
aos_array_header_t *cleanup; \
|
||||
aos_http_transport_options_t *options; \
|
||||
aos_http_controller_ex_t *controller;
|
||||
|
||||
struct aos_http_transport_s {
|
||||
AOS_HTTP_BASE_TRANSPORT_DEFINE
|
||||
};
|
||||
|
||||
struct aos_curl_http_transport_s {
|
||||
AOS_HTTP_BASE_TRANSPORT_DEFINE
|
||||
CURL *curl;
|
||||
char *url;
|
||||
struct curl_slist *headers;
|
||||
curl_read_callback header_callback;
|
||||
curl_read_callback read_callback;
|
||||
curl_write_callback write_callback;
|
||||
};
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
523
include/oss_sdk/aos_util.c
Normal file
523
include/oss_sdk/aos_util.c
Normal file
@@ -0,0 +1,523 @@
|
||||
#include "aos_util.h"
|
||||
#include "aos_log.h"
|
||||
|
||||
static const char *g_s_wday[] = {
|
||||
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
||||
};
|
||||
|
||||
static const char *g_s_mon[] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
static const char g_s_gmt_format[] = "%s, %.2d %s %.4d %.2d:%.2d:%.2d GMT";
|
||||
|
||||
int aos_parse_xml_body(aos_list_t *bc, mxml_node_t **root)
|
||||
{
|
||||
aos_buf_t *b;
|
||||
size_t len;
|
||||
|
||||
*root = NULL;
|
||||
len = (size_t)aos_buf_list_len(bc);
|
||||
|
||||
{
|
||||
int nsize = 0;
|
||||
char *buffer = (char*)malloc(sizeof(char)*(len+1));
|
||||
memset(buffer, 0, len + 1);
|
||||
aos_list_for_each_entry(aos_buf_t, b, bc, node) {
|
||||
memcpy(buffer + nsize, (char *)b->pos, aos_buf_size(b));
|
||||
nsize += aos_buf_size(b);
|
||||
}
|
||||
*root = mxmlLoadString(NULL, buffer, MXML_OPAQUE_CALLBACK);
|
||||
free(buffer);
|
||||
if (NULL == *root) {
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int aos_convert_to_gmt_time(char* date, const char* format, apr_time_exp_t *tm)
|
||||
{
|
||||
int size = apr_snprintf(date, AOS_MAX_GMT_TIME_LEN, format,
|
||||
g_s_wday[tm->tm_wday], tm->tm_mday, g_s_mon[tm->tm_mon], 1900 + tm->tm_year, tm->tm_hour, tm->tm_min, tm->tm_sec);
|
||||
if (size >= 0 && size < AOS_MAX_GMT_TIME_LEN) {
|
||||
return AOSE_OK;
|
||||
} else {
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
int aos_get_gmt_str_time(char datestr[AOS_MAX_GMT_TIME_LEN])
|
||||
{
|
||||
int s;
|
||||
apr_time_t now;
|
||||
char buf[128];
|
||||
apr_time_exp_t result;
|
||||
|
||||
now = apr_time_now();
|
||||
if ((s = apr_time_exp_gmt(&result, now)) != APR_SUCCESS) {
|
||||
aos_error_log("apr_time_exp_gmt fialure, code:%d %s.", s, apr_strerror(s, buf, sizeof(buf)));
|
||||
return AOSE_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((s = aos_convert_to_gmt_time(datestr, g_s_gmt_format, &result))
|
||||
!= AOSE_OK) {
|
||||
aos_error_log("aos_convert_to_GMT failure, code:%d.", s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
int aos_url_encode(char *dest, const char *src, int maxSrcSize)
|
||||
{
|
||||
static const char *hex = "0123456789ABCDEF";
|
||||
|
||||
int len = 0;
|
||||
unsigned char c;
|
||||
|
||||
while (*src) {
|
||||
if (++len > maxSrcSize) {
|
||||
*dest = 0;
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
c = *src;
|
||||
if (isalnum(c) || (c == '-') || (c == '_') || (c == '.') || (c == '~')) {
|
||||
*dest++ = c;
|
||||
} else if (*src == ' ') {
|
||||
*dest++ = '%';
|
||||
*dest++ = '2';
|
||||
*dest++ = '0';
|
||||
} else {
|
||||
*dest++ = '%';
|
||||
*dest++ = hex[c >> 4];
|
||||
*dest++ = hex[c & 15];
|
||||
}
|
||||
src++;
|
||||
}
|
||||
|
||||
*dest = 0;
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int aos_query_params_to_string(aos_pool_t *p, aos_table_t *query_params, aos_string_t *querystr)
|
||||
{
|
||||
int rs;
|
||||
int pos;
|
||||
int len;
|
||||
char sep = '?';
|
||||
char ebuf[AOS_MAX_QUERY_ARG_LEN*3+1];
|
||||
char abuf[AOS_MAX_QUERY_ARG_LEN*6+128];
|
||||
int max_len;
|
||||
const aos_array_header_t *tarr;
|
||||
const aos_table_entry_t *telts;
|
||||
aos_buf_t *querybuf;
|
||||
|
||||
if (apr_is_empty_table(query_params)) {
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
max_len = sizeof(abuf)-1;
|
||||
querybuf = aos_create_buf(p, 256);
|
||||
aos_str_null(querystr);
|
||||
|
||||
tarr = aos_table_elts(query_params);
|
||||
telts = (aos_table_entry_t*)tarr->elts;
|
||||
|
||||
for (pos = 0; pos < tarr->nelts; ++pos) {
|
||||
if ((rs = aos_url_encode(ebuf, telts[pos].key, AOS_MAX_QUERY_ARG_LEN)) != AOSE_OK) {
|
||||
aos_error_log("query params args too big, key:%s.", telts[pos].key);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
len = apr_snprintf(abuf, max_len, "%c%s", sep, ebuf);
|
||||
if (telts[pos].val != NULL && *telts[pos].val != '\0') {
|
||||
if ((rs = aos_url_encode(ebuf, telts[pos].val, AOS_MAX_QUERY_ARG_LEN)) != AOSE_OK) {
|
||||
aos_error_log("query params args too big, value:%s.", telts[pos].val);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
len += apr_snprintf(abuf+len, max_len-len, "=%s", ebuf);
|
||||
if (len >= AOS_MAX_QUERY_ARG_LEN) {
|
||||
aos_error_log("query params args too big, %s.", abuf);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
}
|
||||
aos_buf_append_string(p, querybuf, abuf, len);
|
||||
sep = '&';
|
||||
}
|
||||
|
||||
// result
|
||||
querystr->data = (char *)querybuf->pos;
|
||||
querystr->len = aos_buf_size(querybuf);
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
void aos_gnome_sort(const char **headers, int size)
|
||||
{
|
||||
const char *tmp;
|
||||
int i = 0, last_highest = 0;
|
||||
|
||||
while (i < size) {
|
||||
if ((i == 0) || apr_strnatcasecmp(headers[i-1], headers[i]) < 0) {
|
||||
i = ++last_highest;
|
||||
} else {
|
||||
tmp = headers[i];
|
||||
headers[i] = headers[i - 1];
|
||||
headers[--i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char* aos_http_method_to_string(http_method_e method)
|
||||
{
|
||||
switch (method) {
|
||||
case HTTP_GET:
|
||||
return "GET";
|
||||
case HTTP_HEAD:
|
||||
return "HEAD";
|
||||
case HTTP_PUT:
|
||||
return "PUT";
|
||||
case HTTP_POST:
|
||||
return "POST";
|
||||
case HTTP_DELETE:
|
||||
return "DELETE";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
int aos_base64_encode(const unsigned char *in, int inLen, char *out)
|
||||
{
|
||||
static const char *ENC =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
char *original_out = out;
|
||||
|
||||
while (inLen) {
|
||||
// first 6 bits of char 1
|
||||
*out++ = ENC[*in >> 2];
|
||||
if (!--inLen) {
|
||||
// last 2 bits of char 1, 4 bits of 0
|
||||
*out++ = ENC[(*in & 0x3) << 4];
|
||||
*out++ = '=';
|
||||
*out++ = '=';
|
||||
break;
|
||||
}
|
||||
// last 2 bits of char 1, first 4 bits of char 2
|
||||
*out++ = ENC[((*in & 0x3) << 4) | (*(in + 1) >> 4)];
|
||||
in++;
|
||||
if (!--inLen) {
|
||||
// last 4 bits of char 2, 2 bits of 0
|
||||
*out++ = ENC[(*in & 0xF) << 2];
|
||||
*out++ = '=';
|
||||
break;
|
||||
}
|
||||
// last 4 bits of char 2, first 2 bits of char 3
|
||||
*out++ = ENC[((*in & 0xF) << 2) | (*(in + 1) >> 6)];
|
||||
in++;
|
||||
// last 6 bits of char 3
|
||||
*out++ = ENC[*in & 0x3F];
|
||||
in++, inLen--;
|
||||
}
|
||||
|
||||
return (out - original_out);
|
||||
}
|
||||
|
||||
// HMAC-SHA-1:
|
||||
//
|
||||
// K - is key padded with zeros to 512 bits
|
||||
// m - is message
|
||||
// OPAD - 0x5c5c5c...
|
||||
// IPAD - 0x363636...
|
||||
//
|
||||
// HMAC(K,m) = SHA1((K ^ OPAD) . SHA1((K ^ IPAD) . m))
|
||||
void HMAC_SHA1(unsigned char hmac[20], const unsigned char *key, int key_len,
|
||||
const unsigned char *message, int message_len)
|
||||
{
|
||||
unsigned char kopad[64], kipad[64];
|
||||
int i;
|
||||
unsigned char digest[APR_SHA1_DIGESTSIZE];
|
||||
apr_sha1_ctx_t context;
|
||||
|
||||
if (key_len > 64) {
|
||||
key_len = 64;
|
||||
}
|
||||
|
||||
for (i = 0; i < key_len; i++) {
|
||||
kopad[i] = key[i] ^ 0x5c;
|
||||
kipad[i] = key[i] ^ 0x36;
|
||||
}
|
||||
|
||||
for ( ; i < 64; i++) {
|
||||
kopad[i] = 0 ^ 0x5c;
|
||||
kipad[i] = 0 ^ 0x36;
|
||||
}
|
||||
|
||||
apr_sha1_init(&context);
|
||||
apr_sha1_update(&context, (const char *)kipad, 64);
|
||||
apr_sha1_update(&context, (const char *)message, (unsigned int)message_len);
|
||||
apr_sha1_final(digest, &context);
|
||||
|
||||
apr_sha1_init(&context);
|
||||
apr_sha1_update(&context, (const char *)kopad, 64);
|
||||
apr_sha1_update(&context, (const char *)digest, 20);
|
||||
apr_sha1_final(hmac, &context);
|
||||
}
|
||||
|
||||
unsigned char* aos_md5(aos_pool_t* pool, const char *in, apr_size_t in_len) {
|
||||
unsigned char* out;
|
||||
apr_md5_ctx_t context;
|
||||
|
||||
//APR_MD5_DIGESTSIZE: The MD5 digest size, value is 16
|
||||
out = aos_palloc(pool, APR_MD5_DIGESTSIZE + 1);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != apr_md5_init(&context)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != apr_md5_update(&context, in, in_len)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 != apr_md5_final(out, &context)) {
|
||||
return NULL;
|
||||
}
|
||||
out[APR_MD5_DIGESTSIZE] = '\0';
|
||||
return out;
|
||||
};
|
||||
|
||||
int aos_url_decode(const char *in, char *out)
|
||||
{
|
||||
static const char tbl[256] = {
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,10,11,12,13,14,15,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,
|
||||
-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1
|
||||
};
|
||||
char c, v1, v2;
|
||||
|
||||
if(in != NULL) {
|
||||
while((c=*in++) != '\0') {
|
||||
if(c == '%') {
|
||||
if(!(v1=*in++) || (v1=tbl[(unsigned char)v1])<0 ||
|
||||
!(v2=*in++) || (v2=tbl[(unsigned char)v2])<0) {
|
||||
*out = '\0';
|
||||
return -1;
|
||||
}
|
||||
c = (v1<<4)|v2;
|
||||
} else if (c == '+') {
|
||||
c = ' ';
|
||||
}
|
||||
*out++ = c;
|
||||
}
|
||||
}
|
||||
*out = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a string to a long long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long long aos_strtoll(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
/* LONGLONG */
|
||||
long long int acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/* endptr may be NULL */
|
||||
|
||||
#ifdef __GNUC__
|
||||
/* This outrageous construct just to shut up a GCC warning. */
|
||||
(void) &acc; (void) &cutoff;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Skip white space and pick up leading +/- sign if any.
|
||||
* If base is 0, allow 0x for hex and 0 for octal, else
|
||||
* assume decimal; if base is already 16, allow 0x.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
/*
|
||||
* Compute the cutoff value between legal numbers and illegal
|
||||
* numbers. That is the largest legal value, divided by the
|
||||
* base. An input number that is greater than this value, if
|
||||
* followed by a legal input character, is too big. One that
|
||||
* is equal to this value may be valid or not; the limit
|
||||
* between valid and invalid numbers is then based on the last
|
||||
* digit. For instance, if the range for long longs is
|
||||
* [-9223372036854775808..9223372036854775807] and the input base
|
||||
* is 10, cutoff will be set to 922337203685477580 and cutlim to
|
||||
* either 7 (neg==0) or 8 (neg==1), meaning that if we have
|
||||
* accumulated a value > 922337203685477580, or equal but the
|
||||
* next digit is > 7 (or 8), the number is too big, and we will
|
||||
* return a range error.
|
||||
*
|
||||
* Set any if any `digits' consumed; make it negative to indicate
|
||||
* overflow.
|
||||
*/
|
||||
cutoff = neg ? LLONG_MIN : LLONG_MAX;
|
||||
cutlim = (int)(cutoff % base);
|
||||
cutoff /= base;
|
||||
if (neg) {
|
||||
if (cutlim > 0) {
|
||||
cutlim -= base;
|
||||
cutoff += 1;
|
||||
}
|
||||
cutlim = -cutlim;
|
||||
}
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (neg) {
|
||||
if (acc < cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = LLONG_MIN;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc -= c;
|
||||
}
|
||||
} else {
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = LLONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (endptr != 0)
|
||||
/* LINTED interface specification */
|
||||
*endptr = (char *)(any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
|
||||
int64_t aos_atoi64(const char *nptr)
|
||||
{
|
||||
return aos_strtoull(nptr, NULL, 10);
|
||||
}
|
||||
|
||||
unsigned long long aos_strtoull(const char *nptr, char **endptr, int base)
|
||||
{
|
||||
const char *s;
|
||||
unsigned long long acc, cutoff;
|
||||
int c;
|
||||
int neg, any, cutlim;
|
||||
|
||||
/*
|
||||
* See strtoq for comments as to the logic used.
|
||||
*/
|
||||
s = nptr;
|
||||
do {
|
||||
c = (unsigned char) *s++;
|
||||
} while (isspace(c));
|
||||
if (c == '-') {
|
||||
neg = 1;
|
||||
c = *s++;
|
||||
} else {
|
||||
neg = 0;
|
||||
if (c == '+')
|
||||
c = *s++;
|
||||
}
|
||||
if ((base == 0 || base == 16) &&
|
||||
c == '0' && (*s == 'x' || *s == 'X')) {
|
||||
c = s[1];
|
||||
s += 2;
|
||||
base = 16;
|
||||
}
|
||||
if (base == 0)
|
||||
base = c == '0' ? 8 : 10;
|
||||
|
||||
cutoff = ULLONG_MAX / (unsigned long long)base;
|
||||
cutlim = ULLONG_MAX % (unsigned long long)base;
|
||||
for (acc = 0, any = 0;; c = (unsigned char) *s++) {
|
||||
if (isdigit(c))
|
||||
c -= '0';
|
||||
else if (isalpha(c))
|
||||
c -= isupper(c) ? 'A' - 10 : 'a' - 10;
|
||||
else
|
||||
break;
|
||||
if (c >= base)
|
||||
break;
|
||||
if (any < 0)
|
||||
continue;
|
||||
if (acc > cutoff || (acc == cutoff && c > cutlim)) {
|
||||
any = -1;
|
||||
acc = ULLONG_MAX;
|
||||
errno = ERANGE;
|
||||
} else {
|
||||
any = 1;
|
||||
acc *= (unsigned long long)base;
|
||||
acc += c;
|
||||
}
|
||||
}
|
||||
if (neg && any > 0)
|
||||
#ifdef WIN32
|
||||
#pragma warning(disable : 4146)
|
||||
#endif
|
||||
acc = -acc;
|
||||
#ifdef WIN32
|
||||
#pragma warning(default : 4146)
|
||||
#endif
|
||||
if (endptr != 0)
|
||||
*endptr = (char *) (any ? s - 1 : nptr);
|
||||
return (acc);
|
||||
}
|
||||
|
||||
uint64_t aos_atoui64(const char *nptr)
|
||||
{
|
||||
return aos_strtoull(nptr, NULL, 10);
|
||||
}
|
||||
84
include/oss_sdk/aos_util.h
Normal file
84
include/oss_sdk/aos_util.h
Normal file
@@ -0,0 +1,84 @@
|
||||
#ifndef LIBAOS_UTIL_H
|
||||
#define LIBAOS_UTIL_H
|
||||
|
||||
#include "aos_buf.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_define.h"
|
||||
#include "aos_fstack.h"
|
||||
|
||||
#include <mxml.h>
|
||||
#include <apr_md5.h>
|
||||
#include <apr_sha1.h>
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
int aos_parse_xml_body(aos_list_t *bc, mxml_node_t **root);
|
||||
|
||||
void aos_gnome_sort(const char **headers, int size);
|
||||
|
||||
int aos_convert_to_gmt_time(char* date, const char* format, apr_time_exp_t *tm);
|
||||
int aos_get_gmt_str_time(char datestr[AOS_MAX_GMT_TIME_LEN]);
|
||||
|
||||
/**
|
||||
* URL-encodes a string from [src] into [dest]. [dest] must have at least
|
||||
* 3x the number of characters that [source] has. At most [maxSrcSize] bytes
|
||||
* from [src] are encoded; if more are present in [src], 0 is returned from
|
||||
* urlEncode, else nonzero is returned.
|
||||
*/
|
||||
int aos_url_encode(char *dest, const char *src, int maxSrcSize);
|
||||
|
||||
const char* aos_http_method_to_string(http_method_e method);
|
||||
|
||||
/**
|
||||
* encode query string, check query args < AOS_MAX_QUERY_ARG_LEN
|
||||
* result string "?a&b=x"
|
||||
*/
|
||||
int aos_query_params_to_string(aos_pool_t *p, aos_table_t *query_params, aos_string_t *querystr);
|
||||
|
||||
/**
|
||||
* base64 encode bytes. The output buffer must have at least
|
||||
* ((4 * (inLen + 1)) / 3) bytes in it. Returns the number of bytes written
|
||||
* to [out].
|
||||
*/
|
||||
int aos_base64_encode(const unsigned char *in, int inLen, char *out);
|
||||
|
||||
/**
|
||||
* Compute HMAC-SHA-1 with key [key] and message [message], storing result
|
||||
* in [hmac]
|
||||
*/
|
||||
void HMAC_SHA1(unsigned char hmac[20], const unsigned char *key, int key_len,
|
||||
const unsigned char *message, int message_len);
|
||||
|
||||
unsigned char* aos_md5(aos_pool_t* pool, const char* in, apr_size_t in_len);
|
||||
|
||||
int aos_url_decode(const char *in, char *out);
|
||||
|
||||
/*
|
||||
* Convert a string to a long long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
*/
|
||||
long long aos_strtoll(const char *nptr, char **endptr, int base);
|
||||
|
||||
/*
|
||||
* @brief Convert a string to int64_t.
|
||||
**/
|
||||
int64_t aos_atoi64(const char *nptr);
|
||||
|
||||
/*
|
||||
* @brief Convert a string to an unsigned long long integer.
|
||||
*
|
||||
* Ignores `locale' stuff. Assumes that the upper and lower case
|
||||
* alphabets and digits are each contiguous.
|
||||
**/
|
||||
unsigned long long aos_strtoull(const char *nptr, char **endptr, int base);
|
||||
|
||||
/*
|
||||
* @brief Convert a string to uint64_t.
|
||||
**/
|
||||
uint64_t aos_atoui64(const char *nptr);
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
332
include/oss_sdk/mxml.h
Normal file
332
include/oss_sdk/mxml.h
Normal file
@@ -0,0 +1,332 @@
|
||||
/*
|
||||
* "$Id: mxml.h 451 2014-01-04 21:50:06Z msweet $"
|
||||
*
|
||||
* Header file for Mini-XML, a small XML-like file parsing library.
|
||||
*
|
||||
* Copyright 2003-2014 by Michael R Sweet.
|
||||
*
|
||||
* These coded instructions, statements, and computer programs are the
|
||||
* property of Michael R Sweet and are protected by Federal copyright
|
||||
* law. Distribution and use rights are outlined in the file "COPYING"
|
||||
* which should have been included with this file. If this file is
|
||||
* missing or damaged, see the license at:
|
||||
*
|
||||
* http://www.msweet.org/projects.php/Mini-XML
|
||||
*/
|
||||
|
||||
/*
|
||||
* Prevent multiple inclusion...
|
||||
*/
|
||||
|
||||
#ifndef _mxml_h_
|
||||
# define _mxml_h_
|
||||
|
||||
/*
|
||||
* Include necessary headers...
|
||||
*/
|
||||
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
# include <ctype.h>
|
||||
# include <errno.h>
|
||||
|
||||
|
||||
/*
|
||||
* Constants...
|
||||
*/
|
||||
|
||||
# define MXML_MAJOR_VERSION 2 /* Major version number */
|
||||
# define MXML_MINOR_VERSION 8 /* Minor version number */
|
||||
|
||||
# define MXML_TAB 8 /* Tabs every N columns */
|
||||
|
||||
# define MXML_NO_CALLBACK 0 /* Don't use a type callback */
|
||||
# define MXML_INTEGER_CALLBACK mxml_integer_cb
|
||||
/* Treat all data as integers */
|
||||
# define MXML_OPAQUE_CALLBACK mxml_opaque_cb
|
||||
/* Treat all data as opaque */
|
||||
# define MXML_REAL_CALLBACK mxml_real_cb
|
||||
/* Treat all data as real numbers */
|
||||
# define MXML_TEXT_CALLBACK 0 /* Treat all data as text */
|
||||
# define MXML_IGNORE_CALLBACK mxml_ignore_cb
|
||||
/* Ignore all non-element content */
|
||||
|
||||
# define MXML_NO_PARENT 0 /* No parent for the node */
|
||||
|
||||
# define MXML_DESCEND 1 /* Descend when finding/walking */
|
||||
# define MXML_NO_DESCEND 0 /* Don't descend when finding/walking */
|
||||
# define MXML_DESCEND_FIRST -1 /* Descend for first find */
|
||||
|
||||
# define MXML_WS_BEFORE_OPEN 0 /* Callback for before open tag */
|
||||
# define MXML_WS_AFTER_OPEN 1 /* Callback for after open tag */
|
||||
# define MXML_WS_BEFORE_CLOSE 2 /* Callback for before close tag */
|
||||
# define MXML_WS_AFTER_CLOSE 3 /* Callback for after close tag */
|
||||
|
||||
# define MXML_ADD_BEFORE 0 /* Add node before specified node */
|
||||
# define MXML_ADD_AFTER 1 /* Add node after specified node */
|
||||
# define MXML_ADD_TO_PARENT NULL /* Add node relative to parent */
|
||||
|
||||
|
||||
/*
|
||||
* Data types...
|
||||
*/
|
||||
|
||||
typedef enum mxml_sax_event_e /**** SAX event type. ****/
|
||||
{
|
||||
MXML_SAX_CDATA, /* CDATA node */
|
||||
MXML_SAX_COMMENT, /* Comment node */
|
||||
MXML_SAX_DATA, /* Data node */
|
||||
MXML_SAX_DIRECTIVE, /* Processing directive node */
|
||||
MXML_SAX_ELEMENT_CLOSE, /* Element closed */
|
||||
MXML_SAX_ELEMENT_OPEN /* Element opened */
|
||||
} mxml_sax_event_t;
|
||||
|
||||
typedef enum mxml_type_e /**** The XML node type. ****/
|
||||
{
|
||||
MXML_IGNORE = -1, /* Ignore/throw away node @since Mini-XML 2.3@ */
|
||||
MXML_ELEMENT, /* XML element with attributes */
|
||||
MXML_INTEGER, /* Integer value */
|
||||
MXML_OPAQUE, /* Opaque string */
|
||||
MXML_REAL, /* Real value */
|
||||
MXML_TEXT, /* Text fragment */
|
||||
MXML_CUSTOM /* Custom data @since Mini-XML 2.1@ */
|
||||
} mxml_type_t;
|
||||
|
||||
typedef void (*mxml_custom_destroy_cb_t)(void *);
|
||||
/**** Custom data destructor ****/
|
||||
|
||||
typedef void (*mxml_error_cb_t)(const char *);
|
||||
/**** Error callback function ****/
|
||||
|
||||
typedef struct mxml_attr_s /**** An XML element attribute value. @private@ ****/
|
||||
{
|
||||
char *name; /* Attribute name */
|
||||
char *value; /* Attribute value */
|
||||
} mxml_attr_t;
|
||||
|
||||
typedef struct mxml_element_s /**** An XML element value. @private@ ****/
|
||||
{
|
||||
char *name; /* Name of element */
|
||||
int num_attrs; /* Number of attributes */
|
||||
mxml_attr_t *attrs; /* Attributes */
|
||||
} mxml_element_t;
|
||||
|
||||
typedef struct mxml_text_s /**** An XML text value. @private@ ****/
|
||||
{
|
||||
int whitespace; /* Leading whitespace? */
|
||||
char *string; /* Fragment string */
|
||||
} mxml_text_t;
|
||||
|
||||
typedef struct mxml_custom_s /**** An XML custom value. @private@ ****/
|
||||
{
|
||||
void *data; /* Pointer to (allocated) custom data */
|
||||
mxml_custom_destroy_cb_t destroy; /* Pointer to destructor function */
|
||||
} mxml_custom_t;
|
||||
|
||||
typedef union mxml_value_u /**** An XML node value. @private@ ****/
|
||||
{
|
||||
mxml_element_t element; /* Element */
|
||||
int integer; /* Integer number */
|
||||
char *opaque; /* Opaque string */
|
||||
double real; /* Real number */
|
||||
mxml_text_t text; /* Text fragment */
|
||||
mxml_custom_t custom; /* Custom data @since Mini-XML 2.1@ */
|
||||
} mxml_value_t;
|
||||
|
||||
struct mxml_node_s /**** An XML node. @private@ ****/
|
||||
{
|
||||
mxml_type_t type; /* Node type */
|
||||
struct mxml_node_s *next; /* Next node under same parent */
|
||||
struct mxml_node_s *prev; /* Previous node under same parent */
|
||||
struct mxml_node_s *parent; /* Parent node */
|
||||
struct mxml_node_s *child; /* First child node */
|
||||
struct mxml_node_s *last_child; /* Last child node */
|
||||
mxml_value_t value; /* Node value */
|
||||
int ref_count; /* Use count */
|
||||
void *user_data; /* User data */
|
||||
};
|
||||
|
||||
typedef struct mxml_node_s mxml_node_t; /**** An XML node. ****/
|
||||
|
||||
struct mxml_index_s /**** An XML node index. @private@ ****/
|
||||
{
|
||||
char *attr; /* Attribute used for indexing or NULL */
|
||||
int num_nodes; /* Number of nodes in index */
|
||||
int alloc_nodes; /* Allocated nodes in index */
|
||||
int cur_node; /* Current node */
|
||||
mxml_node_t **nodes; /* Node array */
|
||||
};
|
||||
|
||||
typedef struct mxml_index_s mxml_index_t;
|
||||
/**** An XML node index. ****/
|
||||
|
||||
typedef int (*mxml_custom_load_cb_t)(mxml_node_t *, const char *);
|
||||
/**** Custom data load callback function ****/
|
||||
|
||||
typedef char *(*mxml_custom_save_cb_t)(mxml_node_t *);
|
||||
/**** Custom data save callback function ****/
|
||||
|
||||
typedef int (*mxml_entity_cb_t)(const char *);
|
||||
/**** Entity callback function */
|
||||
|
||||
typedef mxml_type_t (*mxml_load_cb_t)(mxml_node_t *);
|
||||
/**** Load callback function ****/
|
||||
|
||||
typedef const char *(*mxml_save_cb_t)(mxml_node_t *, int);
|
||||
/**** Save callback function ****/
|
||||
|
||||
typedef void (*mxml_sax_cb_t)(mxml_node_t *, mxml_sax_event_t, void *);
|
||||
/**** SAX callback function ****/
|
||||
|
||||
|
||||
/*
|
||||
* C++ support...
|
||||
*/
|
||||
|
||||
# ifdef __cplusplus
|
||||
extern "C" {
|
||||
# endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Prototypes...
|
||||
*/
|
||||
|
||||
extern void mxmlAdd(mxml_node_t *parent, int where,
|
||||
mxml_node_t *child, mxml_node_t *node);
|
||||
extern void mxmlDelete(mxml_node_t *node);
|
||||
extern void mxmlElementDeleteAttr(mxml_node_t *node,
|
||||
const char *name);
|
||||
extern const char *mxmlElementGetAttr(mxml_node_t *node, const char *name);
|
||||
extern void mxmlElementSetAttr(mxml_node_t *node, const char *name,
|
||||
const char *value);
|
||||
extern void mxmlElementSetAttrf(mxml_node_t *node, const char *name,
|
||||
const char *format, ...)
|
||||
# ifdef __GNUC__
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
||||
# endif /* __GNUC__ */
|
||||
;
|
||||
extern int mxmlEntityAddCallback(mxml_entity_cb_t cb);
|
||||
extern const char *mxmlEntityGetName(int val);
|
||||
extern int mxmlEntityGetValue(const char *name);
|
||||
extern void mxmlEntityRemoveCallback(mxml_entity_cb_t cb);
|
||||
extern mxml_node_t *mxmlFindElement(mxml_node_t *node, mxml_node_t *top,
|
||||
const char *name, const char *attr,
|
||||
const char *value, int descend);
|
||||
extern mxml_node_t *mxmlFindPath(mxml_node_t *node, const char *path);
|
||||
extern const char *mxmlGetCDATA(mxml_node_t *node);
|
||||
extern const void *mxmlGetCustom(mxml_node_t *node);
|
||||
extern const char *mxmlGetElement(mxml_node_t *node);
|
||||
extern mxml_node_t *mxmlGetFirstChild(mxml_node_t *node);
|
||||
extern int mxmlGetInteger(mxml_node_t *node);
|
||||
extern mxml_node_t *mxmlGetLastChild(mxml_node_t *node);
|
||||
extern mxml_node_t *mxmlGetNextSibling(mxml_node_t *node);
|
||||
extern const char *mxmlGetOpaque(mxml_node_t *node);
|
||||
extern mxml_node_t *mxmlGetParent(mxml_node_t *node);
|
||||
extern mxml_node_t *mxmlGetPrevSibling(mxml_node_t *node);
|
||||
extern double mxmlGetReal(mxml_node_t *node);
|
||||
extern int mxmlGetRefCount(mxml_node_t *node);
|
||||
extern const char *mxmlGetText(mxml_node_t *node, int *whitespace);
|
||||
extern mxml_type_t mxmlGetType(mxml_node_t *node);
|
||||
extern void *mxmlGetUserData(mxml_node_t *node);
|
||||
extern void mxmlIndexDelete(mxml_index_t *ind);
|
||||
extern mxml_node_t *mxmlIndexEnum(mxml_index_t *ind);
|
||||
extern mxml_node_t *mxmlIndexFind(mxml_index_t *ind,
|
||||
const char *element,
|
||||
const char *value);
|
||||
extern int mxmlIndexGetCount(mxml_index_t *ind);
|
||||
extern mxml_index_t *mxmlIndexNew(mxml_node_t *node, const char *element,
|
||||
const char *attr);
|
||||
extern mxml_node_t *mxmlIndexReset(mxml_index_t *ind);
|
||||
extern mxml_node_t *mxmlLoadFd(mxml_node_t *top, int fd,
|
||||
mxml_type_t (*cb)(mxml_node_t *));
|
||||
extern mxml_node_t *mxmlLoadFile(mxml_node_t *top, FILE *fp,
|
||||
mxml_type_t (*cb)(mxml_node_t *));
|
||||
extern mxml_node_t *mxmlLoadString(mxml_node_t *top, const char *s,
|
||||
mxml_type_t (*cb)(mxml_node_t *));
|
||||
extern mxml_node_t *mxmlNewCDATA(mxml_node_t *parent, const char *string);
|
||||
extern mxml_node_t *mxmlNewCustom(mxml_node_t *parent, void *data,
|
||||
mxml_custom_destroy_cb_t destroy);
|
||||
extern mxml_node_t *mxmlNewElement(mxml_node_t *parent, const char *name);
|
||||
extern mxml_node_t *mxmlNewInteger(mxml_node_t *parent, int integer);
|
||||
extern mxml_node_t *mxmlNewOpaque(mxml_node_t *parent, const char *opaque);
|
||||
extern mxml_node_t *mxmlNewReal(mxml_node_t *parent, double real);
|
||||
extern mxml_node_t *mxmlNewText(mxml_node_t *parent, int whitespace,
|
||||
const char *string);
|
||||
extern mxml_node_t *mxmlNewTextf(mxml_node_t *parent, int whitespace,
|
||||
const char *format, ...)
|
||||
# ifdef __GNUC__
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
||||
# endif /* __GNUC__ */
|
||||
;
|
||||
extern mxml_node_t *mxmlNewXML(const char *version);
|
||||
extern int mxmlRelease(mxml_node_t *node);
|
||||
extern void mxmlRemove(mxml_node_t *node);
|
||||
extern int mxmlRetain(mxml_node_t *node);
|
||||
extern char *mxmlSaveAllocString(mxml_node_t *node,
|
||||
mxml_save_cb_t cb);
|
||||
extern int mxmlSaveFd(mxml_node_t *node, int fd,
|
||||
mxml_save_cb_t cb);
|
||||
extern int mxmlSaveFile(mxml_node_t *node, FILE *fp,
|
||||
mxml_save_cb_t cb);
|
||||
extern int mxmlSaveString(mxml_node_t *node, char *buffer,
|
||||
int bufsize, mxml_save_cb_t cb);
|
||||
extern mxml_node_t *mxmlSAXLoadFd(mxml_node_t *top, int fd,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, void *sax_data);
|
||||
extern mxml_node_t *mxmlSAXLoadFile(mxml_node_t *top, FILE *fp,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, void *sax_data);
|
||||
extern mxml_node_t *mxmlSAXLoadString(mxml_node_t *top, const char *s,
|
||||
mxml_type_t (*cb)(mxml_node_t *),
|
||||
mxml_sax_cb_t sax, void *sax_data);
|
||||
extern int mxmlSetCDATA(mxml_node_t *node, const char *data);
|
||||
extern int mxmlSetCustom(mxml_node_t *node, void *data,
|
||||
mxml_custom_destroy_cb_t destroy);
|
||||
extern void mxmlSetCustomHandlers(mxml_custom_load_cb_t load,
|
||||
mxml_custom_save_cb_t save);
|
||||
extern int mxmlSetElement(mxml_node_t *node, const char *name);
|
||||
extern void mxmlSetErrorCallback(mxml_error_cb_t cb);
|
||||
extern int mxmlSetInteger(mxml_node_t *node, int integer);
|
||||
extern int mxmlSetOpaque(mxml_node_t *node, const char *opaque);
|
||||
extern int mxmlSetReal(mxml_node_t *node, double real);
|
||||
extern int mxmlSetText(mxml_node_t *node, int whitespace,
|
||||
const char *string);
|
||||
extern int mxmlSetTextf(mxml_node_t *node, int whitespace,
|
||||
const char *format, ...)
|
||||
# ifdef __GNUC__
|
||||
__attribute__ ((__format__ (__printf__, 3, 4)))
|
||||
# endif /* __GNUC__ */
|
||||
;
|
||||
extern int mxmlSetUserData(mxml_node_t *node, void *data);
|
||||
extern void mxmlSetWrapMargin(int column);
|
||||
extern mxml_node_t *mxmlWalkNext(mxml_node_t *node, mxml_node_t *top,
|
||||
int descend);
|
||||
extern mxml_node_t *mxmlWalkPrev(mxml_node_t *node, mxml_node_t *top,
|
||||
int descend);
|
||||
|
||||
|
||||
/*
|
||||
* Semi-private functions...
|
||||
*/
|
||||
|
||||
extern void mxml_error(const char *format, ...);
|
||||
extern mxml_type_t mxml_ignore_cb(mxml_node_t *node);
|
||||
extern mxml_type_t mxml_integer_cb(mxml_node_t *node);
|
||||
extern mxml_type_t mxml_opaque_cb(mxml_node_t *node);
|
||||
extern mxml_type_t mxml_real_cb(mxml_node_t *node);
|
||||
|
||||
|
||||
/*
|
||||
* C++ support...
|
||||
*/
|
||||
|
||||
# ifdef __cplusplus
|
||||
}
|
||||
# endif /* __cplusplus */
|
||||
#endif /* !_mxml_h_ */
|
||||
|
||||
|
||||
/*
|
||||
* End of "$Id: mxml.h 451 2014-01-04 21:50:06Z msweet $".
|
||||
*/
|
||||
957
include/oss_sdk/oss_api.h
Normal file
957
include/oss_sdk/oss_api.h
Normal file
@@ -0,0 +1,957 @@
|
||||
#ifndef LIBOSS_API_H
|
||||
#define LIBOSS_API_H
|
||||
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_define.h"
|
||||
#include "oss_util.h"
|
||||
|
||||
OSS_CPP_START
|
||||
|
||||
/*
|
||||
* @brief create oss bucket
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] oss_acl the oss bucket acl
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_create_bucket(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_acl_e oss_acl,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief delete oss bucket
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_delete_bucket(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief put oss bucket acl
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] oss_acl the oss bucket acl
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_bucket_acl(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_acl_e oss_acl,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief get oss bucket acl
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[out] oss_acl the oss bucket acl
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_bucket_acl(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_string_t *oss_acl,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief put oss bucket lifecycle
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] lifecycle_rule_list the oss bucket lifecycle list
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_bucket_lifecycle(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_list_t *lifecycle_rule_list,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief get oss bucket lifecycle
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[out] lifecycle_rule_list the oss bucket lifecycle list
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_bucket_lifecycle(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_list_t *lifecycle_rule_list,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief delete oss bucket lifecycle
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_delete_bucket_lifecycle(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief list oss objects
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] params input params for list object request,
|
||||
including prefix, marker, delimiter, max_ret
|
||||
* @param[out] params output params for list object response,
|
||||
including truncated, next_marker, obje list
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_list_object(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_list_object_params_t *params,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief put oss object from buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] buffer the buffer containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief put oss object from file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] filename the filename to put
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *filename,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief put oss object from buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] buffer the buffer containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_put_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief put oss object from file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] filename the filename to put
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_put_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *filename,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief get oss object to buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[out] buffer the buffer containing object content
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_object_to_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief get oss object to buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] buffer the buffer containing object content
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_get_object_to_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_list_t *buffer,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief get oss object to file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] filename the filename storing object content
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_object_to_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_string_t *filename,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief get oss object to file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] filename the filename storing object content
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_get_object_to_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_string_t *filename,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief head oss object
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers containing object meta
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_head_object(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief delete oss object
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_delete_object(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief delete oss objects
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object_list the oss object list name
|
||||
* @param[in] is_quiet is quiet or verbose
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] deleted_object_list deleted object list
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_delete_objects(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_list_t *object_list,
|
||||
int is_quiet,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *deleted_object_list);
|
||||
|
||||
/*
|
||||
* @brief delete oss objects by prefix
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] prefix prefix of delete objects
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_delete_objects_by_prefix(oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *prefix);
|
||||
|
||||
/*
|
||||
* @brief copy oss objects
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] source_bucket the oss source bucket name
|
||||
* @param[in] object_list the oss source object list name
|
||||
* @param[in] dest_bucket the oss dest bucket name
|
||||
* @param[in] dest_list the oss dest object list name
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_copy_object(const oss_request_options_t *options,
|
||||
const aos_string_t *source_bucket,
|
||||
const aos_string_t *source_object,
|
||||
const aos_string_t *dest_bucket,
|
||||
const aos_string_t *dest_object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief append oss object from buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] position the start position append
|
||||
* @param[in] buffer the buffer containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_append_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief append oss object from buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] position the start position append
|
||||
* @param[in] init_crc the initial crc value
|
||||
* @param[in] buffer the buffer containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_append_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
uint64_t init_crc,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief append oss object from file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] position the start position append
|
||||
* @param[in] append_file the file containing appending content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_append_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
const aos_string_t *append_file,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief append oss object from file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] position the start position append
|
||||
* @param[in] init_crc the initial crc value
|
||||
* @param[in] append_file the file containing appending content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_append_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
uint64_t init_crc,
|
||||
const aos_string_t *append_file,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief gen signed url for oss object api
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] expires the end expire time for signed url
|
||||
* @param[in] req the aos http request
|
||||
* @return signed url, non-NULL success, NULL failure
|
||||
*/
|
||||
char *oss_gen_signed_url(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t expires,
|
||||
aos_http_request_t *req);
|
||||
|
||||
/*
|
||||
* @brief oss put object from buffer using signed url
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] signed_url the signed url for put object
|
||||
* @param[in] buffer the buffer containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_object_from_buffer_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss put object from file using signed url
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] signed_url the signed url for put object
|
||||
* @param[in] filename the filename containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_object_from_file_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_string_t *filename,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss get object to buffer using signed url
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] signed_url the signed url for put object
|
||||
* @param[in] buffer the buffer containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_object_to_buffer_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss get object to file using signed url
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] signed_url the signed url for put object
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] filename the filename containing object content
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_object_to_file_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_string_t *filename,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss head object using signed url
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] signed_url the signed url for put object
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_head_object_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss init multipart upload
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_init_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_string_t *upload_id,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss upload part from buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] part_num the upload part number
|
||||
* @param[in] buffer the buffer containing upload part content
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_upload_part_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss upload part from buffer
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] part_num the upload part number
|
||||
* @param[in] buffer the buffer containing upload part content
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_upload_part_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
aos_list_t *buffer,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief oss upload part from file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] part_num the upload part number
|
||||
* @param[in] upload_file the file containing upload part content
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_upload_part_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
oss_upload_file_t *upload_file,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss upload part from file
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] part_num the upload part number
|
||||
* @param[in] upload_file the file containing upload part content
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_upload_part_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
oss_upload_file_t *upload_file,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief oss abort multipart upload
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_abort_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_string_t *upload_id,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
|
||||
/*
|
||||
* @brief oss complete multipart upload
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] part_list the uploaded part list to complete
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_complete_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
aos_list_t *part_list,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss complete multipart upload
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] part_list the uploaded part list to complete
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_do_complete_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
aos_list_t *part_list,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief oss list upload part with specific upload_id for object
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] params the input list upload part parameters,
|
||||
incluing part_number_marker, max_ret
|
||||
* @param[out] params the output params,
|
||||
including next_part_number_marker, part_list, truncated
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_list_upload_part(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
oss_list_upload_part_params_t *params,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss list multipart upload for bucket
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] params the input list multipart upload parameters
|
||||
* @param[out] params the output params including next_key_marker, next_upload_id_markert, upload_list etc
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_list_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_list_multipart_upload_params_t *params,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss copy large object using upload part copy
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] paramsthe upload part copy parameters
|
||||
* @param[in] headers the headers for request
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_upload_part_copy(const oss_request_options_t *options,
|
||||
oss_upload_part_copy_params_t *params,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss upload file using multipart upload
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] upload_id the upload id to upload if has
|
||||
* @param[in] filename the filename containing object content
|
||||
* @param[in] part_size the part size for multipart upload
|
||||
* @param[in] headers the headers for request
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_upload_file(oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_string_t *upload_id,
|
||||
aos_string_t *filename,
|
||||
int64_t part_size,
|
||||
aos_table_t *headers);
|
||||
|
||||
/*
|
||||
* @brief oss upload file with mulit-thread and resumable
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] filepath the filename containing object content
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] clt_params the control params of upload
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @param[out] resp_body oss server response body
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_resumable_upload_file(oss_request_options_t *options,
|
||||
aos_string_t *bucket,
|
||||
aos_string_t *object,
|
||||
aos_string_t *filepath,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_resumable_clt_params_t *clt_params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
/*
|
||||
* @brief oss upload file with mulit-thread and resumable
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] object the oss object name
|
||||
* @param[in] filepath download object to the file
|
||||
* @param[in] headers the headers for request
|
||||
* @param[in] params the params for request
|
||||
* @param[in] clt_params the control params of upload
|
||||
* @param[in] progress_callback the progress callback function
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_resumable_download_file(oss_request_options_t *options,
|
||||
aos_string_t *bucket,
|
||||
aos_string_t *object,
|
||||
aos_string_t *filepath,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_resumable_clt_params_t *clt_params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss create live channel
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] config the oss live channel configuration
|
||||
* @param[in] publish_url_list the publish url list
|
||||
* @param[in] play_url_list the play url list
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_create_live_channel(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_live_channel_configuration_t *config,
|
||||
aos_list_t *publish_url_list,
|
||||
aos_list_t *play_url_list,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss set live channel status
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[in] live_channel_status the oss live channel status, enabled or disabled
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_put_live_channel_status(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
const aos_string_t *live_channel_status,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss get live channel information
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[out] info the oss live channel information
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_live_channel_info(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
oss_live_channel_configuration_t *info,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss get live channel stat
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[out] stat the oss live channel stat
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_live_channel_stat(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
oss_live_channel_stat_t *stat,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief delete oss live channel
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_delete_live_channel(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief list oss live channels
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] params input params for list live channel request,
|
||||
including prefix, marker, max_key
|
||||
* @param[out] params output params for list object response,
|
||||
including truncated, next_marker, live channel list
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_list_live_channel(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_list_live_channel_params_t *params,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief oss get live record history of live channel
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[out] live_record_list the oss live records of live channel
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_get_live_channel_history(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
aos_list_t *live_record_list,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief generate vod play list for a period of time
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[in] play_list_name the oss live channel play list name
|
||||
* @param[in] start_time the start epoch time of play list, such as 1459922368
|
||||
* @param[in] end_time the end epoch time of play list, such as 1459922563
|
||||
* @param[out] resp_headers oss server response headers
|
||||
* @return aos_status_t, code is 2xx success, other failure
|
||||
*/
|
||||
aos_status_t *oss_gen_vod_play_list(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
const aos_string_t *play_list_name,
|
||||
const int64_t start_time,
|
||||
const int64_t end_time,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
/*
|
||||
* @brief gen signed url for put rtmp stream
|
||||
* @param[in] options the oss request options
|
||||
* @param[in] bucket the oss bucket name
|
||||
* @param[in] live_channel the oss live channel name
|
||||
* @param[in] play_list_name the oss live channel play list name
|
||||
* @param[in] expires the end expire time for signed url
|
||||
* @return signed url, non-NULL success, NULL failure
|
||||
*/
|
||||
char *oss_gen_rtmp_signed_url(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
const aos_string_t *play_list_name,
|
||||
const int64_t expires);
|
||||
|
||||
OSS_CPP_END
|
||||
|
||||
#endif
|
||||
570
include/oss_sdk/oss_auth.c
Normal file
570
include/oss_sdk/oss_auth.c
Normal file
@@ -0,0 +1,570 @@
|
||||
#include "oss_auth.h"
|
||||
#include "aos_log.h"
|
||||
#include "oss_util.h"
|
||||
|
||||
static const char *g_s_oss_sub_resource_list[] = {
|
||||
"acl",
|
||||
"uploadId",
|
||||
"uploads",
|
||||
"partNumber",
|
||||
"response-content-type",
|
||||
"response-content-language",
|
||||
"response-expires",
|
||||
"response-cache-control",
|
||||
"response-content-disposition",
|
||||
"response-content-encoding",
|
||||
"append",
|
||||
"position",
|
||||
"lifecycle",
|
||||
"delete",
|
||||
"live",
|
||||
"status",
|
||||
"comp",
|
||||
"vod",
|
||||
"startTime",
|
||||
"endTime",
|
||||
"x-oss-process",
|
||||
"security-token",
|
||||
NULL,
|
||||
};
|
||||
|
||||
static int is_oss_sub_resource(const char *str);
|
||||
static int is_oss_canonicalized_header(const char *str);
|
||||
static int oss_get_canonicalized_headers(aos_pool_t *p,
|
||||
const aos_table_t *headers, aos_buf_t *signbuf);
|
||||
static int oss_get_canonicalized_resource(aos_pool_t *p,
|
||||
const aos_table_t *params, aos_buf_t *signbuf);
|
||||
static int oss_get_canonicalized_params(aos_pool_t *p,
|
||||
const aos_table_t *params, aos_buf_t *signbuf);
|
||||
|
||||
static int is_oss_sub_resource(const char *str)
|
||||
{
|
||||
int i = 0;
|
||||
for ( ; g_s_oss_sub_resource_list[i]; i++) {
|
||||
if (apr_strnatcmp(g_s_oss_sub_resource_list[i], str) == 0) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_oss_canonicalized_header(const char *str)
|
||||
{
|
||||
size_t len = strlen(OSS_CANNONICALIZED_HEADER_PREFIX);
|
||||
return strncasecmp(str, OSS_CANNONICALIZED_HEADER_PREFIX, len) == 0;
|
||||
}
|
||||
|
||||
static int oss_get_canonicalized_headers(aos_pool_t *p,
|
||||
const aos_table_t *headers,
|
||||
aos_buf_t *signbuf)
|
||||
{
|
||||
int pos;
|
||||
int meta_count = 0;
|
||||
int i;
|
||||
int len;
|
||||
const aos_array_header_t *tarr;
|
||||
const aos_table_entry_t *telts;
|
||||
char **meta_headers;
|
||||
const char *value;
|
||||
aos_string_t tmp_str;
|
||||
char *tmpbuf = (char*)malloc(AOS_MAX_HEADER_LEN + 1);
|
||||
if (NULL == tmpbuf) {
|
||||
aos_error_log("malloc %d memory failed.", AOS_MAX_HEADER_LEN + 1);
|
||||
return AOSE_OVER_MEMORY;
|
||||
}
|
||||
|
||||
if (apr_is_empty_table(headers)) {
|
||||
free(tmpbuf);
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
// sort user meta header
|
||||
tarr = aos_table_elts(headers);
|
||||
telts = (aos_table_entry_t*)tarr->elts;
|
||||
meta_headers = aos_pcalloc(p, tarr->nelts * sizeof(char*));
|
||||
for (pos = 0; pos < tarr->nelts; ++pos) {
|
||||
if (is_oss_canonicalized_header(telts[pos].key)) {
|
||||
aos_string_t key = aos_string(telts[pos].key);
|
||||
aos_string_tolower(&key);
|
||||
meta_headers[meta_count++] = key.data;
|
||||
}
|
||||
}
|
||||
if (meta_count == 0) {
|
||||
free(tmpbuf);
|
||||
return AOSE_OK;
|
||||
}
|
||||
aos_gnome_sort((const char **)meta_headers, meta_count);
|
||||
|
||||
// sign string
|
||||
for (i = 0; i < meta_count; ++i) {
|
||||
value = apr_table_get(headers, meta_headers[i]);
|
||||
aos_str_set(&tmp_str, value);
|
||||
aos_strip_space(&tmp_str);
|
||||
len = apr_snprintf(tmpbuf, AOS_MAX_HEADER_LEN + 1, "%s:%.*s",
|
||||
meta_headers[i], tmp_str.len, tmp_str.data);
|
||||
if (len > AOS_MAX_HEADER_LEN) {
|
||||
free(tmpbuf);
|
||||
aos_error_log("user meta header too many, %d > %d.",
|
||||
len, AOS_MAX_HEADER_LEN);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
tmp_str.data = tmpbuf;
|
||||
tmp_str.len = len;
|
||||
aos_buf_append_string(p, signbuf, tmpbuf, len);
|
||||
aos_buf_append_string(p, signbuf, "\n", sizeof("\n")-1);
|
||||
}
|
||||
|
||||
free(tmpbuf);
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
static int oss_get_canonicalized_resource(aos_pool_t *p,
|
||||
const aos_table_t *params,
|
||||
aos_buf_t *signbuf)
|
||||
{
|
||||
int pos;
|
||||
int subres_count = 0;
|
||||
int i;
|
||||
int len;
|
||||
char sep;
|
||||
const char *value;
|
||||
char tmpbuf[AOS_MAX_QUERY_ARG_LEN+1];
|
||||
char **subres_headers;
|
||||
const aos_array_header_t *tarr;
|
||||
const aos_table_entry_t *telts;
|
||||
|
||||
if (apr_is_empty_table(params)) {
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
// sort sub resource param
|
||||
tarr = aos_table_elts(params);
|
||||
telts = (aos_table_entry_t*)tarr->elts;
|
||||
subres_headers = aos_pcalloc(p, tarr->nelts * sizeof(char*));
|
||||
for (pos = 0; pos < tarr->nelts; ++pos) {
|
||||
if (is_oss_sub_resource(telts[pos].key)) {
|
||||
subres_headers[subres_count++] = telts[pos].key;
|
||||
}
|
||||
}
|
||||
if (subres_count == 0) {
|
||||
return AOSE_OK;
|
||||
}
|
||||
aos_gnome_sort((const char **)subres_headers, subres_count);
|
||||
|
||||
// sign string
|
||||
sep = '?';
|
||||
for (i = 0; i < subres_count; ++i) {
|
||||
value = apr_table_get(params, subres_headers[i]);
|
||||
if (value != NULL && *value != '\0') {
|
||||
len = apr_snprintf(tmpbuf, sizeof(tmpbuf), "%c%s=%s",
|
||||
sep, subres_headers[i], value);
|
||||
} else {
|
||||
len = apr_snprintf(tmpbuf, sizeof(tmpbuf), "%c%s",
|
||||
sep, subres_headers[i]);
|
||||
}
|
||||
if (len >= AOS_MAX_QUERY_ARG_LEN) {
|
||||
aos_error_log("http query params too long, %s.", tmpbuf);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
aos_buf_append_string(p, signbuf, tmpbuf, len);
|
||||
sep = '&';
|
||||
}
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int oss_get_string_to_sign(aos_pool_t *p,
|
||||
http_method_e method,
|
||||
const aos_string_t *canon_res,
|
||||
const aos_table_t *headers,
|
||||
const aos_table_t *params,
|
||||
aos_string_t *signstr)
|
||||
{
|
||||
int res;
|
||||
aos_buf_t *signbuf;
|
||||
const char *value;
|
||||
aos_str_null(signstr);
|
||||
|
||||
signbuf = aos_create_buf(p, 1024);
|
||||
|
||||
#define signbuf_append_from_headers(KEY) do { \
|
||||
if ((value = apr_table_get(headers, KEY)) != NULL) { \
|
||||
aos_buf_append_string(p, signbuf, value, strlen(value)); \
|
||||
} \
|
||||
aos_buf_append_string(p, signbuf, "\n", sizeof("\n")-1); \
|
||||
} while (0)
|
||||
|
||||
#define signbuf_append(VALUE, LEN) do { \
|
||||
aos_buf_append_string(p, signbuf, VALUE, LEN); \
|
||||
aos_buf_append_string(p, signbuf, "\n", sizeof("\n")-1); \
|
||||
} while (0)
|
||||
|
||||
value = aos_http_method_to_string(method);
|
||||
signbuf_append(value, strlen(value));
|
||||
|
||||
signbuf_append_from_headers(OSS_CONTENT_MD5);
|
||||
signbuf_append_from_headers(OSS_CONTENT_TYPE);
|
||||
|
||||
// date
|
||||
if ((value = apr_table_get(headers, OSS_CANNONICALIZED_HEADER_DATE)) == NULL) {
|
||||
value = apr_table_get(headers, OSS_DATE);
|
||||
}
|
||||
if (NULL == value || *value == '\0') {
|
||||
aos_error_log("http header date is empty.");
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
signbuf_append(value, strlen(value));
|
||||
|
||||
// user meta headers
|
||||
if ((res = oss_get_canonicalized_headers(p, headers, signbuf)) != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// canonicalized resource
|
||||
aos_buf_append_string(p, signbuf, canon_res->data, canon_res->len);
|
||||
|
||||
if (params != NULL && (res = oss_get_canonicalized_resource(p, params, signbuf)) != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// result
|
||||
signstr->data = (char *)signbuf->pos;
|
||||
signstr->len = aos_buf_size(signbuf);
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
void oss_sign_headers(aos_pool_t *p,
|
||||
const aos_string_t *signstr,
|
||||
const aos_string_t *access_key_id,
|
||||
const aos_string_t *access_key_secret,
|
||||
aos_table_t *headers)
|
||||
{
|
||||
int b64Len;
|
||||
char *value;
|
||||
unsigned char hmac[20];
|
||||
char b64[((20 + 1) * 4) / 3];
|
||||
|
||||
HMAC_SHA1(hmac, (unsigned char *)access_key_secret->data, access_key_secret->len,
|
||||
(unsigned char *)signstr->data, signstr->len);
|
||||
|
||||
// Now base-64 encode the results
|
||||
b64Len = aos_base64_encode(hmac, 20, b64);
|
||||
value = apr_psprintf(p, "OSS %.*s:%.*s", access_key_id->len, access_key_id->data, b64Len, b64);
|
||||
apr_table_addn(headers, OSS_AUTHORIZATION, value);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int oss_get_signed_headers(aos_pool_t *p,
|
||||
const aos_string_t *access_key_id,
|
||||
const aos_string_t *access_key_secret,
|
||||
const aos_string_t* canon_res,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
int res;
|
||||
aos_string_t signstr;
|
||||
|
||||
res = oss_get_string_to_sign(p, req->method, canon_res,
|
||||
req->headers, req->query_params, &signstr);
|
||||
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
aos_debug_log("signstr:%.*s.", signstr.len, signstr.data);
|
||||
|
||||
oss_sign_headers(p, &signstr, access_key_id, access_key_secret, req->headers);
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int oss_sign_request(aos_http_request_t *req,
|
||||
const oss_config_t *config)
|
||||
{
|
||||
aos_string_t canon_res;
|
||||
char canon_buf[AOS_MAX_URI_LEN];
|
||||
char datestr[AOS_MAX_GMT_TIME_LEN];
|
||||
const char *value;
|
||||
int res = AOSE_OK;
|
||||
int len = 0;
|
||||
|
||||
len = strlen(req->resource);
|
||||
if (len >= AOS_MAX_URI_LEN - 1) {
|
||||
aos_error_log("http resource too long, %s.", req->resource);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
canon_res.data = canon_buf;
|
||||
canon_res.len = apr_snprintf(canon_buf, sizeof(canon_buf), "/%s", req->resource);
|
||||
|
||||
if ((value = apr_table_get(req->headers, OSS_CANNONICALIZED_HEADER_DATE)) == NULL) {
|
||||
aos_get_gmt_str_time(datestr);
|
||||
apr_table_set(req->headers, OSS_DATE, datestr);
|
||||
}
|
||||
|
||||
res = oss_get_signed_headers(req->pool, &config->access_key_id,
|
||||
&config->access_key_secret, &canon_res, req);
|
||||
return res;
|
||||
}
|
||||
|
||||
int get_oss_request_signature(const oss_request_options_t *options,
|
||||
aos_http_request_t *req,
|
||||
const aos_string_t *expires,
|
||||
aos_string_t *signature)
|
||||
{
|
||||
aos_string_t canon_res;
|
||||
char canon_buf[AOS_MAX_URI_LEN];
|
||||
const char *value;
|
||||
aos_string_t signstr;
|
||||
int res = AOSE_OK;
|
||||
int b64Len;
|
||||
unsigned char hmac[20];
|
||||
char b64[((20 + 1) * 4) / 3];
|
||||
|
||||
canon_res.data = canon_buf;
|
||||
canon_res.len = apr_snprintf(canon_buf, sizeof(canon_buf), "/%s", req->resource);
|
||||
|
||||
apr_table_set(req->headers, OSS_DATE, expires->data);
|
||||
|
||||
if ((res = oss_get_string_to_sign(options->pool, req->method, &canon_res,
|
||||
req->headers, req->query_params, &signstr))!= AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HMAC_SHA1(hmac, (unsigned char *)options->config->access_key_secret.data,
|
||||
options->config->access_key_secret.len,
|
||||
(unsigned char *)signstr.data, signstr.len);
|
||||
|
||||
b64Len = aos_base64_encode(hmac, 20, b64);
|
||||
value = apr_psprintf(options->pool, "%.*s", b64Len, b64);
|
||||
aos_str_set(signature, value);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int oss_get_signed_url(const oss_request_options_t *options,
|
||||
aos_http_request_t *req,
|
||||
const aos_string_t *expires,
|
||||
aos_string_t *signed_url)
|
||||
{
|
||||
char *signed_url_str;
|
||||
aos_string_t querystr;
|
||||
char uristr[3*AOS_MAX_URI_LEN+1];
|
||||
int res = AOSE_OK;
|
||||
aos_string_t signature;
|
||||
const char *proto;
|
||||
|
||||
if (options->config->sts_token.data != NULL) {
|
||||
apr_table_set(req->query_params, OSS_SECURITY_TOKEN, options->config->sts_token.data);
|
||||
}
|
||||
|
||||
res = get_oss_request_signature(options, req, expires, &signature);
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
apr_table_set(req->query_params, OSS_ACCESSKEYID, options->config->access_key_id.data);
|
||||
apr_table_set(req->query_params, OSS_EXPIRES, expires->data);
|
||||
apr_table_set(req->query_params, OSS_SIGNATURE, signature.data);
|
||||
|
||||
uristr[0] = '\0';
|
||||
aos_str_null(&querystr);
|
||||
res = aos_url_encode(uristr, req->uri, AOS_MAX_URI_LEN);
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = aos_query_params_to_string(options->pool, req->query_params, &querystr);
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
proto = strlen(req->proto) != 0 ? req->proto : AOS_HTTP_PREFIX;
|
||||
signed_url_str = apr_psprintf(options->pool, "%s%s/%s%.*s",
|
||||
proto, req->host, uristr,
|
||||
querystr.len, querystr.data);
|
||||
aos_str_set(signed_url, signed_url_str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int oss_get_rtmp_signed_url(const oss_request_options_t *options,
|
||||
aos_http_request_t *req,
|
||||
const aos_string_t *expires,
|
||||
const aos_string_t *play_list_name,
|
||||
aos_table_t *params,
|
||||
aos_string_t *signed_url)
|
||||
{
|
||||
char *signed_url_str;
|
||||
aos_string_t querystr;
|
||||
char uristr[3*AOS_MAX_URI_LEN+1];
|
||||
int res = AOSE_OK;
|
||||
aos_string_t signature;
|
||||
int pos = 0;
|
||||
const aos_array_header_t *tarr;
|
||||
const aos_table_entry_t *telts;
|
||||
|
||||
if (NULL != params) {
|
||||
tarr = aos_table_elts(params);
|
||||
telts = (aos_table_entry_t*)tarr->elts;
|
||||
for (pos = 0; pos < tarr->nelts; ++pos) {
|
||||
apr_table_set(req->query_params, telts[pos].key, telts[pos].val);
|
||||
}
|
||||
}
|
||||
apr_table_set(req->query_params, OSS_PLAY_LIST_NAME, play_list_name->data);
|
||||
|
||||
res = get_oss_rtmp_request_signature(options, req, expires,&signature);
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
apr_table_set(req->query_params, OSS_ACCESSKEYID,
|
||||
options->config->access_key_id.data);
|
||||
apr_table_set(req->query_params, OSS_EXPIRES, expires->data);
|
||||
apr_table_set(req->query_params, OSS_SIGNATURE, signature.data);
|
||||
|
||||
uristr[0] = '\0';
|
||||
aos_str_null(&querystr);
|
||||
res = aos_url_encode(uristr, req->uri, AOS_MAX_URI_LEN);
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = aos_query_params_to_string(options->pool, req->query_params, &querystr);
|
||||
if (res != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
signed_url_str = apr_psprintf(options->pool, "%s%s/%s%.*s",
|
||||
req->proto, req->host, uristr,
|
||||
querystr.len, querystr.data);
|
||||
aos_str_set(signed_url, signed_url_str);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int get_oss_rtmp_request_signature(const oss_request_options_t *options,
|
||||
aos_http_request_t *req,
|
||||
const aos_string_t *expires,
|
||||
aos_string_t *signature)
|
||||
{
|
||||
aos_string_t canon_res;
|
||||
char canon_buf[AOS_MAX_URI_LEN];
|
||||
const char *value;
|
||||
aos_string_t signstr;
|
||||
int res = AOSE_OK;
|
||||
int b64Len;
|
||||
unsigned char hmac[20];
|
||||
char b64[((20 + 1) * 4) / 3];
|
||||
|
||||
canon_res.data = canon_buf;
|
||||
canon_res.len = apr_snprintf(canon_buf, sizeof(canon_buf), "/%s", req->resource);
|
||||
|
||||
if ((res = oss_get_rtmp_string_to_sign(options->pool, expires, &canon_res,
|
||||
req->query_params, &signstr))!= AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
HMAC_SHA1(hmac, (unsigned char *)options->config->access_key_secret.data,
|
||||
options->config->access_key_secret.len,
|
||||
(unsigned char *)signstr.data, signstr.len);
|
||||
|
||||
b64Len = aos_base64_encode(hmac, 20, b64);
|
||||
value = apr_psprintf(options->pool, "%.*s", b64Len, b64);
|
||||
aos_str_set(signature, value);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int oss_get_rtmp_string_to_sign(aos_pool_t *p,
|
||||
const aos_string_t *expires,
|
||||
const aos_string_t *canon_res,
|
||||
const aos_table_t *params,
|
||||
aos_string_t *signstr)
|
||||
{
|
||||
int res;
|
||||
aos_buf_t *signbuf;
|
||||
aos_str_null(signstr);
|
||||
|
||||
signbuf = aos_create_buf(p, 1024);
|
||||
|
||||
// expires
|
||||
aos_buf_append_string(p, signbuf, expires->data, expires->len);
|
||||
aos_buf_append_string(p, signbuf, "\n", sizeof("\n")-1);
|
||||
|
||||
// canonicalized params
|
||||
if ((res = oss_get_canonicalized_params(p, params, signbuf)) != AOSE_OK) {
|
||||
return res;
|
||||
}
|
||||
|
||||
// canonicalized resource
|
||||
aos_buf_append_string(p, signbuf, canon_res->data, canon_res->len);
|
||||
|
||||
// result
|
||||
signstr->data = (char *)signbuf->pos;
|
||||
signstr->len = aos_buf_size(signbuf);
|
||||
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
static int oss_get_canonicalized_params(aos_pool_t *p,
|
||||
const aos_table_t *params,
|
||||
aos_buf_t *signbuf)
|
||||
{
|
||||
int pos;
|
||||
int meta_count = 0;
|
||||
int i;
|
||||
int len;
|
||||
const aos_array_header_t *tarr;
|
||||
const aos_table_entry_t *telts;
|
||||
char **meta_headers;
|
||||
const char *value;
|
||||
aos_string_t tmp_str;
|
||||
char *tmpbuf = (char*)malloc(AOS_MAX_HEADER_LEN + 1);
|
||||
if (NULL == tmpbuf) {
|
||||
aos_error_log("malloc %d memory failed.", AOS_MAX_HEADER_LEN + 1);
|
||||
return AOSE_OVER_MEMORY;
|
||||
}
|
||||
|
||||
if (apr_is_empty_table(params)) {
|
||||
free(tmpbuf);
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
// sort user meta header
|
||||
tarr = aos_table_elts(params);
|
||||
telts = (aos_table_entry_t*)tarr->elts;
|
||||
meta_headers = aos_pcalloc(p, tarr->nelts * sizeof(char*));
|
||||
for (pos = 0; pos < tarr->nelts; ++pos) {
|
||||
aos_string_t key = aos_string(telts[pos].key);
|
||||
meta_headers[meta_count++] = key.data;
|
||||
}
|
||||
if (meta_count == 0) {
|
||||
free(tmpbuf);
|
||||
return AOSE_OK;
|
||||
}
|
||||
aos_gnome_sort((const char **)meta_headers, meta_count);
|
||||
|
||||
// sign string
|
||||
for (i = 0; i < meta_count; ++i) {
|
||||
value = apr_table_get(params, meta_headers[i]);
|
||||
aos_str_set(&tmp_str, value);
|
||||
aos_strip_space(&tmp_str);
|
||||
len = apr_snprintf(tmpbuf, AOS_MAX_HEADER_LEN + 1, "%s:%.*s",
|
||||
meta_headers[i], tmp_str.len, tmp_str.data);
|
||||
if (len > AOS_MAX_HEADER_LEN) {
|
||||
free(tmpbuf);
|
||||
aos_error_log("rtmp parameters too many, %d > %d.",
|
||||
len, AOS_MAX_HEADER_LEN);
|
||||
return AOSE_INVALID_ARGUMENT;
|
||||
}
|
||||
tmp_str.data = tmpbuf;
|
||||
tmp_str.len = len;
|
||||
aos_buf_append_string(p, signbuf, tmpbuf, len);
|
||||
aos_buf_append_string(p, signbuf, "\n", sizeof("\n")-1);
|
||||
}
|
||||
|
||||
free(tmpbuf);
|
||||
return AOSE_OK;
|
||||
}
|
||||
76
include/oss_sdk/oss_auth.h
Normal file
76
include/oss_sdk/oss_auth.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef LIB_OSS_AUTH_H
|
||||
#define LIB_OSS_AUTH_H
|
||||
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_http_io.h"
|
||||
#include "oss_define.h"
|
||||
|
||||
OSS_CPP_START
|
||||
|
||||
/**
|
||||
* @brief sign oss headers
|
||||
**/
|
||||
void oss_sign_headers(aos_pool_t *p,
|
||||
const aos_string_t *signstr,
|
||||
const aos_string_t *access_key_id,
|
||||
const aos_string_t *access_key_secret,
|
||||
aos_table_t *headers);
|
||||
|
||||
/**
|
||||
* @brief get string to signature
|
||||
**/
|
||||
int oss_get_string_to_sign(aos_pool_t *p,
|
||||
http_method_e method,
|
||||
const aos_string_t *canon_res,
|
||||
const aos_table_t *headers,
|
||||
const aos_table_t *params,
|
||||
aos_string_t *signstr);
|
||||
|
||||
/**
|
||||
* @brief get signed oss request headers
|
||||
**/
|
||||
int oss_get_signed_headers(aos_pool_t *p, const aos_string_t *access_key_id,
|
||||
const aos_string_t *access_key_secret,
|
||||
const aos_string_t* canon_res, aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief sign oss request
|
||||
**/
|
||||
int oss_sign_request(aos_http_request_t *req, const oss_config_t *config);
|
||||
|
||||
/**
|
||||
* @brief generate oss request Signature
|
||||
**/
|
||||
int get_oss_request_signature(const oss_request_options_t *options, aos_http_request_t *req,
|
||||
const aos_string_t *expires, aos_string_t *signature);
|
||||
|
||||
/**
|
||||
* @brief get oss signed url
|
||||
**/
|
||||
int oss_get_signed_url(const oss_request_options_t *options, aos_http_request_t *req,
|
||||
const aos_string_t *expires, aos_string_t *auth_url);
|
||||
|
||||
/**
|
||||
* @brief get rtmp string to signature
|
||||
**/
|
||||
int oss_get_rtmp_string_to_sign(aos_pool_t *p, const aos_string_t *expires,
|
||||
const aos_string_t *canon_res, const aos_table_t *params,
|
||||
aos_string_t *signstr);
|
||||
|
||||
/**
|
||||
* @brief generate oss rtmp request signature
|
||||
**/
|
||||
int get_oss_rtmp_request_signature(const oss_request_options_t *options, aos_http_request_t *req,
|
||||
const aos_string_t *expires, aos_string_t *signature);
|
||||
|
||||
/**
|
||||
* @brief get oss rtmp signed url
|
||||
**/
|
||||
int oss_get_rtmp_signed_url(const oss_request_options_t *options, aos_http_request_t *req,
|
||||
const aos_string_t *expires, const aos_string_t *play_list_name, aos_table_t *params,
|
||||
aos_string_t *signed_url);
|
||||
|
||||
OSS_CPP_END
|
||||
|
||||
#endif
|
||||
406
include/oss_sdk/oss_bucket.c
Normal file
406
include/oss_sdk/oss_bucket.c
Normal file
@@ -0,0 +1,406 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_define.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_auth.h"
|
||||
#include "oss_util.h"
|
||||
#include "oss_xml.h"
|
||||
#include "oss_api.h"
|
||||
|
||||
aos_status_t *oss_create_bucket(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_acl_e oss_acl,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
const char *oss_acl_str = NULL;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 1);
|
||||
oss_acl_str = get_oss_acl_str(oss_acl);
|
||||
if (oss_acl_str) {
|
||||
apr_table_set(headers, OSS_CANNONICALIZED_HEADER_ACL, oss_acl_str);
|
||||
}
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_PUT, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_delete_bucket(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_DELETE, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_bucket_acl(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_acl_e oss_acl,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
const char *oss_acl_str = NULL;
|
||||
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_ACL, "");
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 1);
|
||||
oss_acl_str = get_oss_acl_str(oss_acl);
|
||||
if (oss_acl_str) {
|
||||
apr_table_set(headers, OSS_CANNONICALIZED_HEADER_ACL, oss_acl_str);
|
||||
}
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_PUT, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_bucket_acl(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_string_t *oss_acl,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
int res;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_ACL, "");
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_GET, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_acl_parse_from_body(options->pool, &resp->body, oss_acl);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_list_object(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_list_object_params_t *params,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 4);
|
||||
apr_table_add(query_params, OSS_PREFIX, params->prefix.data);
|
||||
apr_table_add(query_params, OSS_DELIMITER, params->delimiter.data);
|
||||
apr_table_add(query_params, OSS_MARKER, params->marker.data);
|
||||
aos_table_add_int(query_params, OSS_MAX_KEYS, params->max_ret);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_GET, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_list_objects_parse_from_body(options->pool, &resp->body,
|
||||
¶ms->object_list, ¶ms->common_prefix_list,
|
||||
¶ms->next_marker, ¶ms->truncated);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_bucket_lifecycle(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_list_t *lifecycle_rule_list,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
apr_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
aos_list_t body;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_LIFECYCLE, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_PUT, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
build_lifecycle_body(options->pool, lifecycle_rule_list, &body);
|
||||
oss_write_request_body_from_buffer(&body, req);
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_bucket_lifecycle(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_list_t *lifecycle_rule_list,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_LIFECYCLE, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_GET, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_lifecycle_rules_parse_from_body(options->pool,
|
||||
&resp->body, lifecycle_rule_list);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_delete_bucket_lifecycle(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_LIFECYCLE, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_DELETE, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_delete_objects(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_list_t *object_list,
|
||||
int is_quiet,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *deleted_object_list)
|
||||
{
|
||||
int res;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_list_t body;
|
||||
unsigned char *md5 = NULL;
|
||||
char *buf = NULL;
|
||||
int64_t body_len;
|
||||
char *b64_value = NULL;
|
||||
int b64_buf_len = (20 + 1) * 4 / 3;
|
||||
int b64_len;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_DELETE, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 1);
|
||||
apr_table_set(headers, OSS_CONTENT_TYPE, OSS_MULTIPART_CONTENT_TYPE);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_POST, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
build_delete_objects_body(options->pool, object_list, is_quiet, &body);
|
||||
|
||||
//add Content-MD5
|
||||
body_len = aos_buf_list_len(&body);
|
||||
buf = aos_buf_list_content(options->pool, &body);
|
||||
md5 = aos_md5(options->pool, buf, (apr_size_t)body_len);
|
||||
b64_value = aos_pcalloc(options->pool, b64_buf_len);
|
||||
b64_len = aos_base64_encode(md5, 20, b64_value);
|
||||
b64_value[b64_len] = '\0';
|
||||
apr_table_addn(headers, OSS_CONTENT_MD5, b64_value);
|
||||
|
||||
oss_write_request_body_from_buffer(&body, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_quiet) {
|
||||
return s;
|
||||
}
|
||||
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_delete_objects_parse_from_body(options->pool, &resp->body,
|
||||
deleted_object_list);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_delete_objects_by_prefix(oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *prefix)
|
||||
{
|
||||
aos_pool_t *subpool = NULL;
|
||||
aos_pool_t *parent_pool = NULL;
|
||||
int is_quiet = 1;
|
||||
aos_status_t *s = NULL;
|
||||
aos_status_t *ret = NULL;
|
||||
oss_list_object_params_t *params = NULL;
|
||||
int list_object_count = 0;
|
||||
|
||||
parent_pool = options->pool;
|
||||
params = oss_create_list_object_params(parent_pool);
|
||||
if (prefix->data == NULL) {
|
||||
aos_str_set(¶ms->prefix, "");
|
||||
} else {
|
||||
aos_str_set(¶ms->prefix, prefix->data);
|
||||
}
|
||||
while (params->truncated) {
|
||||
aos_table_t *list_object_resp_headers = NULL;
|
||||
aos_list_t object_list;
|
||||
aos_list_t deleted_object_list;
|
||||
oss_list_object_content_t *list_content = NULL;
|
||||
aos_table_t *delete_objects_resp_headers = NULL;
|
||||
char *key = NULL;
|
||||
|
||||
aos_pool_create(&subpool, parent_pool);
|
||||
options->pool = subpool;
|
||||
list_object_count = 0;
|
||||
aos_list_init(&object_list);
|
||||
s = oss_list_object(options, bucket, params, &list_object_resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
|
||||
aos_list_for_each_entry(oss_list_object_content_t, list_content, ¶ms->object_list, node) {
|
||||
oss_object_key_t *object_key = oss_create_oss_object_key(parent_pool);
|
||||
key = apr_psprintf(parent_pool, "%.*s", list_content->key.len,
|
||||
list_content->key.data);
|
||||
aos_str_set(&object_key->key, key);
|
||||
aos_list_add_tail(&object_key->node, &object_list);
|
||||
list_object_count += 1;
|
||||
}
|
||||
if (list_object_count == 0)
|
||||
{
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
aos_pool_destroy(subpool);
|
||||
|
||||
aos_list_init(&deleted_object_list);
|
||||
aos_pool_create(&subpool, parent_pool);
|
||||
options->pool = subpool;
|
||||
s = oss_delete_objects(options, bucket, &object_list, is_quiet,
|
||||
&delete_objects_resp_headers, &deleted_object_list);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
if (!params->truncated) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
}
|
||||
|
||||
aos_pool_destroy(subpool);
|
||||
|
||||
aos_list_init(¶ms->object_list);
|
||||
if (params->next_marker.data) {
|
||||
aos_str_set(¶ms->marker, params->next_marker.data);
|
||||
}
|
||||
}
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
66
include/oss_sdk/oss_define.c
Normal file
66
include/oss_sdk/oss_define.c
Normal file
@@ -0,0 +1,66 @@
|
||||
#include "oss_define.h"
|
||||
|
||||
const char OSS_CANNONICALIZED_HEADER_PREFIX[] = "x-oss-";
|
||||
const char OSS_CANNONICALIZED_HEADER_DATE[] = "x-oss-date";
|
||||
const char OSS_CANNONICALIZED_HEADER_ACL[] = "x-oss-acl";
|
||||
const char OSS_CANNONICALIZED_HEADER_COPY_SOURCE[] = "x-oss-copy-source";
|
||||
const char OSS_CONTENT_MD5[] = "Content-MD5";
|
||||
const char OSS_CONTENT_TYPE[] = "Content-Type";
|
||||
const char OSS_CONTENT_LENGTH[] = "Content-Length";
|
||||
const char OSS_DATE[] = "Date";
|
||||
const char OSS_AUTHORIZATION[] = "Authorization";
|
||||
const char OSS_ACCESSKEYID[] = "OSSAccessKeyId";
|
||||
const char OSS_EXPECT[] = "Expect";
|
||||
const char OSS_EXPIRES[] = "Expires";
|
||||
const char OSS_SIGNATURE[] = "Signature";
|
||||
const char OSS_ACL[] = "acl";
|
||||
const char OSS_PREFIX[] = "prefix";
|
||||
const char OSS_DELIMITER[] = "delimiter";
|
||||
const char OSS_MARKER[] = "marker";
|
||||
const char OSS_MAX_KEYS[] = "max-keys";
|
||||
const char OSS_UPLOADS[] = "uploads";
|
||||
const char OSS_UPLOAD_ID[] = "uploadId";
|
||||
const char OSS_MAX_PARTS[] = "max-parts";
|
||||
const char OSS_PART_NUMBER_MARKER[] = "part-number-marker";
|
||||
const char OSS_KEY_MARKER[] = "key-marker";
|
||||
const char OSS_UPLOAD_ID_MARKER[] = "upload-id-marker";
|
||||
const char OSS_MAX_UPLOADS[] = "max-uploads";
|
||||
const char OSS_PARTNUMBER[] = "partNumber";
|
||||
const char OSS_APPEND[] = "append";
|
||||
const char OSS_POSITION[] = "position";
|
||||
const char OSS_MULTIPART_CONTENT_TYPE[] = "application/x-www-form-urlencoded";
|
||||
const char OSS_COPY_SOURCE[] = "x-oss-copy-source";
|
||||
const char OSS_COPY_SOURCE_RANGE[] = "x-oss-copy-source-range";
|
||||
const char OSS_SECURITY_TOKEN[] = "security-token";
|
||||
const char OSS_STS_SECURITY_TOKEN[] = "x-oss-security-token";
|
||||
const char OSS_OBJECT_TYPE[] = "x-oss-object-type";
|
||||
const char OSS_NEXT_APPEND_POSITION[] = "x-oss-next-append-position";
|
||||
const char OSS_HASH_CRC64_ECMA[] = "x-oss-hash-crc64ecma";
|
||||
const char OSS_CALLBACK[] = "x-oss-callback";
|
||||
const char OSS_CALLBACK_VAR[] = "x-oss-callback-var";
|
||||
const char OSS_PROCESS[] = "x-oss-process";
|
||||
const char OSS_LIFECYCLE[] = "lifecycle";
|
||||
const char OSS_DELETE[] = "delete";
|
||||
const char OSS_YES[] = "yes";
|
||||
const char OSS_OBJECT_TYPE_NORMAL[] = "Normal";
|
||||
const char OSS_OBJECT_TYPE_APPENDABLE[] = "Appendable";
|
||||
const char OSS_LIVE_CHANNEL[] = "live";
|
||||
const char OSS_LIVE_CHANNEL_STATUS[] = "status";
|
||||
const char OSS_COMP[] = "comp";
|
||||
const char OSS_LIVE_CHANNEL_STAT[] = "stat";
|
||||
const char OSS_LIVE_CHANNEL_HISTORY[] = "history";
|
||||
const char OSS_LIVE_CHANNEL_VOD[] = "vod";
|
||||
const char OSS_LIVE_CHANNEL_START_TIME[] = "startTime";
|
||||
const char OSS_LIVE_CHANNEL_END_TIME[] = "endTime";
|
||||
const char OSS_PLAY_LIST_NAME[] = "playlistName";
|
||||
const char LIVE_CHANNEL_STATUS_DISABLED[] = "disabled";
|
||||
const char LIVE_CHANNEL_STATUS_ENABLED[] = "enabled";
|
||||
const char LIVE_CHANNEL_STATUS_IDLE[] = "idle";
|
||||
const char LIVE_CHANNEL_STATUS_LIVE[] = "live";
|
||||
const char LIVE_CHANNEL_DEFAULT_TYPE[] = "HLS";
|
||||
const char LIVE_CHANNEL_DEFAULT_PLAYLIST[] = "playlist.m3u8";
|
||||
const int LIVE_CHANNEL_DEFAULT_FRAG_DURATION = 5;
|
||||
const int LIVE_CHANNEL_DEFAULT_FRAG_COUNT = 3;
|
||||
const int OSS_MAX_PART_NUM = 10000;
|
||||
const int OSS_PER_RET_NUM = 1000;
|
||||
const int MAX_SUFFIX_LEN = 1024;
|
||||
318
include/oss_sdk/oss_define.h
Normal file
318
include/oss_sdk/oss_define.h
Normal file
@@ -0,0 +1,318 @@
|
||||
#ifndef LIBOSS_DEFINE_H
|
||||
#define LIBOSS_DEFINE_H
|
||||
|
||||
#include "aos_string.h"
|
||||
#include "aos_list.h"
|
||||
#include "aos_transport.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define OSS_CPP_START extern "C" {
|
||||
# define OSS_CPP_END }
|
||||
#else
|
||||
# define OSS_CPP_START
|
||||
# define OSS_CPP_END
|
||||
#endif
|
||||
|
||||
#define aos_xml_error_status_set(STATUS, RES) do { \
|
||||
aos_status_set(STATUS, RES, AOS_XML_PARSE_ERROR_CODE, NULL); \
|
||||
} while(0)
|
||||
|
||||
#define aos_file_error_status_set(STATUS, RES) do { \
|
||||
aos_status_set(STATUS, RES, AOS_OPEN_FILE_ERROR_CODE, NULL); \
|
||||
} while(0)
|
||||
|
||||
#define aos_inconsistent_error_status_set(STATUS, RES) do { \
|
||||
aos_status_set(STATUS, RES, AOS_INCONSISTENT_ERROR_CODE, NULL); \
|
||||
} while(0)
|
||||
|
||||
extern const char OSS_CANNONICALIZED_HEADER_ACL[];
|
||||
extern const char OSS_CANNONICALIZED_HEADER_SOURCE[];
|
||||
extern const char OSS_CANNONICALIZED_HEADER_PREFIX[];
|
||||
extern const char OSS_CANNONICALIZED_HEADER_DATE[];
|
||||
extern const char OSS_CANNONICALIZED_HEADER_COPY_SOURCE[];
|
||||
extern const char OSS_CONTENT_MD5[];
|
||||
extern const char OSS_CONTENT_TYPE[];
|
||||
extern const char OSS_CONTENT_LENGTH[];
|
||||
extern const char OSS_DATE[];
|
||||
extern const char OSS_AUTHORIZATION[];
|
||||
extern const char OSS_ACCESSKEYID[];
|
||||
extern const char OSS_EXPECT[];
|
||||
extern const char OSS_EXPIRES[];
|
||||
extern const char OSS_SIGNATURE[];
|
||||
extern const char OSS_ACL[];
|
||||
extern const char OSS_PREFIX[];
|
||||
extern const char OSS_DELIMITER[];
|
||||
extern const char OSS_MARKER[];
|
||||
extern const char OSS_MAX_KEYS[];
|
||||
extern const char OSS_UPLOADS[];
|
||||
extern const char OSS_UPLOAD_ID[];
|
||||
extern const char OSS_MAX_PARTS[];
|
||||
extern const char OSS_KEY_MARKER[];
|
||||
extern const char OSS_UPLOAD_ID_MARKER[];
|
||||
extern const char OSS_MAX_UPLOADS[];
|
||||
extern const char OSS_PARTNUMBER[];
|
||||
extern const char OSS_PART_NUMBER_MARKER[];
|
||||
extern const char OSS_APPEND[];
|
||||
extern const char OSS_POSITION[];
|
||||
extern const char OSS_MULTIPART_CONTENT_TYPE[];
|
||||
extern const char OSS_COPY_SOURCE[];
|
||||
extern const char OSS_COPY_SOURCE_RANGE[];
|
||||
extern const char OSS_SECURITY_TOKEN[];
|
||||
extern const char OSS_STS_SECURITY_TOKEN[];
|
||||
extern const char OSS_OBJECT_TYPE[];
|
||||
extern const char OSS_NEXT_APPEND_POSITION[];
|
||||
extern const char OSS_HASH_CRC64_ECMA[];
|
||||
extern const char OSS_CALLBACK[];
|
||||
extern const char OSS_CALLBACK_VAR[];
|
||||
extern const char OSS_PROCESS[];
|
||||
extern const char OSS_LIFECYCLE[];
|
||||
extern const char OSS_DELETE[];
|
||||
extern const char OSS_YES[];
|
||||
extern const char OSS_OBJECT_TYPE_NORMAL[];
|
||||
extern const char OSS_OBJECT_TYPE_APPENDABLE[];
|
||||
extern const char OSS_LIVE_CHANNEL[];
|
||||
extern const char OSS_LIVE_CHANNEL_STATUS[];
|
||||
extern const char OSS_COMP[];
|
||||
extern const char OSS_LIVE_CHANNEL_STAT[];
|
||||
extern const char OSS_LIVE_CHANNEL_HISTORY[];
|
||||
extern const char OSS_LIVE_CHANNEL_VOD[];
|
||||
extern const char OSS_LIVE_CHANNEL_START_TIME[];
|
||||
extern const char OSS_LIVE_CHANNEL_END_TIME[];
|
||||
extern const char OSS_PLAY_LIST_NAME[];
|
||||
extern const char LIVE_CHANNEL_STATUS_DISABLED[];
|
||||
extern const char LIVE_CHANNEL_STATUS_ENABLED[];
|
||||
extern const char LIVE_CHANNEL_STATUS_IDLE[];
|
||||
extern const char LIVE_CHANNEL_STATUS_LIVE[];
|
||||
extern const char LIVE_CHANNEL_DEFAULT_TYPE[];
|
||||
extern const char LIVE_CHANNEL_DEFAULT_PLAYLIST[];
|
||||
extern const int LIVE_CHANNEL_DEFAULT_FRAG_DURATION;
|
||||
extern const int LIVE_CHANNEL_DEFAULT_FRAG_COUNT;
|
||||
extern const int OSS_MAX_PART_NUM;
|
||||
extern const int OSS_PER_RET_NUM;
|
||||
extern const int MAX_SUFFIX_LEN;
|
||||
|
||||
typedef struct oss_lib_curl_initializer_s oss_lib_curl_initializer_t;
|
||||
|
||||
/**
|
||||
* oss_acl is an ACL that can be specified when an object is created or
|
||||
* updated. Each canned ACL has a predefined value when expanded to a full
|
||||
* set of OSS ACL Grants.
|
||||
* Private canned ACL gives the owner FULL_CONTROL and no other permissions
|
||||
* are issued
|
||||
* Public Read canned ACL gives the owner FULL_CONTROL and all users Read
|
||||
* permission
|
||||
* Public Read Write canned ACL gives the owner FULL_CONTROL and all users
|
||||
* Read and Write permission
|
||||
**/
|
||||
typedef enum {
|
||||
OSS_ACL_PRIVATE = 0, /*< private */
|
||||
OSS_ACL_PUBLIC_READ = 1, /*< public read */
|
||||
OSS_ACL_PUBLIC_READ_WRITE = 2 /*< public read write */
|
||||
} oss_acl_e;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t endpoint;
|
||||
aos_string_t access_key_id;
|
||||
aos_string_t access_key_secret;
|
||||
aos_string_t sts_token;
|
||||
int is_cname;
|
||||
aos_string_t proxy_host;
|
||||
int proxy_port;
|
||||
aos_string_t proxy_user;
|
||||
aos_string_t proxy_passwd;
|
||||
} oss_config_t;
|
||||
|
||||
typedef struct {
|
||||
oss_config_t *config;
|
||||
aos_http_controller_t *ctl; /*< aos http controller, more see aos_transport.h */
|
||||
aos_pool_t *pool;
|
||||
} oss_request_options_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t key;
|
||||
aos_string_t last_modified;
|
||||
aos_string_t etag;
|
||||
aos_string_t size;
|
||||
aos_string_t owner_id;
|
||||
aos_string_t owner_display_name;
|
||||
} oss_list_object_content_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t prefix;
|
||||
} oss_list_object_common_prefix_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t key;
|
||||
aos_string_t upload_id;
|
||||
aos_string_t initiated;
|
||||
} oss_list_multipart_upload_content_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t part_number;
|
||||
aos_string_t size;
|
||||
aos_string_t etag;
|
||||
aos_string_t last_modified;
|
||||
} oss_list_part_content_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t part_number;
|
||||
aos_string_t etag;
|
||||
} oss_complete_part_content_t;
|
||||
|
||||
typedef struct {
|
||||
int part_num;
|
||||
char *etag;
|
||||
} oss_upload_part_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t prefix;
|
||||
aos_string_t marker;
|
||||
aos_string_t delimiter;
|
||||
int max_ret;
|
||||
int truncated;
|
||||
aos_string_t next_marker;
|
||||
aos_list_t object_list;
|
||||
aos_list_t common_prefix_list;
|
||||
} oss_list_object_params_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t part_number_marker;
|
||||
int max_ret;
|
||||
int truncated;
|
||||
aos_string_t next_part_number_marker;
|
||||
aos_list_t part_list;
|
||||
} oss_list_upload_part_params_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t prefix;
|
||||
aos_string_t key_marker;
|
||||
aos_string_t upload_id_marker;
|
||||
aos_string_t delimiter;
|
||||
int max_ret;
|
||||
int truncated;
|
||||
aos_string_t next_key_marker;
|
||||
aos_string_t next_upload_id_marker;
|
||||
aos_list_t upload_list;
|
||||
} oss_list_multipart_upload_params_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t source_bucket;
|
||||
aos_string_t source_object;
|
||||
aos_string_t dest_bucket;
|
||||
aos_string_t dest_object;
|
||||
aos_string_t upload_id;
|
||||
int part_num;
|
||||
int64_t range_start;
|
||||
int64_t range_end;
|
||||
} oss_upload_part_copy_params_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t filename; /**< file range read filename */
|
||||
int64_t file_pos; /**< file range read start position */
|
||||
int64_t file_last; /**< file range read last position */
|
||||
} oss_upload_file_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t id;
|
||||
aos_string_t prefix;
|
||||
aos_string_t status;
|
||||
int days;
|
||||
aos_string_t date;
|
||||
} oss_lifecycle_rule_content_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t key;
|
||||
} oss_object_key_t;
|
||||
|
||||
typedef struct {
|
||||
char *suffix;
|
||||
char *type;
|
||||
} oss_content_type_t;
|
||||
|
||||
typedef struct {
|
||||
int64_t part_size; // bytes, default 1MB
|
||||
int32_t thread_num; // default 1
|
||||
int enable_checkpoint; // default disable, false
|
||||
aos_string_t checkpoint_path; // dafault ./filepath.ucp or ./filepath.dcp
|
||||
} oss_resumable_clt_params_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t type;
|
||||
int32_t frag_duration;
|
||||
int32_t frag_count;
|
||||
aos_string_t play_list_name;
|
||||
}oss_live_channel_target_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t name;
|
||||
aos_string_t description;
|
||||
aos_string_t status;
|
||||
oss_live_channel_target_t target;
|
||||
} oss_live_channel_configuration_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t publish_url;
|
||||
} oss_live_channel_publish_url_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t play_url;
|
||||
} oss_live_channel_play_url_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t width;
|
||||
int32_t height;
|
||||
int32_t frame_rate;
|
||||
int32_t band_width;
|
||||
aos_string_t codec;
|
||||
} oss_video_stat_t;
|
||||
|
||||
typedef struct {
|
||||
int32_t band_width;
|
||||
int32_t sample_rate;
|
||||
aos_string_t codec;
|
||||
} oss_audio_stat_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t pushflow_status;
|
||||
aos_string_t connected_time;
|
||||
aos_string_t remote_addr;
|
||||
oss_video_stat_t video_stat;
|
||||
oss_audio_stat_t audio_stat;
|
||||
} oss_live_channel_stat_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t name;
|
||||
aos_string_t description;
|
||||
aos_string_t status;
|
||||
aos_string_t last_modified;
|
||||
aos_list_t publish_url_list;
|
||||
aos_list_t play_url_list;
|
||||
} oss_live_channel_content_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t prefix;
|
||||
aos_string_t marker;
|
||||
int max_keys;
|
||||
int truncated;
|
||||
aos_string_t next_marker;
|
||||
aos_list_t live_channel_list;
|
||||
} oss_list_live_channel_params_t;
|
||||
|
||||
typedef struct {
|
||||
aos_list_t node;
|
||||
aos_string_t start_time;
|
||||
aos_string_t end_time;
|
||||
aos_string_t remote_addr;
|
||||
} oss_live_record_content_t;
|
||||
|
||||
#endif
|
||||
336
include/oss_sdk/oss_live.c
Normal file
336
include/oss_sdk/oss_live.c
Normal file
@@ -0,0 +1,336 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_define.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_auth.h"
|
||||
#include "oss_util.h"
|
||||
#include "oss_xml.h"
|
||||
#include "oss_api.h"
|
||||
|
||||
aos_status_t *oss_create_live_channel(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_live_channel_configuration_t *config,
|
||||
aos_list_t *publish_url_list,
|
||||
aos_list_t *play_url_list,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
aos_list_t body;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_live_channel_request(options, bucket, &config->name, HTTP_PUT,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
// build body
|
||||
build_create_live_channel_body(options->pool, config, &body);
|
||||
oss_write_request_body_from_buffer(&body, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// parse result
|
||||
res = oss_create_live_channel_parse_from_body(options->pool, &resp->body,
|
||||
publish_url_list, play_url_list);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_live_channel_status(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
const aos_string_t *live_channel_status,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 2);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL_STATUS, live_channel_status->data);
|
||||
|
||||
//init headers, forbid 'Expect' and 'Transfer-Encoding' of HTTP
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
apr_table_set(headers, "Expect", "");
|
||||
apr_table_set(headers, "Transfer-Encoding", "");
|
||||
|
||||
oss_init_live_channel_request(options, bucket, live_channel, HTTP_PUT,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_live_channel_info(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
oss_live_channel_configuration_t *info,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_live_channel_request(options, bucket, live_channel, HTTP_GET,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// parse result
|
||||
res = oss_live_channel_info_parse_from_body(options->pool, &resp->body, info);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
aos_str_set(&info->name, aos_pstrdup(options->pool, live_channel));
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_live_channel_stat(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
oss_live_channel_stat_t *stat,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 2);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
apr_table_add(query_params, OSS_COMP, OSS_LIVE_CHANNEL_STAT);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_live_channel_request(options, bucket, live_channel, HTTP_GET,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// parse result
|
||||
res = oss_live_channel_stat_parse_from_body(options->pool, &resp->body, stat);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_delete_live_channel(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_live_channel_request(options, bucket, live_channel, HTTP_DELETE,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_list_live_channel(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_list_live_channel_params_t *params,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 4);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
apr_table_add(query_params, OSS_PREFIX, params->prefix.data);
|
||||
apr_table_add(query_params, OSS_MARKER, params->marker.data);
|
||||
aos_table_add_int(query_params, OSS_MAX_KEYS, params->max_keys);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_GET, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// parse result
|
||||
res = oss_list_live_channel_parse_from_body(options->pool, &resp->body,
|
||||
¶ms->live_channel_list, ¶ms->next_marker, ¶ms->truncated);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_live_channel_history(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
aos_list_t *live_record_list,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 2);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL, "");
|
||||
apr_table_add(query_params, OSS_COMP, OSS_LIVE_CHANNEL_HISTORY);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_live_channel_request(options, bucket, live_channel, HTTP_GET,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
// parse result
|
||||
res = oss_live_channel_history_parse_from_body(options->pool, &resp->body, live_record_list);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_gen_vod_play_list(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
const aos_string_t *play_list_name,
|
||||
const int64_t start_time,
|
||||
const int64_t end_time,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
char *resource = NULL;
|
||||
aos_string_t resource_str;
|
||||
|
||||
//init params
|
||||
query_params = aos_table_create_if_null(options, query_params, 3);
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL_VOD, "");
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL_START_TIME,
|
||||
apr_psprintf(options->pool, "%" APR_INT64_T_FMT, start_time));
|
||||
apr_table_add(query_params, OSS_LIVE_CHANNEL_END_TIME,
|
||||
apr_psprintf(options->pool, "%" APR_INT64_T_FMT, end_time));
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 1);
|
||||
apr_table_set(headers, OSS_CONTENT_TYPE, OSS_MULTIPART_CONTENT_TYPE);
|
||||
|
||||
resource = apr_psprintf(options->pool, "%s/%s", live_channel->data, play_list_name->data);
|
||||
aos_str_set(&resource_str, resource);
|
||||
|
||||
oss_init_live_channel_request(options, bucket, &resource_str, HTTP_POST,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
char *oss_gen_rtmp_signed_url(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
const aos_string_t *play_list_name,
|
||||
const int64_t expires)
|
||||
{
|
||||
aos_string_t signed_url;
|
||||
char *expires_str = NULL;
|
||||
aos_string_t expires_time;
|
||||
int res = AOSE_OK;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_table_t *params = NULL;
|
||||
|
||||
expires_str = apr_psprintf(options->pool, "%" APR_INT64_T_FMT, expires);
|
||||
aos_str_set(&expires_time, expires_str);
|
||||
req = aos_http_request_create(options->pool);
|
||||
oss_get_rtmp_uri(options, bucket, live_channel, req);
|
||||
res = oss_get_rtmp_signed_url(options, req, &expires_time, play_list_name,
|
||||
params, &signed_url);
|
||||
if (res != AOSE_OK) {
|
||||
return NULL;
|
||||
}
|
||||
return signed_url.data;
|
||||
}
|
||||
556
include/oss_sdk/oss_multipart.c
Normal file
556
include/oss_sdk/oss_multipart.c
Normal file
@@ -0,0 +1,556 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_define.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_auth.h"
|
||||
#include "oss_util.h"
|
||||
#include "oss_xml.h"
|
||||
#include "oss_api.h"
|
||||
|
||||
aos_status_t *oss_init_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_string_t *upload_id,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_UPLOADS, "");
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 1);
|
||||
set_content_type(NULL, object->data, headers);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_POST,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_upload_id_parse_from_body(options->pool, &resp->body, upload_id);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_abort_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_string_t *upload_id,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 1);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID, upload_id->data);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_DELETE,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_list_upload_part(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
oss_list_upload_part_params_t *params,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 3);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID, upload_id->data);
|
||||
aos_table_add_int(query_params, OSS_MAX_PARTS, params->max_ret);
|
||||
apr_table_add(query_params, OSS_PART_NUMBER_MARKER,
|
||||
params->part_number_marker.data);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_GET,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_list_parts_parse_from_body(options->pool, &resp->body,
|
||||
¶ms->part_list, ¶ms->next_part_number_marker,
|
||||
¶ms->truncated);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_list_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
oss_list_multipart_upload_params_t *params,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 6);
|
||||
apr_table_add(query_params, OSS_UPLOADS, "");
|
||||
apr_table_add(query_params, OSS_PREFIX, params->prefix.data);
|
||||
apr_table_add(query_params, OSS_DELIMITER, params->delimiter.data);
|
||||
apr_table_add(query_params, OSS_KEY_MARKER, params->key_marker.data);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID_MARKER, params->upload_id_marker.data);
|
||||
aos_table_add_int(query_params, OSS_MAX_UPLOADS, params->max_ret);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_bucket_request(options, bucket, HTTP_GET, &req,
|
||||
query_params, headers, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
return s;
|
||||
}
|
||||
|
||||
res = oss_list_multipart_uploads_parse_from_body(options->pool, &resp->body,
|
||||
¶ms->upload_list, ¶ms->next_key_marker,
|
||||
¶ms->next_upload_id_marker, ¶ms->truncated);
|
||||
if (res != AOSE_OK) {
|
||||
aos_xml_error_status_set(s, res);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_complete_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
aos_list_t *part_list,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_complete_multipart_upload(options, bucket, object, upload_id, part_list,
|
||||
headers, NULL, resp_headers, NULL);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_complete_multipart_upload(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
aos_list_t *part_list,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
apr_table_t *query_params = NULL;
|
||||
aos_list_t body;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, params, 1);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID, upload_id->data);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 1);
|
||||
apr_table_set(headers, OSS_CONTENT_TYPE, OSS_MULTIPART_CONTENT_TYPE);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_POST,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
build_complete_multipart_upload_body(options->pool, part_list, &body);
|
||||
oss_write_request_body_from_buffer(&body, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_upload_part_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_upload_part_from_buffer(options, bucket, object, upload_id, part_num,
|
||||
buffer, NULL, NULL, NULL, resp_headers, NULL);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_upload_part_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
aos_list_t *buffer,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, params, 2);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID, upload_id->data);
|
||||
aos_table_add_int(query_params, OSS_PARTNUMBER, part_num);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_PUT, &req, query_params,
|
||||
headers, progress_callback, 0, &resp);
|
||||
|
||||
oss_write_request_body_from_buffer(buffer, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_upload_part_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
oss_upload_file_t *upload_file,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_upload_part_from_file(options, bucket, object, upload_id, part_num,
|
||||
upload_file, NULL, NULL, NULL, resp_headers, NULL);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_upload_part_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
int part_num,
|
||||
oss_upload_file_t *upload_file,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
int res = AOSE_OK;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, params, 2);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID, upload_id->data);
|
||||
aos_table_add_int(query_params, OSS_PARTNUMBER, part_num);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_PUT, &req,
|
||||
query_params, headers, progress_callback, 0, &resp);
|
||||
|
||||
res = oss_write_request_body_from_upload_file(options->pool, upload_file, req);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_upload_part_copy(const oss_request_options_t *options,
|
||||
oss_upload_part_copy_params_t *params,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
char *copy_source = NULL;
|
||||
char *copy_source_range = NULL;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
|
||||
//init query_params
|
||||
query_params = aos_table_create_if_null(options, query_params, 2);
|
||||
apr_table_add(query_params, OSS_UPLOAD_ID, params->upload_id.data);
|
||||
aos_table_add_int(query_params, OSS_PARTNUMBER, params->part_num);
|
||||
|
||||
//init headers
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
copy_source = apr_psprintf(options->pool, "/%.*s/%.*s",
|
||||
params->source_bucket.len, params->source_bucket.data,
|
||||
params->source_object.len, params->source_object.data);
|
||||
apr_table_add(headers, OSS_COPY_SOURCE, copy_source);
|
||||
copy_source_range = apr_psprintf(options->pool,
|
||||
"bytes=%" APR_INT64_T_FMT "-%" APR_INT64_T_FMT,
|
||||
params->range_start, params->range_end);
|
||||
apr_table_add(headers, OSS_COPY_SOURCE_RANGE, copy_source_range);
|
||||
|
||||
oss_init_object_request(options, ¶ms->dest_bucket, ¶ms->dest_object,
|
||||
HTTP_PUT, &req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_sorted_uploaded_part(oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *upload_id,
|
||||
aos_list_t *complete_part_list,
|
||||
int *part_count)
|
||||
{
|
||||
aos_pool_t *subpool = NULL;
|
||||
aos_pool_t *parent_pool = NULL;
|
||||
aos_status_t *s = NULL;
|
||||
aos_status_t *ret = NULL;
|
||||
oss_upload_part_t *part_arr = NULL;
|
||||
int part_index = 0;
|
||||
int index = 0;
|
||||
int uploaded_part_count = 0;
|
||||
oss_list_upload_part_params_t *params = NULL;
|
||||
oss_list_part_content_t *part_content = NULL;
|
||||
oss_complete_part_content_t *complete_content = NULL;
|
||||
aos_table_t *list_part_resp_headers = NULL;
|
||||
char *part_num_str = NULL;
|
||||
|
||||
parent_pool = options->pool;
|
||||
part_arr = aos_palloc(parent_pool, OSS_MAX_PART_NUM * sizeof(oss_upload_part_t *));
|
||||
params = oss_create_list_upload_part_params(parent_pool);
|
||||
while (params->truncated) {
|
||||
aos_pool_create(&subpool, parent_pool);
|
||||
options->pool = subpool;
|
||||
s = oss_list_upload_part(options, bucket, object,
|
||||
upload_id, params, &list_part_resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
if (!params->truncated) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
}
|
||||
aos_list_for_each_entry(oss_list_part_content_t, part_content, ¶ms->part_list, node) {
|
||||
oss_upload_part_t upload_part;
|
||||
upload_part.etag = part_content->etag.data;
|
||||
upload_part.part_num = atoi(part_content->part_number.data);
|
||||
part_arr[part_index++] = upload_part;
|
||||
uploaded_part_count++;
|
||||
}
|
||||
|
||||
aos_list_init(¶ms->part_list);
|
||||
if (params->next_part_number_marker.data != NULL) {
|
||||
aos_str_set(¶ms->part_number_marker,
|
||||
params->next_part_number_marker.data);
|
||||
}
|
||||
|
||||
//sort multipart upload part content
|
||||
qsort(part_arr, uploaded_part_count, sizeof(part_arr[0]), part_sort_cmp);
|
||||
|
||||
for (index = 0; index < part_index; ++index) {
|
||||
complete_content = oss_create_complete_part_content(parent_pool);
|
||||
part_num_str = apr_psprintf(parent_pool, "%d", part_arr[index].part_num);
|
||||
aos_str_set(&complete_content->part_number, part_num_str);
|
||||
aos_str_set(&complete_content->etag, part_arr[index].etag);
|
||||
aos_list_add_tail(&complete_content->node, complete_part_list);
|
||||
}
|
||||
part_index = 0;
|
||||
aos_pool_destroy(subpool);
|
||||
}
|
||||
|
||||
*part_count = uploaded_part_count;
|
||||
options->pool = parent_pool;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
aos_status_t *oss_upload_file(oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_string_t *upload_id,
|
||||
aos_string_t *filepath,
|
||||
int64_t part_size,
|
||||
aos_table_t *headers)
|
||||
{
|
||||
aos_pool_t *subpool = NULL;
|
||||
aos_pool_t *parent_pool = NULL;
|
||||
int64_t start_pos;
|
||||
int64_t end_pos;
|
||||
int part_num;
|
||||
int part_count = 0;
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s = NULL;
|
||||
aos_status_t *ret = NULL;
|
||||
aos_file_buf_t *fb = NULL;
|
||||
oss_upload_file_t *upload_file = NULL;
|
||||
aos_table_t *upload_part_resp_headers = NULL;
|
||||
char *part_num_str = NULL;
|
||||
char *etag = NULL;
|
||||
aos_list_t complete_part_list;
|
||||
oss_complete_part_content_t *complete_content = NULL;
|
||||
aos_table_t *complete_resp_headers = NULL;
|
||||
|
||||
aos_list_init(&complete_part_list);
|
||||
parent_pool = options->pool;
|
||||
|
||||
//get upload_id and uploaded part
|
||||
aos_pool_create(&subpool, options->pool);
|
||||
options->pool = subpool;
|
||||
if (NULL == upload_id->data) {
|
||||
aos_table_t *init_multipart_headers = NULL;
|
||||
aos_table_t *init_multipart_resp_headers = NULL;
|
||||
|
||||
init_multipart_headers = aos_table_make(subpool, 0);
|
||||
s = oss_init_multipart_upload(options, bucket, object,
|
||||
upload_id, init_multipart_headers, &init_multipart_resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
s = oss_get_sorted_uploaded_part(options, bucket, object, upload_id,
|
||||
&complete_part_list, &part_count);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
aos_pool_destroy(subpool);
|
||||
|
||||
//get part size
|
||||
fb = aos_create_file_buf(parent_pool);
|
||||
res = aos_open_file_for_read(parent_pool, filepath->data, fb);
|
||||
if (res != AOSE_OK) {
|
||||
s = aos_status_create(parent_pool);
|
||||
aos_file_error_status_set(s, res);
|
||||
options->pool = parent_pool;
|
||||
return s;
|
||||
}
|
||||
oss_get_part_size(fb->file_last, &part_size);
|
||||
|
||||
//upload part from file
|
||||
upload_file = oss_create_upload_file(parent_pool);
|
||||
aos_str_set(&upload_file->filename, filepath->data);
|
||||
start_pos = part_size * part_count;
|
||||
end_pos = start_pos + part_size;
|
||||
part_num = part_count + 1;
|
||||
|
||||
while (1) {
|
||||
aos_pool_create(&subpool, parent_pool);
|
||||
options->pool = subpool;
|
||||
upload_file->file_pos = start_pos;
|
||||
upload_file->file_last = end_pos;
|
||||
|
||||
s = oss_upload_part_from_file(options, bucket, object, upload_id,
|
||||
part_num, upload_file, &upload_part_resp_headers);
|
||||
if (!aos_status_is_ok(s)) {
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
|
||||
complete_content = oss_create_complete_part_content(parent_pool);
|
||||
part_num_str = apr_psprintf(parent_pool, "%d", part_num);
|
||||
aos_str_set(&complete_content->part_number, part_num_str);
|
||||
etag = apr_pstrdup(parent_pool,
|
||||
(char*)apr_table_get(upload_part_resp_headers, "ETag"));
|
||||
aos_str_set(&complete_content->etag, etag);
|
||||
aos_list_add_tail(&complete_content->node, &complete_part_list);
|
||||
aos_pool_destroy(subpool);
|
||||
if (end_pos >= fb->file_last) {
|
||||
break;
|
||||
}
|
||||
start_pos += part_size;
|
||||
end_pos += part_size;
|
||||
if (end_pos > fb->file_last)
|
||||
end_pos = fb->file_last;
|
||||
part_num += 1;
|
||||
}
|
||||
|
||||
//complete multipart
|
||||
aos_pool_create(&subpool, parent_pool);
|
||||
options->pool = subpool;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
s = oss_complete_multipart_upload(options, bucket, object, upload_id,
|
||||
&complete_part_list, headers, &complete_resp_headers);
|
||||
ret = aos_status_dup(parent_pool, s);
|
||||
aos_pool_destroy(subpool);
|
||||
options->pool = parent_pool;
|
||||
return ret;
|
||||
}
|
||||
642
include/oss_sdk/oss_object.c
Normal file
642
include/oss_sdk/oss_object.c
Normal file
@@ -0,0 +1,642 @@
|
||||
#include "aos_log.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_auth.h"
|
||||
#include "oss_util.h"
|
||||
#include "oss_xml.h"
|
||||
#include "oss_api.h"
|
||||
|
||||
char *oss_gen_signed_url(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t expires,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
aos_string_t signed_url;
|
||||
char *expires_str = NULL;
|
||||
aos_string_t expires_time;
|
||||
int res = AOSE_OK;
|
||||
|
||||
expires_str = apr_psprintf(options->pool, "%" APR_INT64_T_FMT, expires);
|
||||
aos_str_set(&expires_time, expires_str);
|
||||
oss_get_object_uri(options, bucket, object, req);
|
||||
res = oss_get_signed_url(options, req, &expires_time, &signed_url);
|
||||
if (res != AOSE_OK) {
|
||||
return NULL;
|
||||
}
|
||||
return signed_url.data;
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_put_object_from_buffer(options, bucket, object, buffer,
|
||||
headers, NULL, NULL, resp_headers, NULL);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_put_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
set_content_type(NULL, object->data, headers);
|
||||
apr_table_add(headers, OSS_EXPECT, "");
|
||||
|
||||
query_params = aos_table_create_if_null(options, params, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_PUT,
|
||||
&req, query_params, headers, progress_callback, 0, &resp);
|
||||
oss_write_request_body_from_buffer(buffer, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *filename,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_put_object_from_file(options, bucket, object, filename,
|
||||
headers, NULL, NULL, resp_headers, NULL);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_put_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
const aos_string_t *filename,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
int res = AOSE_OK;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
set_content_type(filename->data, object->data, headers);
|
||||
apr_table_add(headers, OSS_EXPECT, "");
|
||||
|
||||
query_params = aos_table_create_if_null(options, params, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_PUT, &req,
|
||||
query_params, headers, progress_callback, 0, &resp);
|
||||
|
||||
res = oss_write_request_body_from_file(options->pool, filename, req);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_object_to_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_get_object_to_buffer(options, bucket, object, headers,
|
||||
params, buffer, NULL, resp_headers);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_get_object_to_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_list_t *buffer,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
params = aos_table_create_if_null(options, params, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_GET,
|
||||
&req, params, headers, progress_callback, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_body(resp, buffer);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp) &&
|
||||
!has_range_or_process_in_request(req)) {
|
||||
oss_check_crc_consistent(resp->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_object_to_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_string_t *filename,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
return oss_do_get_object_to_file(options, bucket, object, headers,
|
||||
params, filename, NULL, resp_headers);
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_get_object_to_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_string_t *filename,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
int res = AOSE_OK;
|
||||
aos_string_t tmp_filename;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
params = aos_table_create_if_null(options, params, 0);
|
||||
|
||||
oss_get_temporary_file_name(options->pool, filename, &tmp_filename);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_GET,
|
||||
&req, params, headers, progress_callback, 0, &resp);
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
res = oss_init_read_response_body_to_file(options->pool, &tmp_filename, resp);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp) &&
|
||||
!has_range_or_process_in_request(req)) {
|
||||
oss_check_crc_consistent(resp->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
oss_temp_file_rename(s, tmp_filename.data, filename->data, options->pool);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_head_object(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_HEAD,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_delete_object(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *headers = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_DELETE,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
oss_get_object_uri(options, bucket, object, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_copy_object(const oss_request_options_t *options,
|
||||
const aos_string_t *source_bucket,
|
||||
const aos_string_t *source_object,
|
||||
const aos_string_t *dest_bucket,
|
||||
const aos_string_t *dest_object,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
char *copy_source = NULL;
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
char buffer[AOS_MAX_QUERY_ARG_LEN*3+1];
|
||||
int res = -1;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
/* init headers */
|
||||
res = aos_url_encode(buffer, source_object->data, AOS_MAX_QUERY_ARG_LEN);
|
||||
if (res != AOSE_OK) {
|
||||
aos_status_set(s, res, AOS_URL_ENCODE_ERROR_CODE, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
copy_source = apr_psprintf(options->pool, "/%.*s/%s",
|
||||
source_bucket->len, source_bucket->data, buffer);
|
||||
apr_table_set(headers, OSS_CANNONICALIZED_HEADER_COPY_SOURCE, copy_source);
|
||||
set_content_type(NULL, dest_object->data, headers);
|
||||
|
||||
oss_init_object_request(options, dest_bucket, dest_object, HTTP_PUT,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_append_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
/* init query_params */
|
||||
query_params = aos_table_create_if_null(options, query_params, 2);
|
||||
apr_table_add(query_params, OSS_APPEND, "");
|
||||
aos_table_add_int64(query_params, OSS_POSITION, position);
|
||||
|
||||
/* init headers */
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
set_content_type(NULL, object->data, headers);
|
||||
apr_table_add(headers, OSS_EXPECT, "");
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_POST,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
oss_write_request_body_from_buffer(buffer, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_append_object_from_buffer(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
uint64_t init_crc,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
/* init query_params */
|
||||
query_params = aos_table_create_if_null(options, params, 2);
|
||||
apr_table_add(query_params, OSS_APPEND, "");
|
||||
aos_table_add_int64(query_params, OSS_POSITION, position);
|
||||
|
||||
/* init headers */
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
set_content_type(NULL, object->data, headers);
|
||||
apr_table_add(headers, OSS_EXPECT, "");
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_POST, &req, query_params,
|
||||
headers, progress_callback, init_crc, &resp);
|
||||
oss_write_request_body_from_buffer(buffer, req);
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_append_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
const aos_string_t *append_file,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
int res = AOSE_OK;
|
||||
|
||||
/* init query_params */
|
||||
query_params = aos_table_create_if_null(options, query_params, 2);
|
||||
apr_table_add(query_params, OSS_APPEND, "");
|
||||
aos_table_add_int64(query_params, OSS_POSITION, position);
|
||||
|
||||
/* init headers */
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
set_content_type(append_file->data, object->data, headers);
|
||||
apr_table_add(headers, OSS_EXPECT, "");
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_POST,
|
||||
&req, query_params, headers, NULL, 0, &resp);
|
||||
res = oss_write_request_body_from_file(options->pool, append_file, req);
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_do_append_object_from_file(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
int64_t position,
|
||||
uint64_t init_crc,
|
||||
const aos_string_t *append_file,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
int res = AOSE_OK;
|
||||
|
||||
/* init query_params */
|
||||
query_params = aos_table_create_if_null(options, params, 2);
|
||||
apr_table_add(query_params, OSS_APPEND, "");
|
||||
aos_table_add_int64(query_params, OSS_POSITION, position);
|
||||
|
||||
/* init headers */
|
||||
headers = aos_table_create_if_null(options, headers, 2);
|
||||
set_content_type(append_file->data, object->data, headers);
|
||||
apr_table_add(headers, OSS_EXPECT, "");
|
||||
|
||||
oss_init_object_request(options, bucket, object, HTTP_POST, &req, query_params,
|
||||
headers, progress_callback, init_crc, &resp);
|
||||
res = oss_write_request_body_from_file(options->pool, append_file, req);
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
oss_fill_read_response_body(resp, resp_body);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_object_from_buffer_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
/* init query_params */
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
oss_init_signed_url_request(options, signed_url, HTTP_PUT,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
oss_write_request_body_from_buffer(buffer, req);
|
||||
|
||||
s = oss_process_signed_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_put_object_from_file_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_string_t *filename,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
int res = AOSE_OK;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
oss_init_signed_url_request(options, signed_url, HTTP_PUT,
|
||||
&req, query_params, headers, &resp);
|
||||
res = oss_write_request_body_from_file(options->pool, filename, req);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_signed_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp)) {
|
||||
oss_check_crc_consistent(req->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_object_to_buffer_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_list_t *buffer,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
params = aos_table_create_if_null(options, params, 0);
|
||||
|
||||
oss_init_signed_url_request(options, signed_url, HTTP_GET,
|
||||
&req, params, headers, &resp);
|
||||
|
||||
s = oss_process_signed_request(options, req, resp);
|
||||
oss_fill_read_response_body(resp, buffer);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp) &&
|
||||
!has_range_or_process_in_request(req)) {
|
||||
oss_check_crc_consistent(resp->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_get_object_to_file_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
aos_string_t *filename,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
int res = AOSE_OK;
|
||||
aos_string_t tmp_filename;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
params = aos_table_create_if_null(options, params, 0);
|
||||
|
||||
oss_get_temporary_file_name(options->pool, filename, &tmp_filename);
|
||||
|
||||
oss_init_signed_url_request(options, signed_url, HTTP_GET,
|
||||
&req, params, headers, &resp);
|
||||
|
||||
res = oss_init_read_response_body_to_file(options->pool, filename, resp);
|
||||
if (res != AOSE_OK) {
|
||||
aos_file_error_status_set(s, res);
|
||||
return s;
|
||||
}
|
||||
|
||||
s = oss_process_signed_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
if (is_enable_crc(options) && has_crc_in_response(resp) &&
|
||||
!has_range_or_process_in_request(req)) {
|
||||
oss_check_crc_consistent(resp->crc64, resp->headers, s);
|
||||
}
|
||||
|
||||
oss_temp_file_rename(s, tmp_filename.data, filename->data, options->pool);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
aos_status_t *oss_head_object_by_url(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
aos_table_t *headers,
|
||||
aos_table_t **resp_headers)
|
||||
{
|
||||
aos_status_t *s = NULL;
|
||||
aos_http_request_t *req = NULL;
|
||||
aos_http_response_t *resp = NULL;
|
||||
aos_table_t *query_params = NULL;
|
||||
|
||||
headers = aos_table_create_if_null(options, headers, 0);
|
||||
query_params = aos_table_create_if_null(options, query_params, 0);
|
||||
|
||||
oss_init_signed_url_request(options, signed_url, HTTP_HEAD,
|
||||
&req, query_params, headers, &resp);
|
||||
|
||||
s = oss_process_signed_request(options, req, resp);
|
||||
oss_fill_read_response_header(resp, resp_headers);
|
||||
|
||||
return s;
|
||||
}
|
||||
1179
include/oss_sdk/oss_resumable.c
Normal file
1179
include/oss_sdk/oss_resumable.c
Normal file
File diff suppressed because it is too large
Load Diff
168
include/oss_sdk/oss_resumable.h
Normal file
168
include/oss_sdk/oss_resumable.h
Normal file
@@ -0,0 +1,168 @@
|
||||
#ifndef LIBOSS_RESUMABLE_H
|
||||
#define LIBOSS_RESUMABLE_H
|
||||
|
||||
#include "aos_define.h"
|
||||
#include "aos_string.h"
|
||||
#include "aos_status.h"
|
||||
#include "apr_atomic.h"
|
||||
#include "apr_queue.h"
|
||||
#include "apr_thread_pool.h"
|
||||
#include "oss_define.h"
|
||||
|
||||
AOS_CPP_START
|
||||
|
||||
#define OSS_CP_UPLOAD 1
|
||||
#define OSS_CP_DOWNLOAD 2
|
||||
|
||||
typedef struct {
|
||||
int32_t index; // the index of part, start from 0
|
||||
int64_t offset; // the offset point of part
|
||||
int64_t size; // the size of part
|
||||
int completed; // AOS_TRUE completed, AOS_FALSE uncompleted
|
||||
aos_string_t etag; // the etag of part, for upload
|
||||
uint64_t crc64;
|
||||
} oss_checkpoint_part_t;
|
||||
|
||||
typedef struct {
|
||||
aos_string_t md5; // the md5 of checkout content
|
||||
int cp_type; // 1 upload, 2 download
|
||||
apr_file_t *thefile; // the handle of checkpoint file
|
||||
|
||||
aos_string_t file_path; // local file path
|
||||
int64_t file_size; // local file size, for upload
|
||||
apr_time_t file_last_modified; // local file last modified time, for upload
|
||||
aos_string_t file_md5; // the md5 of the local file content, for upload, reserved
|
||||
|
||||
aos_string_t object_name; // object name
|
||||
int64_t object_size; // object size, for download
|
||||
aos_string_t object_last_modified; // object last modified time, for download
|
||||
aos_string_t object_etag; // object etag, for download
|
||||
|
||||
aos_string_t upload_id; // upload id
|
||||
|
||||
int part_num; // the total number of parts
|
||||
int64_t part_size; // the part size, byte
|
||||
oss_checkpoint_part_t *parts; // the parts of local or object, from 0
|
||||
} oss_checkpoint_t;
|
||||
|
||||
typedef struct {
|
||||
oss_checkpoint_part_t *part;
|
||||
aos_status_t *s;
|
||||
aos_string_t etag;
|
||||
uint64_t crc64;
|
||||
} oss_part_task_result_t;
|
||||
|
||||
typedef struct {
|
||||
oss_request_options_t options;
|
||||
aos_string_t *bucket;
|
||||
aos_string_t *object;
|
||||
aos_string_t *upload_id;
|
||||
aos_string_t *filepath;
|
||||
oss_checkpoint_part_t *part;
|
||||
oss_part_task_result_t *result;
|
||||
|
||||
apr_uint32_t *launched; // the number of launched part tasks, use atomic
|
||||
apr_uint32_t *failed; // the number of failed part tasks, use atomic
|
||||
apr_uint32_t *completed; // the number of completed part tasks, use atomic
|
||||
apr_queue_t *failed_parts; // the queue of failed parts tasks, thread safe
|
||||
apr_queue_t *completed_parts; // the queue of completed parts tasks, thread safe
|
||||
apr_queue_t *task_result_queue;
|
||||
} oss_thread_params_t;
|
||||
|
||||
int32_t oss_get_thread_num(oss_resumable_clt_params_t *clt_params);
|
||||
|
||||
void oss_get_upload_checkpoint_path(oss_resumable_clt_params_t *clt_params, const aos_string_t *filepath,
|
||||
aos_pool_t *pool, aos_string_t *checkpoint_path);
|
||||
|
||||
void oss_get_download_checkpoint_path(oss_resumable_clt_params_t *clt_params, const aos_string_t *filepath,
|
||||
aos_pool_t *pool, aos_string_t *checkpoint_path);
|
||||
|
||||
int oss_get_file_info(const aos_string_t *filepath, aos_pool_t *pool, apr_finfo_t *finfo);
|
||||
|
||||
int oss_does_file_exist(const aos_string_t *filepath, aos_pool_t *pool);
|
||||
|
||||
int oss_open_checkpoint_file(aos_pool_t *pool, aos_string_t *checkpoint_path, oss_checkpoint_t *checkpoint);
|
||||
|
||||
int oss_open_checkpoint_file(aos_pool_t *pool, aos_string_t *checkpoint_path, oss_checkpoint_t *checkpoint);
|
||||
|
||||
int oss_get_part_num(int64_t file_size, int64_t part_size);
|
||||
|
||||
void oss_build_parts(int64_t file_size, int64_t part_size, oss_checkpoint_part_t *parts);
|
||||
|
||||
void oss_build_thread_params(oss_thread_params_t *thr_params, int part_num,
|
||||
aos_pool_t *parent_pool, oss_request_options_t *options,
|
||||
aos_string_t *bucket, aos_string_t *object, aos_string_t *filepath,
|
||||
aos_string_t *upload_id, oss_checkpoint_part_t *parts,
|
||||
oss_part_task_result_t *result);
|
||||
|
||||
void oss_destroy_thread_pool(oss_thread_params_t *thr_params, int part_num);
|
||||
|
||||
void oss_set_task_tracker(oss_thread_params_t *thr_params, int part_num,
|
||||
apr_uint32_t *launched, apr_uint32_t *failed, apr_uint32_t *completed,
|
||||
apr_queue_t *failed_parts, apr_queue_t *completed_parts);
|
||||
|
||||
int oss_verify_checkpoint_md5(aos_pool_t *pool, const oss_checkpoint_t *checkpoint);
|
||||
|
||||
void oss_build_upload_checkpoint(aos_pool_t *pool, oss_checkpoint_t *checkpoint, aos_string_t *file_path,
|
||||
apr_finfo_t *finfo, aos_string_t *upload_id, int64_t part_size);
|
||||
|
||||
void oss_build_download_checkpoint(aos_pool_t *pool, oss_checkpoint_t *checkpoint, aos_string_t *file_path,
|
||||
const char *object_name, int64_t object_size, const char *object_last_modified,
|
||||
const char *object_etag, int64_t part_size);
|
||||
|
||||
int oss_dump_checkpoint(aos_pool_t *pool, const oss_checkpoint_t *checkpoint);
|
||||
|
||||
int oss_load_checkpoint(aos_pool_t *pool, const aos_string_t *filepath, oss_checkpoint_t *checkpoint);
|
||||
|
||||
int oss_is_upload_checkpoint_valid(aos_pool_t *pool, oss_checkpoint_t *checkpoint, apr_finfo_t *finfo);
|
||||
|
||||
void oss_update_checkpoint(aos_pool_t *pool, oss_checkpoint_t *checkpoint, int32_t part_index,
|
||||
aos_string_t *etag, uint64_t crc64);
|
||||
|
||||
void oss_get_checkpoint_todo_parts(oss_checkpoint_t *checkpoint, int *part_num, oss_checkpoint_part_t *parts);
|
||||
|
||||
void *APR_THREAD_FUNC upload_part(apr_thread_t *thd, void *data);
|
||||
|
||||
aos_status_t *oss_resumable_upload_file_without_cp(oss_request_options_t *options,
|
||||
aos_string_t *bucket,
|
||||
aos_string_t *object,
|
||||
aos_string_t *filepath,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
int32_t thread_num,
|
||||
int64_t part_size,
|
||||
apr_finfo_t *finfo,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
aos_status_t *oss_resumable_upload_file_with_cp(oss_request_options_t *options,
|
||||
aos_string_t *bucket,
|
||||
aos_string_t *object,
|
||||
aos_string_t *filepath,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
int32_t thread_num,
|
||||
int64_t part_size,
|
||||
aos_string_t *checkpoint_path,
|
||||
apr_finfo_t *finfo,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers,
|
||||
aos_list_t *resp_body);
|
||||
|
||||
|
||||
aos_status_t *oss_resumable_download_file_internal(oss_request_options_t *options,
|
||||
aos_string_t *bucket,
|
||||
aos_string_t *object,
|
||||
aos_string_t *filepath,
|
||||
aos_table_t *headers,
|
||||
aos_table_t *params,
|
||||
int32_t thread_num,
|
||||
int64_t part_size,
|
||||
aos_string_t *checkpoint_path,
|
||||
oss_progress_callback progress_callback,
|
||||
aos_table_t **resp_headers);
|
||||
|
||||
AOS_CPP_END
|
||||
|
||||
#endif
|
||||
926
include/oss_sdk/oss_util.c
Normal file
926
include/oss_sdk/oss_util.c
Normal file
@@ -0,0 +1,926 @@
|
||||
#include "aos_string.h"
|
||||
#include "aos_util.h"
|
||||
#include "aos_log.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_auth.h"
|
||||
#include "oss_util.h"
|
||||
|
||||
#ifndef WIN32
|
||||
#include<sys/socket.h>
|
||||
#include<netinet/in.h>
|
||||
#include<arpa/inet.h>
|
||||
#endif
|
||||
|
||||
static char *default_content_type = "application/octet-stream";
|
||||
|
||||
static oss_content_type_t file_type[] = {
|
||||
{"html", "text/html"},
|
||||
{"htm", "text/html"},
|
||||
{"shtml", "text/html"},
|
||||
{"css", "text/css"},
|
||||
{"xml", "text/xml"},
|
||||
{"gif", "image/gif"},
|
||||
{"jpeg", "image/jpeg"},
|
||||
{"jpg", "image/jpeg"},
|
||||
{"js", "application/x-javascript"},
|
||||
{"atom", "application/atom+xml"},
|
||||
{"rss", "application/rss+xml"},
|
||||
{"mml", "text/mathml"},
|
||||
{"txt", "text/plain"},
|
||||
{"jad", "text/vnd.sun.j2me.app-descriptor"},
|
||||
{"wml", "text/vnd.wap.wml"},
|
||||
{"htc", "text/x-component"},
|
||||
{"png", "image/png"},
|
||||
{"tif", "image/tiff"},
|
||||
{"tiff", "image/tiff"},
|
||||
{"wbmp", "image/vnd.wap.wbmp"},
|
||||
{"ico", "image/x-icon"},
|
||||
{"jng", "image/x-jng"},
|
||||
{"bmp", "image/x-ms-bmp"},
|
||||
{"svg", "image/svg+xml"},
|
||||
{"svgz", "image/svg+xml"},
|
||||
{"webp", "image/webp"},
|
||||
{"jar", "application/java-archive"},
|
||||
{"war", "application/java-archive"},
|
||||
{"ear", "application/java-archive"},
|
||||
{"hqx", "application/mac-binhex40"},
|
||||
{"doc ", "application/msword"},
|
||||
{"pdf", "application/pdf"},
|
||||
{"ps", "application/postscript"},
|
||||
{"eps", "application/postscript"},
|
||||
{"ai", "application/postscript"},
|
||||
{"rtf", "application/rtf"},
|
||||
{"xls", "application/vnd.ms-excel"},
|
||||
{"ppt", "application/vnd.ms-powerpoint"},
|
||||
{"wmlc", "application/vnd.wap.wmlc"},
|
||||
{"kml", "application/vnd.google-earth.kml+xml"},
|
||||
{"kmz", "application/vnd.google-earth.kmz"},
|
||||
{"7z", "application/x-7z-compressed"},
|
||||
{"cco", "application/x-cocoa"},
|
||||
{"jardiff", "application/x-java-archive-diff"},
|
||||
{"jnlp", "application/x-java-jnlp-file"},
|
||||
{"run", "application/x-makeself"},
|
||||
{"pl", "application/x-perl"},
|
||||
{"pm", "application/x-perl"},
|
||||
{"prc", "application/x-pilot"},
|
||||
{"pdb", "application/x-pilot"},
|
||||
{"rar", "application/x-rar-compressed"},
|
||||
{"rpm", "application/x-redhat-package-manager"},
|
||||
{"sea", "application/x-sea"},
|
||||
{"swf", "application/x-shockwave-flash"},
|
||||
{"sit", "application/x-stuffit"},
|
||||
{"tcl", "application/x-tcl"},
|
||||
{"tk", "application/x-tcl"},
|
||||
{"der", "application/x-x509-ca-cert"},
|
||||
{"pem", "application/x-x509-ca-cert"},
|
||||
{"crt", "application/x-x509-ca-cert"},
|
||||
{"xpi", "application/x-xpinstall"},
|
||||
{"xhtml", "application/xhtml+xml"},
|
||||
{"zip", "application/zip"},
|
||||
{"wgz", "application/x-nokia-widget"},
|
||||
{"bin", "application/octet-stream"},
|
||||
{"exe", "application/octet-stream"},
|
||||
{"dll", "application/octet-stream"},
|
||||
{"deb", "application/octet-stream"},
|
||||
{"dmg", "application/octet-stream"},
|
||||
{"eot", "application/octet-stream"},
|
||||
{"iso", "application/octet-stream"},
|
||||
{"img", "application/octet-stream"},
|
||||
{"msi", "application/octet-stream"},
|
||||
{"msp", "application/octet-stream"},
|
||||
{"msm", "application/octet-stream"},
|
||||
{"mid", "audio/midi"},
|
||||
{"midi", "audio/midi"},
|
||||
{"kar", "audio/midi"},
|
||||
{"mp3", "audio/mpeg"},
|
||||
{"ogg", "audio/ogg"},
|
||||
{"m4a", "audio/x-m4a"},
|
||||
{"ra", "audio/x-realaudio"},
|
||||
{"3gpp", "video/3gpp"},
|
||||
{"3gp", "video/3gpp"},
|
||||
{"mp4", "video/mp4"},
|
||||
{"mpeg", "video/mpeg"},
|
||||
{"mpg", "video/mpeg"},
|
||||
{"mov", "video/quicktime"},
|
||||
{"webm", "video/webm"},
|
||||
{"flv", "video/x-flv"},
|
||||
{"m4v", "video/x-m4v"},
|
||||
{"mng", "video/x-mng"},
|
||||
{"asx", "video/x-ms-asf"},
|
||||
{"asf", "video/x-ms-asf"},
|
||||
{"wmv", "video/x-ms-wmv"},
|
||||
{"avi", "video/x-msvideo"},
|
||||
{"ts", "video/MP2T"},
|
||||
{"m3u8", "application/x-mpegURL"},
|
||||
{"apk", "application/vnd.android.package-archive"},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
static int starts_with(const aos_string_t *str, const char *prefix) {
|
||||
uint32_t i;
|
||||
if(NULL != str && prefix && str->len > 0 && strlen(prefix)) {
|
||||
for(i = 0; str->data[i] != '\0' && prefix[i] != '\0'; i++) {
|
||||
if(prefix[i] != str->data[i]) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void generate_proto(const oss_request_options_t *options,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
const char *proto;
|
||||
proto = starts_with(&options->config->endpoint, AOS_HTTP_PREFIX) ?
|
||||
AOS_HTTP_PREFIX : "";
|
||||
proto = starts_with(&options->config->endpoint, AOS_HTTPS_PREFIX) ?
|
||||
AOS_HTTPS_PREFIX : proto;
|
||||
req->proto = apr_psprintf(options->pool, "%.*s", (int)strlen(proto), proto);
|
||||
}
|
||||
|
||||
static void generate_rtmp_proto(const oss_request_options_t *options,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
const char *proto = AOS_RTMP_PREFIX;
|
||||
req->proto = apr_psprintf(options->pool, "%.*s", (int)strlen(proto), proto);
|
||||
}
|
||||
|
||||
int is_valid_ip(const char *str)
|
||||
{
|
||||
if (INADDR_NONE == inet_addr(str) || INADDR_ANY == inet_addr(str)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
oss_config_t *oss_config_create(aos_pool_t *p)
|
||||
{
|
||||
return (oss_config_t *)aos_pcalloc(p, sizeof(oss_config_t));
|
||||
}
|
||||
|
||||
void oss_config_resolve(aos_pool_t *pool, oss_config_t *config, aos_http_controller_t *ctl)
|
||||
{
|
||||
if(!aos_is_null_string(&config->proxy_host)) {
|
||||
// proxy host:port
|
||||
if (config->proxy_port == 0) {
|
||||
ctl->options->proxy_host = apr_psprintf(pool, "%.*s", config->proxy_host.len, config->proxy_host.data);
|
||||
} else {
|
||||
ctl->options->proxy_host = apr_psprintf(pool, "%.*s:%d", config->proxy_host.len, config->proxy_host.data,
|
||||
config->proxy_port);
|
||||
}
|
||||
// authorize user:passwd
|
||||
if (!aos_is_null_string(&config->proxy_user) && !aos_is_null_string(&config->proxy_passwd)) {
|
||||
ctl->options->proxy_auth = apr_psprintf(pool, "%.*s:%.*s", config->proxy_user.len,
|
||||
config->proxy_user.data, config->proxy_passwd.len, config->proxy_passwd.data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
oss_request_options_t *oss_request_options_create(aos_pool_t *p)
|
||||
{
|
||||
int s;
|
||||
oss_request_options_t *options;
|
||||
|
||||
if(p == NULL) {
|
||||
if ((s = aos_pool_create(&p, NULL)) != APR_SUCCESS) {
|
||||
aos_fatal_log("aos_pool_create failure.");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
options = (oss_request_options_t *)aos_pcalloc(p, sizeof(oss_request_options_t));
|
||||
options->pool = p;
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
void oss_get_object_uri(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
int32_t proto_len;
|
||||
const char *raw_endpoint_str;
|
||||
aos_string_t raw_endpoint;
|
||||
|
||||
generate_proto(options, req);
|
||||
|
||||
proto_len = strlen(req->proto);
|
||||
|
||||
req->resource = apr_psprintf(options->pool, "%.*s/%.*s",
|
||||
bucket->len, bucket->data,
|
||||
object->len, object->data);
|
||||
|
||||
raw_endpoint_str = aos_pstrdup(options->pool,
|
||||
&options->config->endpoint) + proto_len;
|
||||
raw_endpoint.len = options->config->endpoint.len - proto_len;
|
||||
raw_endpoint.data = options->config->endpoint.data + proto_len;
|
||||
|
||||
if (options->config->is_cname) {
|
||||
req->host = apr_psprintf(options->pool, "%.*s",
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = object->data;
|
||||
} else if (is_valid_ip(raw_endpoint_str)) {
|
||||
req->host = apr_psprintf(options->pool, "%.*s",
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = apr_psprintf(options->pool, "%.*s/%.*s",
|
||||
bucket->len, bucket->data,
|
||||
object->len, object->data);
|
||||
} else {
|
||||
req->host = apr_psprintf(options->pool, "%.*s.%.*s",
|
||||
bucket->len, bucket->data,
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = object->data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void oss_get_bucket_uri(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
int32_t proto_len;
|
||||
const char *raw_endpoint_str;
|
||||
aos_string_t raw_endpoint;
|
||||
|
||||
generate_proto(options, req);
|
||||
|
||||
proto_len = strlen(req->proto);
|
||||
raw_endpoint_str = aos_pstrdup(options->pool,
|
||||
&options->config->endpoint) + proto_len;
|
||||
raw_endpoint.len = options->config->endpoint.len - proto_len;
|
||||
raw_endpoint.data = options->config->endpoint.data + proto_len;
|
||||
|
||||
if (is_valid_ip(raw_endpoint_str)) {
|
||||
req->resource = apr_psprintf(options->pool, "%.*s",
|
||||
bucket->len, bucket->data);
|
||||
} else {
|
||||
req->resource = apr_psprintf(options->pool, "%.*s/",
|
||||
bucket->len, bucket->data);
|
||||
}
|
||||
|
||||
if (options->config->is_cname ||
|
||||
is_valid_ip(raw_endpoint_str))
|
||||
{
|
||||
req->host = apr_psprintf(options->pool, "%.*s",
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = apr_psprintf(options->pool, "%.*s", bucket->len,
|
||||
bucket->data);
|
||||
} else {
|
||||
req->host = apr_psprintf(options->pool, "%.*s.%.*s",
|
||||
bucket->len, bucket->data,
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = apr_psprintf(options->pool, "%s", "");
|
||||
}
|
||||
}
|
||||
|
||||
void oss_get_rtmp_uri(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel_id,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
int32_t proto_len = 0;
|
||||
const char *raw_endpoint_str = NULL;
|
||||
aos_string_t raw_endpoint;
|
||||
|
||||
generate_rtmp_proto(options, req);
|
||||
|
||||
proto_len = strlen(req->proto);
|
||||
|
||||
req->resource = apr_psprintf(options->pool, "%.*s/%.*s", bucket->len, bucket->data,
|
||||
live_channel_id->len, live_channel_id->data);
|
||||
|
||||
raw_endpoint_str = aos_pstrdup(options->pool,
|
||||
&options->config->endpoint) + proto_len;
|
||||
raw_endpoint.len = options->config->endpoint.len - proto_len;
|
||||
raw_endpoint.data = options->config->endpoint.data + proto_len;
|
||||
|
||||
if (options->config->is_cname) {
|
||||
req->host = apr_psprintf(options->pool, "%.*s",
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = apr_psprintf(options->pool, "live/%.*s",
|
||||
live_channel_id->len, live_channel_id->data);
|
||||
} else if (is_valid_ip(raw_endpoint_str)) {
|
||||
req->host = apr_psprintf(options->pool, "%.*s",
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = apr_psprintf(options->pool, "%.*s/live/%.*s",
|
||||
bucket->len, bucket->data,
|
||||
live_channel_id->len, live_channel_id->data);
|
||||
} else {
|
||||
req->host = apr_psprintf(options->pool, "%.*s.%.*s",
|
||||
bucket->len, bucket->data,
|
||||
raw_endpoint.len, raw_endpoint.data);
|
||||
req->uri = apr_psprintf(options->pool, "live/%.*s",
|
||||
live_channel_id->len, live_channel_id->data);
|
||||
}
|
||||
}
|
||||
|
||||
void oss_write_request_body_from_buffer(aos_list_t *buffer,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
aos_list_movelist(buffer, &req->body);
|
||||
req->body_len = aos_buf_list_len(&req->body);
|
||||
}
|
||||
|
||||
int oss_write_request_body_from_file(aos_pool_t *p,
|
||||
const aos_string_t *filename,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_file_buf_t *fb = aos_create_file_buf(p);
|
||||
res = aos_open_file_for_all_read(p, filename->data, fb);
|
||||
if (res != AOSE_OK) {
|
||||
aos_error_log("Open read file fail, filename:%s\n", filename->data);
|
||||
return res;
|
||||
}
|
||||
|
||||
req->body_len = fb->file_last;
|
||||
req->file_path = filename->data;
|
||||
req->file_buf = fb;
|
||||
req->type = BODY_IN_FILE;
|
||||
req->read_body = aos_read_http_body_file;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int oss_write_request_body_from_upload_file(aos_pool_t *p,
|
||||
oss_upload_file_t *upload_file,
|
||||
aos_http_request_t *req)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_file_buf_t *fb = aos_create_file_buf(p);
|
||||
res = aos_open_file_for_range_read(p, upload_file->filename.data,
|
||||
upload_file->file_pos, upload_file->file_last, fb);
|
||||
if (res != AOSE_OK) {
|
||||
aos_error_log("Open read file fail, filename:%s\n",
|
||||
upload_file->filename.data);
|
||||
return res;
|
||||
}
|
||||
|
||||
req->body_len = fb->file_last - fb->file_pos;
|
||||
req->file_path = upload_file->filename.data;
|
||||
req->file_buf = fb;
|
||||
req->type = BODY_IN_FILE;
|
||||
req->read_body = aos_read_http_body_file;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void oss_fill_read_response_body(aos_http_response_t *resp,
|
||||
aos_list_t *buffer)
|
||||
{
|
||||
if (NULL != buffer) {
|
||||
aos_list_movelist(&resp->body, buffer);
|
||||
}
|
||||
}
|
||||
|
||||
int oss_init_read_response_body_to_file(aos_pool_t *p,
|
||||
const aos_string_t *filename,
|
||||
aos_http_response_t *resp)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_file_buf_t *fb = aos_create_file_buf(p);
|
||||
res = aos_open_file_for_write(p, filename->data, fb);
|
||||
if (res != AOSE_OK) {
|
||||
aos_error_log("Open write file fail, filename:%s\n", filename->data);
|
||||
return res;
|
||||
}
|
||||
resp->file_path = filename->data;
|
||||
resp->file_buf = fb;
|
||||
resp->write_body = aos_write_http_body_file;
|
||||
resp->type = BODY_IN_FILE;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int oss_init_read_response_body_to_fb(aos_file_buf_t *fb,
|
||||
const aos_string_t *filename,
|
||||
aos_http_response_t *resp)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
|
||||
resp->file_path = filename->data;
|
||||
resp->file_buf = fb;
|
||||
resp->write_body = aos_write_http_body_file;
|
||||
resp->type = BODY_IN_FILE;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void oss_fill_read_response_header(aos_http_response_t *resp,
|
||||
aos_table_t **headers)
|
||||
{
|
||||
if (NULL != headers && NULL != resp) {
|
||||
*headers = resp->headers;
|
||||
}
|
||||
}
|
||||
|
||||
void *oss_create_api_result_content(aos_pool_t *p, size_t size)
|
||||
{
|
||||
void *result_content = aos_palloc(p, size);
|
||||
if (NULL == result_content) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
aos_list_init((aos_list_t *)result_content);
|
||||
|
||||
return result_content;
|
||||
}
|
||||
|
||||
oss_list_object_content_t *oss_create_list_object_content(aos_pool_t *p)
|
||||
{
|
||||
return (oss_list_object_content_t *)oss_create_api_result_content(
|
||||
p, sizeof(oss_list_object_content_t));
|
||||
}
|
||||
|
||||
oss_list_object_common_prefix_t *oss_create_list_object_common_prefix(aos_pool_t *p)
|
||||
{
|
||||
return (oss_list_object_common_prefix_t *)oss_create_api_result_content(
|
||||
p, sizeof(oss_list_object_common_prefix_t));
|
||||
}
|
||||
|
||||
oss_list_multipart_upload_content_t *oss_create_list_multipart_upload_content(aos_pool_t *p)
|
||||
{
|
||||
return (oss_list_multipart_upload_content_t*)oss_create_api_result_content(
|
||||
p, sizeof(oss_list_multipart_upload_content_t));
|
||||
}
|
||||
|
||||
oss_list_part_content_t *oss_create_list_part_content(aos_pool_t *p)
|
||||
{
|
||||
oss_list_part_content_t *list_part_content = NULL;
|
||||
list_part_content = (oss_list_part_content_t*)oss_create_api_result_content(p,
|
||||
sizeof(oss_list_part_content_t));
|
||||
|
||||
return list_part_content;
|
||||
}
|
||||
|
||||
oss_complete_part_content_t *oss_create_complete_part_content(aos_pool_t *p)
|
||||
{
|
||||
oss_complete_part_content_t *complete_part_content = NULL;
|
||||
complete_part_content = (oss_complete_part_content_t*)oss_create_api_result_content(
|
||||
p, sizeof(oss_complete_part_content_t));
|
||||
|
||||
return complete_part_content;
|
||||
}
|
||||
|
||||
oss_list_object_params_t *oss_create_list_object_params(aos_pool_t *p)
|
||||
{
|
||||
oss_list_object_params_t * params;
|
||||
params = (oss_list_object_params_t *)aos_pcalloc(
|
||||
p, sizeof(oss_list_object_params_t));
|
||||
aos_list_init(¶ms->object_list);
|
||||
aos_list_init(¶ms->common_prefix_list);
|
||||
aos_str_set(¶ms->prefix, "");
|
||||
aos_str_set(¶ms->marker, "");
|
||||
aos_str_set(¶ms->delimiter, "");
|
||||
params->truncated = 1;
|
||||
params->max_ret = OSS_PER_RET_NUM;
|
||||
return params;
|
||||
}
|
||||
|
||||
oss_list_upload_part_params_t *oss_create_list_upload_part_params(aos_pool_t *p)
|
||||
{
|
||||
oss_list_upload_part_params_t *params;
|
||||
params = (oss_list_upload_part_params_t *)aos_pcalloc(
|
||||
p, sizeof(oss_list_upload_part_params_t));
|
||||
aos_list_init(¶ms->part_list);
|
||||
aos_str_set(¶ms->part_number_marker, "");
|
||||
params->max_ret = OSS_PER_RET_NUM;
|
||||
params->truncated = 1;
|
||||
return params;
|
||||
}
|
||||
|
||||
oss_list_multipart_upload_params_t *oss_create_list_multipart_upload_params(aos_pool_t *p)
|
||||
{
|
||||
oss_list_multipart_upload_params_t *params;
|
||||
params = (oss_list_multipart_upload_params_t *)aos_pcalloc(
|
||||
p, sizeof(oss_list_multipart_upload_params_t));
|
||||
aos_list_init(¶ms->upload_list);
|
||||
aos_str_set(¶ms->prefix, "");
|
||||
aos_str_set(¶ms->key_marker, "");
|
||||
aos_str_set(¶ms->upload_id_marker, "");
|
||||
aos_str_set(¶ms->delimiter, "");
|
||||
params->truncated = 1;
|
||||
params->max_ret = OSS_PER_RET_NUM;
|
||||
return params;
|
||||
}
|
||||
|
||||
oss_upload_part_copy_params_t *oss_create_upload_part_copy_params(aos_pool_t *p)
|
||||
{
|
||||
return (oss_upload_part_copy_params_t *)aos_pcalloc(
|
||||
p, sizeof(oss_upload_part_copy_params_t));
|
||||
}
|
||||
|
||||
oss_lifecycle_rule_content_t *oss_create_lifecycle_rule_content(aos_pool_t *p)
|
||||
{
|
||||
oss_lifecycle_rule_content_t *rule;
|
||||
rule = (oss_lifecycle_rule_content_t *)aos_pcalloc(
|
||||
p, sizeof(oss_lifecycle_rule_content_t));
|
||||
aos_str_set(&rule->id, "");
|
||||
aos_str_set(&rule->prefix, "");
|
||||
aos_str_set(&rule->status, "");
|
||||
aos_str_set(&rule->date, "");
|
||||
rule->days = INT_MAX;
|
||||
return rule;
|
||||
}
|
||||
|
||||
oss_upload_file_t *oss_create_upload_file(aos_pool_t *p)
|
||||
{
|
||||
return (oss_upload_file_t *)aos_pcalloc(p, sizeof(oss_upload_file_t));
|
||||
}
|
||||
|
||||
oss_object_key_t *oss_create_oss_object_key(aos_pool_t *p)
|
||||
{
|
||||
return (oss_object_key_t *)aos_pcalloc(p, sizeof(oss_object_key_t));
|
||||
}
|
||||
|
||||
oss_live_channel_publish_url_t *oss_create_live_channel_publish_url(aos_pool_t *p)
|
||||
{
|
||||
return (oss_live_channel_publish_url_t *)aos_pcalloc(p, sizeof(oss_live_channel_publish_url_t));
|
||||
}
|
||||
|
||||
oss_live_channel_play_url_t *oss_create_live_channel_play_url(aos_pool_t *p)
|
||||
{
|
||||
return (oss_live_channel_play_url_t *)aos_pcalloc(p, sizeof(oss_live_channel_play_url_t));
|
||||
}
|
||||
|
||||
oss_live_channel_content_t *oss_create_list_live_channel_content(aos_pool_t *p)
|
||||
{
|
||||
oss_live_channel_content_t *list_live_channel_content = NULL;
|
||||
list_live_channel_content = (oss_live_channel_content_t*)oss_create_api_result_content(p,
|
||||
sizeof(oss_live_channel_content_t));
|
||||
aos_list_init(&list_live_channel_content->publish_url_list);
|
||||
aos_list_init(&list_live_channel_content->play_url_list);
|
||||
return list_live_channel_content;
|
||||
}
|
||||
|
||||
oss_live_record_content_t *oss_create_live_record_content(aos_pool_t *p)
|
||||
{
|
||||
oss_live_record_content_t *live_record_content = NULL;
|
||||
live_record_content = (oss_live_record_content_t*)oss_create_api_result_content(p,
|
||||
sizeof(oss_live_record_content_t));
|
||||
return live_record_content;
|
||||
}
|
||||
|
||||
oss_live_channel_configuration_t *oss_create_live_channel_configuration_content(aos_pool_t *p)
|
||||
{
|
||||
oss_live_channel_configuration_t *config;
|
||||
config = (oss_live_channel_configuration_t *)aos_pcalloc(
|
||||
p, sizeof(oss_live_channel_configuration_t));
|
||||
|
||||
aos_str_set(&config->name, "");
|
||||
aos_str_set(&config->description, "");
|
||||
aos_str_set(&config->status, LIVE_CHANNEL_STATUS_ENABLED);
|
||||
aos_str_set(&config->target.type, LIVE_CHANNEL_DEFAULT_TYPE);
|
||||
aos_str_set(&config->target.play_list_name, LIVE_CHANNEL_DEFAULT_PLAYLIST);
|
||||
config->target.frag_duration = LIVE_CHANNEL_DEFAULT_FRAG_DURATION;
|
||||
config->target.frag_count = LIVE_CHANNEL_DEFAULT_FRAG_COUNT;
|
||||
|
||||
return config;
|
||||
}
|
||||
|
||||
oss_checkpoint_t *oss_create_checkpoint_content(aos_pool_t *p)
|
||||
{
|
||||
oss_checkpoint_t *cp;
|
||||
cp = (oss_checkpoint_t *)aos_pcalloc(p, sizeof(oss_checkpoint_t));
|
||||
cp->parts = (oss_checkpoint_part_t *)aos_pcalloc(p, sizeof(oss_checkpoint_part_t) * OSS_MAX_PART_NUM);
|
||||
aos_str_set(&cp->md5, "");
|
||||
aos_str_set(&cp->file_path, "");
|
||||
aos_str_set(&cp->file_md5, "");
|
||||
aos_str_set(&cp->object_name, "");
|
||||
aos_str_set(&cp->object_last_modified, "");
|
||||
aos_str_set(&cp->object_etag, "");
|
||||
aos_str_set(&cp->upload_id, "");
|
||||
return cp;
|
||||
}
|
||||
|
||||
oss_resumable_clt_params_t *oss_create_resumable_clt_params_content(aos_pool_t *p, int64_t part_size, int32_t thread_num,
|
||||
int enable_checkpoint, const char *checkpoint_path)
|
||||
{
|
||||
oss_resumable_clt_params_t *clt;
|
||||
clt = (oss_resumable_clt_params_t *)aos_pcalloc(p, sizeof(oss_resumable_clt_params_t));
|
||||
clt->part_size = part_size;
|
||||
clt->thread_num = thread_num;
|
||||
clt->enable_checkpoint = enable_checkpoint;
|
||||
if (enable_checkpoint && NULL != checkpoint_path) {
|
||||
aos_str_set(&clt->checkpoint_path, checkpoint_path);
|
||||
}
|
||||
return clt;
|
||||
}
|
||||
|
||||
oss_list_live_channel_params_t *oss_create_list_live_channel_params(aos_pool_t *p)
|
||||
{
|
||||
oss_list_live_channel_params_t *params;
|
||||
params = (oss_list_live_channel_params_t *)aos_pcalloc(
|
||||
p, sizeof(oss_list_live_channel_params_t));
|
||||
aos_list_init(¶ms->live_channel_list);
|
||||
aos_str_set(¶ms->prefix, "");
|
||||
aos_str_set(¶ms->marker, "");
|
||||
params->truncated = 1;
|
||||
params->max_keys = OSS_PER_RET_NUM;
|
||||
return params;
|
||||
}
|
||||
|
||||
const char *get_oss_acl_str(oss_acl_e oss_acl)
|
||||
{
|
||||
switch (oss_acl) {
|
||||
case OSS_ACL_PRIVATE:
|
||||
return "private";
|
||||
case OSS_ACL_PUBLIC_READ:
|
||||
return "public-read";
|
||||
case OSS_ACL_PUBLIC_READ_WRITE:
|
||||
return "public-read-write";
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void oss_init_request(const oss_request_options_t *options,
|
||||
http_method_e method,
|
||||
aos_http_request_t **req,
|
||||
aos_table_t *params,
|
||||
aos_table_t *headers,
|
||||
aos_http_response_t **resp)
|
||||
{
|
||||
*req = aos_http_request_create(options->pool);
|
||||
*resp = aos_http_response_create(options->pool);
|
||||
(*req)->method = method;
|
||||
init_sts_token_header();
|
||||
(*req)->headers = headers;
|
||||
(*req)->query_params = params;
|
||||
}
|
||||
|
||||
void oss_init_bucket_request(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
http_method_e method,
|
||||
aos_http_request_t **req,
|
||||
aos_table_t *params,
|
||||
aos_table_t *headers,
|
||||
aos_http_response_t **resp)
|
||||
{
|
||||
oss_init_request(options, method, req, params, headers, resp);
|
||||
oss_get_bucket_uri(options, bucket, *req);
|
||||
}
|
||||
|
||||
void oss_init_object_request(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
http_method_e method,
|
||||
aos_http_request_t **req,
|
||||
aos_table_t *params,
|
||||
aos_table_t *headers,
|
||||
oss_progress_callback cb,
|
||||
uint64_t init_crc,
|
||||
aos_http_response_t **resp)
|
||||
{
|
||||
oss_init_request(options, method, req, params, headers, resp);
|
||||
if (HTTP_GET == method) {
|
||||
(*resp)->progress_callback = cb;
|
||||
} else if (HTTP_PUT == method || HTTP_POST == method) {
|
||||
(*req)->progress_callback = cb;
|
||||
(*req)->crc64 = init_crc;
|
||||
}
|
||||
|
||||
oss_get_object_uri(options, bucket, object, *req);
|
||||
}
|
||||
|
||||
void oss_init_live_channel_request(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel,
|
||||
http_method_e method,
|
||||
aos_http_request_t **req,
|
||||
aos_table_t *params,
|
||||
aos_table_t *headers,
|
||||
aos_http_response_t **resp)
|
||||
{
|
||||
oss_init_request(options, method, req, params, headers, resp);
|
||||
oss_get_object_uri(options, bucket, live_channel, *req);
|
||||
}
|
||||
|
||||
void oss_init_signed_url_request(const oss_request_options_t *options,
|
||||
const aos_string_t *signed_url,
|
||||
http_method_e method,
|
||||
aos_http_request_t **req,
|
||||
aos_table_t *params,
|
||||
aos_table_t *headers,
|
||||
aos_http_response_t **resp)
|
||||
{
|
||||
*req = aos_http_request_create(options->pool);
|
||||
*resp = aos_http_response_create(options->pool);
|
||||
(*req)->method = method;
|
||||
(*req)->headers = headers;
|
||||
(*req)->query_params = params;
|
||||
(*req)->signed_url = signed_url->data;
|
||||
}
|
||||
|
||||
aos_status_t *oss_send_request(aos_http_controller_t *ctl,
|
||||
aos_http_request_t *req,
|
||||
aos_http_response_t *resp)
|
||||
{
|
||||
aos_status_t *s;
|
||||
const char *reason;
|
||||
int res = AOSE_OK;
|
||||
|
||||
s = aos_status_create(ctl->pool);
|
||||
res = aos_http_send_request(ctl, req, resp);
|
||||
|
||||
if (res != AOSE_OK) {
|
||||
reason = aos_http_controller_get_reason(ctl);
|
||||
aos_status_set(s, res, AOS_HTTP_IO_ERROR_CODE, reason);
|
||||
} else if (!aos_http_is_ok(resp->status)) {
|
||||
s = aos_status_parse_from_body(ctl->pool, &resp->body, resp->status, s);
|
||||
} else {
|
||||
s->code = resp->status;
|
||||
}
|
||||
|
||||
s->req_id = (char*)(apr_table_get(resp->headers, "x-oss-request-id"));
|
||||
if (s->req_id == NULL) {
|
||||
s->req_id = (char*)(apr_table_get(resp->headers, "x-img-request-id"));
|
||||
if (s->req_id == NULL) {
|
||||
s->req_id = "";
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
aos_status_t *oss_process_request(const oss_request_options_t *options,
|
||||
aos_http_request_t *req,
|
||||
aos_http_response_t *resp)
|
||||
{
|
||||
int res = AOSE_OK;
|
||||
aos_status_t *s;
|
||||
|
||||
s = aos_status_create(options->pool);
|
||||
res = oss_sign_request(req, options->config);
|
||||
if (res != AOSE_OK) {
|
||||
aos_status_set(s, res, AOS_CLIENT_ERROR_CODE, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
return oss_send_request(options->ctl, req, resp);
|
||||
}
|
||||
|
||||
aos_status_t *oss_process_signed_request(const oss_request_options_t *options,
|
||||
aos_http_request_t *req,
|
||||
aos_http_response_t *resp)
|
||||
{
|
||||
return oss_send_request(options->ctl, req, resp);
|
||||
}
|
||||
|
||||
void oss_get_part_size(int64_t filesize, int64_t *part_size)
|
||||
{
|
||||
if (filesize > (*part_size) * OSS_MAX_PART_NUM) {
|
||||
*part_size = (filesize + OSS_MAX_PART_NUM -
|
||||
filesize % OSS_MAX_PART_NUM) / OSS_MAX_PART_NUM;
|
||||
|
||||
aos_warn_log("Part number larger than max limit, "
|
||||
"part size Changed to:%" APR_INT64_T_FMT "\n",
|
||||
*part_size);
|
||||
}
|
||||
}
|
||||
|
||||
int part_sort_cmp(const void *a, const void *b)
|
||||
{
|
||||
return (((oss_upload_part_t*)a)->part_num -
|
||||
((oss_upload_part_t*)b)->part_num > 0 ? 1 : -1);
|
||||
}
|
||||
|
||||
|
||||
void oss_headers_add_range(apr_pool_t *pool, apr_table_t *headers, int64_t offset, int64_t size)
|
||||
{
|
||||
char *range;
|
||||
range = apr_psprintf(pool, "bytes=%" APR_INT64_T_FMT "-%" APR_INT64_T_FMT,
|
||||
offset, offset + size - 1);
|
||||
apr_table_set(headers, "Range", range);
|
||||
}
|
||||
|
||||
|
||||
char *get_content_type_by_suffix(const char *suffix)
|
||||
{
|
||||
oss_content_type_t *content_type;
|
||||
|
||||
for (content_type = file_type; content_type->suffix; ++content_type) {
|
||||
if (strcasecmp(content_type->suffix, suffix) == 0)
|
||||
{
|
||||
return content_type->type;
|
||||
}
|
||||
}
|
||||
return default_content_type;
|
||||
}
|
||||
|
||||
char *get_content_type(const char *name)
|
||||
{
|
||||
char *begin;
|
||||
char *content_type = NULL;
|
||||
begin = strrchr(name, '.');
|
||||
if (begin) {
|
||||
content_type = get_content_type_by_suffix(begin + 1);
|
||||
}
|
||||
return content_type;
|
||||
}
|
||||
|
||||
void set_content_type(const char* file_name,
|
||||
const char* key,
|
||||
aos_table_t *headers)
|
||||
{
|
||||
char *user_content_type = NULL;
|
||||
char *content_type = NULL;
|
||||
const char *mime_key = NULL;
|
||||
|
||||
mime_key = file_name == NULL ? key : file_name;
|
||||
|
||||
user_content_type = (char*)apr_table_get(headers, OSS_CONTENT_TYPE);
|
||||
if (NULL == user_content_type && mime_key != NULL) {
|
||||
content_type = get_content_type(mime_key);
|
||||
if (content_type) {
|
||||
apr_table_set(headers, OSS_CONTENT_TYPE, content_type);
|
||||
} else {
|
||||
apr_table_set(headers, OSS_CONTENT_TYPE, default_content_type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aos_table_t* aos_table_create_if_null(const oss_request_options_t *options,
|
||||
aos_table_t *table,
|
||||
int table_size)
|
||||
{
|
||||
if (table == NULL) {
|
||||
table = aos_table_make(options->pool, table_size);
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
int is_enable_crc(const oss_request_options_t *options)
|
||||
{
|
||||
return options->ctl->options->enable_crc;
|
||||
}
|
||||
|
||||
int has_crc_in_response(const aos_http_response_t *resp)
|
||||
{
|
||||
if (NULL != apr_table_get(resp->headers, OSS_HASH_CRC64_ECMA)) {
|
||||
return AOS_TRUE;
|
||||
}
|
||||
|
||||
return AOS_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int has_range_or_process_in_request(const aos_http_request_t *req)
|
||||
{
|
||||
if (NULL != apr_table_get(req->headers, "Range") ||
|
||||
NULL != apr_table_get(req->query_params, OSS_PROCESS)) {
|
||||
return AOS_TRUE;
|
||||
}
|
||||
|
||||
return AOS_FALSE;
|
||||
}
|
||||
|
||||
static int check_crc(uint64_t crc, const apr_table_t *headers)
|
||||
{
|
||||
char * srv_crc = (char*)(apr_table_get(headers, OSS_HASH_CRC64_ECMA));
|
||||
if (NULL != srv_crc && crc != aos_atoui64(srv_crc)) {
|
||||
return AOSE_CRC_INCONSISTENT_ERROR;
|
||||
}
|
||||
return AOSE_OK;
|
||||
}
|
||||
|
||||
int oss_check_crc_consistent(uint64_t crc, const apr_table_t *resp_headers, aos_status_t *s)
|
||||
{
|
||||
int res = check_crc(crc, resp_headers);
|
||||
if (res != AOSE_OK) {
|
||||
aos_inconsistent_error_status_set(s, res);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int oss_get_temporary_file_name(aos_pool_t *p, const aos_string_t *filename, aos_string_t *temp_file_name)
|
||||
{
|
||||
int len = filename->len + 1;
|
||||
char *temp_file_name_ptr = NULL;
|
||||
|
||||
len += strlen(AOS_TEMP_FILE_SUFFIX);
|
||||
temp_file_name_ptr = aos_pcalloc(p, len);
|
||||
|
||||
apr_snprintf(temp_file_name_ptr, len, "%.*s%s", filename->len, filename->data, AOS_TEMP_FILE_SUFFIX);
|
||||
aos_str_set(temp_file_name, temp_file_name_ptr);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int oss_temp_file_rename(aos_status_t *s, const char *from_path, const char *to_path, apr_pool_t *pool)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
if (s != NULL) {
|
||||
if (aos_status_is_ok(s)) {
|
||||
res = apr_file_rename(from_path, to_path, pool);
|
||||
} else {
|
||||
res = apr_file_remove(from_path, pool);
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
298
include/oss_sdk/oss_util.h
Normal file
298
include/oss_sdk/oss_util.h
Normal file
@@ -0,0 +1,298 @@
|
||||
#ifndef LIBOSS_UTIL_H
|
||||
#define LIBOSS_UTIL_H
|
||||
|
||||
#include "aos_string.h"
|
||||
#include "aos_transport.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_define.h"
|
||||
#include "oss_resumable.h"
|
||||
|
||||
OSS_CPP_START
|
||||
|
||||
#define init_sts_token_header() do { \
|
||||
if (options->config->sts_token.data != NULL) {\
|
||||
apr_table_set(headers, OSS_STS_SECURITY_TOKEN, options->config->sts_token.data);\
|
||||
}\
|
||||
} while(0)
|
||||
|
||||
/**
|
||||
* @brief check hostname ends with specific oss domain suffix.
|
||||
**/
|
||||
int is_oss_domain(const aos_string_t *str);
|
||||
|
||||
/**
|
||||
* @brief check hostname is ip.
|
||||
**/
|
||||
int is_valid_ip(const char *str);
|
||||
|
||||
/**
|
||||
* @brief get oss acl str according oss_acl
|
||||
* @param[in] oss_acl the oss bucket acl
|
||||
* @return oss acl str
|
||||
**/
|
||||
const char *get_oss_acl_str(oss_acl_e oss_acl);
|
||||
|
||||
/**
|
||||
* @brief create oss config including host, port, access_key_id, access_key_secret, is_oss_domain
|
||||
**/
|
||||
oss_config_t *oss_config_create(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief evaluate config to curl
|
||||
**/
|
||||
void oss_config_resolve(aos_pool_t *pool, oss_config_t *config, aos_http_controller_t *ctl);
|
||||
|
||||
/**
|
||||
* @brief create oss request options
|
||||
* @return oss request options
|
||||
**/
|
||||
oss_request_options_t *oss_request_options_create(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief init oss request
|
||||
**/
|
||||
void oss_init_request(const oss_request_options_t *options, http_method_e method,
|
||||
aos_http_request_t **req, aos_table_t *params, aos_table_t *headers, aos_http_response_t **resp);
|
||||
|
||||
/**
|
||||
* @brief init oss bucket request
|
||||
**/
|
||||
void oss_init_bucket_request(const oss_request_options_t *options, const aos_string_t *bucket,
|
||||
http_method_e method, aos_http_request_t **req, aos_table_t *params, aos_table_t *headers,
|
||||
aos_http_response_t **resp);
|
||||
|
||||
/**
|
||||
* @brief init oss object request
|
||||
**/
|
||||
void oss_init_object_request(const oss_request_options_t *options, const aos_string_t *bucket,
|
||||
const aos_string_t *object, http_method_e method, aos_http_request_t **req,
|
||||
aos_table_t *params, aos_table_t *headers, oss_progress_callback cb, uint64_t initcrc,
|
||||
aos_http_response_t **resp);
|
||||
|
||||
/**
|
||||
* @brief init oss live channel request
|
||||
**/
|
||||
void oss_init_live_channel_request(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket, const aos_string_t *live_channel,
|
||||
http_method_e method, aos_http_request_t **req, aos_table_t *params,
|
||||
aos_table_t *headers, aos_http_response_t **resp);
|
||||
|
||||
/**
|
||||
* @brief init oss request with signed_url
|
||||
**/
|
||||
void oss_init_signed_url_request(const oss_request_options_t *options, const aos_string_t *signed_url,
|
||||
http_method_e method, aos_http_request_t **req,
|
||||
aos_table_t *params, aos_table_t *headers, aos_http_response_t **resp);
|
||||
|
||||
/**
|
||||
* @brief oss send request
|
||||
**/
|
||||
aos_status_t *oss_send_request(aos_http_controller_t *ctl, aos_http_request_t *req,
|
||||
aos_http_response_t *resp);
|
||||
|
||||
/**
|
||||
* @brief process oss request including sign request, send request, get response
|
||||
**/
|
||||
aos_status_t *oss_process_request(const oss_request_options_t *options,
|
||||
aos_http_request_t *req, aos_http_response_t *resp);
|
||||
|
||||
/**
|
||||
* @brief process oss request with signed_url including send request, get response
|
||||
**/
|
||||
aos_status_t *oss_process_signed_request(const oss_request_options_t *options,
|
||||
aos_http_request_t *req, aos_http_response_t *resp);
|
||||
|
||||
/**
|
||||
* @brief get object uri using third-level domain if hostname is oss domain, otherwise second-level domain
|
||||
**/
|
||||
void oss_get_object_uri(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *object,
|
||||
aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief bucket uri using third-level domain if hostname is oss domain, otherwise second-level domain
|
||||
**/
|
||||
void oss_get_bucket_uri(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief get rtmp uri using third-level domain if hostname is oss domain, otherwise second-level domain
|
||||
**/
|
||||
void oss_get_rtmp_uri(const oss_request_options_t *options,
|
||||
const aos_string_t *bucket,
|
||||
const aos_string_t *live_channel_id,
|
||||
aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief write body content into oss request body from buffer
|
||||
**/
|
||||
void oss_write_request_body_from_buffer(aos_list_t *buffer, aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief write body content into oss request body from file
|
||||
**/
|
||||
int oss_write_request_body_from_file(aos_pool_t *p, const aos_string_t *filename, aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief write body content into oss request body from multipart upload file
|
||||
**/
|
||||
int oss_write_request_body_from_upload_file(aos_pool_t *p, oss_upload_file_t *upload_file, aos_http_request_t *req);
|
||||
|
||||
/**
|
||||
* @brief read body content from oss response body to buffer
|
||||
**/
|
||||
void oss_fill_read_response_body(aos_http_response_t *resp, aos_list_t *buffer);
|
||||
|
||||
/**
|
||||
* @brief read body content from oss response body to file
|
||||
**/
|
||||
int oss_init_read_response_body_to_file(aos_pool_t *p, const aos_string_t *filename, aos_http_response_t *resp);
|
||||
|
||||
/**
|
||||
* @brief read body content from oss response body to file buffer
|
||||
**/
|
||||
int oss_init_read_response_body_to_fb(aos_file_buf_t *fb, const aos_string_t *filename, aos_http_response_t *resp);
|
||||
|
||||
/**
|
||||
* @brief read response header if headers is not null
|
||||
**/
|
||||
void oss_fill_read_response_header(aos_http_response_t *resp, aos_table_t **headers);
|
||||
|
||||
/**
|
||||
* @brief create oss api result content
|
||||
* @return oss api result content
|
||||
**/
|
||||
void *oss_create_api_result_content(aos_pool_t *p, size_t size);
|
||||
oss_list_object_content_t *oss_create_list_object_content(aos_pool_t *p);
|
||||
oss_list_object_common_prefix_t *oss_create_list_object_common_prefix(aos_pool_t *p);
|
||||
oss_list_part_content_t *oss_create_list_part_content(aos_pool_t *p);
|
||||
oss_list_multipart_upload_content_t *oss_create_list_multipart_upload_content(aos_pool_t *p);
|
||||
oss_complete_part_content_t *oss_create_complete_part_content(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss api list parameters
|
||||
* @return oss api list parameters
|
||||
**/
|
||||
oss_list_object_params_t *oss_create_list_object_params(aos_pool_t *p);
|
||||
oss_list_upload_part_params_t *oss_create_list_upload_part_params(aos_pool_t *p);
|
||||
oss_list_multipart_upload_params_t *oss_create_list_multipart_upload_params(aos_pool_t *p);
|
||||
oss_list_live_channel_params_t *oss_create_list_live_channel_params(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create upload part copy params
|
||||
* @return upload part copy params struct for upload part copy
|
||||
**/
|
||||
oss_upload_part_copy_params_t *oss_create_upload_part_copy_params(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create upload file struct for range multipart upload
|
||||
* @return upload file struct for range multipart upload
|
||||
**/
|
||||
oss_upload_file_t *oss_create_upload_file(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create lifecycle rule content
|
||||
* @return lifecycle rule content
|
||||
**/
|
||||
oss_lifecycle_rule_content_t *oss_create_lifecycle_rule_content(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss object content for delete objects
|
||||
* @return oss object content
|
||||
**/
|
||||
oss_object_key_t *oss_create_oss_object_key(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss live channel publish url content for delete objects
|
||||
* @return oss live channel publish url content
|
||||
**/
|
||||
oss_live_channel_publish_url_t *oss_create_live_channel_publish_url(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss live channel play url content for delete objects
|
||||
* @return oss live channel play url content
|
||||
**/
|
||||
oss_live_channel_play_url_t *oss_create_live_channel_play_url(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss list live channel content for delete objects
|
||||
* @return oss list live channel content
|
||||
**/
|
||||
oss_live_channel_content_t *oss_create_list_live_channel_content(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss live recored content for delete objects
|
||||
* @return oss live record content
|
||||
**/
|
||||
oss_live_record_content_t *oss_create_live_record_content(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create live channel configuration content
|
||||
* @return live channel configuration content
|
||||
**/
|
||||
oss_live_channel_configuration_t *oss_create_live_channel_configuration_content(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss checkpoint content
|
||||
* @return oss checkpoint content
|
||||
**/
|
||||
oss_checkpoint_t *oss_create_checkpoint_content(aos_pool_t *p);
|
||||
|
||||
/**
|
||||
* @brief create oss resumable clt params content
|
||||
* @return oss checkpoint content
|
||||
**/
|
||||
oss_resumable_clt_params_t *oss_create_resumable_clt_params_content(aos_pool_t *p, int64_t part_size, int32_t thread_num,
|
||||
int enable_checkpoint, const char *checkpoint_path);
|
||||
|
||||
/**
|
||||
* @brief get part size for multipart upload
|
||||
**/
|
||||
void oss_get_part_size(int64_t filesize, int64_t *part_size);
|
||||
|
||||
/**
|
||||
* @brief compare function for part sort
|
||||
**/
|
||||
int part_sort_cmp(const void *a, const void *b);
|
||||
|
||||
|
||||
/**
|
||||
* @brief add range in http request
|
||||
**/
|
||||
void oss_headers_add_range(apr_pool_t *pool, apr_table_t *headers, int64_t offset, int64_t size);
|
||||
|
||||
/**
|
||||
* @brief set content type for object according to objectname
|
||||
* @return oss content type
|
||||
**/
|
||||
char *get_content_type(const char *name);
|
||||
char *get_content_type_by_suffix(const char *suffix);
|
||||
|
||||
/**
|
||||
* @brief set content type for object according to filename
|
||||
**/
|
||||
void set_content_type(const char* filename, const char* key, aos_table_t *headers);
|
||||
|
||||
aos_table_t* aos_table_create_if_null(const oss_request_options_t *options,
|
||||
aos_table_t *table, int table_size);
|
||||
|
||||
int is_enable_crc(const oss_request_options_t *options);
|
||||
|
||||
int has_crc_in_response(const aos_http_response_t *resp);
|
||||
|
||||
int has_range_or_process_in_request(const aos_http_request_t *req) ;
|
||||
|
||||
/**
|
||||
* @brief check crc consistent between client and server
|
||||
**/
|
||||
int oss_check_crc_consistent(uint64_t crc, const apr_table_t *resp_headers, aos_status_t *s);
|
||||
|
||||
int oss_get_temporary_file_name(aos_pool_t *p, const aos_string_t *filename, aos_string_t *temp_file_name);
|
||||
|
||||
int oss_temp_file_rename(aos_status_t *s, const char *from_path, const char *to_path, apr_pool_t *pool);
|
||||
|
||||
OSS_CPP_END
|
||||
|
||||
#endif
|
||||
1457
include/oss_sdk/oss_xml.c
Normal file
1457
include/oss_sdk/oss_xml.c
Normal file
File diff suppressed because it is too large
Load Diff
188
include/oss_sdk/oss_xml.h
Normal file
188
include/oss_sdk/oss_xml.h
Normal file
@@ -0,0 +1,188 @@
|
||||
#ifndef LIBOSS_XML_H
|
||||
#define LIBOSS_XML_H
|
||||
|
||||
#include <mxml.h>
|
||||
#include "aos_string.h"
|
||||
#include "aos_transport.h"
|
||||
#include "aos_status.h"
|
||||
#include "oss_define.h"
|
||||
#include "oss_resumable.h"
|
||||
|
||||
OSS_CPP_START
|
||||
|
||||
/**
|
||||
* @brief functions for xml body parse
|
||||
**/
|
||||
int get_xmldoc(aos_list_t *bc, mxml_node_t **root);
|
||||
char *get_xmlnode_value(aos_pool_t *p, mxml_node_t * root, const char *xml_path);
|
||||
|
||||
/**
|
||||
* @brief build xml body for complete_multipart_upload
|
||||
**/
|
||||
char *build_complete_multipart_upload_xml(aos_pool_t *p, aos_list_t *bc);
|
||||
|
||||
/**
|
||||
* @brief build body for complete multipart upload
|
||||
**/
|
||||
void build_complete_multipart_upload_body(aos_pool_t *p, aos_list_t *part_list, aos_list_t *body);
|
||||
|
||||
/**
|
||||
* @brief build xml body for put lifecycle
|
||||
**/
|
||||
char *build_lifecycle_xml(aos_pool_t *p, aos_list_t *lifecycle_rule_list);
|
||||
|
||||
/**
|
||||
* @brief build body for put lifecycle
|
||||
**/
|
||||
void build_lifecycle_body(aos_pool_t *p, aos_list_t *lifecycle_rule_list, aos_list_t *body);
|
||||
|
||||
/**
|
||||
* @brief build xml body for delete objects
|
||||
**/
|
||||
char *build_objects_xml(aos_pool_t *p, aos_list_t *object_list, const char *quiet);
|
||||
|
||||
/**
|
||||
* @brief build body for delete objects
|
||||
**/
|
||||
void build_delete_objects_body(aos_pool_t *p, aos_list_t *object_list, int is_quiet,
|
||||
aos_list_t *body);
|
||||
|
||||
mxml_node_t *set_xmlnode_value_str(mxml_node_t *parent, const char *name, const aos_string_t *value);
|
||||
mxml_node_t *set_xmlnode_value_int(mxml_node_t *parent, const char *name, int value);
|
||||
mxml_node_t *set_xmlnode_value_int64(mxml_node_t *parent, const char *name, int64_t value);
|
||||
mxml_node_t *set_xmlnode_value_uint64(mxml_node_t *parent, const char *name, uint64_t value);
|
||||
|
||||
int get_xmlnode_value_str(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, aos_string_t *value);
|
||||
int get_xmlnode_value_int(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, int *value);
|
||||
int get_xmlnode_value_int64(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, int64_t *value);
|
||||
int get_xmlnode_value_uint64(aos_pool_t *p, mxml_node_t *xml_node, const char *xml_path, uint64_t *value);
|
||||
|
||||
/**
|
||||
* @brief build xml for checkpoint
|
||||
**/
|
||||
char *oss_build_checkpoint_xml(aos_pool_t *p, const oss_checkpoint_t *checkpoint);
|
||||
|
||||
/**
|
||||
* @bried parse checkpoint from xml
|
||||
**/
|
||||
int oss_checkpoint_parse_from_body(aos_pool_t *p, const char *xml_body, oss_checkpoint_t *checkpoint);
|
||||
|
||||
/**
|
||||
* @bried parse acl from xml body for get_bucket_acl
|
||||
**/
|
||||
int oss_acl_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_string_t *oss_acl);
|
||||
|
||||
/**
|
||||
* @brief parse upload_id from xml body for init multipart upload
|
||||
**/
|
||||
int oss_upload_id_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_string_t *upload_id);
|
||||
|
||||
/**
|
||||
* @brief parse objects from xml body for list objects
|
||||
**/
|
||||
void oss_list_objects_owner_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_object_content_t *content);
|
||||
void oss_list_objects_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_object_content_t *content);
|
||||
void oss_list_objects_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *object_list);
|
||||
void oss_list_objects_prefix_parse(aos_pool_t *p, mxml_node_t *root,
|
||||
oss_list_object_common_prefix_t *common_prefix);
|
||||
void oss_list_objects_common_prefix_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *common_prefix_list);
|
||||
int oss_list_objects_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *object_list,
|
||||
aos_list_t *common_prefix_list, aos_string_t *marker, int *truncated);
|
||||
|
||||
/**
|
||||
* @brief parse parts from xml body for list upload part
|
||||
**/
|
||||
void oss_list_parts_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *part_list);
|
||||
void oss_list_parts_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_list_part_content_t *content);
|
||||
int oss_list_parts_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *part_list,
|
||||
aos_string_t *part_number_marker, int *truncated);
|
||||
|
||||
/**
|
||||
* @brief parse uploads from xml body for list multipart upload
|
||||
**/
|
||||
void oss_list_multipart_uploads_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *upload_list);
|
||||
void oss_list_multipart_uploads_content_parse(aos_pool_t *p, mxml_node_t *xml_node,
|
||||
oss_list_multipart_upload_content_t *content);
|
||||
int oss_list_multipart_uploads_parse_from_body(aos_pool_t *p, aos_list_t *bc,
|
||||
aos_list_t *upload_list, aos_string_t *key_marker,
|
||||
aos_string_t *upload_id_marker, int *truncated);
|
||||
|
||||
/**
|
||||
* @brief parse lifecycle rules from xml body
|
||||
**/
|
||||
void oss_lifecycle_rule_expire_parse(aos_pool_t *p, mxml_node_t *xml_node,
|
||||
oss_lifecycle_rule_content_t *content);
|
||||
void oss_lifecycle_rule_content_parse(aos_pool_t *p, mxml_node_t *xml_node,
|
||||
oss_lifecycle_rule_content_t *content);
|
||||
void oss_lifecycle_rule_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *lifecycle_rule_list);
|
||||
int oss_lifecycle_rules_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *lifecycle_rule_list);
|
||||
|
||||
/**
|
||||
* @brief parse delete objects contents from xml body
|
||||
**/
|
||||
void oss_delete_objects_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *object_list);
|
||||
void oss_object_key_parse(aos_pool_t *p, mxml_node_t * xml_node, oss_object_key_t *content);
|
||||
int oss_delete_objects_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *object_list);
|
||||
|
||||
/**
|
||||
* @brief build body for create live channel
|
||||
**/
|
||||
char *build_create_live_channel_xml(aos_pool_t *p, oss_live_channel_configuration_t *config);
|
||||
void build_create_live_channel_body(aos_pool_t *p, oss_live_channel_configuration_t *config, aos_list_t *body);
|
||||
|
||||
/**
|
||||
* @brief parse create live channel contents from xml body
|
||||
**/
|
||||
void oss_publish_url_parse(aos_pool_t *p, mxml_node_t *node, oss_live_channel_publish_url_t *content);
|
||||
void oss_play_url_parse(aos_pool_t *p, mxml_node_t *node, oss_live_channel_play_url_t *content);
|
||||
void oss_publish_urls_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *publish_xml_list);
|
||||
void oss_play_urls_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *play_xml_list);
|
||||
void oss_create_live_channel_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *publish_xml_path,
|
||||
aos_list_t *publish_url_list, const char *play_xml_path, aos_list_t *play_url_list);
|
||||
int oss_create_live_channel_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *publish_url_list,
|
||||
aos_list_t *play_url_list);
|
||||
|
||||
/**
|
||||
* @brief parse live channel info content from xml body
|
||||
**/
|
||||
void oss_live_channel_info_target_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_live_channel_target_t *target);
|
||||
void oss_live_channel_info_content_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
oss_live_channel_configuration_t *info);
|
||||
int oss_live_channel_info_parse_from_body(aos_pool_t *p, aos_list_t *bc, oss_live_channel_configuration_t *info);
|
||||
|
||||
/**
|
||||
* @brief parse live channel stat content from xml body
|
||||
**/
|
||||
void oss_live_channel_stat_video_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_video_stat_t *video_stat);
|
||||
void oss_live_channel_stat_audio_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_audio_stat_t *audio_stat);
|
||||
void oss_live_channel_stat_content_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path, oss_live_channel_stat_t *stat);
|
||||
int oss_live_channel_stat_parse_from_body(aos_pool_t *p, aos_list_t *bc, oss_live_channel_stat_t *stat);
|
||||
|
||||
/**
|
||||
* @brief parse live channel from xml body for list list channel
|
||||
**/
|
||||
void oss_list_live_channel_content_parse(aos_pool_t *p, mxml_node_t *xml_node, oss_live_channel_content_t *content);
|
||||
void oss_list_live_channel_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *live_channel_list);
|
||||
int oss_list_live_channel_parse_from_body(aos_pool_t *p, aos_list_t *bc,
|
||||
aos_list_t *live_channel_list, aos_string_t *next_marker, int *truncated);
|
||||
|
||||
/**
|
||||
* @brief parse live channel history content from xml body
|
||||
**/
|
||||
void oss_live_channel_history_content_parse(aos_pool_t *p, mxml_node_t * xml_node, oss_live_record_content_t *content);
|
||||
void oss_live_channel_history_contents_parse(aos_pool_t *p, mxml_node_t *root, const char *xml_path,
|
||||
aos_list_t *live_record_list);
|
||||
int oss_live_channel_history_parse_from_body(aos_pool_t *p, aos_list_t *bc, aos_list_t *live_record_list);
|
||||
|
||||
OSS_CPP_END
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user