4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jungki Kwak <jungki.kwak@samsung.com>, Keunsoon Lee <keunsoon.lee@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
20 * @file download-agent-plugin-libsoup.c
21 * @brief Platform dependent functions for interface of libsoup http module
22 * @author Keunsoon Lee (keunsoon.lee@samsung.com)
23 * @author Jungki Kwak (jungki.kwak@samsung.com)
29 #include "download-agent-debug.h"
30 #include "download-agent-plugin-libsoup.h"
31 #include "download-agent-http-misc.h"
32 #include "download-agent-utils.h"
33 #include "download-agent-pthread.h"
35 pthread_mutex_t mutex_for_session_table = PTHREAD_MUTEX_INITIALIZER;
37 pi_session_table_t pi_session_table[MAX_SESSION_COUNT] = { { 0, }, };
38 da_bool_t using_content_sniffing;
40 da_bool_t _pi_http_is_this_session_table_entry_using(
41 const int in_session_table_entry);
43 da_result_t PI_http_init(void)
45 DA_LOG_FUNC_START(HTTPManager);
47 using_content_sniffing = DA_TRUE;
52 void PI_http_deinit(void)
54 DA_LOG_FUNC_START(HTTPManager);
59 da_result_t _set_proxy_on_soup_session(SoupSession *session, char *proxy_addr)
61 da_result_t ret = DA_RESULT_OK;
64 if (proxy_addr && strlen(proxy_addr) > 0) {
65 DA_LOG_CRITICAL(HTTPManager,"received proxy = %s \n", proxy_addr);
66 if (!strstr(proxy_addr, "0.0.0.0")) {
67 if (strstr((const char *)proxy_addr, "http") == DA_NULL) {
68 /* DA_LOG(Default,"There is no \"http://\" on received uri, so, add it."); */
70 char *tmp_str = DA_NULL;
73 needed_len = strlen(proxy_addr) + strlen(
75 tmp_str = (char *) calloc(1, needed_len);
77 DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
78 ret = DA_ERR_FAIL_TO_MEMALLOC;
81 snprintf(tmp_str, needed_len, "%s%s",
82 SCHEME_HTTP, proxy_addr);
84 g_object_set(session, SOUP_SESSION_PROXY_URI,
85 soup_uri_new(tmp_str), NULL);
89 DA_LOG(HTTPManager,"There is \"http\" on uri, so, push this address to soup directly.");
90 g_object_set(session, SOUP_SESSION_PROXY_URI,
91 soup_uri_new(proxy_addr), NULL);
95 DA_LOG(HTTPManager,"There is no proxy value");
101 void _fill_soup_msg_header(SoupMessage *msg,
102 const input_for_tranx_t *input_for_tranx)
104 SoupMessageHeaders *headers = msg->request_headers;
106 http_msg_request_t *input_http_msg_request;
107 http_msg_iter_t http_msg_iter;
108 http_msg_iter_t http_msg_iter_pre;
113 input_http_msg_request = input_for_tranx->http_msg_request;
115 http_msg_request_get_iter(input_http_msg_request, &http_msg_iter);
116 http_msg_iter_pre = http_msg_iter;
117 while (http_msg_get_field_with_iter(&http_msg_iter, &field, &value)) {
118 if ((field != DA_NULL) && (value != DA_NULL)) {
119 DA_LOG(HTTPManager,"[%s] %s", field, value);
120 soup_message_headers_append(headers, field, value);
122 http_msg_iter_pre = http_msg_iter;
125 if (input_http_msg_request->http_body) {
126 char body_len_str[16] = { 0, };
127 int body_len = strlen(input_http_msg_request->http_body);
129 snprintf(body_len_str, sizeof(body_len_str), "%d", body_len);
131 soup_message_headers_append(headers, "Content-Length",
133 soup_message_headers_append(headers, "Content-Type",
135 soup_message_body_append(msg->request_body, SOUP_MEMORY_COPY,
136 input_http_msg_request->http_body, body_len);
140 da_result_t PI_http_start_transaction(const input_for_tranx_t *input_for_tranx,
143 da_result_t ret = DA_RESULT_OK;
145 int session_table_entry = -1;
146 pi_http_method_t pi_http_method = PI_HTTP_METHOD_GET;
148 queue_t *queue = DA_NULL;
152 SoupSession *session = DA_NULL;
153 SoupMessage *msg = DA_NULL;
155 DA_LOG_FUNC_START(HTTPManager);
157 if (DA_FALSE == _pi_http_is_valid_input_for_tranx(input_for_tranx)) {
158 DA_LOG_ERR(HTTPManager,"input_for_tranx is invalid");
159 ret = DA_ERR_INVALID_ARGUMENT;
162 queue = input_for_tranx->queue;
163 pi_http_method = input_for_tranx->http_method;
164 url = input_for_tranx->http_msg_request->url;
167 session_table_entry = _pi_http_get_avaiable_session_table_entry();
168 if (session_table_entry == -1) {
169 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
172 DA_LOG(HTTPManager,"session_table_entry = %d", session_table_entry);
174 if (DA_FALSE == _pi_http_register_queue_to_session_table(
175 session_table_entry, queue)) {
176 _pi_http_destroy_session_table_entry(session_table_entry);
177 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
181 /* modified by keunsoon.lee 2010-09-20 use sync_new() instead of async_new() for make different soup thread from UI main thread*/
182 session = soup_session_sync_new();
183 /* session=soup_session_async_new(); */
185 DA_LOG_ERR(HTTPManager,"Fail to create session");
186 return DA_ERR_INVALID_URL;
188 DA_LOG(HTTPManager,"session[%p]", session);
190 SoupLogger* logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1);
191 soup_logger_attach(logger, session);
192 g_object_unref(logger);
194 if (DA_FALSE == _pi_http_register_session_to_session_table(
195 session_table_entry, session)) {
196 _pi_http_init_session_table_entry(session_table_entry);
197 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
201 g_object_set(session, SOUP_SESSION_MAX_CONNS, MAX_SESSION_COUNT, NULL);
202 /* Set timeout unlimited time to resume a download which has ETag when the network is re-connected
203 * => This is changed to 180 seconds due to limitation of max downloading items.
205 g_object_set(session, SOUP_SESSION_TIMEOUT, MAX_TIMEOUT, NULL);
207 _set_proxy_on_soup_session(session, input_for_tranx->proxy_addr);
209 switch (pi_http_method) {
210 case PI_HTTP_METHOD_GET:
211 msg = soup_message_new(METHOD_GET, url);
213 case PI_HTTP_METHOD_POST:
214 msg = soup_message_new(METHOD_POST, url);
216 case PI_HTTP_METHOD_HEAD:
217 msg = soup_message_new(METHOD_HEAD, url);
220 DA_LOG_ERR(HTTPManager,"Cannot enter here");
223 DA_LOG(HTTPManager,"msg[%p]", msg);
224 /* if it is failed to create a msg, the url can be invalid, becasue of the input argument of soup_message_new API */
226 DA_LOG_ERR(HTTPManager,"Fail to create message");
227 ret = DA_ERR_INVALID_URL;
231 _fill_soup_msg_header(msg, input_for_tranx);
233 g_signal_connect(msg, "restarted", G_CALLBACK(_pi_http_restarted_cb),
234 NULL); /* for redirection case */
235 g_signal_connect(msg, "got-headers",
236 G_CALLBACK(_pi_http_gotheaders_cb), NULL);
237 g_signal_connect(msg, "got-chunk", G_CALLBACK(_pi_http_gotchunk_cb),
240 if (using_content_sniffing) {
241 soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER);
242 g_signal_connect(msg, "content-sniffed",
243 G_CALLBACK(_pi_http_contentsniffed_cb), NULL);
245 soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER);
248 soup_session_queue_message(session, msg, _pi_http_finished_cb, NULL);
249 // g_signal_connect(msg, "finished", G_CALLBACK(_pi_http_finished_cb), NULL);
251 if (DA_FALSE == _pi_http_register_msg_to_session_table(
252 session_table_entry, msg)) {
253 _pi_http_destroy_session_table_entry(session_table_entry);
254 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
258 *out_tranx_id = session_table_entry;
259 DA_LOG(HTTPManager,"*out_tranx_id = %d", *out_tranx_id);
265 da_result_t PI_http_disconnect_transaction(int in_tranx_id)
267 da_result_t ret = DA_RESULT_OK;
268 int session_table_entry = -1;
270 DA_LOG_FUNC_START(HTTPManager);
272 DA_LOG(HTTPManager,"in_tranx_id = %d", in_tranx_id);
274 session_table_entry = in_tranx_id;
276 _pi_http_destroy_session_table_entry(session_table_entry);
281 da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option)
283 da_result_t ret = DA_RESULT_OK;
284 SoupSession *session;
286 int session_table_entry = -1;
288 DA_LOG_FUNC_START(HTTPManager);
290 DA_LOG(HTTPManager,"in_tranx_id = %d", in_tranx_id);
292 session_table_entry = in_tranx_id;
293 if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) {
294 DA_LOG_CRITICAL(HTTPManager,"not using session");
297 session = GET_SESSION_FROM_TABLE_ENTRY(session_table_entry);
298 msg = GET_MSG_FROM_TABLE_ENTRY(session_table_entry);
300 if (DA_NULL == session) {
301 DA_LOG_ERR(HTTPManager,"invalid session = %p", session);
305 if (DA_NULL == msg) {
306 DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
309 DA_LOG(HTTPManager,"Call soup cancel API : abort option[%d]",abort_option);
311 soup_session_abort(session);
313 soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED);
314 DA_LOG(HTTPManager,"Call soup cancel API-Done");
319 void PI_http_pause_transaction(int transaction_id)
321 int session_table_entry = -1;
322 pthread_mutex_t *mutex;
323 pthread_cond_t *cond;
325 DA_LOG_FUNC_START(HTTPManager);
327 DA_LOG(HTTPManager,"in_tranx_id = %d", transaction_id);
329 session_table_entry = transaction_id;
331 if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
334 mutex = &(pi_session_table[session_table_entry].mutex);
335 cond = &(pi_session_table[session_table_entry].cond);
337 _da_thread_mutex_lock (mutex);
339 if (pi_session_table[session_table_entry].is_paused == DA_FALSE) {
340 DA_LOG_CRITICAL(HTTPManager,"paused!");
341 pi_session_table[session_table_entry].is_paused = DA_TRUE;
342 _da_thread_cond_wait(cond, mutex);
344 DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
347 _da_thread_mutex_unlock (mutex);
351 void PI_http_unpause_transaction(int transaction_id)
353 int session_table_entry = -1;
354 pthread_mutex_t* mutex;
355 pthread_cond_t* cond;
357 /* DA_LOG_FUNC_START(Default); */
359 session_table_entry = transaction_id;
361 if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
364 mutex = &(pi_session_table[session_table_entry].mutex);
365 cond = &(pi_session_table[session_table_entry].cond);
367 _da_thread_mutex_lock (mutex);
369 if (pi_session_table[session_table_entry].is_paused == DA_TRUE) {
370 DA_LOG_CRITICAL(HTTPManager,"wake up!");
371 pi_session_table[session_table_entry].is_paused = DA_FALSE;
372 _da_thread_cond_signal(cond);
375 _da_thread_mutex_unlock (mutex);
379 da_bool_t _pi_http_is_valid_input_for_tranx(
380 const input_for_tranx_t *input_for_tranx)
382 if (!(input_for_tranx->http_msg_request)) {
383 DA_LOG_ERR(HTTPManager,"http_msg_request is NULL");
387 if (!((input_for_tranx->http_method == PI_HTTP_METHOD_GET) ||
388 (input_for_tranx->http_method == PI_HTTP_METHOD_POST) ||
389 (input_for_tranx->http_method == PI_HTTP_METHOD_HEAD))) {
390 DA_LOG_ERR(HTTPManager,"http_method is neither GET or POST or HEAD");
397 da_bool_t _pi_http_is_this_session_table_entry_using(
398 const int in_session_table_entry)
400 da_bool_t is_using = DA_FALSE;
402 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(in_session_table_entry))
405 _da_thread_mutex_lock (&mutex_for_session_table);
407 is_using = pi_session_table[in_session_table_entry].is_using;
409 _da_thread_mutex_unlock (&mutex_for_session_table);
414 void _pi_http_init_session_table_entry(const int in_session_table_entry)
416 int entry = in_session_table_entry;
418 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
421 // _da_thread_mutex_lock (&mutex_for_session_table);
423 pi_session_table[entry].is_using = DA_TRUE;
424 pi_session_table[entry].msg = NULL;
425 pi_session_table[entry].session = NULL;
426 pi_session_table[entry].queue = NULL;
428 _da_thread_mutex_init(&(pi_session_table[entry].mutex), DA_NULL);
429 _da_thread_cond_init(&(pi_session_table[entry].cond), NULL);
430 pi_session_table[entry].is_paused = DA_FALSE;
432 // _da_thread_mutex_unlock (&mutex_for_session_table);
437 void _pi_http_destroy_session_table_entry(const int in_session_table_entry)
439 int entry = in_session_table_entry;
441 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
444 _da_thread_mutex_lock (&mutex_for_session_table);
446 if (pi_session_table[entry].is_paused == DA_TRUE)
447 PI_http_unpause_transaction(entry);
449 /* Warning! Do not g_object_unref(msg) here!
450 * soup_session_queue_message() steals msg's reference count,
451 * so, we don't need to do anything for memory management.
453 * But, if using soup_session_send_message(), MUST call g_object_unref(msg). */
454 /* if (pi_session_table[entry].msg)
455 g_object_unref(pi_session_table[entry].msg); */
457 pi_session_table[entry].msg = NULL;
459 /* FIXME Cannot g_object_unref(session) here,
460 * because msg inside this session is not destoryed yet.
461 * The msg's reference count is stealed by soup_session_queue_message(),
462 * and it will be destroyed when _pi_http_finished_cb() is returned.
463 * For now, this _pi_http_destroy_session_table_entry() is called inside
464 * _pi_http_finished_cb(), so, g_object_unref(session) is not working.
465 * Should find out call this function after _pi_http_finished_cb(). */
466 if (pi_session_table[entry].session)
467 g_object_unref(pi_session_table[entry].session);
469 DA_LOG_ERR(HTTPManager,"session is NULL. Cannot unref this.");
470 DA_LOG(HTTPManager,"unref session [%p]",pi_session_table[entry].session);
472 pi_session_table[entry].session = NULL;
474 pi_session_table[entry].queue = NULL;
475 pi_session_table[entry].is_paused = DA_FALSE;
476 pi_session_table[entry].is_using = DA_FALSE;
478 _da_thread_mutex_destroy(&(pi_session_table[entry].mutex));
479 _da_thread_cond_destroy(&(pi_session_table[entry].cond));
481 _da_thread_mutex_unlock (&mutex_for_session_table);
486 int _pi_http_get_avaiable_session_table_entry(void)
489 int avaiable_entry = -1;
491 _da_thread_mutex_lock (&mutex_for_session_table);
493 for (i = 0; i < MAX_SESSION_COUNT; i++) {
494 if (pi_session_table[i].is_using == DA_FALSE) {
495 /* pi_session_table[i].is_using = DA_TRUE; */
496 DA_LOG(HTTPManager,"available entry = %d", i);
503 _pi_http_init_session_table_entry(avaiable_entry);
504 _da_thread_mutex_unlock (&mutex_for_session_table);
506 return avaiable_entry;
509 da_bool_t _pi_http_register_queue_to_session_table(
510 const int in_session_table_entry, const queue_t *in_queue)
512 int entry = in_session_table_entry;
513 queue_t *queue = (queue_t *) in_queue;
514 da_bool_t ret = DA_FALSE;
516 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
517 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
521 _da_thread_mutex_lock (&mutex_for_session_table);
523 if (pi_session_table[entry].is_using == DA_FALSE) {
524 DA_LOG_ERR(HTTPManager,"this entry [%d] is not using", entry);
527 pi_session_table[entry].queue = queue;
528 DA_LOG(HTTPManager,"queue = %p", pi_session_table[entry].queue);
532 _da_thread_mutex_unlock (&mutex_for_session_table);
537 da_bool_t _pi_http_register_session_to_session_table(
538 const int in_session_table_entry, SoupSession *session)
540 int entry = in_session_table_entry;
541 da_bool_t ret = DA_FALSE;
543 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
544 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
548 if (DA_NULL == session) {
549 DA_LOG_ERR(HTTPManager,"invalid session = %p",session);
553 _da_thread_mutex_lock (&mutex_for_session_table);
555 if (pi_session_table[entry].is_using == DA_FALSE) {
558 pi_session_table[entry].session = session;
562 _da_thread_mutex_unlock (&mutex_for_session_table);
567 da_bool_t _pi_http_register_msg_to_session_table(
568 const int in_session_table_entry, SoupMessage *msg)
570 int entry = in_session_table_entry;
571 da_bool_t ret = DA_FALSE;
573 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
574 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
578 if (DA_NULL == msg) {
579 DA_LOG_ERR(HTTPManager,"invalid msg = %p",msg);
583 _da_thread_mutex_lock (&mutex_for_session_table);
585 if (pi_session_table[entry].is_using == DA_FALSE) {
588 pi_session_table[entry].msg = msg;
592 _da_thread_mutex_unlock (&mutex_for_session_table);
597 queue_t *_pi_http_get_queue_from_session_table_entry(
598 const int in_session_table_entry)
600 int entry = in_session_table_entry;
601 queue_t *out_queue = NULL;
603 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
604 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
608 _da_thread_mutex_lock (&mutex_for_session_table);
610 out_queue = pi_session_table[entry].queue;
611 _da_thread_mutex_unlock (&mutex_for_session_table);
616 void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType)
618 da_result_t ret = DA_RESULT_OK;
620 queue_t *da_queue = NULL;
621 q_event_t *da_event = NULL;
622 q_event_type_data da_event_type_data;
624 int session_table_entry = -1;
625 SoupMessageHeadersIter headers_iter;
627 const char *header_name;
628 const char *header_value;
630 http_msg_response_t *http_msg_response = NULL;
632 /* DA_LOG_FUNC_START(Default); */
634 if (msg->response_headers) {
635 ret = http_msg_response_create(&http_msg_response);
636 if (ret != DA_RESULT_OK)
639 http_msg_response_set_status_code(http_msg_response,
642 DA_LOG(HTTPManager,"\n----raw header---------------------------------------------");
643 DA_LOG_CRITICAL(HTTPManager,"status code = %d", msg->status_code);
644 soup_message_headers_iter_init(&headers_iter,
645 msg->response_headers);
646 while (soup_message_headers_iter_next(&headers_iter,
647 &header_name, &header_value)) {
648 if ((header_name != DA_NULL) && (header_value
650 http_msg_response_add_field(http_msg_response,
651 header_name, header_value);
654 DA_LOG(HTTPManager,"\n-------------------------------------------------------------\n");
658 if (using_content_sniffing && sniffedType)
659 http_msg_response_set_content_type(http_msg_response, sniffedType);
662 = _pi_http_get_session_table_entry_from_message(msg);
663 if (session_table_entry == -1) {
664 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
665 ret = DA_ERR_INVALID_ARGUMENT;
669 da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
671 da_queue = _pi_http_get_queue_from_session_table_entry(
672 session_table_entry);
674 ret = Q_make_http_data_event(da_event_type_data, &da_event);
675 if (ret != DA_RESULT_OK) {
676 DA_LOG_ERR(HTTPManager,"fail to make da_event");
679 Q_set_status_code_on_http_data_event(da_event, msg->status_code);
680 da_event->type.q_event_data_http.http_response_msg
683 Q_push_event(da_queue, da_event);
688 if (DA_RESULT_OK != ret)
689 http_msg_response_destroy(&http_msg_response);
694 void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char* body_data,
695 int received_body_len)
697 da_result_t ret = DA_RESULT_OK;
698 da_bool_t b_ret = DA_FALSE;
700 char *body_buffer = NULL;
701 queue_t *da_queue = NULL;
702 q_event_t *da_event = NULL;
703 q_event_type_data da_event_type_data;
704 int session_table_entry = -1;
705 int http_status = -1;
707 /* DA_LOG_FUNC_START(Default); */
709 http_status = msg->status_code;
712 = _pi_http_get_session_table_entry_from_message(msg);
713 if (session_table_entry == -1) {
714 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
715 ret = DA_ERR_INVALID_ARGUMENT;
719 if (received_body_len == 0) {
720 DA_LOG(HTTPManager,"Q_EVENT_TYPE_DATA_FINAL");
721 da_event_type_data = Q_EVENT_TYPE_DATA_FINAL;
723 da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
724 if (received_body_len > 0) {
725 body_buffer = (char*) calloc(1, received_body_len);
726 DA_LOG(HTTPManager,"body_buffer[%p]msg[%p]",body_buffer,msg);
727 if (body_buffer == DA_NULL) {
728 DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
731 memcpy(body_buffer, body_data, received_body_len);
735 da_queue = _pi_http_get_queue_from_session_table_entry(
736 session_table_entry);
738 ret = Q_make_http_data_event(da_event_type_data, &da_event);
739 if (ret != DA_RESULT_OK) {
740 DA_LOG_ERR(HTTPManager,"fail to make da_event");
743 Q_set_status_code_on_http_data_event(da_event, http_status);
744 Q_set_http_body_on_http_data_event(da_event, received_body_len,
747 _da_thread_mutex_lock (&(da_queue->mutex_queue));
748 b_ret = Q_push_event_without_lock(da_queue, da_event);
749 if (b_ret == DA_FALSE) {
750 DA_LOG_CRITICAL(HTTPManager,"----------------------------------------fail to push!");
752 pthread_mutex_t *session_mutex = NULL;
753 pthread_cond_t *session_cond = NULL;
756 = &(pi_session_table[session_table_entry].mutex);
758 = &(pi_session_table[session_table_entry].cond);
760 /* MUST keep this order for these mutexes */
761 _da_thread_mutex_lock (session_mutex);
762 _da_thread_mutex_unlock (&(da_queue->mutex_queue));
764 if (pi_session_table[session_table_entry].is_paused
766 DA_LOG_CRITICAL(HTTPManager,"paused!");
767 pi_session_table[session_table_entry].is_paused
769 _da_thread_cond_wait(session_cond, session_mutex);
771 DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
774 _da_thread_mutex_unlock (session_mutex);
776 DA_LOG_CRITICAL(HTTPManager,"wake up! push again");
777 Q_push_event(da_queue, da_event);
779 _da_thread_mutex_unlock (&(da_queue->mutex_queue));
787 if (DA_RESULT_OK != ret) {
788 if (DA_NULL != body_buffer) {
796 int _translate_error_code(int soup_error)
798 switch (soup_error) {
799 case SOUP_STATUS_CANT_RESOLVE:
800 case SOUP_STATUS_CANT_RESOLVE_PROXY:
801 case SOUP_STATUS_CANT_CONNECT:
802 case SOUP_STATUS_CANT_CONNECT_PROXY:
803 case SOUP_STATUS_IO_ERROR:
804 case SOUP_STATUS_MALFORMED:
805 case SOUP_STATUS_TRY_AGAIN:
806 case SOUP_STATUS_TOO_MANY_REDIRECTS:
807 return DA_ERR_NETWORK_FAIL;
809 case SOUP_STATUS_SSL_FAILED:
810 return DA_ERR_SSL_FAIL;
817 void _pi_http_store_neterr_to_queue(SoupMessage *msg)
819 da_result_t ret = DA_RESULT_OK;
821 queue_t *da_queue = NULL;
822 q_event_t *da_event = NULL;
823 int session_table_entry = -1;
825 DA_LOG_FUNC_START(HTTPManager);
827 error_type = _translate_error_code(msg->status_code);
830 = _pi_http_get_session_table_entry_from_message(msg);
831 if (session_table_entry == -1) {
832 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
833 ret = DA_ERR_INVALID_ARGUMENT;
837 da_queue = _pi_http_get_queue_from_session_table_entry(
838 session_table_entry);
840 DA_LOG_CRITICAL(HTTPManager,"Q_EVENT_TYPE_DATA_ABORT");
841 ret = Q_make_http_data_event(Q_EVENT_TYPE_DATA_ABORT, &da_event);
842 if (ret != DA_RESULT_OK) {
843 DA_LOG_ERR(HTTPManager,"fail to make da_event");
846 Q_set_error_type_on_http_data_event(da_event, error_type);
848 Q_push_event(da_queue, da_event);
855 int _pi_http_get_session_table_entry_from_message(SoupMessage *msg)
861 if (DA_NULL == msg) {
862 DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
866 _da_thread_mutex_lock (&mutex_for_session_table);
868 for (i = 0; i < MAX_SESSION_COUNT; i++) {
869 if (pi_session_table[i].is_using == DA_TRUE) {
870 if (pi_session_table[i].msg == msg) {
877 _da_thread_mutex_unlock (&mutex_for_session_table);
879 if (i == MAX_SESSION_COUNT) {
880 DA_LOG_ERR(HTTPManager,"fail to find message = %p", msg);
887 void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data)
891 DA_LOG_FUNC_START(HTTPManager);
893 url = soup_uri_to_string(soup_message_get_uri(msg), DA_FALSE);
895 DA_LOG(HTTPManager,"status_code[%d], reason[%s], url[%s]",msg->status_code,msg->reason_phrase,url);
902 if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
903 if (msg->status_code == SOUP_STATUS_CANCELLED) {
904 _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
906 _pi_http_store_neterr_to_queue(msg);
909 _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
914 /* this callback is called in case of redirection */
915 void _pi_http_restarted_cb(SoupMessage *msg, gpointer data)
917 DA_LOG_FUNC_START(HTTPManager);
918 /* Location URL is needed when extracting the file name from url.
919 * So, the response header should be handled by http mgr.*/
920 _pi_http_store_read_header_to_queue(msg, NULL);
923 void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data)
925 DA_LOG_FUNC_START(HTTPManager);
927 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
928 DA_LOG(HTTPManager,"Redirection !!");
929 if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
933 soup_message_body_set_accumulate(msg->response_body, FALSE);
935 if (!using_content_sniffing)
936 _pi_http_store_read_header_to_queue(msg, NULL);
938 DA_LOG(HTTPManager,"ignore because content sniffing is turned on");
941 void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType,
942 GHashTable *params, gpointer data)
944 DA_LOG_FUNC_START(HTTPManager);
946 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
947 DA_LOG(HTTPManager,"Redirection !!");
948 if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
952 if (using_content_sniffing)
953 _pi_http_store_read_header_to_queue(msg, sniffedType);
956 void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data)
958 DA_LOG_FUNC_START(HTTPManager);
960 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code))
963 if (chunk->data && chunk->length > 0) {
964 _pi_http_store_read_data_to_queue(msg, chunk->data,