2018-09-18 11:14:11 +08:00
|
|
|
|
#include <sys/types.h>
|
|
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
#include <sys/time.h>
|
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
#include <string.h>
|
|
|
|
|
|
#include <curl/curl.h>
|
|
|
|
|
|
|
|
|
|
|
|
#include "tango_cache_transfer.h"
|
|
|
|
|
|
#include "tango_cache_xml.h"
|
|
|
|
|
|
#include "tango_cache_tools.h"
|
|
|
|
|
|
|
|
|
|
|
|
//response body<64>̻ܶ<CCBB><F2B2BBB9><EFBFBD>ʱ
|
|
|
|
|
|
size_t curl_response_any_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
|
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t curl_put_multipart_header_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)userp;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
size_t totallen = size*count;
|
|
|
|
|
|
char *start = (char *)ptr, *end = start + totallen;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
struct multipart_etag_list *etag;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(!strncmp(start, "Etag:", totallen>5?5:totallen))
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
start += 5; end -= 1; totallen -= 5;
|
|
|
|
|
|
while(totallen>0 && (*start==' ')) {start++; totallen--;}
|
|
|
|
|
|
while(totallen>0 && (*end=='\r'||*end=='\n')) {end--; totallen--;}
|
|
|
|
|
|
if(totallen > 0)
|
|
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
etag = (struct multipart_etag_list *)malloc(sizeof(struct multipart_etag_list));
|
2018-09-18 11:14:11 +08:00
|
|
|
|
totallen = end - start + 1;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
etag->etag = (char *)malloc(totallen + 1);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
etag->part_number = ctx->put.part_index;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
memcpy(etag->etag, start, totallen);
|
|
|
|
|
|
*(etag->etag + totallen) = '\0';
|
2018-09-27 15:04:56 +08:00
|
|
|
|
TAILQ_INSERT_TAIL(&ctx->put.etag_head, etag, node);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t curl_put_once_send_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
|
|
|
|
|
size_t len;
|
|
|
|
|
|
struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)userp;
|
|
|
|
|
|
|
|
|
|
|
|
if(size==0 || count==0 || ctx->response.len>=ctx->response.size)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0; //<2F><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
len = ctx->response.size - ctx->response.len; //ʣ<><CAA3><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD><CFB4>ij<EFBFBD><C4B3><EFBFBD>
|
|
|
|
|
|
if(len > size * count)
|
|
|
|
|
|
{
|
|
|
|
|
|
len = size * count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
memcpy(ptr, ctx->response.buff + ctx->response.len, len);
|
|
|
|
|
|
ctx->response.len += len;
|
|
|
|
|
|
|
|
|
|
|
|
if(ctx->response.len >= ctx->response.size)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->instance->statistic.memory_used -= ctx->response.size; //δʹ<CEB4><CAB9>cache buffer<65><72><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><DAB4><EFBFBD><EFBFBD><EFBFBD>
|
2018-09-21 14:50:41 +08:00
|
|
|
|
easy_string_destroy(&ctx->response);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
return len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t curl_put_multipart_send_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
size_t len, space=size*count, send_len;
|
|
|
|
|
|
struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)userp;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(size==0 || count==0 || ctx->put.upload_offset>=ctx->put.upload_length)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
len = ctx->put.upload_length - ctx->put.upload_offset;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(len > space)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
len = space;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
send_len = evbuffer_remove(ctx->put.evbuf, ptr, len);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
assert(send_len>0);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.upload_offset += send_len;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
ctx->instance->statistic.memory_used -= send_len;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-23 15:35:13 +08:00
|
|
|
|
return send_len;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//return value: <0:fail; =0: not exec; >0: OK
|
2018-09-21 14:50:41 +08:00
|
|
|
|
static int http_put_bodypart_request_evbuf(struct tango_cache_ctx *ctx, bool full)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.upload_offset = 0;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(full)
|
|
|
|
|
|
{
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s?partNumber=%d&uploadId=%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key, ++ctx->put.part_index, ctx->put.uploadID);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HEADERFUNCTION, curl_put_multipart_header_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HEADERDATA, ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L);
|
2018-09-23 15:35:13 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_UPLOAD, 1L);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_INFILESIZE, ctx->put.upload_length);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_READFUNCTION, curl_put_multipart_send_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_READDATA, ctx);
|
|
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
assert(rc==CURLM_OK);
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t curl_write_uploadID_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)userp;
|
|
|
|
|
|
struct easy_string *estr = &ctx->response;
|
|
|
|
|
|
CURLcode code;
|
|
|
|
|
|
|
|
|
|
|
|
if(ctx->fail_state)
|
|
|
|
|
|
{
|
|
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(ctx->res_code == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
code = curl_easy_getinfo(ctx->curl, CURLINFO_RESPONSE_CODE, &ctx->res_code);
|
|
|
|
|
|
if(code != CURLE_OK || ctx->res_code!=200L)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(code != CURLE_OK) MESA_HANDLE_RUNTIME_LOGV2(ctx->instance->runtime_log, RLOG_LV_DEBUG, "%s", ctx->error);
|
|
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-09-21 14:50:41 +08:00
|
|
|
|
|
|
|
|
|
|
easy_string_savedata(estr, (const char*)ptr, size*count);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int curl_get_minio_uploadID(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
|
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
|
|
|
|
|
{
|
|
|
|
|
|
free(ctx);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s?uploads", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_POST, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL,1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_write_uploadID_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L);
|
2018-09-23 15:35:13 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
|
|
|
|
|
assert(rc==CURLM_OK);
|
|
|
|
|
|
return 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
int cache_delete_minio_object(struct tango_cache_ctx *ctx)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
2018-09-29 11:28:09 +08:00
|
|
|
|
ctx->instance->statistic.del_recv_num += 1;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
return 0;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
|
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
|
|
|
|
|
assert(rc==CURLM_OK);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
return 1;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//return value: true-<2D>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>false-δ<><CEB4><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
|
|
|
|
|
bool cache_cancel_upload_minio(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
|
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s?uploadId=%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key, ctx->put.uploadID);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CUSTOMREQUEST, "DELETE");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
|
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
|
|
|
|
|
assert(rc==CURLM_OK);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//return value: true-<2D>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>false-δ<><CEB4><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
|
|
|
|
|
bool cache_kick_combine_minio(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
int len=0;
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
|
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
|
|
|
|
|
{
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
construct_complete_xml(ctx, &ctx->put.combine_xml, &len);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s?uploadId=%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key, ctx->put.uploadID);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_POST, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL,1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDS, ctx->put.combine_xml);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_POSTFIELDSIZE, len); //<2F><><EFBFBD><EFBFBD>Content-Length
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(ctx->headers != NULL)
|
|
|
|
|
|
{
|
|
|
|
|
|
curl_slist_free_all(ctx->headers);
|
|
|
|
|
|
ctx->headers = NULL;
|
|
|
|
|
|
}
|
2018-09-18 11:14:11 +08:00
|
|
|
|
ctx->headers = curl_slist_append(ctx->headers, "Content-Type: application/xml");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers);
|
|
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
|
|
|
|
|
assert(rc==CURLM_OK);
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//return value: true-<2D>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>false-δ<><CEB4><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD>
|
2018-09-21 14:50:41 +08:00
|
|
|
|
bool cache_kick_upload_minio_multipart(struct tango_cache_ctx *ctx, size_t block_len)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
int ret = 1;
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
switch(ctx->put.state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
case PUT_STATE_START:
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_WAIT_START;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
ret = curl_get_minio_uploadID(ctx);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case PUT_STATE_PART:
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(ctx->curl == NULL)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.upload_length = block_len;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
ret = http_put_bodypart_request_evbuf(ctx, false);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
default: break;//nothing to do
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if(ret <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
|
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
int http_put_complete_part_evbuf(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ret=0;
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_END;
|
|
|
|
|
|
ctx->put.upload_length = evbuffer_get_length(ctx->put.evbuf);
|
|
|
|
|
|
if(ctx->put.upload_length > 0)
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
ret = http_put_bodypart_request_evbuf(ctx, true);
|
|
|
|
|
|
if(ret <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-18 11:14:11 +08:00
|
|
|
|
int cache_kick_upload_minio_end(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
int ret = 0;
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.close_state = true;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>رգ<D8B1><D5A3>ڲ<EFBFBD>״̬<D7B4><CCAC><EFBFBD><EFBFBD>ת<EFBFBD><D7AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٹر<D9B9>
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(ctx->fail_state)
|
|
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
switch(ctx->put.state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
case PUT_STATE_START:
|
2018-09-21 14:50:41 +08:00
|
|
|
|
http_put_complete_part_evbuf(ctx);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
break;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
|
2018-09-18 11:14:11 +08:00
|
|
|
|
case PUT_STATE_PART:
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(ctx->curl == NULL)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.upload_length = evbuffer_get_length(ctx->put.evbuf);
|
|
|
|
|
|
if(ctx->put.upload_length == 0)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
if(cache_kick_combine_minio(ctx))
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_END;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
2018-09-21 14:50:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ret = http_put_bodypart_request_evbuf(ctx, false);
|
|
|
|
|
|
if(ret <= 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(cache_cancel_upload_minio(ctx))
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_CANCEL;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case PUT_STATE_END: assert(0); //<2F>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>endʱ<64><CAB1><EFBFBD><EFBFBD><EFBFBD>ܴ<EFBFBD><DCB4>ڴ<EFBFBD>״̬
|
|
|
|
|
|
case PUT_STATE_WAIT_START: //<2F><>ʱδ<CAB1><CEB4>ȡ<EFBFBD><C8A1>uploadId<49><64><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><DEB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ϴ<EFBFBD>
|
|
|
|
|
|
default: break;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
void tango_cache_curl_put_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
switch(ctx->put.state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
case PUT_STATE_WAIT_START:
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(res!=CURLE_OK||res_code!=200L|| ctx->fail_state || !parse_uploadID_xml(ctx->response.buff, ctx->response.len, &ctx->put.uploadID))
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
easy_string_destroy(&ctx->response);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
|
|
|
|
|
ctx->fail_state = true;
|
|
|
|
|
|
if(res != CURLE_OK) MESA_HANDLE_RUNTIME_LOGV2(ctx->instance->runtime_log, RLOG_LV_DEBUG, "%s", ctx->error);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->put.close_state)
|
2018-09-23 18:13:46 +08:00
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
easy_string_destroy(&ctx->response);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_PART;
|
|
|
|
|
|
if(ctx->put.close_state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
cache_kick_upload_minio_end(ctx);
|
|
|
|
|
|
}
|
2018-09-21 14:50:41 +08:00
|
|
|
|
else
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
size_t upload_length = evbuffer_get_length(ctx->put.evbuf);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(upload_length >= ctx->instance->upload_block_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
cache_kick_upload_minio_multipart(ctx, upload_length);
|
|
|
|
|
|
}
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case PUT_STATE_PART:
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(res != CURLE_OK || res_code!=200L)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(res != CURLE_OK) MESA_HANDLE_RUNTIME_LOGV2(ctx->instance->runtime_log, RLOG_LV_DEBUG, "%s", ctx->error);
|
|
|
|
|
|
}
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(ctx->fail_state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(cache_cancel_upload_minio(ctx))
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_CANCEL;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
else if(ctx->put.close_state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
else if(ctx->put.close_state)
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
cache_kick_upload_minio_end(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
size_t upload_length = evbuffer_get_length(ctx->put.evbuf);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(upload_length >= ctx->instance->upload_block_size)
|
|
|
|
|
|
{
|
|
|
|
|
|
cache_kick_upload_minio_multipart(ctx, upload_length);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2018-09-18 11:14:11 +08:00
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case PUT_STATE_CANCEL: //<2F>ȴ<EFBFBD><C8B4>ر<EFBFBD>
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->put.close_state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case PUT_STATE_END:
|
|
|
|
|
|
if(res != CURLE_OK || res_code!=200L)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(res != CURLE_OK) MESA_HANDLE_RUNTIME_LOGV2(ctx->instance->runtime_log, RLOG_LV_DEBUG, "%s", ctx->error);
|
|
|
|
|
|
}
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default: break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
int tango_cache_upload_once_start_data(struct tango_cache_ctx *ctx, enum PUT_MEMORY_COPY_WAY way, const char *data, size_t size)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
2018-09-29 11:28:09 +08:00
|
|
|
|
ctx->instance->statistic.put_recv_num += 1;
|
|
|
|
|
|
ctx->instance->error_code = CACHE_OK;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
|
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(way == PUT_MEM_FREE)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
free((void *)data);
|
|
|
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->put.state = PUT_STATE_END;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_response_any_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HTTPHEADER, ctx->headers);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L);
|
2018-09-23 15:35:13 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(way == PUT_MEM_COPY)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
ctx->response.buff = (char *)malloc(size);
|
|
|
|
|
|
memcpy(ctx->response.buff, data, size);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->response.buff = (char *)data;
|
|
|
|
|
|
}
|
|
|
|
|
|
ctx->response.size = size;
|
|
|
|
|
|
ctx->response.len = 0;
|
|
|
|
|
|
ctx->instance->statistic.memory_used += size;
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_UPLOAD, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_INFILESIZE, ctx->response.size);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_READFUNCTION, curl_put_once_send_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_READDATA, ctx);
|
|
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
|
|
|
|
|
assert(rc==CURLM_OK);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
int tango_cache_upload_once_start_evbuf(struct tango_cache_ctx *ctx, enum EVBUFFER_COPY_WAY way, struct evbuffer *evbuf)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
size_t size;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-29 11:28:09 +08:00
|
|
|
|
ctx->instance->statistic.put_recv_num += 1;
|
|
|
|
|
|
ctx->instance->error_code = CACHE_OK;
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
size = evbuffer_get_length(evbuf);
|
|
|
|
|
|
if(way == EVBUFFER_MOVE)
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(evbuffer_add_buffer(ctx->put.evbuf, evbuf))
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(evbuffer_add_buffer_reference(ctx->put.evbuf, evbuf))
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
ctx->instance->statistic.memory_used += size;
|
|
|
|
|
|
|
|
|
|
|
|
return http_put_complete_part_evbuf(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
void tango_cache_curl_del_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code)
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(res!=CURLE_OK || (res_code!=204L && res_code!=200L ))
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void tango_cache_curl_get_done(struct tango_cache_ctx *ctx, CURLcode res, long res_code)
|
|
|
|
|
|
{
|
|
|
|
|
|
switch(ctx->get.state)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
case GET_STATE_START:
|
|
|
|
|
|
if(!ctx->fail_state)
|
|
|
|
|
|
{
|
|
|
|
|
|
if(res!=CURLE_OK || res_code!=200L)
|
|
|
|
|
|
{
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = (res!=CURLE_OK)?CACHE_ERR_CURL:CACHE_CACHE_MISS;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
promise_failed(future_to_promise(ctx->future), FUTURE_ERROR_CANCEL, ctx->error);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
promise_success(future_to_promise(ctx->future), NULL);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case GET_STATE_DELETE:
|
|
|
|
|
|
if(cache_delete_minio_object(ctx))
|
|
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->get.state = GET_STATE_END;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
case GET_STATE_END:
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default: assert(0);break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static size_t curl_get_response_body_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)userp;
|
|
|
|
|
|
struct tango_cache_result result;
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->fail_state || ctx->get.state==GET_STATE_DELETE)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->get.need_hdrs!=RESPONSE_HDR_ALL) //<2F><>Expiresʱ
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = CACHE_ERR_CURL;
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->get.state = GET_STATE_DELETE;
|
|
|
|
|
|
promise_failed(future_to_promise(ctx->future), FUTURE_ERROR_CANCEL, "cache Expires or x-amz-meta-lm not found");
|
2018-09-23 18:13:46 +08:00
|
|
|
|
return size*count;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-23 18:13:46 +08:00
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->get.response_tag.len > 0)
|
2018-09-23 18:13:46 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
result.data_frag = ctx->get.response_tag.buff;
|
|
|
|
|
|
result.size = ctx->get.response_tag.len;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
result.type = RESULT_TYPE_USERTAG;
|
|
|
|
|
|
promise_success(future_to_promise(ctx->future), &result);
|
2018-09-27 15:04:56 +08:00
|
|
|
|
easy_string_destroy(&ctx->get.response_tag);
|
2018-09-23 18:13:46 +08:00
|
|
|
|
}
|
|
|
|
|
|
if(ctx->response.len > 0)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-23 18:13:46 +08:00
|
|
|
|
result.data_frag = ctx->response.buff;
|
|
|
|
|
|
result.size = ctx->response.len;
|
|
|
|
|
|
result.type = RESULT_TYPE_HEADER;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
promise_success(future_to_promise(ctx->future), &result);
|
2018-09-23 18:13:46 +08:00
|
|
|
|
easy_string_destroy(&ctx->response);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-23 18:13:46 +08:00
|
|
|
|
result.data_frag = ptr;
|
|
|
|
|
|
result.size = size * count;
|
|
|
|
|
|
result.type = RESULT_TYPE_BODY;
|
|
|
|
|
|
promise_success(future_to_promise(ctx->future), &result);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
return size*count;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-21 14:50:41 +08:00
|
|
|
|
static bool check_expires_header(struct tango_cache_ctx *ctx, const char *expires_val, size_t len)
|
|
|
|
|
|
{
|
|
|
|
|
|
time_t time_gmt;
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->get.expires = expires_hdr2timestamp(expires_val, len);
|
2018-09-21 14:50:41 +08:00
|
|
|
|
time_gmt = get_gmtime_timestamp(time(NULL));
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(time_gmt > ctx->get.expires) //<2F><><EFBFBD><EFBFBD>ʧЧ<CAA7><D0A7>TODO relative_age<67>ĺ<EFBFBD><C4BA><EFBFBD><EFBFBD><EFBFBD>ɶ
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
|
|
|
|
|
ctx->error_code = CACHE_TIMEOUT;
|
2018-09-27 15:04:56 +08:00
|
|
|
|
ctx->get.state = GET_STATE_DELETE; //<2F><><EFBFBD><EFBFBD>ʧЧʱ<D0A7><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
2018-09-21 14:50:41 +08:00
|
|
|
|
easy_string_destroy(&ctx->response);
|
|
|
|
|
|
promise_failed(future_to_promise(ctx->future), FUTURE_ERROR_CANCEL, "cache not fresh");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool check_fresh_header(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
time_t now_gmt;
|
|
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->get.need_hdrs != RESPONSE_HDR_ALL)
|
2018-09-21 14:50:41 +08:00
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
|
|
now_gmt = get_gmtime_timestamp(time(NULL));
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->get.last_modify+ctx->get.max_age > now_gmt || now_gmt+ctx->get.min_fresh>ctx->get.expires)
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
|
|
|
|
|
ctx->error_code = CACHE_TIMEOUT;
|
|
|
|
|
|
easy_string_destroy(&ctx->response);
|
|
|
|
|
|
promise_failed(future_to_promise(ctx->future), FUTURE_ERROR_CANCEL, "cache not fresh");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static bool check_get_result_code(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
CURLcode code;
|
|
|
|
|
|
|
|
|
|
|
|
code = curl_easy_getinfo(ctx->curl, CURLINFO_RESPONSE_CODE, &ctx->res_code);
|
|
|
|
|
|
if(code != CURLE_OK || ctx->res_code!=200L)
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->fail_state = true;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
ctx->error_code = (code!=CURLE_OK)?CACHE_ERR_CURL:CACHE_CACHE_MISS;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
promise_failed(future_to_promise(ctx->future), FUTURE_ERROR_CANCEL, (code!=CURLE_OK)?ctx->error:"cache not hit");
|
|
|
|
|
|
return false;
|
|
|
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-18 11:14:11 +08:00
|
|
|
|
static size_t curl_get_response_header_cb(void *ptr, size_t size, size_t count, void *userp)
|
|
|
|
|
|
{
|
|
|
|
|
|
struct tango_cache_ctx *ctx = (struct tango_cache_ctx *)userp;
|
2018-09-23 18:13:46 +08:00
|
|
|
|
char *start=(char *)ptr, *pos_colon;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
size_t raw_len = size*count, hdrlen=size*count;
|
2018-09-23 15:35:13 +08:00
|
|
|
|
char usertag[2048];
|
2018-09-27 15:04:56 +08:00
|
|
|
|
size_t datalen;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
2018-09-27 15:04:56 +08:00
|
|
|
|
if(ctx->fail_state || ctx->get.state==GET_STATE_DELETE)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
|
|
|
|
|
return raw_len;
|
|
|
|
|
|
}
|
2018-09-21 14:50:41 +08:00
|
|
|
|
if(ctx->res_code==0 && !check_get_result_code(ctx)) //<2F>״<EFBFBD>Ӧ<EFBFBD><D3A6>ʱ<EFBFBD>ȿ<EFBFBD>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>200
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-21 14:50:41 +08:00
|
|
|
|
return raw_len;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
pos_colon = (char*)memchr(start, ':', raw_len);
|
|
|
|
|
|
if(pos_colon == NULL)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
return raw_len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
datalen = pos_colon - start;
|
|
|
|
|
|
switch(datalen)
|
|
|
|
|
|
{
|
|
|
|
|
|
case 7:
|
|
|
|
|
|
if(strcmp_one_word_mesa_equal_len("expires", "EXPIRES", start, 7))
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->get.need_hdrs |= RESPONSE_HDR_EXPIRES;
|
|
|
|
|
|
if(!check_expires_header(ctx, pos_colon + 1, raw_len - datalen - 1) || !check_fresh_header(ctx))
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
return raw_len;
|
2018-09-21 14:50:41 +08:00
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 13:
|
|
|
|
|
|
if(strcmp_one_word_mesa_equal_len("x-amz-meta-lm", "X-AMZ-META-LM", start, 13))
|
|
|
|
|
|
{
|
|
|
|
|
|
ctx->get.need_hdrs |= RESPONSE_HDR_LAST_MOD;
|
|
|
|
|
|
sscanf(pos_colon+1, "%lu", &ctx->get.last_modify);
|
|
|
|
|
|
if(!check_fresh_header(ctx))
|
2018-09-21 14:50:41 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
return raw_len;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 15:
|
|
|
|
|
|
if(strcmp_one_word_mesa_equal_len("x-amz-meta-user", "X-AMZ-META-USER", start, 15))
|
|
|
|
|
|
{
|
|
|
|
|
|
if((hdrlen = Base64_DecodeBlock((unsigned char*)pos_colon+1, raw_len-datalen-1, (unsigned char*)usertag, 2048))>0)
|
2018-09-18 11:14:11 +08:00
|
|
|
|
{
|
2018-09-27 15:04:56 +08:00
|
|
|
|
easy_string_savedata(&ctx->get.response_tag, usertag, hdrlen);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
2018-09-27 15:04:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 11: if(strcmp_one_word_mesa_equal_len("content-md5", "CONTENT-MD5", start, 11)) easy_string_savedata(&ctx->response, (const char*)ptr, raw_len); break;
|
|
|
|
|
|
case 12: if(strcmp_one_word_mesa_equal_len("content-type", "CONTENT-TYPE", start, 12)) easy_string_savedata(&ctx->response, (const char*)ptr, raw_len); break;
|
|
|
|
|
|
case 14: if(strcmp_one_word_mesa_equal_len("content-length", "CONTENT-LENGTH", start, 14)) easy_string_savedata(&ctx->response, (const char*)ptr, raw_len); break;
|
|
|
|
|
|
case 16: if(strcmp_one_word_mesa_equal_len("content-encoding", "CONTENT-ENCODING", start, 16)) easy_string_savedata(&ctx->response, (const char*)ptr, raw_len); break;
|
|
|
|
|
|
case 19: if(strcmp_one_word_mesa_equal_len("content-disposition", "CONTENT-DISPOSITION", start, 19)) easy_string_savedata(&ctx->response, (const char*)ptr, raw_len); break;
|
|
|
|
|
|
default: break;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
}
|
|
|
|
|
|
return raw_len;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
int tango_cache_fetch_start(struct tango_cache_ctx *ctx)
|
|
|
|
|
|
{
|
|
|
|
|
|
CURLMcode rc;
|
|
|
|
|
|
char minio_url[256];
|
|
|
|
|
|
|
2018-09-29 11:28:09 +08:00
|
|
|
|
ctx->instance->statistic.get_recv_num += 1;
|
2018-09-18 11:14:11 +08:00
|
|
|
|
if(NULL == (ctx->curl=curl_easy_init()))
|
|
|
|
|
|
{
|
|
|
|
|
|
tango_cache_ctx_destroy(ctx);
|
|
|
|
|
|
return -1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2018-09-28 15:16:28 +08:00
|
|
|
|
snprintf(minio_url, 256, "http://%s/%s/%s", ctx->hostaddr, ctx->instance->bucketname, ctx->object_key);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_URL, minio_url);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_USERAGENT, "aws-sdk-cpp/1.5.24 Linux/3.10.0-327.el7.x86_64 x86_64 pangu_cache");
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_NOSIGNAL,1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEFUNCTION, curl_get_response_body_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_WRITEDATA, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_ERRORBUFFER, ctx->error);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_PRIVATE, ctx);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_FOLLOWLOCATION, 1L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_CONNECTTIMEOUT_MS, 500L);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HEADERFUNCTION, curl_get_response_header_cb);
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_HEADERDATA, ctx);
|
|
|
|
|
|
//ctx->error="Operation too slow. Less than 1024 bytes/sec transferred the last 3 seconds"
|
|
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_TIME, 2L);
|
2018-09-23 15:35:13 +08:00
|
|
|
|
curl_easy_setopt(ctx->curl, CURLOPT_LOW_SPEED_LIMIT, 100L);
|
2018-09-18 11:14:11 +08:00
|
|
|
|
|
|
|
|
|
|
rc = curl_multi_add_handle(ctx->instance->multi_hd, ctx->curl);
|
|
|
|
|
|
assert(rc==CURLM_OK);
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
|