Apply the secure log in exception log
[framework/osp/net.git] / src / http / FNetHttp_HttpTransactionImpl.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19  * @file                FNetHttp_HttpTransactionImpl.cpp
20  * @brief               This is the implementation file for _HttpTransactionImpl class.
21  */
22
23 #include <unique_ptr.h>
24 #include <unistd.h>
25 #include <stdlib.h>
26 #include <vconf.h>
27 #include <FBaseByteBuffer.h>
28 #include <FBaseUtilStringUtil.h>
29 #include <FIoDirectory.h>
30 #include <FAppApp.h>
31 #include <FNetHttpHttpTypes.h>
32 #include <FNetHttpHttpRequest.h>
33 #include <FNetHttpHttpResponse.h>
34 #include <FNetHttpHttpHeader.h>
35 #include <FNetHttpHttpSession.h>
36 #include <FNetHttpHttpAuthentication.h>
37 #include <FNetHttpIHttpTransactionEventListener.h>
38 #include <FNetHttpIHttpEntity.h>
39 #include <FNetHttpIHttpProgressEventListener.h>
40 #include <FBaseSysLog.h>
41 #include <FSecurity.h>
42 #include <FBase_StringConverter.h>
43 #include <FBaseRt_EventDispatcher.h>
44 #include <FSecCert_CertService.h>
45 #include <FSecCert_CertServiceProxy.h>
46 #include "FNet_ManagedNetConnectionImpl.h"
47 #include "FNetHttp_HttpCommon.h"
48 #include "FNetHttp_HttpMultipleConnectionInfo.h"
49 #include "FNetHttp_HttpTransactionImpl.h"
50 #include "FNetHttp_HttpTransactionUserData.h"
51 #include "FNetHttp_HttpCurl.h"
52 #include "FNetHttp_HttpDeleter.h"
53 #include "FNetHttp_HttpSocketInfo.h"
54 #include "FNetHttp_HttpHeaderImpl.h"
55 #include "FNetHttp_HttpSessionImpl.h"
56 #include "FNetHttp_HttpRequestImpl.h"
57 #include "FNetHttp_HttpResponseImpl.h"
58 #include "FNetHttp_HttpAuthenticationImpl.h"
59 #include "FNetHttp_HttpTransactionEvent.h"
60 #include "FNetHttp_HttpTransactionEventArg.h"
61
62 using namespace std;
63 using namespace Tizen::Base;
64 using namespace Tizen::Base::Utility;
65 using namespace Tizen::Base::Collection;
66 using namespace Tizen::Base::Runtime;
67 using namespace Tizen::Security::Cert;
68 using namespace Tizen::Io;
69
70 namespace Tizen { namespace Net { namespace Http
71 {
72
73 int _HttpTransactionImpl::__generatedTransactionId = -1;
74
75 _HttpTransactionImpl::_HttpTransactionImpl(HttpTransaction* pHttpTransaction)
76         : __transactionId(-1)
77         , __sessionId(-1)
78         , __pHttpSessionImpl(null)
79         , __pHttpMultipleConnectionInfo(null)
80         , __pHttpTransaction(pHttpTransaction)
81         , __pHttpRequest(null)
82         , __pHttpResponse(null)
83         , __pHttpTransactionEvent(null)
84         , __authType(NET_HTTP_AUTH_NONE)
85         , __pHttpAuthenticationImpl(null)
86         , __pRequestBuffer(null)
87         , __pUserData(null)
88         , __isClosed(false)
89         , __isCanceled(false)
90         , __isSubmitted(false)
91         , __isPendingTransaction(false)
92         , __enableTransactionReadyToWrite(false)
93         , __isHeaderEventFired(false)
94         , __uploadCurrentProgress(0)
95         , __donwloadCurrentProgress(0)
96         , __timeout(0)
97         , __certificateId(-1)
98         , __isAlreadyResumed(false)
99         , __isAlreadyPaused(false)
100         , __isCertRequiredEventFired(false)
101         , __certificateFlag(HTTP_CV_FLAG_AUTOMATIC)
102         , __pHttpProgressListener(null)
103         , __pHttpTransactionUserData(null)
104         , __pHttpCurl(null)
105         , __pTimerSource(null)
106 {
107 }
108
109 _HttpTransactionImpl::~_HttpTransactionImpl(void)
110 {
111         SysLog(NID_NET_HTTP, "The _HttpTransactionImpl instance will be deleted.");
112
113         Dispose();
114
115         if (__pHttpRequest != null)
116         {
117                 _HttpRequestImpl::DeleteHttpRequest(__pHttpRequest);
118                 __pHttpRequest = null;
119         }
120
121         if (__pHttpResponse != null)
122         {
123                 _HttpResponseImpl::DeleteHttpResponse(__pHttpResponse);
124                 __pHttpResponse = null;
125         }
126
127         if (__pHttpTransactionUserData != null)
128         {
129                 __pHttpTransactionUserData->__pHttpTransactionImpl = null;
130                 __pHttpTransactionUserData->Release();
131         }
132
133         if (__pHttpAuthenticationImpl != null)
134         {
135                 delete __pHttpAuthenticationImpl;
136                 __pHttpAuthenticationImpl = null;
137         }
138
139         if (__pHttpCurl != null)
140         {
141                 __pHttpCurl->Release();
142         }
143
144         __transactionListenerList.RemoveAll();
145
146         if (__pHttpTransactionEvent != null)
147         {
148                 delete __pHttpTransactionEvent;
149                 __pHttpTransactionEvent = null;
150         }
151
152         if (__pRequestBuffer != null)
153         {
154                 delete __pRequestBuffer;
155                 __pRequestBuffer = null;
156         }
157
158         if (__pTimerSource != null)
159         {
160                 int timerId = g_source_get_id(__pTimerSource);
161                 g_source_set_callback(__pTimerSource, null, null, null);
162                 SysLog(NID_NET_HTTP, "Deleted g_source_destroy(%d)", timerId);
163                 g_source_destroy(__pTimerSource);
164                 g_source_unref(__pTimerSource);
165                 __pTimerSource = null;
166                 SysLog(NID_NET_HTTP, "Cancelled the TimerSource[%d] of HttpTransaction[%d].", timerId, __transactionId);
167         }
168
169         __pHttpMultipleConnectionInfo = null;
170
171         SysLog(NID_NET_HTTP, "The _HttpTransactionImpl instance was deleted.");
172 }
173
174 result
175 _HttpTransactionImpl::Construct(_HttpSessionImpl& httpSessionImpl, HttpHeader* pCommonHeader, CURL* pCurl)
176 {
177         result r = E_SUCCESS;
178
179         bool isCreatedCurl = false;
180         unique_ptr<HttpRequest, _HttpRequestDeleter> pHttpRequest;
181         unique_ptr<HttpResponse, _HttpResponseDeleter> pHttpResponse;
182         unique_ptr<_HttpTransactionEvent> pHttpTransactionEvent;
183         unique_ptr<_HttpTransactionUserData> pHttpTransactionUserData;
184
185         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
186                                            E_INVALID_STATE, "Already closed.");
187
188         __pHttpSessionImpl = &httpSessionImpl;
189         __pHttpMultipleConnectionInfo = __pHttpSessionImpl->GetHttpMultipleConnectionInfo();
190         SysTryReturnResult(NID_NET_HTTP, __pHttpMultipleConnectionInfo != null,
191                                            E_SYSTEM, "__pHttpMultipleConnectionInfo is null.");
192
193         __sessionId = __pHttpSessionImpl->GetSessionId();
194
195         pHttpRequest.reset(_HttpRequestImpl::CreateHttpRequestN());
196         SysTryReturnResult(NID_NET_HTTP, pHttpRequest != null,
197                                            E_OUT_OF_MEMORY, "Memory allocation failed.");
198
199         r = _HttpRequestImpl::GetInstance(*pHttpRequest)->Construct(*this, pCommonHeader);
200         SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Propagating.");
201
202         pHttpResponse.reset(_HttpResponseImpl::CreateHttpResponseN());
203         SysTryReturnResult(NID_NET_HTTP, pHttpResponse != null,
204                                            E_OUT_OF_MEMORY, "Memory allocation failed.");
205
206         r = _HttpResponseImpl::GetInstance(*pHttpResponse)->Construct(*this);
207         SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Propagating.");
208
209         if (pCurl == null)
210         {
211                 pCurl = curl_easy_init();
212                 SysTryReturnResult(NID_NET_HTTP, pCurl != null, E_SYSTEM, "Failed to call curl_easy_init(), the pCurl must not be null.");
213                 SysLog(NID_NET_HTTP, "Created an instance of CURL. [%x]", pCurl);
214                 isCreatedCurl = true;
215         }
216         else
217         {
218                 SysLog(NID_NET_HTTP, "Reused the pCurl[%x]", pCurl);
219         }
220
221         __pHttpCurl = new (std::nothrow) _HttpCurl(pCurl, false);
222         if (__pHttpCurl == null)
223         {
224                 if (isCreatedCurl)
225                 {
226                         curl_easy_cleanup(pCurl);
227                 }
228                 r = E_OUT_OF_MEMORY;
229                 SysLogException(NID_NET_HTTP, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
230                 goto CATCH;
231         }
232
233         __transactionId = GenerateTransactionId();
234         __transactionListenerList.Construct();
235
236         pHttpTransactionEvent.reset(new (std::nothrow) _HttpTransactionEvent());
237         SysTryCatch(NID_NET_HTTP, pHttpTransactionEvent != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
238                                 "[E_OUT_OF_MEMORY] Memory allocation failed.");
239
240         pHttpTransactionEvent->Construct(__pHttpSessionImpl, this);
241
242         pHttpTransactionUserData.reset(new (std::nothrow) _HttpTransactionUserData(this, __pHttpCurl));
243         SysTryCatch(NID_NET_HTTP, pHttpTransactionUserData != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY,
244                                 "[E_OUT_OF_MEMORY] Memory allocation failed.");
245
246         __pHttpRequest = pHttpRequest.release();
247         __pHttpResponse = pHttpResponse.release();
248         __pHttpTransactionEvent = pHttpTransactionEvent.release();
249         __pHttpTransactionUserData = pHttpTransactionUserData.release();
250
251         SysLog(NID_NET_HTTP, "The HttpTransaction[%d] was constructed.", __transactionId);
252
253         return r;
254
255 CATCH:
256
257         if (__pHttpCurl != null)
258         {
259                 __pHttpCurl->Release();
260                 __pHttpCurl = null;
261         }
262
263         return r;
264 }
265
266 HttpTransaction*
267 _HttpTransactionImpl::CreateHttpTransactionN(void)
268 {
269         return new (std::nothrow) HttpTransaction();
270 }
271
272 void
273 _HttpTransactionImpl::DeleteHttpTransaction(HttpTransaction* pHttpTransaction)
274 {
275         delete pHttpTransaction;
276 }
277
278 result
279 _HttpTransactionImpl::Dispose()
280 {
281         result r = E_SUCCESS;
282
283         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
284                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
285
286         r = __pHttpSessionImpl->CloseTransaction(*__pHttpTransaction);
287
288         return r;
289 }
290
291 result
292 _HttpTransactionImpl::Close(void)
293 {
294         result r = E_SUCCESS;
295
296         IEnumeratorT< IHttpTransactionEventListener* >* pEnum = null;
297         IHttpTransactionEventListener* pHttpTransactionEventListener = null;
298         int sockFd = 0;
299
300         pEnum = __transactionListenerList.GetEnumeratorN();
301         while (pEnum->MoveNext() == E_SUCCESS)
302         {
303                 r = pEnum->GetCurrent(pHttpTransactionEventListener);
304
305                 if (pHttpTransactionEventListener != null)
306                         __pHttpTransactionEvent->RemoveListener(*pHttpTransactionEventListener);
307         }
308         delete pEnum;
309
310         if (__pHttpTransactionUserData->GetSocketFd() >= 0)
311         {
312                 sockFd = __pHttpTransactionUserData->GetSocketFd();
313                 SysLog(NID_NET_HTTP, "The socket(%d) was closed.", sockFd);
314         }
315
316         __isClosed = true;
317
318         __pHttpTransactionUserData->__isAlreadyClosedTransaction = true;
319
320         __pHttpTransactionUserData->__isAbortedTransaction = true;
321
322         SysLog(NID_NET_HTTP, "The HttpTransaction[%d] was closed.", __transactionId);
323
324         ClearLastResult();
325
326         return E_SUCCESS;
327 }
328
329 result
330 _HttpTransactionImpl::Abort(void)
331 {
332         result r = E_SUCCESS;
333
334         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
335                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
336
337         if (__pHttpTransactionUserData->GetSocketFd() >= 0)
338         {
339                 int sockFd = __pHttpTransactionUserData->GetSocketFd();
340                 SysLog(NID_NET_HTTP, "SocketFd(%d) will be closed. HttpTransaction[%d]", sockFd, __transactionId);
341                 close(sockFd);
342                 SysLog(NID_NET_HTTP, "Socket was closed. HttpTransaction[%d]");
343
344         }
345         __pHttpTransactionUserData->__isAbortedTransaction = true;
346
347         return r;
348 }
349
350 result
351 _HttpTransactionImpl::Set(_HttpTransactionImpl* pHttpTransactionImpl)
352 {
353         result r = E_SUCCESS;
354
355         HttpRequest* pHttpRequest = null;
356         _HttpRequestImpl* pHttpRequestImpl = null;
357         _HttpRequestImpl* pSrcHttpRequestImpl = null;
358
359         ByteBuffer* pRequestBuffer = null;
360         ArrayListT< IHttpTransactionEventListener* > listenerList;
361         Object* pUserObject = null;
362
363         //Sets user object.
364         pUserObject = pHttpTransactionImpl->GetUserObject();
365         __pUserData = pUserObject;
366
367         //Sets event listener.
368         r = listenerList.Construct(*(pHttpTransactionImpl->GetEventListenerList()));
369         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, E_OUT_OF_MEMORY,
370                                  "[E_OUT_OF_MEMORY] Memory allocation failed.");
371
372         for (int i = 0; i < listenerList.GetCount(); i++)
373         {
374                 IHttpTransactionEventListener* pListener = null;
375                 r = listenerList.GetAt(i, pListener);
376                 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS && pListener != null, null, E_SYSTEM,
377                                         "[E_SYSTEM] A system error has occurred.");
378
379                 r = this->AddHttpTransactionListener(*pListener);
380                 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, r,
381                                         "[%s] Failed to add the HttpTransactionEventListener.", GetErrorMessage(r));
382         }
383
384         __pHttpProgressListener = pHttpTransactionImpl->GetHttpProgressEventListener();
385
386         __enableTransactionReadyToWrite = pHttpTransactionImpl->IsTransactionReadyToWriteEanbled();
387         __timeout = pHttpTransactionImpl->GetTimeout();
388         __certificateId = pHttpTransactionImpl->GetClientCertificate();
389         __isAlreadyResumed = pHttpTransactionImpl->IsAlreadyResumed();
390         __certificateFlag = pHttpTransactionImpl->GetServerCertificateVerification();
391
392         pHttpRequest = pHttpTransactionImpl->GetRequest();
393         SysTryReturn(NID_NET_HTTP, pHttpRequest != null, null, E_SYSTEM,
394                                  "[E_SYSTEM] An internal error has occurred.");
395
396         pHttpRequestImpl = _HttpRequestImpl::GetInstance(*pHttpRequest);
397         SysTryReturn(NID_NET_HTTP, pHttpRequestImpl != null, null, E_SYSTEM,
398                                  "[E_SYSTEM] An internal error has occurred.");
399
400         pSrcHttpRequestImpl = _HttpRequestImpl::GetInstance(*__pHttpRequest);
401         SysTryReturn(NID_NET_HTTP, pSrcHttpRequestImpl != null, null, E_SYSTEM,
402                                  "[E_SYSTEM] An internal error has occurred.");
403
404         //Sets HttpRequest.
405         r = pSrcHttpRequestImpl->Set(pHttpRequestImpl);
406         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, E_SYSTEM,
407                                  "[E_SYSTEM] An internal error has occurred.");
408
409         pRequestBuffer = pHttpTransactionImpl->GetRequestBuffer();
410         if (pRequestBuffer != null)
411         {
412                 //Clear the flag of _HttpRequestImpl
413                 pSrcHttpRequestImpl->SetReceivedTransactionReadyToWriteEvent(false);
414
415                 r = pSrcHttpRequestImpl->WriteBody(*pRequestBuffer);
416                 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, r, "[%s] Failed to write the body.", GetErrorMessage(r));
417
418                 SysLog(NID_NET_HTTP, "The __pRequestBuffer is added to the Body.");
419         }
420
421         return r;
422 }
423
424 String
425 _HttpTransactionImpl::GetDefaultUserAgent(void)
426 {
427         ClearLastResult();
428
429         SysLog(NID_NET_HTTP, "Set the Default User-Agent.");
430
431         char* pUserAgent = vconf_get_str(VCONFKEY_BROWSER_USER_AGENT);
432         SysAssertf(pUserAgent != null, "Failed to get default user agent(VCONFKEY_BROWSER_USER_AGENT)");
433
434         String userAgent(pUserAgent);
435         SysLog(NID_NET_HTTP, "Default User-Agent is %ls.", userAgent.GetPointer());
436         free(pUserAgent);
437
438         return userAgent;
439 }
440
441 result
442 _HttpTransactionImpl::Submit(void)
443 {
444         result r = E_SUCCESS;
445
446         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
447                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
448
449         SysTryReturnResult(NID_NET_HTTP, __isSubmitted == false,
450                                            E_INVALID_STATE, "HttpTransaction[%d] is already submitted.", __transactionId);
451
452         SysTryReturnResult(NID_NET_HTTP, __pHttpSessionImpl->IsSessionValid(),
453                                            E_INVALID_SESSION, "The HttpSession is invalid. Construct a new HttpSession.");
454
455         CURL* pCurl = null;
456         CURLMcode rc;
457         char* pUrl = null;
458         char* pMethodName = null;
459         struct curl_slist* pRequestHeaderList = null;
460
461         HttpVersion httpVersion;
462         String hostAddress;
463         String url;
464         bool hasProtocolScheme = false;
465         bool compareHost = false;
466         String methodName;
467         String contentLength;
468         HttpHeader* pHeader = null;
469         _HttpHeaderImpl* pHeaderImpl = null;
470         _HttpRequestImpl* pRequestImpl = null;
471
472         ByteBuffer* pBodyBuffer = null;
473         int bodySize = 0;
474         long long contentLen = -1;
475         NetHttpAuthScheme authScheme = NET_HTTP_AUTH_NONE;
476         String outFiledName;
477         String encoding;
478
479         bool isEnableOnHttpBodyReadyToWrite = false;
480
481         SysLog(NID_NET_HTTP, "The HttpTransaction[%d] will be submitted. HttpSessionId[%d]", __transactionId, __sessionId);
482
483         pRequestImpl = _HttpRequestImpl::GetInstance(*__pHttpRequest);
484         pHeader = pRequestImpl->GetHeader();
485         SysTryReturnResult(NID_NET_HTTP, pHeader != null,
486                                            E_SYSTEM, "The header must not be null.");
487
488         pHeaderImpl = _HttpHeaderImpl::GetInstance(*pHeader);
489         SysTryReturnResult(NID_NET_HTTP, pHeaderImpl != null,
490                                            E_SYSTEM, "The header must not be null.");
491
492         pCurl = __pHttpCurl->GetCurl();
493         SysTryReturnResult(NID_NET_HTTP, pCurl != null,
494                                            E_SYSTEM, "The Curl must not be null.");
495
496         //Set the http version.
497         httpVersion = pRequestImpl->GetVersion();
498         if (httpVersion == HTTP_VERSION_1_0)
499         {
500                 curl_easy_setopt(pCurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
501         }
502         else
503         {
504                 curl_easy_setopt(pCurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
505         }
506
507         //Check if the host of url equals the host address of HttpSession.
508         r = pRequestImpl->GetUri(url);
509         SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS && url.IsEmpty() == false,
510                                            E_INVALID_ARG, "Failed to get the uri.");
511
512         SysSecureLog(NID_NET_HTTP, "The request uri is %ls.", url.GetPointer());
513
514         hostAddress = __pHttpSessionImpl->GetHostAddress();
515
516         hasProtocolScheme = _HttpUtility::HasProtocolScheme(url);
517         if (!hasProtocolScheme)
518         {
519                 if (__pHttpSessionImpl->GetSessionMode() == NET_HTTP_SESSION_MODE_MULTIPLE_HOST)
520                 {
521                         url = _HTTP_PROTOCOL_SCHEME + url;
522                 }
523                 else
524                 {
525                         //Add the scheme of host address.
526                         String scheme = _HttpUtility::GetProtocolScheme(hostAddress);
527                         scheme.Trim();
528                         url = scheme + url;
529                         SysSecureLog(NID_NET_HTTP, "Added the scheme to url(%ls).", url.GetPointer());
530                 }
531
532                 SysSecureLog(NID_NET_HTTP, "Added the scheme to url(%ls).", url.GetPointer());
533         }
534
535         //Compare the host of HttpSessoin with the host of uri.
536         if (__pHttpSessionImpl->GetSessionMode() != NET_HTTP_SESSION_MODE_MULTIPLE_HOST)
537         {
538                 compareHost = _HttpUtility::CompareHost(hostAddress, url);
539                 r = GetLastResult();
540                 r = TransExceptionsExclusive(r, E_INVALID_ARG, E_OUT_OF_MEMORY);
541                 SysSecureTryReturnResult(NID_NET_HTTP, compareHost,
542                                                    r, "The host address(%ls) of HttpSession is different with url(%ls).", hostAddress.GetPointer(), url.GetPointer());
543         }
544
545         pUrl = _StringConverter::CopyToCharArrayN(url);
546         SysTryReturnResult(NID_NET_HTTP, pUrl != null,
547                                            E_OUT_OF_MEMORY, "Memory allocation failed.");
548
549         //Set the url.
550         curl_easy_setopt(pCurl, CURLOPT_URL, pUrl);
551         delete[] pUrl;
552
553         //Set the network interface.
554         if (!__pHttpSessionImpl->GetDeviceName().IsEmpty())
555         {
556                 char* pDeviceName = _StringConverter::CopyToCharArrayN(__pHttpSessionImpl->GetDeviceName());
557                 SysTryReturnResult(NID_NET_HTTP, pDeviceName != null,
558                                                    E_OUT_OF_MEMORY, "Memory allocation failed.");
559
560                 SysLog(NID_NET_HTTP, "[Target] The device name is %s.", pDeviceName);
561                 curl_easy_setopt(pCurl, CURLOPT_INTERFACE, pDeviceName);
562                 delete[] pDeviceName;
563         }
564
565         //Set the proxy address.
566         if (__pHttpSessionImpl->GetProxyAddress() != null)
567         {
568                 char* pProxyAddress = _StringConverter::CopyToCharArrayN(*__pHttpSessionImpl->GetProxyAddress());
569                 SysTryReturnResult(NID_NET_HTTP, pProxyAddress != null,
570                                                    E_OUT_OF_MEMORY, "Memory allocation failed.");
571
572                 curl_easy_setopt(pCurl, CURLOPT_PROXY, pProxyAddress);
573                 delete[] pProxyAddress;
574         }
575
576         //Set the method.
577         methodName = pRequestImpl->GetMethodName();
578         SysTryReturnResult(NID_NET_HTTP, !methodName.IsEmpty(), E_INVALID_ARG, "Method name is empty.");
579
580         pMethodName = _StringConverter::CopyToCharArrayN(methodName);
581         curl_easy_setopt(pCurl, CURLOPT_CUSTOMREQUEST, pMethodName);
582         delete[] pMethodName;
583
584         //Set the user-agent.
585         if (!pHeaderImpl->HasHeader(_HTTP_USERAGENT_HEADER_NAME, outFiledName))
586         {
587                 SysLog(NID_NET_HTTP, "Set the default user agent.");
588                 String userAgent = GetDefaultUserAgent();
589                 SysTryReturnResult(NID_NET_HTTP, userAgent.IsEmpty() == false, E_SYSTEM, "Default User-Agent is empty.");
590
591                 r = pHeaderImpl->AddField(_HTTP_USERAGENT_HEADER_NAME, userAgent);
592                 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS,
593                                                    r, "Propagating.");
594         }
595
596         //Set the headers.
597         pRequestHeaderList = pHeaderImpl->MakeCurlHeaderList();
598         if (pRequestHeaderList != null)
599         {
600                 curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pRequestHeaderList);
601                 __pHttpTransactionUserData->__pCurlRequestHeaderList = pRequestHeaderList;
602         }
603
604         //Set the cookie.
605         if (__pHttpSessionImpl->GetHttpCookieFlag() == NET_HTTP_COOKIE_FLAG_ALWAYS_MANUAL)
606         {
607                 if (pRequestImpl->HasCookie())
608                 {
609                         String cookies = pRequestImpl->GetCookie();
610                         SysLog(NID_NET_HTTP, "Set the Cookies(%ls).", cookies.GetPointer());
611                         char* pCookies = _StringConverter::CopyToCharArrayN(cookies);
612                         SysTryReturnResult(NID_NET_HTTP, pCookies != null,
613                                                            E_OUT_OF_MEMORY, "Memory allocation failed.");
614
615                         curl_easy_setopt(pCurl, CURLOPT_COOKIE, pCookies);
616                         delete[] pCookies;
617                 }
618
619         }
620         else if (__pHttpSessionImpl->GetHttpCookieFlag() == NET_HTTP_COOKIE_FLAG_ALWAYS_AUTOMATIC)
621         {
622                 String filePath = _HttpUtility::GetCookieFilePath();
623                 r = GetLastResult();
624                 r = TransExceptionsExclusive(r, E_SYSTEM, E_OUT_OF_MEMORY);
625                 SysTryReturnResult(NID_NET_HTTP, !filePath.IsEmpty(), r, "Failed to get cookie path of system.");
626
627                 char* pFilePath = _StringConverter::CopyToCharArrayN(filePath);
628                 SysTryReturnResult(NID_NET_HTTP, pFilePath != null,
629                                                    E_OUT_OF_MEMORY, "Memory allocation failed.");
630
631                 curl_easy_setopt(pCurl, CURLOPT_COOKIEFILE, pFilePath);
632                 curl_easy_setopt(pCurl, CURLOPT_COOKIEJAR, pFilePath);
633
634                 delete[] pFilePath;
635
636                 SysLog(NID_NET_HTTP, "Set the Cookies automatically.");
637         }
638
639         encoding = pRequestImpl->GetAcceptEncoding();
640
641         if (!encoding.IsEmpty())
642         {
643                 char* pEncodingType = _StringConverter::CopyToCharArrayN(encoding);
644                 SysTryReturnResult(NID_NET_HTTP, pEncodingType != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
645
646                 curl_easy_setopt(pCurl, CURLOPT_ENCODING, pEncodingType);
647                 delete[] pEncodingType;
648         }
649
650         if (pHeaderImpl->GetHeaderValue(_HTTP_CONTENT_LENGTH_HEADER_NAME, contentLength))
651         {
652                 r = LongLong::Parse(contentLength, contentLen);
653                 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS,
654                                                    E_INVALID_ARG, "Failed to parse the content-length.");
655                 //Set Content-Length
656                 if (contentLen > 0)
657                 {
658                         curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE_LARGE, static_cast< curl_off_t >(contentLen));
659                         SysLog(NID_NET_HTTP, "Set the Content-Length(%lld).", contentLen);
660                 }
661                 else if (contentLen == 0)
662                 {
663                         curl_easy_setopt(pCurl, CURLOPT_POSTFIELDSIZE_LARGE, static_cast< curl_off_t >(contentLen));
664                         curl_easy_setopt(pCurl, CURLOPT_COPYPOSTFIELDS, NULL);
665                         SysLog(NID_NET_HTTP, "Set the Content-Length(%lld).", contentLen);
666                 }
667
668                 SysLog(NID_NET_HTTP, "The Content-Length is %lld.", contentLen);
669         }
670         else
671         {
672                 SysLog(NID_NET_HTTP, "The Content-Length is not set.");
673         }
674
675         bodySize = pRequestImpl->GetTotalBodyLength();
676
677         if (__enableTransactionReadyToWrite)
678         {
679                 if (contentLen >= 0 && contentLen <= bodySize)
680                 {
681                         SysLog(NID_NET_HTTP, "Content-Length(%lld) is equals or less than the bodySize(%u).", contentLen, bodySize);
682                         isEnableOnHttpBodyReadyToWrite = false;
683                 }
684                 else
685                 {
686                         isEnableOnHttpBodyReadyToWrite = true;
687                 }
688                 SysLog(NID_NET_HTTP, "The isEnableOnHttpBodyReadyToWrite is %d.", isEnableOnHttpBodyReadyToWrite);
689         }
690
691         //Set the content and content size.
692         if (!isEnableOnHttpBodyReadyToWrite)
693         {
694                 if (!pRequestImpl->IsEmptyBody())
695                 {
696                         if (__pRequestBuffer != null)
697                         {
698                                 delete __pRequestBuffer;
699                         }
700
701                         __pRequestBuffer = pRequestImpl->ReadAllBodyN();
702
703                         pBodyBuffer = pRequestImpl->ReadBodyN();
704                         if (pBodyBuffer != null)
705                         {
706                                 int bodySize = pBodyBuffer->GetRemaining();
707                                 const byte* pBodyBytes = pBodyBuffer->GetPointer();
708
709                                 curl_easy_setopt(pCurl, CURLOPT_COPYPOSTFIELDS, pBodyBytes);
710                                 delete pBodyBuffer;
711
712                                 SysLog(NID_NET_HTTP, "The Body Size is %d.", bodySize);
713                         }
714                 }
715         }
716
717         //The connection timeout is 30s. (default)
718         curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, _HTTP_DEFAULT_CONNECTION_TIMEOUT);
719
720         //Set the transaction timeout. The timeout includes connection timeout.
721         if (__timeout > 0)
722         {
723                 curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, __timeout);
724         }
725         else if (__timeout == 0)
726         {
727                 curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_LIMIT, 1L);
728                 curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_TIME, 30L);
729         }
730
731         if (__certificateFlag == HTTP_CV_FLAG_IGNORED)
732         {
733                 curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0);
734                 curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 0);
735                 SysLog(NID_NET_HTTP, "The server certificate verification is ignored.");
736
737         } else
738         {
739                 //Set default CA path.
740                 String caPath = _CertService::GetCertificateCrtFilePath();
741                 SysLog(NID_NET_HTTP, "The CA Path is %ls.", caPath.GetPointer());
742
743                 char* pCaPath = _StringConverter::CopyToCharArrayN(caPath);
744                 SysTryReturnResult(NID_NET_HTTP, pCaPath != null,
745                                                    E_OUT_OF_MEMORY, "Memory allocation failed.");
746
747                 curl_easy_setopt(pCurl, CURLOPT_CAINFO, pCaPath);
748                 curl_easy_setopt(pCurl, CURLOPT_CAPATH, null);
749                 delete[] pCaPath;
750
751                 curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0);
752                 curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 2);
753         }
754
755         if (__certificateId >= 0)
756         {
757                 SysLog(NID_NET_HTTP, "Set the client certificate(%d)", __certificateId);
758         }
759
760         //Set Redirection
761         if (__pHttpSessionImpl->IsAutoRedirectionEnabled())
762         {
763                 curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 1L);
764                 curl_easy_setopt(pCurl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
765                 SysLog(NID_NET_HTTP, "Enabled Auto-Redirection");
766         }
767         else
768         {
769                 curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 0L);
770                 SysLog(NID_NET_HTTP, "Disabled Auto-Redirection");
771         }
772
773         if (__pHttpAuthenticationImpl != null)
774         {
775                 if (__pHttpAuthenticationImpl->IsProxyAuthenticationType())
776                 {
777                         String userPwd;
778                         char* pUserPwd = null;
779
780                         userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetName());
781                         userPwd.Append(L":");
782                         userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetPassword());
783
784                         pUserPwd = _StringConverter::CopyToCharArrayN(userPwd);
785                         if (pUserPwd != null)
786                         {
787                                 authScheme = __pHttpAuthenticationImpl->GetAuthScheme();
788                                 SysLog(NID_NET_HTTP, "Set the ProxyAuthentication(%s), userPwd",
789                                                 _HttpUtility::GetHttpAuthSchemeByString(authScheme));
790
791                                 curl_easy_setopt(pCurl, CURLOPT_PROXYAUTH, _HttpUtility::GetHttpCurlAuthScheme(authScheme));
792                                 curl_easy_setopt(pCurl, CURLOPT_PROXYUSERPWD, pUserPwd);
793
794                                 delete[] pUserPwd;
795                         }
796                 }
797                 else
798                 {
799                         String userPwd;
800                         char* pUserPwd = null;
801
802                         userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetName());
803                         userPwd.Append(L":");
804                         userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetPassword());
805
806                         pUserPwd = _StringConverter::CopyToCharArrayN(userPwd);
807                         if (pUserPwd != null)
808                         {
809                                 authScheme = __pHttpAuthenticationImpl->GetAuthScheme();
810                                 SysLog(NID_NET_HTTP, "Set the HttpAuthentication(%s), userPwd", _HttpUtility::GetHttpAuthSchemeByString(authScheme));
811
812                                 curl_easy_setopt(pCurl, CURLOPT_HTTPAUTH, _HttpUtility::GetHttpCurlAuthScheme(authScheme));
813                                 curl_easy_setopt(pCurl, CURLOPT_USERPWD, pUserPwd);
814
815                                 delete[] pUserPwd;
816                         }
817                 }
818         }
819
820         //the Call back for the Response Header.
821         curl_easy_setopt(pCurl, CURLOPT_HEADERFUNCTION, _HttpTransactionImpl::OnHttpHeaderReceived);
822         curl_easy_setopt(pCurl, CURLOPT_HEADERDATA, __pHttpTransactionUserData);
823
824         //the Call back for the Response Body.
825         curl_easy_setopt(pCurl, CURLOPT_WRITEFUNCTION, _HttpTransactionImpl::OnHttpBodyReceived);
826         curl_easy_setopt(pCurl, CURLOPT_WRITEDATA, __pHttpTransactionUserData);
827
828         //the Call back for uploading the Body.
829         if (isEnableOnHttpBodyReadyToWrite)
830         {
831                 curl_easy_setopt(pCurl, CURLOPT_POST, 1L); //For receiving the OnHttpBodyReadyToWrite
832
833                 //curl_easy_setopt(pCurl, CURLOPT_UPLOAD, 1L);
834                 curl_easy_setopt(pCurl, CURLOPT_READFUNCTION, _HttpTransactionImpl::OnHttpBodyReadyToWrite);
835                 curl_easy_setopt(pCurl, CURLOPT_READDATA, __pHttpTransactionUserData);
836         }
837
838         curl_easy_setopt(pCurl, CURLOPT_NOPROGRESS, false);
839         curl_easy_setopt(pCurl, CURLOPT_PROGRESSFUNCTION, _HttpTransactionImpl::OnHttpProgress);
840         curl_easy_setopt(pCurl, CURLOPT_PROGRESSDATA, __pHttpTransactionUserData);
841
842         curl_easy_setopt(pCurl, CURLOPT_SSL_CTX_FUNCTION, _HttpTransactionImpl::OnHttpSslHandshake);
843         curl_easy_setopt(pCurl, CURLOPT_SSL_CTX_DATA, __pHttpTransactionUserData);
844
845         curl_easy_setopt(pCurl, CURLOPT_VERBOSE, 1L);
846         curl_easy_setopt(pCurl, CURLOPT_DEBUGFUNCTION, _HttpTransactionImpl::OnHttpDebugReceived);
847         curl_easy_setopt(pCurl, CURLOPT_ERRORBUFFER, __pHttpTransactionUserData->__error);
848
849         curl_easy_setopt(pCurl, CURLOPT_OPENSOCKETDATA, &__pHttpTransactionUserData->__socketFd);
850         curl_easy_setopt(pCurl, CURLOPT_OPENSOCKETFUNCTION, _HttpTransactionImpl::OnSocketOpened);
851
852         curl_easy_setopt(pCurl, CURLOPT_PRIVATE, __pHttpTransactionUserData); //curl_getinfo(PRIVATE)
853
854         //if current network is Custom NetConnection, Default Mode of ManagedNetConnection or Preference Mode of ManagedNetConnection is already started.
855         if (__pHttpSessionImpl->IsConnectionStarted())
856         {
857                 CURLM* pCurlM = __pHttpMultipleConnectionInfo->GetCurlM();
858                 SysTryReturnResult(NID_NET_HTTP, pCurlM != null,
859                                                    E_SYSTEM, "The pCurlM must not be null. HttpTransaction[%d]", __transactionId);
860
861                 //Adds the Curl handle to CurlM
862                 rc = curl_multi_add_handle(pCurlM, pCurl);
863                 if (rc == CURLM_OK)
864                 {
865                         SysLog(NID_NET_HTTP, "CURLM_OK: Called curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
866                 }
867                 else
868                 {
869                         _HttpUtility::PrintCurlMultiErrorCode(rc);
870                         SysTryReturnResult(NID_NET_HTTP, false,
871                                                            E_SYSTEM, "Failed to curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
872                 }
873                 __pHttpCurl->AddRef();
874
875                 __pHttpTransactionUserData->AddRef();
876
877                 __pHttpSessionImpl->GetHttpMultipleConnectionInfo()->AddRef();
878
879                 SysLog(NID_NET_HTTP, "Submitted the HttpTransaction[%d] successfully.", __transactionId);
880
881         }
882         else
883         {
884                 __isPendingTransaction = true;
885                 SysLog(NID_NET_HTTP, "[Preference Mode] The HttpTransaction is pending. The HttpTransaction[%d] will be submitted after the managed connection is started.", __transactionId);
886         }
887
888         __isSubmitted = true;
889
890         ClearLastResult();
891
892         return r;
893 }
894
895 result
896 _HttpTransactionImpl::SubmitPendingTransaction(const String& deviceName, const String& proxyAddress)
897 {
898         result r = E_SUCCESS;
899         CURLMcode rc;
900         CURLM* pCurlM = null;
901
902         CURL* pCurl = __pHttpCurl->GetCurl();
903         SysTryReturnResult(NID_NET_HTTP, pCurl != null,
904                                            E_SYSTEM, "The Curl must not be null.");
905
906         if (!deviceName.IsEmpty())
907         {
908                 char* pDeviceName = _StringConverter::CopyToCharArrayN(deviceName);
909                 SysTryReturnResult(NID_NET_HTTP, pDeviceName != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
910
911                 SysLog(NID_NET_HTTP, "[Target] The device name is %s.", pDeviceName);
912                 curl_easy_setopt(pCurl, CURLOPT_INTERFACE, pDeviceName);
913                 delete[] pDeviceName;
914         }
915
916         if (__pHttpSessionImpl->GetProxyAddress() != null)
917         {
918                 char* pProxyAddress = _StringConverter::CopyToCharArrayN(*__pHttpSessionImpl->GetProxyAddress());
919                 SysTryReturnResult(NID_NET_HTTP, pProxyAddress != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
920
921                 curl_easy_setopt(pCurl, CURLOPT_PROXY, pProxyAddress);
922                 delete[] pProxyAddress;
923         }
924
925         pCurlM = __pHttpMultipleConnectionInfo->GetCurlM();
926         SysTryReturnResult(NID_NET_HTTP, pCurlM != null,
927                                            E_SYSTEM, "The pCurlM must not be null. HttpTransaction[%d]", __transactionId);
928
929         //Adds the Curl handle to CurlM
930         rc = curl_multi_add_handle(pCurlM, pCurl);
931         if (rc == CURLM_OK)
932         {
933                 SysLog(NID_NET_HTTP, "CURLM_OK: Called curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
934         }
935         else
936         {
937                 _HttpUtility::PrintCurlMultiErrorCode(rc);
938                 SysTryReturnResult(NID_NET_HTTP, false,
939                                                    E_SYSTEM, "Failed to curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
940         }
941         __pHttpCurl->AddRef();
942
943         __pHttpTransactionUserData->AddRef();
944
945         __pHttpSessionImpl->GetHttpMultipleConnectionInfo()->AddRef();
946
947         SysLog(NID_NET_HTTP, "Submitted the pending HttpTransaction[%d] successfully.", __transactionId);
948
949         ClearLastResult();
950
951         return r;
952 }
953
954 HttpRequest*
955 _HttpTransactionImpl::GetRequest() const
956 {
957         ClearLastResult();
958
959         SysTryReturn(NID_NET_HTTP, __isClosed == false, null, E_INVALID_STATE,
960                                  "[E_INVALID_STATE] HttpTransaction(%d) is already closed.", __transactionId);
961
962         SysTryReturn(NID_NET_HTTP, __pHttpRequest != null, null, E_INVALID_DATA,
963                                  "[E_INVALID_DATA] HttpRequest must not be null.", __transactionId);
964
965         return __pHttpRequest;
966 }
967
968 HttpResponse*
969 _HttpTransactionImpl::GetResponse(void) const
970 {
971         ClearLastResult();
972
973         _HttpResponseImpl* pHttpResponseImpl = _HttpResponseImpl::GetInstance(*__pHttpResponse);
974
975         SysTryReturn(NID_NET_HTTP, !__isClosed, null, E_INVALID_STATE,
976                                  "[E_INVALID_STATE] HttpTransaction[%d] is already closed.", __transactionId);
977
978         SysTryReturn(NID_NET_HTTP, pHttpResponseImpl->IsHeaderReceived() || pHttpResponseImpl->IsBodyReceived(), null, E_INVALID_DATA,
979                                  "[E_INVALID_DATA] Header or Body of the HttpResponse are not received yet.");
980
981         return __pHttpResponse;
982 }
983
984 result
985 _HttpTransactionImpl::AddHttpTransactionListener(IHttpTransactionEventListener& listener)
986 {
987         result r = E_SUCCESS;
988
989         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
990                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
991
992         r = __pHttpTransactionEvent->AddListener(listener, true);
993         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, r, r, "[%s] Failed to add the listener.", GetErrorMessage(r));
994
995         IHttpTransactionEventListener* pListener = const_cast< IHttpTransactionEventListener* >(&listener);
996         SysTryReturnResult(NID_NET_HTTP, pListener != null,
997                                            E_SYSTEM, "A system error has occurred.");
998
999         r = __transactionListenerList.Add(pListener);
1000         SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Failed to add the listener.");
1001
1002         SysLog(NID_NET_HTTP, "Added the listener(HttpTransaction[%d]).", __transactionId);
1003
1004         return r;
1005 }
1006
1007 result
1008 _HttpTransactionImpl::RemoveHttpTransactionListener(IHttpTransactionEventListener& listener)
1009 {
1010         result r = E_SUCCESS;
1011
1012         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1013                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1014
1015         r = __pHttpTransactionEvent->RemoveListener(listener);
1016         SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Failed to add the listener.");
1017
1018         IHttpTransactionEventListener* pListener = const_cast< IHttpTransactionEventListener* >(&listener);
1019         r = __transactionListenerList.Remove(pListener);
1020         if (IsFailed(r))
1021         {
1022                 SysLog(NID_NET_HTTP, "Failed to remove the listener(HttpTransaction[%d]).", __transactionId);
1023         }
1024
1025         SysLog(NID_NET_HTTP, "Removed the listener(HttpTransaction[%d]).", __transactionId);
1026
1027         return r;
1028 }
1029
1030 result
1031 _HttpTransactionImpl::SetHttpProgressListener(IHttpProgressEventListener& listener)
1032 {
1033         result r = E_SUCCESS;
1034
1035         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1036                                            E_INVALID_STATE, "HttpTransaction(%d) is already closed.", __transactionId);
1037
1038         __pHttpProgressListener = &listener;
1039         __pHttpTransactionEvent->SetHttpProgressListener(__pHttpProgressListener);
1040
1041         return r;
1042 }
1043
1044 result
1045 _HttpTransactionImpl::SetUserObject(const Tizen::Base::Object* pUserData)
1046 {
1047         result r = E_SUCCESS;
1048
1049         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1050                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1051
1052         __pUserData = pUserData;
1053
1054         return r;
1055 }
1056
1057 Tizen::Base::Object*
1058 _HttpTransactionImpl::GetUserObject(void) const
1059 {
1060         return const_cast< Object* >(__pUserData);
1061 }
1062
1063 bool
1064 _HttpTransactionImpl::EnableTransactionReadyToWrite(void)
1065 {
1066         if (__isSubmitted)
1067         {
1068                 SysLog(NID_NET_HTTP, "Should be called before the HttpTransaction is submitted.");
1069                 return false;
1070         }
1071         __enableTransactionReadyToWrite = true;
1072
1073         SysLog(NID_NET_HTTP, "Enable OnTransactionReadyToWrite().");
1074
1075         return true;
1076 }
1077
1078 result
1079 _HttpTransactionImpl::Resume()
1080 {
1081         result r = E_SUCCESS;
1082
1083         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1084                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1085
1086         SysTryReturnResult(NID_NET_HTTP, __isCertRequiredEventFired == true,
1087                                            E_INVALID_STATE, "Should be called after the OnTransactionCertVerificationRequiredN() is invoked.");
1088
1089         SysTryReturnResult(NID_NET_HTTP, __isAlreadyResumed == false,
1090                                            E_INVALID_STATE, "The HttpTransaction[%d] is already resumed.", __transactionId);
1091
1092         SysLog(NID_NET_HTTP, "Calling Resume() to ignore server certificate verification.");
1093
1094         //Rollback the HttpTransaction.
1095
1096         if (__pHttpCurl != null)
1097         {
1098                 __pHttpCurl->Release();
1099         }
1100
1101         CURL* pCurl = curl_easy_init();
1102         SysTryReturnResult(NID_NET_HTTP, pCurl != null,
1103                                            E_INVALID_STATE, "Failed to call curl_easy_init(), easy is null");
1104         SysLog(NID_NET_HTTP, "Created an instance of CURL. [%x]", pCurl);
1105
1106         __pHttpCurl = new (std::nothrow) _HttpCurl(pCurl, false);
1107         SysTryReturnResult(NID_NET_HTTP, __pHttpCurl != null,
1108                                            E_OUT_OF_MEMORY, "Memory allocation failed.");
1109
1110         if (__pHttpTransactionUserData != null)
1111         {
1112                 __pHttpTransactionUserData->Release();
1113         }
1114
1115         __pHttpTransactionUserData = new (std::nothrow) _HttpTransactionUserData(this, __pHttpCurl);
1116         SysTryReturnResult(NID_NET_HTTP, __pHttpTransactionUserData != null,
1117                                                 E_OUT_OF_MEMORY, "Memory allocation failed.");
1118
1119
1120         __isSubmitted = false;
1121         __transactionId = GenerateTransactionId();
1122
1123         if (__pRequestBuffer != null)
1124         {
1125                 _HttpRequestImpl* pHttpRequestImpl = _HttpRequestImpl::GetInstance(*__pHttpRequest);
1126                 SysTryReturnResult(NID_NET_HTTP, pHttpRequestImpl != null,
1127                                                    E_INVALID_STATE, "The current state of the instance prohibits the execution of the specified operation.");
1128
1129                 //Clear the flag of _HttpRequestImpl
1130                 pHttpRequestImpl->SetReceivedTransactionReadyToWriteEvent(false);
1131
1132                 r = pHttpRequestImpl->WriteBody(*__pRequestBuffer);
1133                 r = TransExceptionsExclusive(r, E_INVALID_STATE, E_OUT_OF_MEMORY);
1134                 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS,
1135                                                    r, "The current state of the instance prohibits the execution of the specified operation.");
1136
1137                 SysLog(NID_NET_HTTP, "__pRequestBuffer is added the Body.");
1138         }
1139         __pHttpSessionImpl->IgnoreSslVerification();
1140         __isAlreadyResumed = true;
1141
1142         r = Submit();
1143         r = TransExceptionsExclusive(r, E_INVALID_STATE, E_OUT_OF_MEMORY);
1144         SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS,
1145                                            r, "Failed to submit the transaction.");
1146
1147         SysLog(NID_NET_HTTP, "Called Resume() to ignore server certificate verification.");
1148
1149         return r;
1150 }
1151 result
1152 _HttpTransactionImpl::Pause(void)
1153 {
1154         result r = E_SUCCESS;
1155
1156         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1157                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1158
1159         SysTryReturnResult(NID_NET_HTTP, __isCertRequiredEventFired == true,
1160                                            E_INVALID_STATE, "Should be called after the OnTransactionCertVerificationRequiredN() is invoked.");
1161
1162         SysTryReturnResult(NID_NET_HTTP, __isAlreadyPaused == false,
1163                                            E_INVALID_STATE, "The HttpTransaction[%d] is already paused.", __transactionId);
1164
1165         SysLog(NID_NET_HTTP, "Calling Pause().");
1166
1167         __isAlreadyPaused = true;
1168
1169         //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_ABORTED) - E_HTTP_USER
1170         __pHttpTransactionEvent->FireTransactionAbortedEvent(E_HTTP_USER, true);
1171
1172         SysLog(NID_NET_HTTP, "Called Pause().");
1173
1174         return r;
1175 }
1176
1177 result
1178 _HttpTransactionImpl::SetTimeout(int timeout)
1179 {
1180         result r = E_SUCCESS;
1181
1182         SysTryReturnResult(NID_NET_HTTP, timeout >= 0,
1183                                            E_INVALID_ARG, "The specified input parameter is invalid.");
1184
1185         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1186                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1187
1188         SysTryReturnResult(NID_NET_HTTP, __isSubmitted == false,
1189                                            E_INVALID_STATE, "HttpTransaction[%d] is already submitted.", __transactionId);
1190
1191         __timeout = timeout;
1192
1193         SysLog(NID_NET_HTTP, "Set the timeout[%d].", timeout);
1194
1195         return r;
1196 }
1197
1198 int
1199 _HttpTransactionImpl::GetTimeout(void) const
1200 {
1201         return __timeout;
1202 }
1203
1204 result
1205 _HttpTransactionImpl::SetClientCertificate(int certificateId)
1206 {
1207         result r = E_SUCCESS;
1208
1209         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1210                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1211
1212         SysTryReturnResult(NID_NET_HTTP, certificateId >= 0,
1213                                            E_INVALID_ARG, "The certificateId is invalid.");
1214
1215         __certificateId = certificateId;
1216
1217         SysLog(NID_NET_HTTP, "Selected Client Certificate ID[%d].", certificateId);
1218
1219         return r;
1220 }
1221
1222 int
1223 _HttpTransactionImpl::GetClientCertificate(void) const
1224 {
1225         return __certificateId;
1226 }
1227
1228 result
1229 _HttpTransactionImpl::SetServerCertificateVerification(NetHttpCertificateVerificationFlag flag)
1230 {
1231         result r = E_SUCCESS;
1232
1233         SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1234                                            E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1235
1236         SysTryReturnResult(NID_NET_HTTP, __isSubmitted == false,
1237                                            E_INVALID_STATE, "HttpTransaction[%d] is already submitted.", __transactionId);
1238
1239         __certificateFlag = flag;
1240
1241         SysLog(NID_NET_HTTP, "Set the flag for certificate verification.[%s].", _HttpUtility::ConvertNetHttpCertificateVerificationFlagToString(flag));
1242
1243         return r;
1244 }
1245
1246 NetHttpCertificateVerificationFlag
1247 _HttpTransactionImpl::GetServerCertificateVerification(void) const
1248 {
1249         return __certificateFlag;
1250 }
1251
1252 _HttpTransactionImpl*
1253 _HttpTransactionImpl::GetInstance(HttpTransaction& httpTransaction)
1254 {
1255         return httpTransaction.__pHttpTransactionImpl;
1256 }
1257
1258 const _HttpTransactionImpl*
1259 _HttpTransactionImpl::GetInstance(const HttpTransaction& httpTransaction)
1260 {
1261         return httpTransaction.__pHttpTransactionImpl;
1262 }
1263
1264 _HttpSessionImpl*
1265 _HttpTransactionImpl::GetHttpSessioinImpl(void) const
1266 {
1267         return __pHttpSessionImpl;
1268 }
1269
1270 HttpTransaction*
1271 _HttpTransactionImpl::GetHttpTransaction(void) const
1272 {
1273         return __pHttpTransaction;
1274 }
1275
1276 _HttpTransactionEvent*
1277 _HttpTransactionImpl::GetHttpTransactionEvent(void) const
1278 {
1279         return __pHttpTransactionEvent;
1280 }
1281
1282 bool
1283 _HttpTransactionImpl::IsTransactionReadyToWriteEanbled(void) const
1284 {
1285         return __enableTransactionReadyToWrite;
1286 }
1287
1288 HttpAuthentication*
1289 _HttpTransactionImpl::OpenAuthenticationInfoN(void)
1290 {
1291         ClearLastResult();
1292         result r = E_SUCCESS;
1293         _HttpAuthenticationImpl* pHttpAuthenticationImpl = null;
1294         unique_ptr<HttpAuthentication> pHttpAuthentication(_HttpAuthenticationImpl::CreateHttpAuthenticationN());
1295         SysTryReturn(NID_NET_HTTP, pHttpAuthentication != null, null, E_OUT_OF_MEMORY,
1296                                  "[E_OUT_OF_MEMORY] Memory allocation failed.");
1297
1298         pHttpAuthenticationImpl = _HttpAuthenticationImpl::GetInstance(*pHttpAuthentication);
1299
1300         r = pHttpAuthenticationImpl->Construct(*this);
1301         r = TransExceptionsExclusive(r, E_SYSTEM, E_OUT_OF_MEMORY);
1302         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, r,
1303                                 "[%s] Failed to construct HttpAuthentication.", GetErrorMessage(r));
1304
1305         SetHttpAuthenticationImpl(pHttpAuthenticationImpl);
1306
1307         SysLog(NID_NET_HTTP, "The HttpAuthentication instance is created.");
1308
1309         return pHttpAuthentication.release();
1310 }
1311
1312 int
1313 _HttpTransactionImpl::GenerateTransactionId(void)
1314 {
1315         int transactionId = 0;
1316         Mutex* pHttpMutex = null;
1317
1318         pHttpMutex = _HttpUtility::GetHttpMutex();
1319
1320         MutexGuard locked(*pHttpMutex);
1321         SysTryReturn(NID_NET_HTTP, locked.IsLocked(), _HTTP_INVALID_ID, E_SYSTEM,
1322                         "[E_SYSTEM] Failed to lock mutex.");
1323
1324         if (__generatedTransactionId >= Integer::VALUE_MAX)
1325         {
1326                 __generatedTransactionId = 0;
1327         }
1328         else
1329         {
1330                 __generatedTransactionId++;
1331         }
1332
1333         transactionId = __generatedTransactionId;
1334
1335         return transactionId;
1336 }
1337
1338 int
1339 _HttpTransactionImpl::GetTransactionId(void) const
1340 {
1341         return __transactionId;
1342 }
1343
1344 void
1345 _HttpTransactionImpl::SetHttpAuthType(NetHttpAuthScheme authType)
1346 {
1347         __authType = authType;
1348 }
1349
1350 NetHttpAuthScheme
1351 _HttpTransactionImpl::GetHttpAuthType(void) const
1352 {
1353         return __authType;
1354 }
1355
1356 void
1357 _HttpTransactionImpl::SetHttpAuthenticationImpl(const _HttpAuthenticationImpl* pAuthenticationImpl)
1358 {
1359         result r = E_SUCCESS;
1360
1361         if (__pHttpAuthenticationImpl != null)
1362         {
1363                 delete __pHttpAuthenticationImpl;
1364         }
1365
1366         __pHttpAuthenticationImpl = new (std::nothrow) _HttpAuthenticationImpl();
1367         SysTryReturnVoidResult(NID_NET_HTTP, __pHttpAuthenticationImpl != null, E_OUT_OF_MEMORY,
1368                                 "[E_OUT_OF_MEMORY] Memory allocation failed.");
1369
1370         r = __pHttpAuthenticationImpl->Construct(*pAuthenticationImpl, *this);
1371         SysTryReturnVoidResult(NID_NET_HTTP, r == E_SUCCESS, r,
1372                                 "[%s] Propagating.", GetErrorMessage(r));
1373 }
1374
1375 _HttpAuthenticationImpl*
1376 _HttpTransactionImpl::GetHttpAuthenticationImpl(void) const
1377 {
1378         return __pHttpAuthenticationImpl;
1379 }
1380
1381 ByteBuffer*
1382 _HttpTransactionImpl::GetRequestBuffer(void)
1383 {
1384         return __pRequestBuffer;
1385 }
1386
1387 ArrayListT< IHttpTransactionEventListener* >*
1388 _HttpTransactionImpl::GetEventListenerList(void)
1389 {
1390         return &__transactionListenerList;
1391 }
1392
1393 _HttpTransactionUserData*
1394 _HttpTransactionImpl::GetHttpTransactionUserData(void) const
1395 {
1396         return __pHttpTransactionUserData;
1397 }
1398
1399 bool
1400 _HttpTransactionImpl::IsClosed(void) const
1401 {
1402         return __isClosed;
1403 }
1404
1405 bool
1406 _HttpTransactionImpl::IsCanceled(void) const
1407 {
1408         return __isCanceled;
1409 }
1410
1411 void
1412 _HttpTransactionImpl::SetTransactionCanceled(bool isCanceled)
1413 {
1414         __isCanceled = isCanceled;
1415 }
1416
1417 bool
1418 _HttpTransactionImpl::IsSubmitted(void) const
1419 {
1420         return __isSubmitted;
1421 }
1422
1423 bool
1424 _HttpTransactionImpl::IsPendingTransaction(void) const
1425 {
1426         return __isPendingTransaction;
1427 }
1428
1429 bool
1430 _HttpTransactionImpl::IsHeaderEventFired(void) const
1431 {
1432         return __isHeaderEventFired;
1433 }
1434
1435 void
1436 _HttpTransactionImpl::SetCertRequiredEventFired(bool isFired)
1437 {
1438         __isCertRequiredEventFired = isFired;
1439 }
1440
1441 bool
1442 _HttpTransactionImpl::IsAlreadyResumed(void) const
1443 {
1444         if (__isAlreadyResumed || __isAlreadyPaused)
1445         {
1446                 return true;
1447         }
1448         else
1449         {
1450                 return false;
1451         }
1452 }
1453
1454 void
1455 _HttpTransactionImpl::IgnoreSslVerification(void)
1456 {
1457         __isAlreadyResumed = true;
1458 }
1459
1460 void
1461 _HttpTransactionImpl::SetTimer(void)
1462 {
1463         int timerId = -1;
1464         GMainContext* pGMainContext = __pHttpMultipleConnectionInfo->GetGMainContext();
1465         SysTryReturnVoidResult(NID_NET_HTTP, pGMainContext != null, E_SYSTEM,
1466                                                    "[E_SYSTEM] The pGMainContext must not be null.");
1467
1468         __pTimerSource = g_timeout_source_new(_HTTP_DEFAULT_CONNECTION_TIMEOUT * 1000);
1469         g_source_set_callback(__pTimerSource, _HttpTransactionImpl::OnHttpTransactionTimerExpiredEvent, this, null);
1470         g_source_attach(__pTimerSource, pGMainContext);
1471
1472         timerId = g_source_get_id(__pTimerSource);
1473         SysLog(NID_NET_HTTP, "Created the TimerSource[%d] of HttpTransaction[%d], timeout[%d].", timerId, __transactionId, _HTTP_DEFAULT_CONNECTION_TIMEOUT * 1000);
1474 }
1475
1476 _HttpCurl*
1477 _HttpTransactionImpl::GetHttpCurl(void) const
1478 {
1479         return __pHttpCurl;
1480 }
1481
1482 const IHttpProgressEventListener*
1483 _HttpTransactionImpl::GetHttpProgressEventListener(void) const
1484 {
1485         return __pHttpProgressListener;
1486 }
1487
1488 _HttpResponseImpl*
1489 _HttpTransactionImpl::GetHttpResponseImpl(void) const
1490 {
1491         return _HttpResponseImpl::GetInstance(*__pHttpResponse);
1492 }
1493
1494 gboolean
1495 _HttpTransactionImpl::OnSocketReceivedEvent(GIOChannel* pSource, GIOCondition condition, gpointer pUserData)
1496 {
1497         if (condition == G_IO_IN)
1498         {
1499                 SysLog(NID_NET_HTTP, "====> [Event] Received the socket event(G_IO_IN).");
1500         }
1501         else if (condition == G_IO_OUT)
1502         {
1503                 SysLog(NID_NET_HTTP, "====> [Event] Received the socket event(G_IO_OUT).");
1504         }
1505         else
1506         {
1507                 SysLog(NID_NET_HTTP, "====> [Event] Received the socket event(%d).", condition);
1508         }
1509
1510         _HttpMultipleConnectionInfo* pHttpMultipleConnectionInfo = static_cast< _HttpMultipleConnectionInfo* >(pUserData);
1511         int remainsConnection = -1;
1512
1513         CURLMcode rc;
1514         int fd = g_io_channel_unix_get_fd(pSource);
1515         //CURL_CSELECT_IN : 1, CURL_CSELECT_OUT: 2
1516         int action = (condition & G_IO_IN ? CURL_CSELECT_IN : 0) | (condition & G_IO_OUT ? CURL_CSELECT_OUT : 0);
1517
1518         CURLM* pCurlM = pHttpMultipleConnectionInfo->GetCurlM();
1519         SysTryReturn(NID_NET_HTTP, pCurlM != null, false, E_SYSTEM, "[E_SYSTEM] The pCurlM must not be null.");
1520         rc = curl_multi_socket_action(pCurlM, fd, action, &remainsConnection);
1521
1522         pHttpMultipleConnectionInfo->SetRemainsConnection(remainsConnection);
1523         if (rc == CURLM_OK)
1524         {
1525                 SysLog(NID_NET_HTTP, "CURLM_OK: Called curl_multi_socket_action(%d)", action);
1526         }
1527         else
1528         {
1529                 _HttpUtility::PrintCurlMultiErrorCode(rc);
1530         }
1531
1532         pHttpMultipleConnectionInfo->CheckCurlMultiStatus();
1533
1534         if (remainsConnection > 0)
1535         {
1536                 return true;
1537         }
1538         else
1539         {
1540                 return false;
1541         }
1542 }
1543
1544 curl_socket_t
1545 _HttpTransactionImpl::OnSocketOpened(int* pSocketFd, curlsocktype purpose, struct curl_sockaddr* addr)
1546 {
1547         int socketFd = socket(addr->family, addr->socktype, addr->protocol);
1548         SysLog(NID_NET_HTTP, "SOCKET FD (%d)", socketFd);
1549
1550         *pSocketFd = socketFd;
1551
1552         return socketFd;
1553 }
1554
1555 size_t
1556 _HttpTransactionImpl::OnHttpProgress(void* pUserData, double totalDownloadSize, double currentDownloadedSize,
1557                                                                          double totalUploadSize,
1558                                                                          double currentUploadedSize)
1559 {
1560         _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1561         _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1562
1563         if (pHttpTransactionUserData->IsAbortedTransaction())
1564         {
1565                 SysLog(NID_NET_HTTP, "The HttpTransaction is already closed.");
1566                 return _HTTP_NETWORK_ERROR;
1567         }
1568
1569         if (pHttpTransactionImpl->__pHttpProgressListener != null)
1570         {
1571                 long long donwloadTotalProgress = static_cast< long long >(totalDownloadSize);
1572                 long long donwloadCurrentProgress = static_cast< long long >(currentDownloadedSize);
1573
1574                 long long uploadTotalProgress = static_cast< long long >(totalUploadSize);
1575                 long long uploadCurrentProgress = static_cast< long long >(currentUploadedSize);
1576
1577                 SysLog(NID_NET_HTTP, "===> Progress  UP(%lld/%lld) DOWN(%lld/%lld)", uploadCurrentProgress, uploadTotalProgress,
1578                            donwloadCurrentProgress,
1579                            donwloadTotalProgress);
1580
1581                 if (donwloadCurrentProgress != pHttpTransactionImpl->__donwloadCurrentProgress)
1582                 {
1583                         _HttpResponseImpl* pHttpResponseImpl = _HttpResponseImpl::GetInstance(*pHttpTransactionImpl->__pHttpResponse);
1584
1585                         if (pHttpResponseImpl->IsCurrentBodyReceived())
1586                         {
1587                                 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_DOWNLOAD_PROGRESS)
1588                                 pHttpTransactionImpl->__pHttpTransactionEvent->FireHttpDownloadInProgressEvent(pHttpResponseImpl->GetCurrentBodyLength(), donwloadTotalProgress);
1589
1590                                 pHttpResponseImpl->SetReceivedBody(false);
1591                                 pHttpResponseImpl->SetTotalBodyLength(donwloadTotalProgress);
1592                         }
1593
1594                         pHttpTransactionImpl->__donwloadCurrentProgress = donwloadCurrentProgress;
1595
1596                 }
1597                 else if (uploadCurrentProgress != pHttpTransactionImpl->__uploadCurrentProgress)
1598                 {
1599                         //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_UPLOAD_PROGRESS)
1600                         pHttpTransactionImpl->__pHttpTransactionEvent->FireHttpUploadInProgressEvent(uploadCurrentProgress, uploadTotalProgress);
1601                         pHttpTransactionImpl->__uploadCurrentProgress = uploadCurrentProgress;
1602                 }
1603         }
1604
1605         return 0;
1606 }
1607
1608 size_t
1609 _HttpTransactionImpl::OnHttpHeaderReceived(void* pHeaderMsg, size_t size, size_t nmemb, void* pUserData)
1610 {
1611         result r = E_SUCCESS;
1612         int bytesSize = size * nmemb;
1613
1614         //SysLog(NID_NET_HTTP, "===> Received the header(Bytes: %d).", bytesSize);
1615
1616         if (pHeaderMsg == null || bytesSize <= 0)
1617         {
1618                 SysLog(NID_NET_HTTP, "Invalid header was received.");
1619                 return bytesSize;
1620         }
1621
1622         byte* pBytes = static_cast< byte* >(pHeaderMsg);
1623         _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1624         _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1625         _HttpResponseImpl* pHttpResponseImpl = null;
1626
1627         String headerLine((char*) pBytes);
1628
1629         if (pHttpTransactionUserData->IsAbortedTransaction())
1630         {
1631                 SysLog(NID_NET_HTTP, "The HttpTransaction is already closed.");
1632                 return bytesSize;
1633         }
1634
1635         pHttpResponseImpl = _HttpResponseImpl::GetInstance(*pHttpTransactionImpl->__pHttpResponse);
1636         r = pHttpResponseImpl->AddRawHeader(pBytes, bytesSize, false);
1637         if (IsFailed(r))
1638         {
1639                 SysLogException(NID_NET_HTTP, r, "[%s] Propagating.", GetErrorMessage(r));
1640         }
1641
1642         return bytesSize;
1643 }
1644
1645 //Call back Function for curl.
1646 size_t
1647 _HttpTransactionImpl::OnHttpBodyReceived(void* pBodyMsg, size_t size, size_t nmemb, void* pUserData)
1648 {
1649         result r = E_SUCCESS;
1650         int bytesSize = size * nmemb;
1651
1652         SysLog(NID_NET_HTTP, "===> Received the body(Bytes: %d).", bytesSize);
1653
1654         if (pBodyMsg == null || bytesSize <= 0)
1655         {
1656                 SysLog(NID_NET_HTTP, "Invalid body was received.");
1657                 return bytesSize;
1658         }
1659
1660         byte* pBytes = (byte*) pBodyMsg;
1661         _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1662         _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1663         _HttpResponseImpl* pHttpResponseImpl = null;
1664         CURL* pCurl = null;
1665         bool isFullBuffer = false;
1666         int readBodySize = -1;
1667
1668         if (pHttpTransactionUserData->IsAbortedTransaction())
1669         {
1670                 SysLog(NID_NET_HTTP, "The HttpTransaction was aborted.");
1671                 return bytesSize;
1672         }
1673
1674         pHttpResponseImpl = _HttpResponseImpl::GetInstance(*pHttpTransactionImpl->__pHttpResponse);
1675         pCurl = pHttpTransactionImpl->__pHttpCurl->GetCurl();
1676
1677         if (!pHttpTransactionImpl->__isHeaderEventFired)
1678         {
1679                 SysLog(NID_NET_HTTP, "The header event will be fired in OnHttpBodyReceived()");
1680
1681                 r = pHttpResponseImpl->AddRawHeader(null, 0, true);
1682                 if (IsFailed(r))
1683                 {
1684                         SysLogException(NID_NET_HTTP, r, "[%s] Propagating.", GetErrorMessage(r));
1685                 }
1686
1687                 long httpAuth = _CURL_HTTP_AUTH_NONE;
1688                 long proxyAuth = _CURL_HTTP_AUTH_NONE;
1689                 curl_easy_getinfo(pCurl, CURLINFO_HTTPAUTH_AVAIL, &httpAuth);
1690                 curl_easy_getinfo(pCurl, CURLINFO_PROXYAUTH_AVAIL, &proxyAuth);
1691
1692                 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_HEADER_COMPLETED)
1693                 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionHeaderCompletedEvent(pHttpResponseImpl->GetHeaderLength(), proxyAuth, httpAuth);
1694
1695                 pHttpTransactionImpl->__isHeaderEventFired = true;
1696
1697                 if (pHttpTransactionUserData->IsAbortedTransaction())
1698                 {
1699                         SysLog(NID_NET_HTTP, "The HttpTransaction was aborted.");
1700                         return bytesSize;
1701                 }
1702         }
1703
1704         r = pHttpResponseImpl->AddRawBody(pBytes, bytesSize, isFullBuffer, readBodySize);
1705         if (IsFailed(r))
1706         {
1707                 SysLogException(NID_NET_HTTP, r, "[%s] Propagating.", GetErrorMessage(r));
1708         }
1709
1710         //Check if the Buffer is full.
1711         if (isFullBuffer && readBodySize > 0)
1712         {
1713                 //Fire the event(NET_HTTP_TRANSACTION_EVENT_READY_TO_READ)
1714                 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionReadyToReadEvent(readBodySize);
1715
1716                 pHttpResponseImpl->SetCurrentBodyLength(readBodySize);
1717                 pHttpResponseImpl->SetReceivedBody(true);
1718         }
1719
1720         return bytesSize;
1721 }
1722
1723 size_t
1724 _HttpTransactionImpl::OnHttpDebugReceived(CURL* pCurl, curl_infotype type, char* pChar, size_t size, void* pUserData)
1725 {
1726         char logBuffer[_HTTP_DEFAULT_HEADER_SIZE];
1727         int logSize = 0;
1728
1729         if (_HTTP_DEFAULT_HEADER_SIZE > static_cast< int >(size))
1730         {
1731                 logSize = size;
1732         }
1733         else
1734         {
1735                 logSize = _HTTP_DEFAULT_HEADER_SIZE - 1;
1736         }
1737
1738         if (type == CURLINFO_TEXT)
1739         {
1740                 strncpy(logBuffer, pChar, logSize);
1741                 logBuffer[logSize] = '\0';
1742                 SysLog(NID_NET_HTTP, "[DEBUG] %s", logBuffer);
1743         }
1744         else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT)
1745         {
1746                 //Ignore the body message.
1747                 if (size >= 2 && pChar[0] == 0x0D && pChar[1] == 0x0A)
1748                 {
1749                         return 0;
1750                 }
1751                 else
1752                 {
1753                         strncpy(logBuffer, pChar, logSize);
1754                         logBuffer[logSize] = '\0';
1755                         SysLog(NID_NET_HTTP, "[DEBUG] %s", logBuffer);
1756                 }
1757         }
1758
1759         return 0;
1760 }
1761
1762 size_t
1763 _HttpTransactionImpl::OnHttpBodyReadyToWrite(void* pBodyMsg, size_t size, size_t nmemb, void* pUserData)
1764 {
1765         result r = E_SUCCESS;
1766         int recommendedSize = size * nmemb;
1767
1768         SysLog(NID_NET_HTTP, "===> Called(%d).", recommendedSize);
1769
1770         _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1771         _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1772         _HttpRequestImpl* pHttpRequestImpl = null;
1773         ByteBuffer* pBodyBuffer = null;
1774         int bufferSize = 0;
1775
1776         if (pHttpTransactionUserData->IsAbortedTransaction())
1777         {
1778                 SysLog(NID_NET_HTTP, "The HttpTransaction was aborted.");
1779                 return CURL_READFUNC_ABORT;
1780         }
1781
1782         pHttpRequestImpl = _HttpRequestImpl::GetInstance(*pHttpTransactionImpl->__pHttpRequest);
1783         pHttpRequestImpl->SetRecommendedSize(recommendedSize);
1784         if (pHttpRequestImpl->IsFirstChunkBody())
1785         {
1786                 SysLog(NID_NET_HTTP,
1787                            "First chunk Body. Ignore to fire the event(OnTransactionReadyToWriteEvent) to send the first chunk");
1788         }
1789         else
1790         {
1791                 pHttpRequestImpl->SetReceivedTransactionReadyToWriteEvent(true);
1792                 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_READY_TO_WRITE)
1793                 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionReadyToWriteEvent(recommendedSize);
1794         }
1795
1796         pBodyBuffer = pHttpRequestImpl->GetSendingBuffer();
1797         if (pBodyBuffer == null)
1798         {
1799                 if (pHttpRequestImpl->IsLastChunkBody()) //Last chunk (ByteBuffer is an empty(0))
1800                 {
1801                         SysLog(NID_NET_HTTP, "Sent the last chunk.");
1802                         return 0;
1803                 }
1804                 //Read the body from the Queue.
1805                 pBodyBuffer = pHttpRequestImpl->ReadBodyN();
1806                 SysTryReturn(NID_NET_HTTP, pBodyBuffer != null, CURL_READFUNC_ABORT, E_IO,
1807                                          "[E_IO] Failed to read the body. pBodyBuffer is null[CURL_READFUNC_ABORT].");
1808         }
1809
1810         bufferSize = pBodyBuffer->GetRemaining();
1811         if (bufferSize > recommendedSize)
1812         {
1813                 r = pBodyBuffer->GetArray(static_cast< byte* >(pBodyMsg), 0, recommendedSize);
1814                 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, CURL_READFUNC_ABORT, E_IO,
1815                                          "[E_IO] Failed to read the body[CURL_READFUNC_ABORT].");
1816
1817                 pHttpRequestImpl->SetSendingBuffer(pBodyBuffer);
1818                 SysLog(NID_NET_HTTP, "[bufferSize(%d) > recommendedSize(%d)] Sent the chunk(size: %d).", bufferSize, recommendedSize,
1819                            recommendedSize);
1820                 return recommendedSize;
1821
1822         }
1823         else
1824         {
1825                 r = pBodyBuffer->GetArray(static_cast< byte* >(pBodyMsg), 0, bufferSize);
1826                 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, CURL_READFUNC_ABORT, E_IO,
1827                                          "[E_IO] Failed to read the body[CURL_READFUNC_ABORT].");
1828                 pHttpRequestImpl->SetSendingBuffer(null);
1829                 delete pBodyBuffer;
1830
1831                 if (pHttpRequestImpl->IsFirstChunkBody())
1832                 {
1833                         pHttpRequestImpl->SetFirstChunkBody(false);
1834                         SysLog(NID_NET_HTTP, "Ended the first chunk body.");
1835                 }
1836
1837                 SysLog(NID_NET_HTTP, "[bufferSize(%d) <= recommendedSize(%d)] Sent the chunk(size: %d).", bufferSize, recommendedSize,
1838                            bufferSize);
1839                 return bufferSize;
1840         }
1841
1842         SysLogException(NID_NET_HTTP, E_IO, "[E_IO] CURL_READFUNC_ABORT.");
1843
1844         return CURL_READFUNC_ABORT;
1845 }
1846
1847 CURLcode
1848 _HttpTransactionImpl::OnHttpSslHandshake(CURL* pCurl, SSL_CTX* pSslctx, void* pUserData)
1849 {
1850         ClearLastResult();
1851         result r = E_SUCCESS;
1852         CURLcode curlCode = CURLE_OK;
1853
1854         SysLog(NID_NET_HTTP, "Received OnHttpSslHandshake()");
1855
1856         _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1857         _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1858
1859         if (pHttpTransactionImpl->__isAlreadyResumed || pHttpTransactionImpl->__certificateFlag == HTTP_CV_FLAG_IGNORED)
1860         {
1861                 SysLog(NID_NET_HTTP, "Resume the HttpTransaction. Ignore to verify the server cert.");
1862         }
1863         else
1864         {
1865                 if (pHttpTransactionImpl->__certificateFlag == HTTP_CV_FLAG_MANUAL)
1866                 {
1867                         unique_ptr<_HttpSslInfo> pSSLInfo;
1868
1869                         SysLog(NID_NET_HTTP, "The certificate mode is HTTP_CV_FLAG_MANUAL");
1870
1871                         pSSLInfo.reset(new (std::nothrow) _HttpSslInfo(pHttpTransactionUserData->GetSocketFd(), pHttpTransactionImpl->__pHttpTransactionEvent));
1872                         SysTryReturn(NID_NET_HTTP, pSSLInfo != null, CURLE_SSL_CERTPROBLEM, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1873
1874                         r = _HttpUtility::SetSslCertInfo(*pSSLInfo);
1875                         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, CURLE_SSL_CERTPROBLEM, r, "[%s] Memory allocation failed.", GetErrorMessage(r));
1876
1877                         pSSLInfo.release();
1878                 }
1879
1880                 SSL_CTX_set_verify_depth(pSslctx, _HTTP_CERT_VERIFICATION_DEPTH_LIMIT);
1881                 SSL_CTX_set_verify(pSslctx, SSL_VERIFY_PEER, _HttpTransactionImpl::OnHttpSslVerify);
1882         }
1883
1884         if (pHttpTransactionImpl->__certificateId >= 0)
1885         {
1886                 X509* pClientCert = null;
1887                 EVP_PKEY* pClientKey = null;
1888
1889                 _CertServiceProxy* pCertProxy = null;
1890                 pCertProxy = _CertServiceProxy::GetInstance();
1891                 SysTryReturn(NID_NET_HTTP, pCertProxy != null, CURLE_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1892
1893                 unique_ptr<_CertInfo, _CertInfoDeleter> pClientCertInfo(pCertProxy->GetUserCertificateByCertIdN(pHttpTransactionImpl->__certificateId, _CERT_ENC_TYPE_PEM));
1894                 r = GetLastResult();
1895                 r = TransExceptionsExclusive(r, E_NO_CERTIFICATE, E_OUT_OF_MEMORY);
1896                 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS && pClientCertInfo != null, CURLE_SSL_CERTPROBLEM, r, "[%s] Certificate(%d) is not found.", GetErrorMessage(r), pHttpTransactionImpl->__certificateId);
1897
1898                 BIO* pNewBIoCert = BIO_new(BIO_s_mem());
1899                 unique_ptr<BIO, _BIoDeleter> pBIoCert(pNewBIoCert);
1900                 SysTryReturn(NID_NET_HTTP, pBIoCert != null, CURLE_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1901
1902                 BIO_write(pNewBIoCert, (const void*)pClientCertInfo->certificate, pClientCertInfo->certLength);
1903                 pClientCert = PEM_read_bio_X509(pNewBIoCert, null, 0, null);
1904                 SysTryReturn(NID_NET_HTTP, pClientCert != null, CURLE_SSL_CERTPROBLEM, E_NO_CERTIFICATE, "[E_NO_CERTIFICATE] Failed to read Certificate(%d).", pHttpTransactionImpl->__transactionId);
1905
1906                 char tempSubjectName[_HTTP_CERT_SUBJECT_SIZE];
1907                 X509_NAME_oneline(X509_get_subject_name(pClientCert), tempSubjectName, _HTTP_CERT_SUBJECT_SIZE);
1908                 String clientCertString = String(tempSubjectName);
1909
1910                 SysLog(NID_NET_HTTP, "The subject of certificate is %ls.", clientCertString.GetPointer());
1911
1912                 SysTryReturn(NID_NET_HTTP, SSL_CTX_use_certificate(pSslctx, pClientCert), CURLE_SSL_CERTPROBLEM, E_NO_CERTIFICATE, "[E_NO_CERTIFICATE] Failed to use Certificate(%d).", pHttpTransactionImpl->__transactionId);
1913
1914                 BIO* pNewBIoKey = BIO_new(BIO_s_mem());
1915                 unique_ptr<BIO, _BIoDeleter> pBIoKey(pNewBIoKey);
1916                 SysTryReturn(NID_NET_HTTP, pBIoKey != null, CURLE_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1917
1918                 BIO_write(pNewBIoKey, (const void*)pClientCertInfo->privatekey, pClientCertInfo->privateKeyLen);
1919                 pClientKey = PEM_read_bio_PrivateKey(pNewBIoKey, null, 0, null);
1920                 SysTryReturn(NID_NET_HTTP, pClientKey != null, CURLE_SSL_CERTPROBLEM, E_NO_CERTIFICATE, "[E_NO_CERTIFICATE] Failed to read Private Key(%d).", pHttpTransactionImpl->__transactionId);
1921
1922                 SysTryReturn(NID_NET_HTTP, SSL_CTX_use_PrivateKey(pSslctx, pClientKey), CURLE_SSL_CERTPROBLEM, E_NO_CERTIFICATE, "[E_NO_CERTIFICATE] Failed to use Private Key(%d).", pHttpTransactionImpl->__transactionId);
1923                 SysTryReturn(NID_NET_HTTP, SSL_CTX_check_private_key(pSslctx), CURLE_SSL_CERTPROBLEM, E_NO_CERTIFICATE, "[E_NO_CERTIFICATE] Failed to check Private Key(%d).", pHttpTransactionImpl->__transactionId);
1924
1925         }
1926
1927         return curlCode;
1928 }
1929
1930 int
1931 _HttpTransactionImpl::OnHttpSslVerify(int preverify_ok, X509_STORE_CTX* pX509ctx)
1932 {
1933         result r = E_SUCCESS;
1934         int socketFd = -1;
1935         unique_ptr<_HttpSslInfo> pSSLInfo;
1936         _HttpSslInfo* pExistSslInfo = null;
1937         int sslIndex = SSL_get_ex_data_X509_STORE_CTX_idx();
1938         SSL* pSsl = (SSL*) X509_STORE_CTX_get_ex_data(pX509ctx, sslIndex);
1939
1940         SysTryReturn(NID_NET_HTTP, pSsl != null, 0, E_SYSTEM, "[E_SYSTEM] The ssl must not be null.");
1941
1942         socketFd = SSL_get_fd(pSsl);
1943         SysLog(NID_NET_HTTP, "The ssl socket is %d.", socketFd);
1944
1945         X509* pSrcServerCert = null;
1946         unique_ptr<X509, _X509Deleter> pServerCert;
1947         int depth = X509_STORE_CTX_get_error_depth(pX509ctx);
1948         int error = X509_STORE_CTX_get_error(pX509ctx);
1949
1950         pExistSslInfo = _HttpUtility::GetSslCertInfo(socketFd);
1951
1952         if (pExistSslInfo != null)
1953         {
1954                 SysLog(NID_NET_HTTP, "The SslInfo is existed.");
1955
1956                 bool certVerificationResult = false;
1957
1958                 _HttpTransactionEvent* pHttpTransactionEvent = pExistSslInfo->GetHttpTransactionEvent();
1959                 SysTryReturn(NID_NET_HTTP, pHttpTransactionEvent != null, 0, E_SYSTEM, "[E_SYSTEM] pHttpTransactionEvent must not be null.");
1960
1961                 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionEvent->GetHttpTransactionImpl();
1962                 SysTryReturn(NID_NET_HTTP, pHttpTransactionImpl != null, 0, E_SYSTEM, "[E_SYSTEM] pHttpTransactionImpl must not be null.");
1963
1964                 if (pHttpTransactionImpl->GetServerCertificateVerification() != HTTP_CV_FLAG_MANUAL)
1965                 {
1966                         SysLog(NID_NET_HTTP, "The server certificate verification is not HTTP_CV_FLAG_MANUAL.");
1967                         return 1;
1968                 }
1969
1970                 if (pHttpTransactionEvent->GetCertRequestedResult())
1971                 {
1972                         SysLog(NID_NET_HTTP, "The certificate verification is already resumed.");
1973                         return 1;
1974                 }
1975
1976                 //The certificateFlag is HTTP_CV_FLAG_MANUAL.
1977                 String serverCertString;
1978                 STACK_OF(X509)* pSrcServerCertChain = X509_STORE_CTX_get1_chain(pX509ctx);
1979                 unique_ptr<STACK_OF(X509), _X509ChainDeleter> pServerCertChain(pSrcServerCertChain);
1980                 if (pServerCertChain != null)
1981                 {
1982                         unique_ptr<IList, _CollectionDeleter> pCertList(new (nothrow) LinkedList(SingleObjectDeleter));
1983                         SysTryReturn(NID_NET_HTTP, pCertList != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
1984
1985                         int numberOfCerts = pServerCertChain->stack.num;
1986                         for (int i = numberOfCerts; i > 0; i--)
1987                         {
1988                                 pSrcServerCert = sk_X509_pop(pSrcServerCertChain);
1989                                 pServerCert.reset(pSrcServerCert);
1990                                 if (pServerCert != null)
1991                                 {
1992                                         char tempSubjectName[_HTTP_CERT_SUBJECT_SIZE];
1993                                         X509_NAME_oneline(X509_get_subject_name(pSrcServerCert), tempSubjectName, _HTTP_CERT_SUBJECT_SIZE);
1994                                         serverCertString = String(tempSubjectName);
1995
1996                                         SysLog(NID_NET_HTTP, "Count of Certs(%d), The subject of certificate is %ls[depth: %d].", numberOfCerts, serverCertString.GetPointer(), i -1);
1997
1998                                         // Converter X509 to ByteBuffer.
1999                                         int bufferSize = -1;
2000                                         int len = -1;
2001                                         ByteBuffer buffer;
2002                                         unique_ptr<X509Certificate> pX509Certificate;
2003                                         char* pSrcCertBytes = null;
2004                                         unique_ptr<char, _CharDeleter> pCertBytes;
2005
2006                                         BIO* pNewBIoCert = BIO_new(BIO_s_mem());
2007                                         unique_ptr<BIO, _BIoDeleter> pBIoCert(pNewBIoCert);
2008                                         SysTryReturn(NID_NET_HTTP, pBIoCert != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
2009
2010                                         PEM_write_bio_X509(pNewBIoCert, pSrcServerCert);
2011                                         bufferSize = BIO_number_written(pNewBIoCert);
2012
2013                                         pSrcCertBytes = (char*) calloc(bufferSize, sizeof(char));
2014                                         pCertBytes.reset(pSrcCertBytes);
2015                                         SysTryReturn(NID_NET_HTTP, pCertBytes != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
2016
2017                                         len = BIO_read(pNewBIoCert, pSrcCertBytes, bufferSize);
2018                                         SysLog(NID_NET_HTTP, "The buffer size is %d.", len);
2019
2020                                         r = buffer.Construct((byte*)pSrcCertBytes, 0, len, len);
2021                                         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
2022
2023                                         pX509Certificate.reset(new (nothrow) X509Certificate());
2024                                         SysTryReturn(NID_NET_HTTP, pX509Certificate != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
2025
2026                                         r = pX509Certificate->Construct(buffer);
2027                                         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, 0, E_SYSTEM, "[E_SYSTEM] Failed to construct X509Certificate.");
2028
2029                                         SysLog(NID_NET_HTTP, "Subject: %ls, Issuer: %ls", pX509Certificate->GetSubject().GetPointer(), pX509Certificate->GetIssuer().GetPointer());
2030
2031                                         r = pCertList->Add(*pX509Certificate);
2032                                         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
2033
2034                                         pX509Certificate.release();
2035                                 }
2036                         }
2037
2038                         //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_CERT_VERIFICATION_REQUESTED)
2039                         pHttpTransactionEvent->FireTransactionCertVerificationRequestedNEvent(pCertList.release());
2040
2041                         certVerificationResult = pHttpTransactionEvent->GetCertRequestedResult();
2042                         if (certVerificationResult)
2043                         {
2044                                 _HttpSessionImpl* pHttpSessionImpl = pHttpTransactionEvent->GetHttpSessionImpl();
2045                                 pHttpSessionImpl->IgnoreSslVerification();
2046                         }
2047
2048                         //Check the result
2049                         return pHttpTransactionEvent->GetCertRequestedResult();
2050                 }
2051
2052                 return 0;
2053
2054         } else
2055         {
2056                 SysLog(NID_NET_HTTP, "The SslInfo is not existed.");
2057
2058                 // The certificateFlag is HTTP_CV_FLAG_AUTOMATIC.
2059                 if (error != X509_V_OK)
2060                 {
2061                         String serverCertString;
2062                         STACK_OF(X509)* pSrcServerCertChain = X509_STORE_CTX_get1_chain(pX509ctx);
2063                         unique_ptr<STACK_OF(X509), _X509ChainDeleter> pServerCertChain(pSrcServerCertChain);
2064                         if (pServerCertChain != null)
2065                         {
2066                                 int numberOfCerts = pServerCertChain->stack.num;
2067                                 for (int i = numberOfCerts; i > 0; i--)
2068                                 {
2069                                         pSrcServerCert = sk_X509_pop(pSrcServerCertChain);
2070                                         pServerCert.reset(pSrcServerCert);
2071                                         if (pServerCert != null)
2072                                         {
2073                                                 char tempSubjectName[_HTTP_CERT_SUBJECT_SIZE];
2074                                                 X509_NAME_oneline(X509_get_subject_name(pSrcServerCert), tempSubjectName, _HTTP_CERT_SUBJECT_SIZE);
2075                                                 serverCertString = String(tempSubjectName);
2076
2077                                                 SysLog(NID_NET_HTTP, "The subject of certificate is %ls[depth: %d].", serverCertString.GetPointer(), i -1);
2078                                                 depth = i -1;
2079                                         }
2080                                 }
2081                         }
2082
2083                         const char* pErrorMsg = X509_verify_cert_error_string(error);
2084                         SysLog(NID_NET_HTTP, "Failed to verify the cert. depth(%d) - error(%s)", depth, pErrorMsg);
2085                         SysLog(NID_NET_HTTP, "The subject of last certificate is %ls.", serverCertString.GetPointer());
2086
2087                         pSSLInfo.reset(new (std::nothrow) _HttpSslInfo(socketFd, depth, serverCertString, pErrorMsg));
2088                         SysTryReturn(NID_NET_HTTP, pSSLInfo != null, 0, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
2089
2090                         r = _HttpUtility::SetSslCertInfo(*pSSLInfo);
2091                         SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, 0, r, "[%s] Memory allocation failed.", GetErrorMessage(r));
2092
2093                         pSSLInfo.release();
2094
2095                         return 0;
2096
2097                 }
2098                 else
2099                 {
2100                         return 1;
2101                 }
2102
2103         }
2104 }
2105
2106 gboolean
2107 _HttpTransactionImpl::OnHttpTransactionTimerExpiredEvent(gpointer pUserData)
2108 {
2109         int timerId = -1;
2110         _HttpTransactionImpl* pHttpTransactionImpl = static_cast< _HttpTransactionImpl* >(pUserData);
2111
2112         if (pHttpTransactionImpl->__pTimerSource != null)
2113         {
2114                 timerId = g_source_get_id(pHttpTransactionImpl->__pTimerSource);
2115                 g_source_set_callback(pHttpTransactionImpl->__pTimerSource, null, null, null);
2116                 pHttpTransactionImpl->__pTimerSource = null;
2117                 SysLog(NID_NET_HTTP, "Deleted g_source_destroy(%d)", timerId);
2118
2119                 if (!pHttpTransactionImpl->IsClosed())
2120                 {
2121                         //Fire the event(NET_HTTP_TRANSACTION_EVENT_ABORTED) - E_TIMEOUT
2122                         pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionAbortedEvent(E_TIMEOUT, true);
2123                 }
2124         }
2125
2126         return false;
2127 }
2128
2129 } } } // Tizen::Net::Http