#ifndef http_client_h
#define http_client_h
#include <stddef.h>
typedef size_t (*write_callback)(char *ptr, size_t size, size_t nmemb, void *userdata);
typedef size_t (*progress_callback)(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow);
int http_client_post_file(const char* url, const char* filename, write_callback w_cb, progress_callback p_cb);
int http_client_tester(int argc, char **argv);
#endif /* http_client_h */
#include "http_client.h"
#include <curl/curl.h>
#define USE_STDOUT
#ifndef USE_STDOUT
#ifdef WIN32
#include "debug.h"
#else
#include "../debug.h"
#endif
#endif
int http_client_post_file(const char* url, const char* filename, write_callback w_callback, progress_callback p_callback) {
int ret = 0;
struct curl_slist *headers = NULL;
CURL* curl = curl_easy_init();
if (curl)
{
#if 1
//set headers
//headers = curl_slist_append(headers, "Host: 192.168.110.119");
headers = curl_slist_append(headers, "Content-Type: multipart/form-data");
headers = curl_slist_append(headers, "Connection: Keep-Alive");
headers = curl_slist_append(headers, "Cache-Control: no-cache");
//set headers
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
#endif
curl_easy_setopt(curl, CURLOPT_URL, url);
if(p_callback != NULL) {
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0); //
curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, p_callback); //
}
else {
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1); //
}
/*
This callback function gets called by libcurl as soon as there is data received that needs to be saved.
*/
if(w_callback != NULL) {
curl_easy_setopt(curl, CURLOPT_WRITEDATA, NULL);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, w_callback);
}
/*
This callback function gets called by libcurl as soon as it needs to read data in order to send it to the peer - like if you ask it to upload or post data to the server.
*/
//curl_easy_setopt(curl, CURLOPT_READDATA, NULL);
//curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
//not needed
curl_easy_setopt(curl, CURLOPT_POST, 1L); //post
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L); //log
/* set the file size or it will stop if read '\0'*/
//curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, fsize);
curl_mime *multipart = curl_mime_init(curl);
curl_mimepart *part = curl_mime_addpart(multipart);
curl_mime_name(part, "name");
curl_mime_data(part, "alex", CURL_ZERO_TERMINATED);
part = curl_mime_addpart(multipart);
curl_mime_name(part, "role");
curl_mime_data(part, "bat man", CURL_ZERO_TERMINATED);
part = curl_mime_addpart(multipart);
curl_mime_name(part, "file");
curl_mime_filedata(part,filename);
/* Set the form info */
curl_easy_setopt(curl, CURLOPT_MIMEPOST, multipart);
CURLcode code = curl_easy_perform(curl);
curl_mime_free(multipart);
if (code == CURLE_OK) {
ret = 0;
}
else {
char msg[512];
sprintf(msg, "line:%d curl_easy_perform() failed: %s\n", __LINE__, curl_easy_strerror(code));
#ifdef USE_STDOUT
printf("%s", msg);
#else
JANUS_LOG(LOG_WARN, "%s", msg);
#endif
ret = -1;
}
curl_easy_cleanup(curl);
curl_slist_free_all(headers);
}
//fclose(fp);
return ret;
}
static size_t w_callback(char *ptr, size_t size, size_t nmemb, void *userdata) {
size_t realsize = size * nmemb;
char msg[512];
sprintf(msg, "%s: %zu bytes, %s\n", __FUNCTION__, realsize, ptr);
#ifdef USE_STDOUT
printf("%s", msg);
#else
JANUS_LOG(LOG_WARN, "%s", msg);
#endif
return realsize;
}
static size_t p_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow) {
char msg[512];
sprintf(msg, "%s: dltotal=%f, dlnow=%f, ultotal=%f, ulnow=%f \n", __FUNCTION__, dltotal, dlnow, ultotal, ulnow);
#ifdef USE_STDOUT
printf("%s", msg);
#else
JANUS_LOG(LOG_WARN, "%s", msg);
#endif
return 0;
}
int http_client_tester(int argc, char **argv) {
#ifndef USE_STDOUT
janus_log_init(FALSE, TRUE, NULL);
#endif
const char* url = "http://localhost:8080/upload";
const char* filepath = "/Users/alex/work/xcode-workspace/janus/janus_gateway/ffmpeg_tools/recording/ext_recorder_2.ts";
http_client_post_file(url, filepath, w_callback, p_callback);
#ifndef USE_STDOUT
janus_log_destroy();
#endif
return 0;
}