Fixed write callback and added test case for chunked message 77/86477/2 submit/tizen/20160907.003226
authorSeonah Moon <seonah1.moon@samsung.com>
Thu, 1 Sep 2016 10:03:38 +0000 (19:03 +0900)
committerSeonah Moon <seonah1.moon@samsung.com>
Thu, 1 Sep 2016 10:58:13 +0000 (19:58 +0900)
Change-Id: I6f5dbb98de8fc84e4ce5b4eb3aac49cb84aeb68f
Signed-off-by: Seonah Moon <seonah1.moon@samsung.com>
src/http_transaction.c
test/http_test.c

index 33302ec9c4805a2ce4e49fdc017636859dce3438..11967c91e08d365c941f88850975780b32b7beab 100644 (file)
@@ -94,18 +94,20 @@ size_t __handle_write_cb(gchar *ptr, size_t size, size_t nmemb, gpointer user_da
 {
        __http_transaction_h *transaction = (__http_transaction_h *)user_data;
        __http_request_h *request = transaction->request;
-       size_t recommended_size = size * nmemb;
        size_t body_size = 0;
+       char *data = NULL;
 
-       if (transaction->write_cb)
-               transaction->write_cb(transaction, recommended_size, transaction->write_user_data);
-
-       ptr = (gchar*)g_queue_pop_head(request->body_queue);
-       if (ptr == NULL) {
+       data = (char *)g_queue_pop_head(request->body_queue);
+       if (data) {
+               body_size = strlen(data);
+               memcpy(ptr, data, body_size);
+       } else {
                DBG("Sent the last chunk.\n");
                return 0;
        }
-       body_size = strlen(ptr);
+
+       if (transaction->write_cb)
+               transaction->write_cb(transaction, body_size, transaction->write_user_data);
 
        return body_size;
 }
@@ -372,7 +374,6 @@ int _transaction_submit(gpointer user_data)
 
        if (write_event) {
                curl_easy_setopt(transaction->easy_handle, CURLOPT_POST, 1);
-               curl_easy_setopt(transaction->easy_handle, CURLOPT_POSTFIELDSIZE, body_size);
                curl_easy_setopt(transaction->easy_handle, CURLOPT_READFUNCTION, __handle_write_cb);
                curl_easy_setopt(transaction->easy_handle, CURLOPT_READDATA, transaction);
        }
index 6f34cb6151e533c0f12f679d9ce3966644eef57f..f4d1aa2c0d436dca75a3534e8dbd1e807a65a136 100644 (file)
@@ -19,6 +19,7 @@
 #include <string.h>
 #include <glib.h>
 #include <gio/gio.h>
+#include <sys/stat.h>
 
 #include "http.h"
 #include "http_internal.h"
@@ -33,6 +34,7 @@ FILE* fp2 = NULL;
 
 http_session_h session = NULL;
 void _register_callbacks(http_transaction_h transaction);
+void _write_message_body(http_transaction_h transaction, const char *file_path);
 
 void __transaction_header_cb(http_transaction_h transaction, char *header, size_t header_len, void *user_data)
 {
@@ -122,6 +124,33 @@ void _register_callbacks(http_transaction_h transaction)
        http_transaction_set_progress_cb(transaction, __transaction_progress_cb, NULL);
 }
 
+void _write_message_body(http_transaction_h transaction, const char *file_path)
+{
+       struct stat file_info;
+       FILE *fp;
+       size_t file_size;
+       size_t chunk_size = 1000;
+       char *buf = malloc(chunk_size);
+
+       stat(file_path, &file_info);
+       file_size = file_info.st_size;
+
+       DBG("File size (%d)", file_size);
+       fp = fopen(file_path, "rb");
+
+       while (fread(buf, 1, chunk_size, fp) > 0) {
+               if (file_size < chunk_size)
+                       http_transaction_request_write_body(transaction, strndup(buf, file_size));
+               else
+                       http_transaction_request_write_body(transaction, strdup(buf));
+
+               file_size -= chunk_size;
+       }
+
+       free(buf);
+       fclose(fp);
+}
+
 int test_http_init(void)
 {
        int ret = http_init();
@@ -253,7 +282,6 @@ int test_simple_post(void)
        http_transaction_request_write_body(transaction, post_msg);
 
        snprintf(field_value, sizeof(field_value), "%d", (int)strlen(post_msg));
-       printf("[dbg] post size (%s)\n", field_value);
        http_transaction_header_add_field(transaction, "Content-Length", field_value);
 
        _register_callbacks(transaction);
@@ -364,6 +392,39 @@ int test_simple_authentication_get(void)
        return 1;
 }
 
+int test_post_chunk(void)
+{
+       int ret;
+       http_transaction_h transaction;
+       char path[1024] = {0, };
+
+       printf("Input path: ");
+       ret = scanf("%1023s", path);
+
+       ret = http_session_open_transaction(session, HTTP_METHOD_POST, &transaction);
+       if (ret != 0) {
+               ERR("Fail to open transaction", ret);
+               return 0;
+       }
+
+       ret = http_transaction_request_set_uri(transaction, "http://httpbin.org/post");
+       if (ret != 0) {
+               ERR("Fail to set URI", ret);
+               return 0;
+       }
+
+       _register_callbacks(transaction);
+       _write_message_body(transaction, path);
+
+       http_transaction_set_ready_to_write(transaction, TRUE);
+       http_transaction_header_add_field(transaction, "Transfer-Encoding", "chunked");
+       http_transaction_header_add_field(transaction, "Expect", "");
+
+       http_transaction_submit(transaction);
+
+       return 1;
+}
+
 gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
 {
        int rv;
@@ -389,6 +450,7 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
                printf("8       - Multipart POST\n");
                printf("9       - Simple Authentication GET\n");
                printf("a       - Upload file (PUT)\n");
+               printf("b       - Upload file (POST)\n");
                printf("0       - Exit \n");
                printf("ENTER  - Show options menu.......\n");
        }
@@ -424,6 +486,9 @@ gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
        case 'a':
                rv = test_put();
                break;
+       case 'b':
+               rv = test_post_chunk();
+               break;
        }
 
        if (rv == 1)