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;
135 int session_table_entry = -1;
136 pi_http_method_t pi_http_method = PI_HTTP_METHOD_GET;
137 queue_t *queue = DA_NULL;
139 SoupSession *session = DA_NULL;
140 SoupMessage *msg = DA_NULL;
142 DA_LOG_FUNC_START(HTTPManager);
144 if (DA_FALSE == _pi_http_is_valid_input_for_tranx(input_for_tranx)) {
145 DA_LOG_ERR(HTTPManager,"input_for_tranx is invalid");
146 ret = DA_ERR_INVALID_ARGUMENT;
149 queue = input_for_tranx->queue;
150 pi_http_method = input_for_tranx->http_method;
151 url = input_for_tranx->http_msg_request->url;
154 session_table_entry = _pi_http_get_avaiable_session_table_entry();
155 if (session_table_entry == -1) {
156 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
159 DA_LOG(HTTPManager,"session_table_entry = %d", session_table_entry);
161 if (DA_FALSE == _pi_http_register_queue_to_session_table(
162 session_table_entry, queue)) {
163 _pi_http_destroy_session_table_entry(session_table_entry);
164 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
168 /* modified by keunsoon.lee 2010-09-20 use sync_new() instead of async_new() for make different soup thread from UI main thread*/
169 session = soup_session_sync_new();
170 /* session=soup_session_async_new(); */
172 DA_LOG_ERR(HTTPManager,"Fail to create session");
173 return DA_ERR_INVALID_URL;
175 DA_LOG(HTTPManager,"session[%p]", session);
177 SoupLogger* logger = soup_logger_new(SOUP_LOGGER_LOG_BODY, -1);
178 soup_logger_attach(logger, session);
179 g_object_unref(logger);
181 if (DA_FALSE == _pi_http_register_session_to_session_table(
182 session_table_entry, session)) {
183 _pi_http_init_session_table_entry(session_table_entry);
184 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
188 g_object_set(session, SOUP_SESSION_MAX_CONNS, MAX_SESSION_COUNT, NULL);
189 /* Set timeout unlimited time to resume a download which has ETag when the network is re-connected
190 * => This is changed to 180 seconds due to limitation of max downloading items.
192 g_object_set(session, SOUP_SESSION_TIMEOUT, MAX_TIMEOUT, NULL);
194 _set_proxy_on_soup_session(session, input_for_tranx->proxy_addr);
196 switch (pi_http_method) {
197 case PI_HTTP_METHOD_GET:
198 msg = soup_message_new(METHOD_GET, url);
200 case PI_HTTP_METHOD_POST:
201 msg = soup_message_new(METHOD_POST, url);
203 case PI_HTTP_METHOD_HEAD:
204 msg = soup_message_new(METHOD_HEAD, url);
207 DA_LOG_ERR(HTTPManager,"Cannot enter here");
210 DA_LOG(HTTPManager,"msg[%p]", msg);
211 /* if it is failed to create a msg, the url can be invalid, becasue of the input argument of soup_message_new API */
213 DA_LOG_ERR(HTTPManager,"Fail to create message");
214 ret = DA_ERR_INVALID_URL;
218 _fill_soup_msg_header(msg, input_for_tranx);
220 g_signal_connect(msg, "restarted", G_CALLBACK(_pi_http_restarted_cb),
221 NULL); /* for redirection case */
222 g_signal_connect(msg, "got-headers",
223 G_CALLBACK(_pi_http_gotheaders_cb), NULL);
224 g_signal_connect(msg, "got-chunk", G_CALLBACK(_pi_http_gotchunk_cb),
227 if (using_content_sniffing) {
228 soup_session_add_feature_by_type(session, SOUP_TYPE_CONTENT_SNIFFER);
229 g_signal_connect(msg, "content-sniffed",
230 G_CALLBACK(_pi_http_contentsniffed_cb), NULL);
232 soup_message_disable_feature(msg, SOUP_TYPE_CONTENT_SNIFFER);
235 soup_session_queue_message(session, msg, _pi_http_finished_cb, NULL);
236 // g_signal_connect(msg, "finished", G_CALLBACK(_pi_http_finished_cb), NULL);
238 if (DA_FALSE == _pi_http_register_msg_to_session_table(
239 session_table_entry, msg)) {
240 _pi_http_destroy_session_table_entry(session_table_entry);
241 ret = DA_ERR_ALREADY_MAX_DOWNLOAD;
245 *out_tranx_id = session_table_entry;
246 DA_LOG(HTTPManager,"*out_tranx_id = %d", *out_tranx_id);
252 da_result_t PI_http_disconnect_transaction(int in_tranx_id)
254 da_result_t ret = DA_RESULT_OK;
255 int session_table_entry = -1;
257 DA_LOG_FUNC_START(HTTPManager);
259 DA_LOG(HTTPManager,"in_tranx_id = %d", in_tranx_id);
261 session_table_entry = in_tranx_id;
263 _pi_http_destroy_session_table_entry(session_table_entry);
268 da_result_t PI_http_cancel_transaction(int in_tranx_id, da_bool_t abort_option)
270 da_result_t ret = DA_RESULT_OK;
271 SoupSession *session;
273 int session_table_entry = -1;
275 DA_LOG_FUNC_START(HTTPManager);
277 DA_LOG(HTTPManager,"in_tranx_id = %d", in_tranx_id);
279 session_table_entry = in_tranx_id;
280 if (!_pi_http_is_this_session_table_entry_using(session_table_entry)) {
281 DA_LOG_CRITICAL(HTTPManager,"not using session");
284 session = GET_SESSION_FROM_TABLE_ENTRY(session_table_entry);
285 msg = GET_MSG_FROM_TABLE_ENTRY(session_table_entry);
287 if (DA_NULL == session) {
288 DA_LOG_ERR(HTTPManager,"invalid session = %p", session);
292 if (DA_NULL == msg) {
293 DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
296 DA_LOG(HTTPManager,"Call soup cancel API : abort option[%d]",abort_option);
298 soup_session_abort(session);
300 soup_session_cancel_message(session, msg, SOUP_STATUS_CANCELLED);
301 DA_LOG(HTTPManager,"Call soup cancel API-Done");
306 void PI_http_pause_transaction(int transaction_id)
308 int session_table_entry = -1;
309 pthread_mutex_t *mutex;
310 pthread_cond_t *cond;
312 DA_LOG_FUNC_START(HTTPManager);
314 DA_LOG(HTTPManager,"in_tranx_id = %d", transaction_id);
316 session_table_entry = transaction_id;
318 if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
321 mutex = &(pi_session_table[session_table_entry].mutex);
322 cond = &(pi_session_table[session_table_entry].cond);
324 _da_thread_mutex_lock (mutex);
326 if (pi_session_table[session_table_entry].is_paused == DA_FALSE) {
327 DA_LOG_CRITICAL(HTTPManager,"paused!");
328 pi_session_table[session_table_entry].is_paused = DA_TRUE;
329 _da_thread_cond_wait(cond, mutex);
331 DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
334 _da_thread_mutex_unlock (mutex);
338 void PI_http_unpause_transaction(int transaction_id)
340 int session_table_entry = -1;
341 pthread_mutex_t *mutex;
342 pthread_cond_t *cond;
344 /* DA_LOG_FUNC_START(Default); */
346 session_table_entry = transaction_id;
348 if (!_pi_http_is_this_session_table_entry_using(session_table_entry))
351 mutex = &(pi_session_table[session_table_entry].mutex);
352 cond = &(pi_session_table[session_table_entry].cond);
354 _da_thread_mutex_lock (mutex);
356 if (pi_session_table[session_table_entry].is_paused == DA_TRUE) {
357 DA_LOG_CRITICAL(HTTPManager,"wake up!");
358 pi_session_table[session_table_entry].is_paused = DA_FALSE;
359 _da_thread_cond_signal(cond);
362 _da_thread_mutex_unlock (mutex);
366 da_bool_t _pi_http_is_valid_input_for_tranx(
367 const input_for_tranx_t *input_for_tranx)
369 if (!(input_for_tranx->http_msg_request)) {
370 DA_LOG_ERR(HTTPManager,"http_msg_request is NULL");
374 if (!((input_for_tranx->http_method == PI_HTTP_METHOD_GET) ||
375 (input_for_tranx->http_method == PI_HTTP_METHOD_POST) ||
376 (input_for_tranx->http_method == PI_HTTP_METHOD_HEAD))) {
377 DA_LOG_ERR(HTTPManager,"http_method is neither GET or POST or HEAD");
384 da_bool_t _pi_http_is_this_session_table_entry_using(
385 const int in_session_table_entry)
387 da_bool_t is_using = DA_FALSE;
389 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(in_session_table_entry))
392 _da_thread_mutex_lock (&mutex_for_session_table);
394 is_using = pi_session_table[in_session_table_entry].is_using;
396 _da_thread_mutex_unlock (&mutex_for_session_table);
401 void _pi_http_init_session_table_entry(const int in_session_table_entry)
403 int entry = in_session_table_entry;
405 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
408 // _da_thread_mutex_lock (&mutex_for_session_table);
410 pi_session_table[entry].is_using = DA_TRUE;
411 pi_session_table[entry].msg = NULL;
412 pi_session_table[entry].session = NULL;
413 pi_session_table[entry].queue = NULL;
415 _da_thread_mutex_init(&(pi_session_table[entry].mutex), DA_NULL);
416 _da_thread_cond_init(&(pi_session_table[entry].cond), NULL);
417 pi_session_table[entry].is_paused = DA_FALSE;
419 // _da_thread_mutex_unlock (&mutex_for_session_table);
424 void _pi_http_destroy_session_table_entry(const int in_session_table_entry)
426 int entry = in_session_table_entry;
428 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry))
431 _da_thread_mutex_lock (&mutex_for_session_table);
433 if (pi_session_table[entry].is_paused == DA_TRUE)
434 PI_http_unpause_transaction(entry);
436 /* Warning! Do not g_object_unref(msg) here!
437 * soup_session_queue_message() steals msg's reference count,
438 * so, we don't need to do anything for memory management.
440 * But, if using soup_session_send_message(), MUST call g_object_unref(msg). */
441 /* if (pi_session_table[entry].msg)
442 g_object_unref(pi_session_table[entry].msg); */
444 pi_session_table[entry].msg = NULL;
446 /* FIXME Cannot g_object_unref(session) here,
447 * because msg inside this session is not destoryed yet.
448 * The msg's reference count is stealed by soup_session_queue_message(),
449 * and it will be destroyed when _pi_http_finished_cb() is returned.
450 * For now, this _pi_http_destroy_session_table_entry() is called inside
451 * _pi_http_finished_cb(), so, g_object_unref(session) is not working.
452 * Should find out call this function after _pi_http_finished_cb(). */
453 if (pi_session_table[entry].session)
454 g_object_unref(pi_session_table[entry].session);
456 DA_LOG_ERR(HTTPManager,"session is NULL. Cannot unref this.");
457 DA_LOG(HTTPManager,"unref session [%p]",pi_session_table[entry].session);
459 pi_session_table[entry].session = NULL;
461 pi_session_table[entry].queue = NULL;
462 pi_session_table[entry].is_paused = DA_FALSE;
463 pi_session_table[entry].is_using = DA_FALSE;
465 _da_thread_mutex_destroy(&(pi_session_table[entry].mutex));
466 _da_thread_cond_destroy(&(pi_session_table[entry].cond));
468 _da_thread_mutex_unlock (&mutex_for_session_table);
473 int _pi_http_get_avaiable_session_table_entry(void)
476 int avaiable_entry = -1;
478 _da_thread_mutex_lock (&mutex_for_session_table);
480 for (i = 0; i < MAX_SESSION_COUNT; i++) {
481 if (pi_session_table[i].is_using == DA_FALSE) {
482 /* pi_session_table[i].is_using = DA_TRUE; */
483 DA_LOG_VERBOSE(HTTPManager,"available entry = %d", i);
490 _pi_http_init_session_table_entry(avaiable_entry);
491 _da_thread_mutex_unlock (&mutex_for_session_table);
493 return avaiable_entry;
496 da_bool_t _pi_http_register_queue_to_session_table(
497 const int in_session_table_entry, const queue_t *in_queue)
499 int entry = in_session_table_entry;
500 queue_t *queue = (queue_t *) in_queue;
501 da_bool_t ret = DA_FALSE;
503 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
504 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
508 _da_thread_mutex_lock (&mutex_for_session_table);
510 if (pi_session_table[entry].is_using == DA_FALSE) {
511 DA_LOG_ERR(HTTPManager,"this entry [%d] is not using", entry);
514 pi_session_table[entry].queue = queue;
515 DA_LOG_VERBOSE(HTTPManager,"queue = %p", pi_session_table[entry].queue);
519 _da_thread_mutex_unlock (&mutex_for_session_table);
524 da_bool_t _pi_http_register_session_to_session_table(
525 const int in_session_table_entry, SoupSession *session)
527 int entry = in_session_table_entry;
528 da_bool_t ret = DA_FALSE;
530 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
531 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
535 if (DA_NULL == session) {
536 DA_LOG_ERR(HTTPManager,"invalid session = %p",session);
540 _da_thread_mutex_lock (&mutex_for_session_table);
542 if (pi_session_table[entry].is_using == DA_FALSE) {
545 pi_session_table[entry].session = session;
549 _da_thread_mutex_unlock (&mutex_for_session_table);
554 da_bool_t _pi_http_register_msg_to_session_table(
555 const int in_session_table_entry, SoupMessage *msg)
557 int entry = in_session_table_entry;
558 da_bool_t ret = DA_FALSE;
560 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
561 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
565 if (DA_NULL == msg) {
566 DA_LOG_ERR(HTTPManager,"invalid msg = %p",msg);
570 _da_thread_mutex_lock (&mutex_for_session_table);
572 if (pi_session_table[entry].is_using == DA_FALSE) {
575 pi_session_table[entry].msg = msg;
579 _da_thread_mutex_unlock (&mutex_for_session_table);
584 queue_t *_pi_http_get_queue_from_session_table_entry(
585 const int in_session_table_entry)
587 int entry = in_session_table_entry;
588 queue_t *out_queue = NULL;
590 if (DA_FALSE == IS_VALID_SESSION_TABLE_ENTRY(entry)) {
591 DA_LOG_ERR(HTTPManager,"invalid entry = %d", entry);
595 _da_thread_mutex_lock (&mutex_for_session_table);
597 out_queue = pi_session_table[entry].queue;
598 _da_thread_mutex_unlock (&mutex_for_session_table);
603 void _pi_http_store_read_header_to_queue(SoupMessage *msg, const char *sniffedType)
605 da_result_t ret = DA_RESULT_OK;
607 queue_t *da_queue = NULL;
608 q_event_t *da_event = NULL;
609 q_event_type_data da_event_type_data;
611 int session_table_entry = -1;
612 SoupMessageHeadersIter headers_iter;
614 const char *header_name;
615 const char *header_value;
617 http_msg_response_t *http_msg_response = NULL;
619 /* DA_LOG_FUNC_START(Default); */
621 if (msg->response_headers) {
622 ret = http_msg_response_create(&http_msg_response);
623 if (ret != DA_RESULT_OK)
626 http_msg_response_set_status_code(http_msg_response,
629 DA_LOG(HTTPManager,"\n----raw header---------------------------------------------");
630 DA_LOG_CRITICAL(HTTPManager,"status code = %d", msg->status_code);
631 soup_message_headers_iter_init(&headers_iter,
632 msg->response_headers);
633 while (soup_message_headers_iter_next(&headers_iter,
634 &header_name, &header_value)) {
635 if ((header_name != DA_NULL) && (header_value
637 http_msg_response_add_field(http_msg_response,
638 header_name, header_value);
641 DA_LOG(HTTPManager,"\n-------------------------------------------------------------\n");
645 if (using_content_sniffing && sniffedType)
646 http_msg_response_set_content_type(http_msg_response, sniffedType);
649 = _pi_http_get_session_table_entry_from_message(msg);
650 if (session_table_entry == -1) {
651 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
652 ret = DA_ERR_INVALID_ARGUMENT;
656 da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
658 da_queue = _pi_http_get_queue_from_session_table_entry(
659 session_table_entry);
661 ret = Q_make_http_data_event(da_event_type_data, &da_event);
662 if (ret != DA_RESULT_OK) {
663 DA_LOG_ERR(HTTPManager,"fail to make da_event");
666 Q_set_status_code_on_http_data_event(da_event, msg->status_code);
667 da_event->type.q_event_data_http.http_response_msg
670 Q_push_event(da_queue, da_event);
675 if (DA_RESULT_OK != ret)
676 http_msg_response_destroy(&http_msg_response);
681 void _pi_http_store_read_data_to_queue(SoupMessage *msg, const char *body_data,
682 int received_body_len)
684 da_result_t ret = DA_RESULT_OK;
685 da_bool_t b_ret = DA_FALSE;
687 char *body_buffer = NULL;
688 queue_t *da_queue = NULL;
689 q_event_t *da_event = NULL;
690 q_event_type_data da_event_type_data;
691 int session_table_entry = -1;
692 int http_status = -1;
694 /* DA_LOG_FUNC_START(Default); */
696 http_status = msg->status_code;
699 = _pi_http_get_session_table_entry_from_message(msg);
700 if (session_table_entry == -1) {
701 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
702 ret = DA_ERR_INVALID_ARGUMENT;
706 if (received_body_len == 0) {
707 DA_LOG(HTTPManager,"Q_EVENT_TYPE_DATA_FINAL");
708 da_event_type_data = Q_EVENT_TYPE_DATA_FINAL;
710 da_event_type_data = Q_EVENT_TYPE_DATA_PACKET;
711 if (received_body_len > 0) {
712 body_buffer = (char*) calloc(1, received_body_len);
713 DA_LOG_VERBOSE(HTTPManager,"body_buffer[%p]msg[%p]",body_buffer,msg);
714 if (body_buffer == DA_NULL) {
715 DA_LOG_ERR(HTTPManager,"DA_ERR_FAIL_TO_MEMALLOC");
718 memcpy(body_buffer, body_data, received_body_len);
722 da_queue = _pi_http_get_queue_from_session_table_entry(
723 session_table_entry);
725 ret = Q_make_http_data_event(da_event_type_data, &da_event);
726 if (ret != DA_RESULT_OK) {
727 DA_LOG_ERR(HTTPManager,"fail to make da_event");
730 Q_set_status_code_on_http_data_event(da_event, http_status);
731 Q_set_http_body_on_http_data_event(da_event, received_body_len,
734 _da_thread_mutex_lock (&(da_queue->mutex_queue));
735 b_ret = Q_push_event_without_lock(da_queue, da_event);
736 if (b_ret == DA_FALSE) {
737 DA_LOG_CRITICAL(HTTPManager,"----------------------------------------fail to push!");
739 pthread_mutex_t *session_mutex = NULL;
740 pthread_cond_t *session_cond = NULL;
743 = &(pi_session_table[session_table_entry].mutex);
745 = &(pi_session_table[session_table_entry].cond);
747 /* MUST keep this order for these mutexes */
748 _da_thread_mutex_lock (session_mutex);
749 _da_thread_mutex_unlock (&(da_queue->mutex_queue));
751 if (pi_session_table[session_table_entry].is_paused
753 DA_LOG_CRITICAL(HTTPManager,"paused!");
754 pi_session_table[session_table_entry].is_paused
756 _da_thread_cond_wait(session_cond, session_mutex);
758 DA_LOG_CRITICAL(HTTPManager,"NOT paused!");
761 _da_thread_mutex_unlock (session_mutex);
763 DA_LOG_CRITICAL(HTTPManager,"wake up! push again");
764 Q_push_event(da_queue, da_event);
766 _da_thread_mutex_unlock (&(da_queue->mutex_queue));
774 if (DA_RESULT_OK != ret) {
775 if (DA_NULL != body_buffer) {
783 int _translate_error_code(int soup_error)
785 DA_LOG_CRITICAL(HTTPManager, "soup error code[%d]", soup_error);
786 switch (soup_error) {
787 case SOUP_STATUS_CANT_RESOLVE:
788 case SOUP_STATUS_CANT_RESOLVE_PROXY:
789 case SOUP_STATUS_CANT_CONNECT:
790 case SOUP_STATUS_CANT_CONNECT_PROXY:
791 case SOUP_STATUS_IO_ERROR:
792 case SOUP_STATUS_MALFORMED:
793 case SOUP_STATUS_TRY_AGAIN:
794 return DA_ERR_NETWORK_FAIL;
795 case SOUP_STATUS_SSL_FAILED:
796 return DA_ERR_SSL_FAIL;
797 case SOUP_STATUS_REQUEST_TIMEOUT:
798 return DA_ERR_HTTP_TIMEOUT;
799 case SOUP_STATUS_TOO_MANY_REDIRECTS:
800 return DA_ERR_TOO_MANY_REDIECTS;
802 return DA_ERR_NETWORK_FAIL;
806 void _pi_http_store_neterr_to_queue(SoupMessage *msg)
808 da_result_t ret = DA_RESULT_OK;
810 queue_t *da_queue = NULL;
811 q_event_t *da_event = NULL;
812 int session_table_entry = -1;
814 DA_LOG_FUNC_START(HTTPManager);
816 error_type = _translate_error_code(msg->status_code);
819 = _pi_http_get_session_table_entry_from_message(msg);
820 if (session_table_entry == -1) {
821 DA_LOG_ERR(HTTPManager,"Fail to find matched session table entry..");
822 ret = DA_ERR_INVALID_ARGUMENT;
826 da_queue = _pi_http_get_queue_from_session_table_entry(
827 session_table_entry);
829 DA_LOG_CRITICAL(HTTPManager,"Q_EVENT_TYPE_DATA_ABORT");
830 ret = Q_make_http_data_event(Q_EVENT_TYPE_DATA_ABORT, &da_event);
831 if (ret != DA_RESULT_OK) {
832 DA_LOG_ERR(HTTPManager,"fail to make da_event");
835 Q_set_error_type_on_http_data_event(da_event, error_type);
837 Q_push_event(da_queue, da_event);
844 int _pi_http_get_session_table_entry_from_message(SoupMessage *msg)
850 if (DA_NULL == msg) {
851 DA_LOG_ERR(HTTPManager,"invalid message = %p", msg);
855 _da_thread_mutex_lock (&mutex_for_session_table);
857 for (i = 0; i < MAX_SESSION_COUNT; i++) {
858 if (pi_session_table[i].is_using == DA_TRUE) {
859 if (pi_session_table[i].msg == msg) {
866 _da_thread_mutex_unlock (&mutex_for_session_table);
868 if (i == MAX_SESSION_COUNT) {
869 DA_LOG_ERR(HTTPManager,"fail to find message = %p", msg);
876 void _pi_http_finished_cb(SoupSession *session, SoupMessage *msg, gpointer data)
880 DA_LOG_FUNC_START(HTTPManager);
883 DA_LOG_ERR(HTTPManager, "Check NULL:msg");
887 url = soup_uri_to_string(soup_message_get_uri(msg), DA_FALSE);
889 DA_LOG(HTTPManager,"status_code[%d], reason[%s], url[%s]",msg->status_code,msg->reason_phrase,url);
896 if (SOUP_STATUS_IS_TRANSPORT_ERROR(msg->status_code)) {
897 if (msg->status_code == SOUP_STATUS_CANCELLED) {
898 _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
900 _pi_http_store_neterr_to_queue(msg);
903 _pi_http_store_read_data_to_queue(msg, DA_NULL, 0);
908 /* this callback is called in case of redirection */
909 void _pi_http_restarted_cb(SoupMessage *msg, gpointer data)
911 DA_LOG_FUNC_START(HTTPManager);
912 /* Location URL is needed when extracting the file name from url.
913 * So, the response header should be handled by http mgr.*/
916 DA_LOG_ERR(HTTPManager, "Check NULL:msg");
919 // If there are user id and password at url, libsoup handle it automatically.
920 if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
921 DA_LOG(HTTPManager,"Ignore:Unauthorized");
924 _pi_http_store_read_header_to_queue(msg, NULL);
927 void _pi_http_gotheaders_cb(SoupMessage *msg, gpointer data)
929 DA_LOG_FUNC_START(HTTPManager);
932 DA_LOG_ERR(HTTPManager, "Check NULL:msg");
936 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
937 DA_LOG(HTTPManager,"Redirection !!");
938 if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
942 // If there are user id and password at url, libsoup handle it automatically.
943 if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
944 DA_LOG(HTTPManager,"Ignore:Unauthorized");
948 soup_message_body_set_accumulate(msg->response_body, DA_FALSE);
950 if (!using_content_sniffing)
951 _pi_http_store_read_header_to_queue(msg, NULL);
953 DA_LOG(HTTPManager,"ignore because content sniffing is turned on");
956 void _pi_http_contentsniffed_cb(SoupMessage *msg, const char *sniffedType,
957 GHashTable *params, gpointer data)
959 DA_LOG_FUNC_START(HTTPManager);
962 DA_LOG_ERR(HTTPManager, "Check NULL:msg");
966 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code)) {
967 DA_LOG(HTTPManager,"Redirection !!");
968 if (SOUP_STATUS_NOT_MODIFIED != msg->status_code)
972 // If there are user id and password at url, libsoup handle it automatically.
973 if (msg->status_code == SOUP_STATUS_UNAUTHORIZED) {
974 DA_LOG(HTTPManager,"Ignore:Unauthorized");
978 if (using_content_sniffing)
979 _pi_http_store_read_header_to_queue(msg, sniffedType);
982 void _pi_http_gotchunk_cb(SoupMessage *msg, SoupBuffer *chunk, gpointer data)
984 // DA_LOG_FUNC_START(HTTPManager);
987 DA_LOG_ERR(HTTPManager, "Check NULL:msg");
992 DA_LOG_ERR(HTTPManager, "Check NULL:chunk");
996 if (SOUP_STATUS_IS_REDIRECTION(msg->status_code))
999 if (chunk->data && chunk->length > 0) {
1000 _pi_http_store_read_data_to_queue(msg, chunk->data,