我正在尝试通过使用CURL Lib的C包装器从我的Amazon S3获取图像和PDF文件,目前我可以像txt文件一样,HTTP HTML响应如错误,但是当我尝试获取PDF和JPEG文件时得到回应:
(DEBUG) Size : 90343
(DEBUG) Response : ����
我不知道奇怪的角色来自哪里,但我怀疑我需要添加CURLOPT_BINARYTRANSFER
使用CURL:
与HTTP GET函数和定义结合const char *url = "http://bucket.s3.amazonaws.com/file.pdf";
long rc;
struct buf_string response = {0};
rc = http_get(url, &response, (const char *[]){"Accept: */*", "Accept-Encoding: gzip, deflate", "User-Agent: web-service/0.1", NULL});
if (rc != 200) { /* error */ }
logprintf(ts, D_DEBUG, "Size : %d", response.pos);
logprintf(ts, D_ERROR, "Response : %s", response.buf);
long
http_get(const char *url, struct buf_string *response, const char *headers[]) {
struct http *h = http_create();
long rc;
h->method = "GET";
h->url = url;
h->headers = headers;
if (response) {
memset(response, 0, sizeof(*response));
h->response_body = response;
h->write_function = default_write_data;
}
rc = http_perform(h);
http_free(h);
return rc;
}
struct http *
http_create() {
struct http *h;
h = zmalloc(sizeof(struct http));
h->write_function = null_write_data;
h->header_write_function = null_write_data;
return h;
}
void
http_free(struct http *h) {
curl_easy_cleanup(h->ch);
free(h);
}
long
http_perform(struct http *h) {
long response_code;
struct curl_slist *header_list = NULL;
if (h->response_body && (h->write_function == NULL || h->write_function == null_write_data))
h->write_function = default_write_data;
if (h->response_header && (h->header_write_function == NULL || h->header_write_function == null_write_data))
h->header_write_function = default_write_data;
h->curl_status = CURLE_OK;
if ((h->ch = curl_easy_init()) == NULL) {
return -1;
}
curl_easy_setopt(h->ch, CURLOPT_URL, h->url);
curl_easy_setopt(h->ch, CURLOPT_CUSTOMREQUEST, h->method);
curl_easy_setopt(h->ch, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
curl_easy_setopt(h->ch, CURLOPT_FOLLOWLOCATION, 1);
curl_easy_setopt(h->ch, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
curl_easy_setopt(h->ch, CURLOPT_WRITEFUNCTION, h->write_function);
curl_easy_setopt(h->ch, CURLOPT_WRITEDATA, h->response_body);
curl_easy_setopt(h->ch, CURLOPT_HEADERFUNCTION, h->header_write_function);
curl_easy_setopt(h->ch, CURLOPT_HEADERDATA, h->response_header);
curl_easy_setopt(h->ch, CURLOPT_ERRORBUFFER, h->error);
curl_easy_setopt(h->ch, CURLOPT_NOSIGNAL, 1);
if (h->body) {
curl_easy_setopt(h->ch, CURLOPT_POSTFIELDS, (const char *) h->body);
curl_easy_setopt(h->ch, CURLOPT_POSTFIELDSIZE_LARGE, (curl_off_t)h->body_length);
}
if (h->headers) {
while (*(h->headers)) {
header_list = curl_slist_append(header_list, *h->headers++);
}
curl_easy_setopt(h->ch, CURLOPT_HTTPHEADER, header_list);
}
if (h->extra_config_function && h->extra_config_function(h->ch, h->extra_config_data) != 0) {
response_code = -1;
goto out;
}
if ((h->curl_status = curl_easy_perform(h->ch)) != CURLE_OK) {
response_code = -1;
goto out;
}
curl_easy_getinfo(h->ch, CURLINFO_RESPONSE_CODE, &response_code);
out:
curl_slist_free_all(header_list);
return response_code;
}
解决: 根据theamk的回答,我设法直接通过base64解决了问题,然后将文件传递给我的模板引擎,并且工作正常,当HTTP响应代码为200时,文件成功返回,只是printf转义它。
long rc;
struct buf_string response = {0};
rc = http_get(url, &response, (const char *[]){"Accept: */*", "Accept-Encoding: gzip, deflate", "User-Agent: micro-service/0.1", NULL});
/* If the file is not found, abort */
if (rc != 200) {
cs->error = "ATTACHMENT_FILE_NOT_FOUND";
continue;
}
/* Convert the file payload to Base64, then pass it to the email params */
int len = response.pos;
size_t sz = BASE64_NEEDED(len);
char *b64 = zmalloc(sz);
base64_encode(b64, response.buf, len);
template_parse("send_reply.tmpl", "attachment_data", b64);
free(b64);
答案 0 :(得分:1)
您正在正确获取文件,您无法将PDF和JPEG打印到屏幕上 - 您将获得您所看到的随机字符。
具体来说,您的4个字符的示例似乎来自JPEG文件 - 其中许多以ff:d8:ff:e0:00字符开头,它们将在下面打印为字符串(四个无效字符,然后是'printf'会停止打印,因为它会遇到代码为0的字符
要确保正确下载文件,请将数据保存到文件,然后使用JPEG / PDF查看器打开文件。确保在写入数据时使用fwrite()(printf()或fputs()由于嵌入的二进制零而无法工作)