2 * Copyright (c) 2012 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
20 #include "download-agent-debug.h"
21 #include "download-agent-plugin-libsoup.h"
22 #include "download-agent-http-misc.h"
23 #include "download-agent-utils.h"
24 #include "download-agent-pthread.h"
26 pthread_mutex_t mutex_for_session_table = PTHREAD_MUTEX_INITIALIZER;
28 pi_session_table_t pi_session_table[MAX_SESSION_COUNT] = { { 0, }, };
29 da_bool_t using_content_sniffing;
31 da_bool_t _pi_http_is_this_session_table_entry_using(
32 const int in_session_table_entry);
34 da_result_t PI_http_init(void)
36 DA_LOG_FUNC_START(HTTPManager);
38 using_content_sniffing = DA_TRUE;
43 void PI_http_deinit(void)
45 DA_LOG_FUNC_START(HTTPManager);
50 da_result_t _set_proxy_on_soup_session(SoupSession *session, char *proxy_addr)
52 da_result_t ret = DA_RESULT_OK;
55 if (proxy_addr && strlen(proxy_addr) > 0) {
56 DA_LOG_CRITICAL(HTTPManager,"received proxy = %s \n", proxy_addr);
57 if (!strstr(proxy_addr, "0.0.0.0")) {
58 if (strstr((const char *)proxy_addr, "http") == DA_NULL) {
59 /* DA_LOG(Default,"There is no \"http://\" on received uri, so, add it."); */
61 char *tmp_str = DA_NULL;
64 needed_len = strlen(proxy_addr) + strlen(
66 tmp_str = (char *) calloc(1, needed_len);
68 DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
69 ret = DA_ERR_FAIL_TO_MEMALLOC;
72 snprintf(tmp_str, needed_len, "%s%s",
73 SCHEME_HTTP, proxy_addr);
75 g_object_set(session, SOUP_SESSION_PROXY_URI,
76 soup_uri_new(tmp_str), NULL);
80 DA_LOG(HTTPManager,"There is \"http\" on uri, so, push this address to soup directly.");
81 g_object_set(session, SOUP_SESSION_PROXY_URI,
82 soup_uri_new(proxy_addr), NULL);
86 DA_LOG(HTTPManager,"There is no proxy value");
92 void _fill_soup_msg_header(SoupMessage *msg,
93 const input_for_tranx_t *input_for_tranx)
95 SoupMessageHeaders *headers = msg->request_headers;
97 http_msg_request_t *input_http_msg_request;
98 http_msg_iter_t http_msg_iter;
99 http_msg_iter_t http_msg_iter_pre;
104 input_http_msg_request = input_for_tranx->http_msg_request;
106 http_msg_request_get_iter(input_http_msg_request, &http_msg_iter);
107 http_msg_iter_pre = http_msg_iter;
108 while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) {
109 if ((field != DA_NULL) && (value != DA_NULL)) {
110 DA_LOG(HTTPManager,"[%s] %s", field, value);
111 soup_message_headers_append(headers, field, value);
113 http_msg_iter_pre = http_msg_iter;
116 if (input_http_msg_request->http_body) {
117 char body_len_str[16] = { 0, };
118 int body_len = strlen(input_http_msg_request->http_body);
120 snprintf(body_len_str, sizeof(body_len_str), "%d", body_len);
122 soup_message_headers_append(headers, "Content-Length",
124 soup_message_headers_append(headers, "Content-Type",
126 soup_message_body_append(msg->request_body, SOUP_MEMORY_COPY,
127 input_http_msg_request->http_body, body_len);
131 da_result_t PI_http_start_transaction(const input_for_tranx_t *input_for_tranx,
134 da_result_t ret = DA_RESULT_OK;
136 int session_table_entry = -1;
137 pi_http_method_t pi_http_method = PI_HTTP_METHOD_GET;
139 queue_t *queue = DA_NULL;
143 SoupSession *session = DA_NULL;
144 SoupMessage *msg = DA_NULL;
146 DA_LOG_FUNC_START(HTTPManager);
148 if (DA_FALSE == _pi_http_is_valid_input_for_tranx(input_for_tranx)) {
149 DA_LOG_ERR(HTTPManager,"input_for_tranx is invalid");
150 ret = DA_ERR_INVALID_ARGUMENT;
153 queue = input_for_tranx->queue;
154 pi_http_method = input_for_tranx->http_method;
155 url = input_for_tranx->http_msg_request->url;
158 session_table_entry = _pi_http_get_avaiable_session_table_entry();
159 if (session_table_entry == -1) {
160 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
163 DA_LOG(HTTPManager,"session_table_entry = %d", session_table_entry);
165 if (DA_FALSE == _pi_http_register_queue_to_session_table(
166 session_table_entry, queue)) {
167 _pi_http_destroy_session_table_entry(session_table_entry);
168 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
172 /* modified by keunsoon.lee 2010-09-20 use sync_new() instead of async_new() for make different soup thread from UI main thread*/
173 session = soup_session_sync_new();
174 /* session=soup_session_async_new(); */
176 DA_LOG_ERR(HTTPManager,"Fail to create session");
177 return DA_ERR_INVALID_URL;
179 DA_LOG(HTTPManager,"session[%p]", session);
181 SoupLogger* logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1);
182 soup_logger_attach(logger, session);
183 g_object_unref(logger);
185 if (DA_FALSE == _pi_http_register_session_to_session_table(
186 session_table_entry, session)) {
187 _pi_http_init_session_table_entry(session_table_entry);
188 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
192 g_object_set(session, SOUP_SESSION_MAX_CONNS, MAX_SESSION_COUNT, NULL);
193 /* Set timeout unlimited time to resume a download which has ETag when the network is re-connected
194 * => This is changed to 180 seconds due to limitation of max downloading items.
196 g_object_set(session, SOUP_SESSION_TIMEOUT, MAX_TIMEOUT, NULL);
198 _set_proxy_on_soup_session(session, input_for_tranx->proxy_addr);
200 switch (pi_http_method) {
201 case PI_HTTP_METHOD_GET:
202 msg = soup_message_new(METHOD_GET, url);
204 case PI_HTTP_METHOD_POST:
205 msg = soup_message_new(METHOD_POST, url);
207 case PI_HTTP_METHOD_HEAD:
208 msg = soup_message_new(METHOD_HEAD, url);
211 DA_LOG_ERR(HTTPManager,"Cannot enter here");
214 DA_LOG(HTTPManager,"msg[%p]", msg);
215 /* if it is failed to create a msg, the url can be invalid, becasue of the input argument of soup_message_new API */
217 DA_LOG_ERR(HTTPManager,"Fail to create message");
218 ret = DA_ERR_INVALID_URL;
222 _fill_soup_msg_header(msg, input_for_tranx);
224 g_signal_connect(msg, "restarted", G_CALLBACK(_pi_http_restarted_cb),
225 NULL); /* for redirection case */
226 g_signal_connect(msg, "got-headers",
227 G_CALLBACK(_pi_http_gotheaders_cb), NULL);
228 g_signal_connect(msg, "got-chunk", G_CALLBACK(_pi_http_gotchunk_cb),
231 if (using_content_sniffing) {
232 soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER);
233 g_signal_connect(msg, "content-sniffed",
234 G_CALLBACK(_pi_http_contentsniffed_cb), NULL);
236 soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER);
239 soup_session_queue_message(session, msg, _pi_http_finished_cb, NULL);
240 // g_signal_connect(msg, "finished", G_CALLBACK(_pi_http_finished_cb), NULL);
242 if (DA_FALSE == _pi_http_register_msg_to_session_table(
243 session_table_entry, msg)) {
244 _pi_http_destroy_session_table_entry(session_table_entry);
245 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
249 *out_tranx_id = session_table_entry;
250 DA_LOG(HTTPManager,"*out_tranx_id = %d", *out_tranx_id);
256 da_result_t PI_http_disconnect_transaction(int in_tranx_id)
258 da_result_t ret = DA_RESULT_OK;
259 int session_table_entry = -1;
261 DA_LOG_FUNC_START(HTTPManager);
263 DA_LOG(HTTPManager,"in_tranx_id = %d", in_tranx_id);
265 session_table_entry = in_tranx_id;
267 _pi_http_destroy_session_table_entry(session_table_entry);
272 da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option)
274 da_result_t ret = DA_RESULT_OK;
275 SoupSession *session;
277 int session_table_entry = -1;
279 DA_LOG_FUNC_START(HTTPManager);
281 DA_LOG(HTTPManager,"in_tranx_id = %d", in_tranx_id);
283 session_table_entry = in_tranx_id;
284 if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) {
285 DA_LOG_CRITICAL(HTTPManager,"not using session");
288 session = GET_SESSION_FROM_TABLE_ENTRY(session_table_entry);
289 msg = GET_MSG_FROM_TABLE_ENTRY(session_table_entry);
291 if (DA_NULL == session) {
292 DA_LOG_ERR(HTTPManager,"invalid session = %p", session);
296 if (DA_NULL == msg) {
297 DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
300 DA_LOG(HTTPManager,"Call soup cancel API : abort option[%d]",abort_option);
302 soup_session_abort(session);
304 soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED);
305 DA_LOG(HTTPManager,"Call soup cancel API-Done");
310 void PI_http_pause_transaction(int transaction_id)
312 int session_table_entry = -1;
313 pthread_mutex_t *mutex;
314 pthread_cond_t *cond;
316 DA_LOG_FUNC_START(HTTPManager);
318 DA_LOG(HTTPManager,"in_tranx_id = %d", transaction_id);
320 session_table_entry = transaction_id;
322 if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
325 mutex = &(pi_session_table[session_table_entry].mutex);
326 cond = &(pi_session_table[session_table_entry].cond);
328 _da_thread_mutex_lock (mutex);
330 if (pi_session_table[session_table_entry].is_paused == DA_FALSE) {
331 DA_LOG_CRITICAL(HTTPManager,"paused!");
332 pi_session_table[session_table_entry].is_paused = DA_TRUE;
333 _da_thread_cond_wait(cond, mutex);
335 DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
338 _da_thread_mutex_unlock (mutex);
342 void PI_http_unpause_transaction(int transaction_id)
344 int session_table_entry = -1;
345 pthread_mutex_t *mutex;
346 pthread_cond_t *cond;
348 /* DA_LOG_FUNC_START(Default); */
350 session_table_entry = transaction_id;
352 if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
355 mutex = &(pi_session_table[session_table_entry].mutex);
356 cond = &(pi_session_table[session_table_entry].cond);
358 _da_thread_mutex_lock (mutex);
360 if (pi_session_table[session_table_entry].is_paused == DA_TRUE) {
361 DA_LOG_CRITICAL(HTTPManager,"wake up!");
362 pi_session_table[session_table_entry].is_paused = DA_FALSE;
363 _da_thread_cond_signal(cond);
366 _da_thread_mutex_unlock (mutex);
370 da_bool_t _pi_http_is_valid_input_for_tranx(
371 const input_for_tranx_t *input_for_tranx)
373 if (!(input_for_tranx->http_msg_request)) {
374 DA_LOG_ERR(HTTPManager,"http_msg_request is NULL");
378 if (!((input_for_tranx->http_method == PI_HTTP_METHOD_GET) ||
379 (input_for_tranx->http_method == PI_HTTP_METHOD_POST) ||
380 (input_for_tranx->http_method == PI_HTTP_METHOD_HEAD))) {
381 DA_LOG_ERR(HTTPManager,"http_method is neither GET or POST or HEAD");
388 da_bool_t _pi_http_is_this_session_table_entry_using(
389 const int in_session_table_entry)
391 da_bool_t is_using = DA_FALSE;
393 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(in_session_table_entry))
396 _da_thread_mutex_lock (&mutex_for_session_table);
398 is_using = pi_session_table[in_session_table_entry].is_using;
400 _da_thread_mutex_unlock (&mutex_for_session_table);
405 void _pi_http_init_session_table_entry(const int in_session_table_entry)
407 int entry = in_session_table_entry;
409 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
412 // _da_thread_mutex_lock (&mutex_for_session_table);
414 pi_session_table[entry].is_using = DA_TRUE;
415 pi_session_table[entry].msg = NULL;
416 pi_session_table[entry].session = NULL;
417 pi_session_table[entry].queue = NULL;
419 _da_thread_mutex_init(&(pi_session_table[entry].mutex), DA_NULL);
420 _da_thread_cond_init(&(pi_session_table[entry].cond), NULL);
421 pi_session_table[entry].is_paused = DA_FALSE;
423 // _da_thread_mutex_unlock (&mutex_for_session_table);
428 void _pi_http_destroy_session_table_entry(const int in_session_table_entry)
430 int entry = in_session_table_entry;
432 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
435 _da_thread_mutex_lock (&mutex_for_session_table);
437 if (pi_session_table[entry].is_paused == DA_TRUE)
438 PI_http_unpause_transaction(entry);
440 /* Warning! Do not g_object_unref(msg) here!
441 * soup_session_queue_message() steals msg's reference count,
442 * so, we don't need to do anything for memory management.
444 * But, if using soup_session_send_message(), MUST call g_object_unref(msg). */
445 /* if (pi_session_table[entry].msg)
446 g_object_unref(pi_session_table[entry].msg); */
448 pi_session_table[entry].msg = NULL;
450 /* FIXME Cannot g_object_unref(session) here,
451 * because msg inside this session is not destoryed yet.
452 * The msg's reference count is stealed by soup_session_queue_message(),
453 * and it will be destroyed when _pi_http_finished_cb() is returned.
454 * For now, this _pi_http_destroy_session_table_entry() is called inside
455 * _pi_http_finished_cb(), so, g_object_unref(session) is not working.
456 * Should find out call this function after _pi_http_finished_cb(). */
457 if (pi_session_table[entry].session)
458 g_object_unref(pi_session_table[entry].session);
460 DA_LOG_ERR(HTTPManager,"session is NULL. Cannot unref this.");
461 DA_LOG(HTTPManager,"unref session [%p]",pi_session_table[entry].session);
463 pi_session_table[entry].session = NULL;
465 pi_session_table[entry].queue = NULL;
466 pi_session_table[entry].is_paused = DA_FALSE;
467 pi_session_table[entry].is_using = DA_FALSE;
469 _da_thread_mutex_destroy(&(pi_session_table[entry].mutex));
470 _da_thread_cond_destroy(&(pi_session_table[entry].cond));
472 _da_thread_mutex_unlock (&mutex_for_session_table);
477 int _pi_http_get_avaiable_session_table_entry(void)
480 int avaiable_entry = -1;
482 _da_thread_mutex_lock (&mutex_for_session_table);
484 for (i = 0; i < MAX_SESSION_COUNT; i++) {
485 if (pi_session_table[i].is_using == DA_FALSE) {
486 /* pi_session_table[i].is_using = DA_TRUE; */
487 DA_LOG_VERBOSE(HTTPManager,"available entry = %d", i);
494 _pi_http_init_session_table_entry(avaiable_entry);
495 _da_thread_mutex_unlock (&mutex_for_session_table);
497 return avaiable_entry;
500 da_bool_t _pi_http_register_queue_to_session_table(
501 const int in_session_table_entry, const queue_t *in_queue)
503 int entry = in_session_table_entry;
504 queue_t *queue = (queue_t *) in_queue;
505 da_bool_t ret = DA_FALSE;
507 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
508 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
512 _da_thread_mutex_lock (&mutex_for_session_table);
514 if (pi_session_table[entry].is_using == DA_FALSE) {
515 DA_LOG_ERR(HTTPManager,"this entry [%d] is not using", entry);
518 pi_session_table[entry].queue = queue;
519 DA_LOG_VERBOSE(HTTPManager,"queue = %p", pi_session_table[entry].queue);
523 _da_thread_mutex_unlock (&mutex_for_session_table);
528 da_bool_t _pi_http_register_session_to_session_table(
529 const int in_session_table_entry, SoupSession *session)
531 int entry = in_session_table_entry;
532 da_bool_t ret = DA_FALSE;
534 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
535 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
539 if (DA_NULL == session) {
540 DA_LOG_ERR(HTTPManager,"invalid session = %p",session);
544 _da_thread_mutex_lock (&mutex_for_session_table);
546 if (pi_session_table[entry].is_using == DA_FALSE) {
549 pi_session_table[entry].session = session;
553 _da_thread_mutex_unlock (&mutex_for_session_table);
558 da_bool_t _pi_http_register_msg_to_session_table(
559 const int in_session_table_entry, SoupMessage *msg)
561 int entry = in_session_table_entry;
562 da_bool_t ret = DA_FALSE;
564 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
565 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
569 if (DA_NULL == msg) {
570 DA_LOG_ERR(HTTPManager,"invalid msg = %p",msg);
574 _da_thread_mutex_lock (&mutex_for_session_table);
576 if (pi_session_table[entry].is_using == DA_FALSE) {
579 pi_session_table[entry].msg = msg;
583 _da_thread_mutex_unlock (&mutex_for_session_table);
588 queue_t *_pi_http_get_queue_from_session_table_entry(
589 const int in_session_table_entry)
591 int entry = in_session_table_entry;
592 queue_t *out_queue = NULL;
594 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
595 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
599 _da_thread_mutex_lock (&mutex_for_session_table);
601 out_queue = pi_session_table[entry].queue;
602 _da_thread_mutex_unlock (&mutex_for_session_table);
607 void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType)
609 da_result_t ret = DA_RESULT_OK;
611 queue_t *da_queue = NULL;
612 q_event_t *da_event = NULL;
613 q_event_type_data da_event_type_data;
615 int session_table_entry = -1;
616 SoupMessageHeadersIter headers_iter;
618 const char *header_name;
619 const char *header_value;
621 http_msg_response_t *http_msg_response = NULL;
623 /* DA_LOG_FUNC_START(Default); */
625 if (msg->response_headers) {
626 ret = http_msg_response_create(&http_msg_response);
627 if (ret != DA_RESULT_OK)
630 http_msg_response_set_status_code(http_msg_response,
633 DA_LOG(HTTPManager,"\n----raw header---------------------------------------------");
634 DA_LOG_CRITICAL(HTTPManager,"status code = %d", msg->status_code);
635 soup_message_headers_iter_init(&headers_iter,
636 msg->response_headers);
637 while (soup_message_headers_iter_next(&headers_iter,
638 &header_name, &header_value)) {
639 if ((header_name != DA_NULL) && (header_value
641 http_msg_response_add_field(http_msg_response,
642 header_name, header_value);
645 DA_LOG(HTTPManager,"\n-------------------------------------------------------------\n");
649 if (using_content_sniffing && sniffedType)
650 http_msg_response_set_content_type(http_msg_response, sniffedType);
653 = _pi_http_get_session_table_entry_from_message(msg);
654 if (session_table_entry == -1) {
655 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
656 ret = DA_ERR_INVALID_ARGUMENT;
660 da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
662 da_queue = _pi_http_get_queue_from_session_table_entry(
663 session_table_entry);
665 ret = Q_make_http_data_event(da_event_type_data, &da_event);
666 if (ret != DA_RESULT_OK) {
667 DA_LOG_ERR(HTTPManager,"fail to make da_event");
670 Q_set_status_code_on_http_data_event(da_event, msg->status_code);
671 da_event->type.q_event_data_http.http_response_msg
674 Q_push_event(da_queue, da_event);
679 if (DA_RESULT_OK != ret)
680 http_msg_response_destroy(&http_msg_response);
685 void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char *body_data,
686 int received_body_len)
688 da_result_t ret = DA_RESULT_OK;
689 da_bool_t b_ret = DA_FALSE;
691 char *body_buffer = NULL;
692 queue_t *da_queue = NULL;
693 q_event_t *da_event = NULL;
694 q_event_type_data da_event_type_data;
695 int session_table_entry = -1;
696 int http_status = -1;
698 /* DA_LOG_FUNC_START(Default); */
700 http_status = msg->status_code;
703 = _pi_http_get_session_table_entry_from_message(msg);
704 if (session_table_entry == -1) {
705 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
706 ret = DA_ERR_INVALID_ARGUMENT;
710 if (received_body_len == 0) {
711 DA_LOG(HTTPManager,"Q_EVENT_TYPE_DATA_FINAL");
712 da_event_type_data = Q_EVENT_TYPE_DATA_FINAL;
714 da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
715 if (received_body_len > 0) {
716 body_buffer = (char*) calloc(1, received_body_len);
717 DA_LOG_VERBOSE(HTTPManager,"body_buffer[%p]msg[%p]",body_buffer,msg);
718 if (body_buffer == DA_NULL) {
719 DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
722 memcpy(body_buffer, body_data, received_body_len);
726 da_queue = _pi_http_get_queue_from_session_table_entry(
727 session_table_entry);
729 ret = Q_make_http_data_event(da_event_type_data, &da_event);
730 if (ret != DA_RESULT_OK) {
731 DA_LOG_ERR(HTTPManager,"fail to make da_event");
734 Q_set_status_code_on_http_data_event(da_event, http_status);
735 Q_set_http_body_on_http_data_event(da_event, received_body_len,
738 _da_thread_mutex_lock (&(da_queue->mutex_queue));
739 b_ret = Q_push_event_without_lock(da_queue, da_event);
740 if (b_ret == DA_FALSE) {
741 DA_LOG_CRITICAL(HTTPManager,"----------------------------------------fail to push!");
743 pthread_mutex_t *session_mutex = NULL;
744 pthread_cond_t *session_cond = NULL;
747 = &(pi_session_table[session_table_entry].mutex);
749 = &(pi_session_table[session_table_entry].cond);
751 /* MUST keep this order for these mutexes */
752 _da_thread_mutex_lock (session_mutex);
753 _da_thread_mutex_unlock (&(da_queue->mutex_queue));
755 if (pi_session_table[session_table_entry].is_paused
757 DA_LOG_CRITICAL(HTTPManager,"paused!");
758 pi_session_table[session_table_entry].is_paused
760 _da_thread_cond_wait(session_cond, session_mutex);
762 DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
765 _da_thread_mutex_unlock (session_mutex);
767 DA_LOG_CRITICAL(HTTPManager,"wake up! push again");
768 Q_push_event(da_queue, da_event);
770 _da_thread_mutex_unlock (&(da_queue->mutex_queue));
778 if (DA_RESULT_OK != ret) {
779 if (DA_NULL != body_buffer) {
787 int _translate_error_code(int soup_error)
789 DA_LOG_CRITICAL(HTTPManager, "soup error code[%d]", soup_error);
790 switch (soup_error) {
791 case SOUP_STATUS_CANT_RESOLVE:
792 case SOUP_STATUS_CANT_RESOLVE_PROXY:
793 case SOUP_STATUS_CANT_CONNECT:
794 case SOUP_STATUS_CANT_CONNECT_PROXY:
795 case SOUP_STATUS_IO_ERROR:
796 case SOUP_STATUS_MALFORMED:
797 case SOUP_STATUS_TRY_AGAIN:
798 return DA_ERR_NETWORK_FAIL;
799 case SOUP_STATUS_SSL_FAILED:
800 return DA_ERR_SSL_FAIL;
801 case SOUP_STATUS_REQUEST_TIMEOUT:
802 return DA_ERR_HTTP_TIMEOUT;
803 case SOUP_STATUS_TOO_MANY_REDIRECTS:
804 return DA_ERR_TOO_MANY_REDIECTS;
806 return DA_ERR_NETWORK_FAIL;
810 void _pi_http_store_neterr_to_queue(SoupMessage *msg)
812 da_result_t ret = DA_RESULT_OK;
814 queue_t *da_queue = NULL;
815 q_event_t *da_event = NULL;
816 int session_table_entry = -1;
818 DA_LOG_FUNC_START(HTTPManager);
820 error_type = _translate_error_code(msg->status_code);
823 = _pi_http_get_session_table_entry_from_message(msg);
824 if (session_table_entry == -1) {
825 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
826 ret = DA_ERR_INVALID_ARGUMENT;
830 da_queue = _pi_http_get_queue_from_session_table_entry(
831 session_table_entry);
833 DA_LOG_CRITICAL(HTTPManager,"Q_EVENT_TYPE_DATA_ABORT");
834 ret = Q_make_http_data_event(Q_EVENT_TYPE_DATA_ABORT, &da_event);
835 if (ret != DA_RESULT_OK) {
836 DA_LOG_ERR(HTTPManager,"fail to make da_event");
839 Q_set_error_type_on_http_data_event(da_event, error_type);
841 Q_push_event(da_queue, da_event);
848 int _pi_http_get_session_table_entry_from_message(SoupMessage *msg)
854 if (DA_NULL == msg) {
855 DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
859 _da_thread_mutex_lock (&mutex_for_session_table);
861 for (i = 0; i < MAX_SESSION_COUNT; i++) {
862 if (pi_session_table[i].is_using == DA_TRUE) {
863 if (pi_session_table[i].msg == msg) {
870 _da_thread_mutex_unlock (&mutex_for_session_table);
872 if (i == MAX_SESSION_COUNT) {
873 DA_LOG_ERR(HTTPManager,"fail to find message = %p", msg);
880 void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data)
884 DA_LOG_FUNC_START(HTTPManager);
886 url = soup_uri_to_string(soup_message_get_uri(msg), DA_FALSE);
888 DA_LOG(HTTPManager,"status_code[%d], reason[%s], url[%s]",msg->status_code,msg->reason_phrase,url);
895 if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
896 if (msg->status_code == SOUP_STATUS_CANCELLED) {
897 _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
899 _pi_http_store_neterr_to_queue(msg);
902 _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
907 /* this callback is called in case of redirection */
908 void _pi_http_restarted_cb(SoupMessage *msg, gpointer data)
910 DA_LOG_FUNC_START(HTTPManager);
911 /* Location URL is needed when extracting the file name from url.
912 * So, the response header should be handled by http mgr.*/
913 _pi_http_store_read_header_to_queue(msg, NULL);
916 void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data)
918 DA_LOG_FUNC_START(HTTPManager);
920 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
921 DA_LOG(HTTPManager,"Redirection !!");
922 if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
926 soup_message_body_set_accumulate(msg->response_body, DA_FALSE);
928 if (!using_content_sniffing)
929 _pi_http_store_read_header_to_queue(msg, NULL);
931 DA_LOG(HTTPManager,"ignore because content sniffing is turned on");
934 void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType,
935 GHashTable *params, gpointer data)
937 DA_LOG_FUNC_START(HTTPManager);
939 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
940 DA_LOG(HTTPManager,"Redirection !!");
941 if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
945 if (using_content_sniffing)
946 _pi_http_store_read_header_to_queue(msg, sniffedType);
949 void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data)
951 // DA_LOG_FUNC_START(HTTPManager);
953 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code))
956 if (chunk->data && chunk->length > 0) {
957 _pi_http_store_read_data_to_queue(msg, chunk->data,