2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
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
9 // http://floralicense.org/license/
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.
19 * @file FNetHttp_HttpTransactionImpl.cpp
20 * @brief This is the implementation file for _HttpTransactionImpl class.
23 #include <unique_ptr.h>
27 #include <FBaseByteBuffer.h>
28 #include <FBaseUtilStringUtil.h>
29 #include <FIoDirectory.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"
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;
70 namespace Tizen { namespace Net { namespace Http
73 int _HttpTransactionImpl::__generatedTransactionId = -1;
75 _HttpTransactionImpl::_HttpTransactionImpl(HttpTransaction* pHttpTransaction)
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)
90 , __isSubmitted(false)
91 , __isPendingTransaction(false)
92 , __enableTransactionReadyToWrite(false)
93 , __isHeaderEventFired(false)
94 , __uploadCurrentProgress(0)
95 , __donwloadCurrentProgress(0)
98 , __isAlreadyResumed(false)
99 , __isAlreadyPaused(false)
100 , __isCertRequiredEventFired(false)
101 , __certificateFlag(HTTP_CV_FLAG_AUTOMATIC)
102 , __pHttpProgressListener(null)
103 , __pHttpTransactionUserData(null)
105 , __pTimerSource(null)
109 _HttpTransactionImpl::~_HttpTransactionImpl(void)
111 SysLog(NID_NET_HTTP, "The _HttpTransactionImpl instance will be deleted.");
115 if (__pHttpRequest != null)
117 _HttpRequestImpl::DeleteHttpRequest(__pHttpRequest);
118 __pHttpRequest = null;
121 if (__pHttpResponse != null)
123 _HttpResponseImpl::DeleteHttpResponse(__pHttpResponse);
124 __pHttpResponse = null;
127 if (__pHttpTransactionUserData != null)
129 __pHttpTransactionUserData->__pHttpTransactionImpl = null;
130 __pHttpTransactionUserData->Release();
133 if (__pHttpAuthenticationImpl != null)
135 delete __pHttpAuthenticationImpl;
136 __pHttpAuthenticationImpl = null;
139 if (__pHttpCurl != null)
141 __pHttpCurl->Release();
144 __transactionListenerList.RemoveAll();
146 if (__pHttpTransactionEvent != null)
148 delete __pHttpTransactionEvent;
149 __pHttpTransactionEvent = null;
152 if (__pRequestBuffer != null)
154 delete __pRequestBuffer;
155 __pRequestBuffer = null;
158 if (__pTimerSource != null)
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);
169 __pHttpMultipleConnectionInfo = null;
171 SysLog(NID_NET_HTTP, "The _HttpTransactionImpl instance was deleted.");
175 _HttpTransactionImpl::Construct(_HttpSessionImpl& httpSessionImpl, HttpHeader* pCommonHeader, CURL* pCurl)
177 result r = E_SUCCESS;
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;
185 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
186 E_INVALID_STATE, "Already closed.");
188 __pHttpSessionImpl = &httpSessionImpl;
189 __pHttpMultipleConnectionInfo = __pHttpSessionImpl->GetHttpMultipleConnectionInfo();
190 SysTryReturnResult(NID_NET_HTTP, __pHttpMultipleConnectionInfo != null,
191 E_SYSTEM, "__pHttpMultipleConnectionInfo is null.");
193 __sessionId = __pHttpSessionImpl->GetSessionId();
195 pHttpRequest.reset(_HttpRequestImpl::CreateHttpRequestN());
196 SysTryReturnResult(NID_NET_HTTP, pHttpRequest != null,
197 E_OUT_OF_MEMORY, "Memory allocation failed.");
199 r = _HttpRequestImpl::GetInstance(*pHttpRequest)->Construct(*this, pCommonHeader);
200 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Propagating.");
202 pHttpResponse.reset(_HttpResponseImpl::CreateHttpResponseN());
203 SysTryReturnResult(NID_NET_HTTP, pHttpResponse != null,
204 E_OUT_OF_MEMORY, "Memory allocation failed.");
206 r = _HttpResponseImpl::GetInstance(*pHttpResponse)->Construct(*this);
207 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Propagating.");
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;
218 SysLog(NID_NET_HTTP, "Reused the pCurl[%x]", pCurl);
221 __pHttpCurl = new (std::nothrow) _HttpCurl(pCurl, false);
222 if (__pHttpCurl == null)
226 curl_easy_cleanup(pCurl);
229 SysLogException(NID_NET_HTTP, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Memory allocation failed.");
233 __transactionId = GenerateTransactionId();
234 __transactionListenerList.Construct();
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.");
240 pHttpTransactionEvent->Construct(__pHttpSessionImpl, this);
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.");
246 __pHttpRequest = pHttpRequest.release();
247 __pHttpResponse = pHttpResponse.release();
248 __pHttpTransactionEvent = pHttpTransactionEvent.release();
249 __pHttpTransactionUserData = pHttpTransactionUserData.release();
251 SysLog(NID_NET_HTTP, "The HttpTransaction[%d] was constructed.", __transactionId);
257 if (__pHttpCurl != null)
259 __pHttpCurl->Release();
267 _HttpTransactionImpl::CreateHttpTransactionN(void)
269 return new (std::nothrow) HttpTransaction();
273 _HttpTransactionImpl::DeleteHttpTransaction(HttpTransaction* pHttpTransaction)
275 delete pHttpTransaction;
279 _HttpTransactionImpl::Dispose()
281 result r = E_SUCCESS;
283 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
284 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
286 r = __pHttpSessionImpl->CloseTransaction(*__pHttpTransaction);
292 _HttpTransactionImpl::Close(void)
294 result r = E_SUCCESS;
296 IEnumeratorT< IHttpTransactionEventListener* >* pEnum = null;
297 IHttpTransactionEventListener* pHttpTransactionEventListener = null;
300 pEnum = __transactionListenerList.GetEnumeratorN();
301 while (pEnum->MoveNext() == E_SUCCESS)
303 r = pEnum->GetCurrent(pHttpTransactionEventListener);
305 if (pHttpTransactionEventListener != null)
306 __pHttpTransactionEvent->RemoveListener(*pHttpTransactionEventListener);
310 if (__pHttpTransactionUserData->GetSocketFd() >= 0)
312 sockFd = __pHttpTransactionUserData->GetSocketFd();
313 SysLog(NID_NET_HTTP, "The socket(%d) was closed.", sockFd);
318 __pHttpTransactionUserData->__isAlreadyClosedTransaction = true;
320 __pHttpTransactionUserData->__isAbortedTransaction = true;
322 SysLog(NID_NET_HTTP, "The HttpTransaction[%d] was closed.", __transactionId);
330 _HttpTransactionImpl::Abort(void)
332 result r = E_SUCCESS;
334 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
335 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
337 if (__pHttpTransactionUserData->GetSocketFd() >= 0)
339 int sockFd = __pHttpTransactionUserData->GetSocketFd();
340 SysLog(NID_NET_HTTP, "SocketFd(%d) will be closed. HttpTransaction[%d]", sockFd, __transactionId);
342 SysLog(NID_NET_HTTP, "Socket was closed. HttpTransaction[%d]");
345 __pHttpTransactionUserData->__isAbortedTransaction = true;
351 _HttpTransactionImpl::Set(_HttpTransactionImpl* pHttpTransactionImpl)
353 result r = E_SUCCESS;
355 HttpRequest* pHttpRequest = null;
356 _HttpRequestImpl* pHttpRequestImpl = null;
357 _HttpRequestImpl* pSrcHttpRequestImpl = null;
359 ByteBuffer* pRequestBuffer = null;
360 ArrayListT< IHttpTransactionEventListener* > listenerList;
361 Object* pUserObject = null;
364 pUserObject = pHttpTransactionImpl->GetUserObject();
365 __pUserData = pUserObject;
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.");
372 for (int i = 0; i < listenerList.GetCount(); i++)
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.");
379 r = this->AddHttpTransactionListener(*pListener);
380 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, r,
381 "[%s] Failed to add the HttpTransactionEventListener.", GetErrorMessage(r));
384 __pHttpProgressListener = pHttpTransactionImpl->GetHttpProgressEventListener();
386 __enableTransactionReadyToWrite = pHttpTransactionImpl->IsTransactionReadyToWriteEanbled();
387 __timeout = pHttpTransactionImpl->GetTimeout();
388 __certificateId = pHttpTransactionImpl->GetClientCertificate();
389 __isAlreadyResumed = pHttpTransactionImpl->IsAlreadyResumed();
390 __certificateFlag = pHttpTransactionImpl->GetServerCertificateVerification();
392 pHttpRequest = pHttpTransactionImpl->GetRequest();
393 SysTryReturn(NID_NET_HTTP, pHttpRequest != null, null, E_SYSTEM,
394 "[E_SYSTEM] An internal error has occurred.");
396 pHttpRequestImpl = _HttpRequestImpl::GetInstance(*pHttpRequest);
397 SysTryReturn(NID_NET_HTTP, pHttpRequestImpl != null, null, E_SYSTEM,
398 "[E_SYSTEM] An internal error has occurred.");
400 pSrcHttpRequestImpl = _HttpRequestImpl::GetInstance(*__pHttpRequest);
401 SysTryReturn(NID_NET_HTTP, pSrcHttpRequestImpl != null, null, E_SYSTEM,
402 "[E_SYSTEM] An internal error has occurred.");
405 r = pSrcHttpRequestImpl->Set(pHttpRequestImpl);
406 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, E_SYSTEM,
407 "[E_SYSTEM] An internal error has occurred.");
409 pRequestBuffer = pHttpTransactionImpl->GetRequestBuffer();
410 if (pRequestBuffer != null)
412 //Clear the flag of _HttpRequestImpl
413 pSrcHttpRequestImpl->SetReceivedTransactionReadyToWriteEvent(false);
415 r = pSrcHttpRequestImpl->WriteBody(*pRequestBuffer);
416 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, null, r, "[%s] Failed to write the body.", GetErrorMessage(r));
418 SysLog(NID_NET_HTTP, "The __pRequestBuffer is added to the Body.");
425 _HttpTransactionImpl::GetDefaultUserAgent(void)
429 SysLog(NID_NET_HTTP, "Set the Default User-Agent.");
431 char* pUserAgent = vconf_get_str(VCONFKEY_BROWSER_USER_AGENT);
432 SysAssertf(pUserAgent != null, "Failed to get default user agent(VCONFKEY_BROWSER_USER_AGENT)");
434 String userAgent(pUserAgent);
435 SysLog(NID_NET_HTTP, "Default User-Agent is %ls.", userAgent.GetPointer());
442 _HttpTransactionImpl::Submit(void)
444 result r = E_SUCCESS;
446 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
447 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
449 SysTryReturnResult(NID_NET_HTTP, __isSubmitted == false,
450 E_INVALID_STATE, "HttpTransaction[%d] is already submitted.", __transactionId);
452 SysTryReturnResult(NID_NET_HTTP, __pHttpSessionImpl->IsSessionValid(),
453 E_INVALID_SESSION, "The HttpSession is invalid. Construct a new HttpSession.");
458 char* pMethodName = null;
459 struct curl_slist* pRequestHeaderList = null;
461 HttpVersion httpVersion;
464 bool hasProtocolScheme = false;
465 bool compareHost = false;
467 String contentLength;
468 HttpHeader* pHeader = null;
469 _HttpHeaderImpl* pHeaderImpl = null;
470 _HttpRequestImpl* pRequestImpl = null;
472 ByteBuffer* pBodyBuffer = null;
474 long long contentLen = -1;
475 NetHttpAuthScheme authScheme = NET_HTTP_AUTH_NONE;
479 bool isEnableOnHttpBodyReadyToWrite = false;
481 SysLog(NID_NET_HTTP, "The HttpTransaction[%d] will be submitted. HttpSessionId[%d]", __transactionId, __sessionId);
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.");
488 pHeaderImpl = _HttpHeaderImpl::GetInstance(*pHeader);
489 SysTryReturnResult(NID_NET_HTTP, pHeaderImpl != null,
490 E_SYSTEM, "The header must not be null.");
492 pCurl = __pHttpCurl->GetCurl();
493 SysTryReturnResult(NID_NET_HTTP, pCurl != null,
494 E_SYSTEM, "The Curl must not be null.");
496 //Set the http version.
497 httpVersion = pRequestImpl->GetVersion();
498 if (httpVersion == HTTP_VERSION_1_0)
500 curl_easy_setopt(pCurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
504 curl_easy_setopt(pCurl, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
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.");
512 SysSecureLog(NID_NET_HTTP, "The request uri is %ls.", url.GetPointer());
514 hostAddress = __pHttpSessionImpl->GetHostAddress();
516 hasProtocolScheme = _HttpUtility::HasProtocolScheme(url);
517 if (!hasProtocolScheme)
519 if (__pHttpSessionImpl->GetSessionMode() == NET_HTTP_SESSION_MODE_MULTIPLE_HOST)
521 url = _HTTP_PROTOCOL_SCHEME + url;
525 //Add the scheme of host address.
526 String scheme = _HttpUtility::GetProtocolScheme(hostAddress);
529 SysSecureLog(NID_NET_HTTP, "Added the scheme to url(%ls).", url.GetPointer());
532 SysSecureLog(NID_NET_HTTP, "Added the scheme to url(%ls).", url.GetPointer());
535 //Compare the host of HttpSessoin with the host of uri.
536 if (__pHttpSessionImpl->GetSessionMode() != NET_HTTP_SESSION_MODE_MULTIPLE_HOST)
538 compareHost = _HttpUtility::CompareHost(hostAddress, url);
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());
545 pUrl = _StringConverter::CopyToCharArrayN(url);
546 SysTryReturnResult(NID_NET_HTTP, pUrl != null,
547 E_OUT_OF_MEMORY, "Memory allocation failed.");
550 curl_easy_setopt(pCurl, CURLOPT_URL, pUrl);
553 //Set the network interface.
554 if (!__pHttpSessionImpl->GetDeviceName().IsEmpty())
556 char* pDeviceName = _StringConverter::CopyToCharArrayN(__pHttpSessionImpl->GetDeviceName());
557 SysTryReturnResult(NID_NET_HTTP, pDeviceName != null,
558 E_OUT_OF_MEMORY, "Memory allocation failed.");
560 SysLog(NID_NET_HTTP, "[Target] The device name is %s.", pDeviceName);
561 curl_easy_setopt(pCurl, CURLOPT_INTERFACE, pDeviceName);
562 delete[] pDeviceName;
565 //Set the proxy address.
566 if (__pHttpSessionImpl->GetProxyAddress() != null)
568 char* pProxyAddress = _StringConverter::CopyToCharArrayN(*__pHttpSessionImpl->GetProxyAddress());
569 SysTryReturnResult(NID_NET_HTTP, pProxyAddress != null,
570 E_OUT_OF_MEMORY, "Memory allocation failed.");
572 curl_easy_setopt(pCurl, CURLOPT_PROXY, pProxyAddress);
573 delete[] pProxyAddress;
577 methodName = pRequestImpl->GetMethodName();
578 SysTryReturnResult(NID_NET_HTTP, !methodName.IsEmpty(), E_INVALID_ARG, "Method name is empty.");
580 pMethodName = _StringConverter::CopyToCharArrayN(methodName);
581 curl_easy_setopt(pCurl, CURLOPT_CUSTOMREQUEST, pMethodName);
582 delete[] pMethodName;
584 //Set the user-agent.
585 if (!pHeaderImpl->HasHeader(_HTTP_USERAGENT_HEADER_NAME, outFiledName))
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.");
591 r = pHeaderImpl->AddField(_HTTP_USERAGENT_HEADER_NAME, userAgent);
592 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS,
597 pRequestHeaderList = pHeaderImpl->MakeCurlHeaderList();
598 if (pRequestHeaderList != null)
600 curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pRequestHeaderList);
601 __pHttpTransactionUserData->__pCurlRequestHeaderList = pRequestHeaderList;
605 if (__pHttpSessionImpl->GetHttpCookieFlag() == NET_HTTP_COOKIE_FLAG_ALWAYS_MANUAL)
607 if (pRequestImpl->HasCookie())
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.");
615 curl_easy_setopt(pCurl, CURLOPT_COOKIE, pCookies);
620 else if (__pHttpSessionImpl->GetHttpCookieFlag() == NET_HTTP_COOKIE_FLAG_ALWAYS_AUTOMATIC)
622 String filePath = _HttpUtility::GetCookieFilePath();
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.");
627 char* pFilePath = _StringConverter::CopyToCharArrayN(filePath);
628 SysTryReturnResult(NID_NET_HTTP, pFilePath != null,
629 E_OUT_OF_MEMORY, "Memory allocation failed.");
631 curl_easy_setopt(pCurl, CURLOPT_COOKIEFILE, pFilePath);
632 curl_easy_setopt(pCurl, CURLOPT_COOKIEJAR, pFilePath);
636 SysLog(NID_NET_HTTP, "Set the Cookies automatically.");
639 encoding = pRequestImpl->GetAcceptEncoding();
641 if (!encoding.IsEmpty())
643 char* pEncodingType = _StringConverter::CopyToCharArrayN(encoding);
644 SysTryReturnResult(NID_NET_HTTP, pEncodingType != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
646 curl_easy_setopt(pCurl, CURLOPT_ENCODING, pEncodingType);
647 delete[] pEncodingType;
650 if (pHeaderImpl->GetHeaderValue(_HTTP_CONTENT_LENGTH_HEADER_NAME, contentLength))
652 r = LongLong::Parse(contentLength, contentLen);
653 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS,
654 E_INVALID_ARG, "Failed to parse the content-length.");
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);
661 else if (contentLen == 0)
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);
668 SysLog(NID_NET_HTTP, "The Content-Length is %lld.", contentLen);
672 SysLog(NID_NET_HTTP, "The Content-Length is not set.");
675 bodySize = pRequestImpl->GetTotalBodyLength();
677 if (__enableTransactionReadyToWrite)
679 if (contentLen >= 0 && contentLen <= bodySize)
681 SysLog(NID_NET_HTTP, "Content-Length(%lld) is equals or less than the bodySize(%u).", contentLen, bodySize);
682 isEnableOnHttpBodyReadyToWrite = false;
686 isEnableOnHttpBodyReadyToWrite = true;
688 SysLog(NID_NET_HTTP, "The isEnableOnHttpBodyReadyToWrite is %d.", isEnableOnHttpBodyReadyToWrite);
691 //Set the content and content size.
692 if (!isEnableOnHttpBodyReadyToWrite)
694 if (!pRequestImpl->IsEmptyBody())
696 if (__pRequestBuffer != null)
698 delete __pRequestBuffer;
701 __pRequestBuffer = pRequestImpl->ReadAllBodyN();
703 pBodyBuffer = pRequestImpl->ReadBodyN();
704 if (pBodyBuffer != null)
706 int bodySize = pBodyBuffer->GetRemaining();
707 const byte* pBodyBytes = pBodyBuffer->GetPointer();
709 curl_easy_setopt(pCurl, CURLOPT_COPYPOSTFIELDS, pBodyBytes);
712 SysLog(NID_NET_HTTP, "The Body Size is %d.", bodySize);
717 //The connection timeout is 30s. (default)
718 curl_easy_setopt(pCurl, CURLOPT_CONNECTTIMEOUT, _HTTP_DEFAULT_CONNECTION_TIMEOUT);
720 //Set the transaction timeout. The timeout includes connection timeout.
723 curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, __timeout);
725 else if (__timeout == 0)
727 curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_LIMIT, 1L);
728 curl_easy_setopt(pCurl, CURLOPT_LOW_SPEED_TIME, 30L);
731 if (__certificateFlag == HTTP_CV_FLAG_IGNORED)
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.");
739 //Set default CA path.
740 String caPath = _CertService::GetCertificateCrtFilePath();
741 SysLog(NID_NET_HTTP, "The CA Path is %ls.", caPath.GetPointer());
743 char* pCaPath = _StringConverter::CopyToCharArrayN(caPath);
744 SysTryReturnResult(NID_NET_HTTP, pCaPath != null,
745 E_OUT_OF_MEMORY, "Memory allocation failed.");
747 curl_easy_setopt(pCurl, CURLOPT_CAINFO, pCaPath);
748 curl_easy_setopt(pCurl, CURLOPT_CAPATH, null);
751 curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, 0);
752 curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYHOST, 2);
755 if (__certificateId >= 0)
757 SysLog(NID_NET_HTTP, "Set the client certificate(%d)", __certificateId);
761 if (__pHttpSessionImpl->IsAutoRedirectionEnabled())
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");
769 curl_easy_setopt(pCurl, CURLOPT_FOLLOWLOCATION, 0L);
770 SysLog(NID_NET_HTTP, "Disabled Auto-Redirection");
773 if (__pHttpAuthenticationImpl != null)
775 if (__pHttpAuthenticationImpl->IsProxyAuthenticationType())
778 char* pUserPwd = null;
780 userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetName());
781 userPwd.Append(L":");
782 userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetPassword());
784 pUserPwd = _StringConverter::CopyToCharArrayN(userPwd);
785 if (pUserPwd != null)
787 authScheme = __pHttpAuthenticationImpl->GetAuthScheme();
788 SysLog(NID_NET_HTTP, "Set the ProxyAuthentication(%s), userPwd",
789 _HttpUtility::GetHttpAuthSchemeByString(authScheme));
791 curl_easy_setopt(pCurl, CURLOPT_PROXYAUTH, _HttpUtility::GetHttpCurlAuthScheme(authScheme));
792 curl_easy_setopt(pCurl, CURLOPT_PROXYUSERPWD, pUserPwd);
800 char* pUserPwd = null;
802 userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetName());
803 userPwd.Append(L":");
804 userPwd.Append(__pHttpAuthenticationImpl->GetCredentials().GetPassword());
806 pUserPwd = _StringConverter::CopyToCharArrayN(userPwd);
807 if (pUserPwd != null)
809 authScheme = __pHttpAuthenticationImpl->GetAuthScheme();
810 SysLog(NID_NET_HTTP, "Set the HttpAuthentication(%s), userPwd", _HttpUtility::GetHttpAuthSchemeByString(authScheme));
812 curl_easy_setopt(pCurl, CURLOPT_HTTPAUTH, _HttpUtility::GetHttpCurlAuthScheme(authScheme));
813 curl_easy_setopt(pCurl, CURLOPT_USERPWD, pUserPwd);
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);
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);
828 //the Call back for uploading the Body.
829 if (isEnableOnHttpBodyReadyToWrite)
831 curl_easy_setopt(pCurl, CURLOPT_POST, 1L); //For receiving the OnHttpBodyReadyToWrite
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);
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);
842 curl_easy_setopt(pCurl, CURLOPT_SSL_CTX_FUNCTION, _HttpTransactionImpl::OnHttpSslHandshake);
843 curl_easy_setopt(pCurl, CURLOPT_SSL_CTX_DATA, __pHttpTransactionUserData);
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);
849 curl_easy_setopt(pCurl, CURLOPT_OPENSOCKETDATA, &__pHttpTransactionUserData->__socketFd);
850 curl_easy_setopt(pCurl, CURLOPT_OPENSOCKETFUNCTION, _HttpTransactionImpl::OnSocketOpened);
852 curl_easy_setopt(pCurl, CURLOPT_PRIVATE, __pHttpTransactionUserData); //curl_getinfo(PRIVATE)
854 //if current network is Custom NetConnection, Default Mode of ManagedNetConnection or Preference Mode of ManagedNetConnection is already started.
855 if (__pHttpSessionImpl->IsConnectionStarted())
857 CURLM* pCurlM = __pHttpMultipleConnectionInfo->GetCurlM();
858 SysTryReturnResult(NID_NET_HTTP, pCurlM != null,
859 E_SYSTEM, "The pCurlM must not be null. HttpTransaction[%d]", __transactionId);
861 //Adds the Curl handle to CurlM
862 rc = curl_multi_add_handle(pCurlM, pCurl);
865 SysLog(NID_NET_HTTP, "CURLM_OK: Called curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
869 _HttpUtility::PrintCurlMultiErrorCode(rc);
870 SysTryReturnResult(NID_NET_HTTP, false,
871 E_SYSTEM, "Failed to curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
873 __pHttpCurl->AddRef();
875 __pHttpTransactionUserData->AddRef();
877 __pHttpSessionImpl->GetHttpMultipleConnectionInfo()->AddRef();
879 SysLog(NID_NET_HTTP, "Submitted the HttpTransaction[%d] successfully.", __transactionId);
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);
888 __isSubmitted = true;
896 _HttpTransactionImpl::SubmitPendingTransaction(const String& deviceName, const String& proxyAddress)
898 result r = E_SUCCESS;
900 CURLM* pCurlM = null;
902 CURL* pCurl = __pHttpCurl->GetCurl();
903 SysTryReturnResult(NID_NET_HTTP, pCurl != null,
904 E_SYSTEM, "The Curl must not be null.");
906 if (!deviceName.IsEmpty())
908 char* pDeviceName = _StringConverter::CopyToCharArrayN(deviceName);
909 SysTryReturnResult(NID_NET_HTTP, pDeviceName != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
911 SysLog(NID_NET_HTTP, "[Target] The device name is %s.", pDeviceName);
912 curl_easy_setopt(pCurl, CURLOPT_INTERFACE, pDeviceName);
913 delete[] pDeviceName;
916 if (__pHttpSessionImpl->GetProxyAddress() != null)
918 char* pProxyAddress = _StringConverter::CopyToCharArrayN(*__pHttpSessionImpl->GetProxyAddress());
919 SysTryReturnResult(NID_NET_HTTP, pProxyAddress != null, E_OUT_OF_MEMORY, "Memory allocation failed.");
921 curl_easy_setopt(pCurl, CURLOPT_PROXY, pProxyAddress);
922 delete[] pProxyAddress;
925 pCurlM = __pHttpMultipleConnectionInfo->GetCurlM();
926 SysTryReturnResult(NID_NET_HTTP, pCurlM != null,
927 E_SYSTEM, "The pCurlM must not be null. HttpTransaction[%d]", __transactionId);
929 //Adds the Curl handle to CurlM
930 rc = curl_multi_add_handle(pCurlM, pCurl);
933 SysLog(NID_NET_HTTP, "CURLM_OK: Called curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
937 _HttpUtility::PrintCurlMultiErrorCode(rc);
938 SysTryReturnResult(NID_NET_HTTP, false,
939 E_SYSTEM, "Failed to curl_multi_add_handle(). HttpTransaction[%d]", __transactionId);
941 __pHttpCurl->AddRef();
943 __pHttpTransactionUserData->AddRef();
945 __pHttpSessionImpl->GetHttpMultipleConnectionInfo()->AddRef();
947 SysLog(NID_NET_HTTP, "Submitted the pending HttpTransaction[%d] successfully.", __transactionId);
955 _HttpTransactionImpl::GetRequest() const
959 SysTryReturn(NID_NET_HTTP, __isClosed == false, null, E_INVALID_STATE,
960 "[E_INVALID_STATE] HttpTransaction(%d) is already closed.", __transactionId);
962 SysTryReturn(NID_NET_HTTP, __pHttpRequest != null, null, E_INVALID_DATA,
963 "[E_INVALID_DATA] HttpRequest must not be null.", __transactionId);
965 return __pHttpRequest;
969 _HttpTransactionImpl::GetResponse(void) const
973 _HttpResponseImpl* pHttpResponseImpl = _HttpResponseImpl::GetInstance(*__pHttpResponse);
975 SysTryReturn(NID_NET_HTTP, !__isClosed, null, E_INVALID_STATE,
976 "[E_INVALID_STATE] HttpTransaction[%d] is already closed.", __transactionId);
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.");
981 return __pHttpResponse;
985 _HttpTransactionImpl::AddHttpTransactionListener(IHttpTransactionEventListener& listener)
987 result r = E_SUCCESS;
989 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
990 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
992 r = __pHttpTransactionEvent->AddListener(listener, true);
993 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, r, r, "[%s] Failed to add the listener.", GetErrorMessage(r));
995 IHttpTransactionEventListener* pListener = const_cast< IHttpTransactionEventListener* >(&listener);
996 SysTryReturnResult(NID_NET_HTTP, pListener != null,
997 E_SYSTEM, "A system error has occurred.");
999 r = __transactionListenerList.Add(pListener);
1000 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Failed to add the listener.");
1002 SysLog(NID_NET_HTTP, "Added the listener(HttpTransaction[%d]).", __transactionId);
1008 _HttpTransactionImpl::RemoveHttpTransactionListener(IHttpTransactionEventListener& listener)
1010 result r = E_SUCCESS;
1012 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1013 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1015 r = __pHttpTransactionEvent->RemoveListener(listener);
1016 SysTryReturnResult(NID_NET_HTTP, r == E_SUCCESS, r, "Failed to add the listener.");
1018 IHttpTransactionEventListener* pListener = const_cast< IHttpTransactionEventListener* >(&listener);
1019 r = __transactionListenerList.Remove(pListener);
1022 SysLog(NID_NET_HTTP, "Failed to remove the listener(HttpTransaction[%d]).", __transactionId);
1025 SysLog(NID_NET_HTTP, "Removed the listener(HttpTransaction[%d]).", __transactionId);
1031 _HttpTransactionImpl::SetHttpProgressListener(IHttpProgressEventListener& listener)
1033 result r = E_SUCCESS;
1035 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1036 E_INVALID_STATE, "HttpTransaction(%d) is already closed.", __transactionId);
1038 __pHttpProgressListener = &listener;
1039 __pHttpTransactionEvent->SetHttpProgressListener(__pHttpProgressListener);
1045 _HttpTransactionImpl::SetUserObject(const Tizen::Base::Object* pUserData)
1047 result r = E_SUCCESS;
1049 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1050 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1052 __pUserData = pUserData;
1057 Tizen::Base::Object*
1058 _HttpTransactionImpl::GetUserObject(void) const
1060 return const_cast< Object* >(__pUserData);
1064 _HttpTransactionImpl::EnableTransactionReadyToWrite(void)
1068 SysLog(NID_NET_HTTP, "Should be called before the HttpTransaction is submitted.");
1071 __enableTransactionReadyToWrite = true;
1073 SysLog(NID_NET_HTTP, "Enable OnTransactionReadyToWrite().");
1079 _HttpTransactionImpl::Resume()
1081 result r = E_SUCCESS;
1083 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1084 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1086 SysTryReturnResult(NID_NET_HTTP, __isCertRequiredEventFired == true,
1087 E_INVALID_STATE, "Should be called after the OnTransactionCertVerificationRequiredN() is invoked.");
1089 SysTryReturnResult(NID_NET_HTTP, __isAlreadyResumed == false,
1090 E_INVALID_STATE, "The HttpTransaction[%d] is already resumed.", __transactionId);
1092 SysLog(NID_NET_HTTP, "Calling Resume() to ignore server certificate verification.");
1094 //Rollback the HttpTransaction.
1096 if (__pHttpCurl != null)
1098 __pHttpCurl->Release();
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);
1106 __pHttpCurl = new (std::nothrow) _HttpCurl(pCurl, false);
1107 SysTryReturnResult(NID_NET_HTTP, __pHttpCurl != null,
1108 E_OUT_OF_MEMORY, "Memory allocation failed.");
1110 if (__pHttpTransactionUserData != null)
1112 __pHttpTransactionUserData->Release();
1115 __pHttpTransactionUserData = new (std::nothrow) _HttpTransactionUserData(this, __pHttpCurl);
1116 SysTryReturnResult(NID_NET_HTTP, __pHttpTransactionUserData != null,
1117 E_OUT_OF_MEMORY, "Memory allocation failed.");
1120 __isSubmitted = false;
1121 __transactionId = GenerateTransactionId();
1123 if (__pRequestBuffer != null)
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.");
1129 //Clear the flag of _HttpRequestImpl
1130 pHttpRequestImpl->SetReceivedTransactionReadyToWriteEvent(false);
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.");
1137 SysLog(NID_NET_HTTP, "__pRequestBuffer is added the Body.");
1139 __pHttpSessionImpl->IgnoreSslVerification();
1140 __isAlreadyResumed = true;
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.");
1147 SysLog(NID_NET_HTTP, "Called Resume() to ignore server certificate verification.");
1152 _HttpTransactionImpl::Pause(void)
1154 result r = E_SUCCESS;
1156 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1157 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1159 SysTryReturnResult(NID_NET_HTTP, __isCertRequiredEventFired == true,
1160 E_INVALID_STATE, "Should be called after the OnTransactionCertVerificationRequiredN() is invoked.");
1162 SysTryReturnResult(NID_NET_HTTP, __isAlreadyPaused == false,
1163 E_INVALID_STATE, "The HttpTransaction[%d] is already paused.", __transactionId);
1165 SysLog(NID_NET_HTTP, "Calling Pause().");
1167 __isAlreadyPaused = true;
1169 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_ABORTED) - E_HTTP_USER
1170 __pHttpTransactionEvent->FireTransactionAbortedEvent(E_HTTP_USER, true);
1172 SysLog(NID_NET_HTTP, "Called Pause().");
1178 _HttpTransactionImpl::SetTimeout(int timeout)
1180 result r = E_SUCCESS;
1182 SysTryReturnResult(NID_NET_HTTP, timeout >= 0,
1183 E_INVALID_ARG, "The specified input parameter is invalid.");
1185 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1186 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1188 SysTryReturnResult(NID_NET_HTTP, __isSubmitted == false,
1189 E_INVALID_STATE, "HttpTransaction[%d] is already submitted.", __transactionId);
1191 __timeout = timeout;
1193 SysLog(NID_NET_HTTP, "Set the timeout[%d].", timeout);
1199 _HttpTransactionImpl::GetTimeout(void) const
1205 _HttpTransactionImpl::SetClientCertificate(int certificateId)
1207 result r = E_SUCCESS;
1209 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1210 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1212 SysTryReturnResult(NID_NET_HTTP, certificateId >= 0,
1213 E_INVALID_ARG, "The certificateId is invalid.");
1215 __certificateId = certificateId;
1217 SysLog(NID_NET_HTTP, "Selected Client Certificate ID[%d].", certificateId);
1223 _HttpTransactionImpl::GetClientCertificate(void) const
1225 return __certificateId;
1229 _HttpTransactionImpl::SetServerCertificateVerification(NetHttpCertificateVerificationFlag flag)
1231 result r = E_SUCCESS;
1233 SysTryReturnResult(NID_NET_HTTP, __isClosed == false,
1234 E_INVALID_STATE, "HttpTransaction[%d] is already closed.", __transactionId);
1236 SysTryReturnResult(NID_NET_HTTP, __isSubmitted == false,
1237 E_INVALID_STATE, "HttpTransaction[%d] is already submitted.", __transactionId);
1239 __certificateFlag = flag;
1241 SysLog(NID_NET_HTTP, "Set the flag for certificate verification.[%s].", _HttpUtility::ConvertNetHttpCertificateVerificationFlagToString(flag));
1246 NetHttpCertificateVerificationFlag
1247 _HttpTransactionImpl::GetServerCertificateVerification(void) const
1249 return __certificateFlag;
1252 _HttpTransactionImpl*
1253 _HttpTransactionImpl::GetInstance(HttpTransaction& httpTransaction)
1255 return httpTransaction.__pHttpTransactionImpl;
1258 const _HttpTransactionImpl*
1259 _HttpTransactionImpl::GetInstance(const HttpTransaction& httpTransaction)
1261 return httpTransaction.__pHttpTransactionImpl;
1265 _HttpTransactionImpl::GetHttpSessioinImpl(void) const
1267 return __pHttpSessionImpl;
1271 _HttpTransactionImpl::GetHttpTransaction(void) const
1273 return __pHttpTransaction;
1276 _HttpTransactionEvent*
1277 _HttpTransactionImpl::GetHttpTransactionEvent(void) const
1279 return __pHttpTransactionEvent;
1283 _HttpTransactionImpl::IsTransactionReadyToWriteEanbled(void) const
1285 return __enableTransactionReadyToWrite;
1289 _HttpTransactionImpl::OpenAuthenticationInfoN(void)
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.");
1298 pHttpAuthenticationImpl = _HttpAuthenticationImpl::GetInstance(*pHttpAuthentication);
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));
1305 SetHttpAuthenticationImpl(pHttpAuthenticationImpl);
1307 SysLog(NID_NET_HTTP, "The HttpAuthentication instance is created.");
1309 return pHttpAuthentication.release();
1313 _HttpTransactionImpl::GenerateTransactionId(void)
1315 int transactionId = 0;
1316 Mutex* pHttpMutex = null;
1318 pHttpMutex = _HttpUtility::GetHttpMutex();
1320 MutexGuard locked(*pHttpMutex);
1321 SysTryReturn(NID_NET_HTTP, locked.IsLocked(), _HTTP_INVALID_ID, E_SYSTEM,
1322 "[E_SYSTEM] Failed to lock mutex.");
1324 if (__generatedTransactionId >= Integer::VALUE_MAX)
1326 __generatedTransactionId = 0;
1330 __generatedTransactionId++;
1333 transactionId = __generatedTransactionId;
1335 return transactionId;
1339 _HttpTransactionImpl::GetTransactionId(void) const
1341 return __transactionId;
1345 _HttpTransactionImpl::SetHttpAuthType(NetHttpAuthScheme authType)
1347 __authType = authType;
1351 _HttpTransactionImpl::GetHttpAuthType(void) const
1357 _HttpTransactionImpl::SetHttpAuthenticationImpl(const _HttpAuthenticationImpl* pAuthenticationImpl)
1359 result r = E_SUCCESS;
1361 if (__pHttpAuthenticationImpl != null)
1363 delete __pHttpAuthenticationImpl;
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.");
1370 r = __pHttpAuthenticationImpl->Construct(*pAuthenticationImpl, *this);
1371 SysTryReturnVoidResult(NID_NET_HTTP, r == E_SUCCESS, r,
1372 "[%s] Propagating.", GetErrorMessage(r));
1375 _HttpAuthenticationImpl*
1376 _HttpTransactionImpl::GetHttpAuthenticationImpl(void) const
1378 return __pHttpAuthenticationImpl;
1382 _HttpTransactionImpl::GetRequestBuffer(void)
1384 return __pRequestBuffer;
1387 ArrayListT< IHttpTransactionEventListener* >*
1388 _HttpTransactionImpl::GetEventListenerList(void)
1390 return &__transactionListenerList;
1393 _HttpTransactionUserData*
1394 _HttpTransactionImpl::GetHttpTransactionUserData(void) const
1396 return __pHttpTransactionUserData;
1400 _HttpTransactionImpl::IsClosed(void) const
1406 _HttpTransactionImpl::IsCanceled(void) const
1408 return __isCanceled;
1412 _HttpTransactionImpl::SetTransactionCanceled(bool isCanceled)
1414 __isCanceled = isCanceled;
1418 _HttpTransactionImpl::IsSubmitted(void) const
1420 return __isSubmitted;
1424 _HttpTransactionImpl::IsPendingTransaction(void) const
1426 return __isPendingTransaction;
1430 _HttpTransactionImpl::IsHeaderEventFired(void) const
1432 return __isHeaderEventFired;
1436 _HttpTransactionImpl::SetCertRequiredEventFired(bool isFired)
1438 __isCertRequiredEventFired = isFired;
1442 _HttpTransactionImpl::IsAlreadyResumed(void) const
1444 if (__isAlreadyResumed || __isAlreadyPaused)
1455 _HttpTransactionImpl::IgnoreSslVerification(void)
1457 __isAlreadyResumed = true;
1461 _HttpTransactionImpl::SetTimer(void)
1464 GMainContext* pGMainContext = __pHttpMultipleConnectionInfo->GetGMainContext();
1465 SysTryReturnVoidResult(NID_NET_HTTP, pGMainContext != null, E_SYSTEM,
1466 "[E_SYSTEM] The pGMainContext must not be null.");
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);
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);
1477 _HttpTransactionImpl::GetHttpCurl(void) const
1482 const IHttpProgressEventListener*
1483 _HttpTransactionImpl::GetHttpProgressEventListener(void) const
1485 return __pHttpProgressListener;
1489 _HttpTransactionImpl::GetHttpResponseImpl(void) const
1491 return _HttpResponseImpl::GetInstance(*__pHttpResponse);
1495 _HttpTransactionImpl::OnSocketReceivedEvent(GIOChannel* pSource, GIOCondition condition, gpointer pUserData)
1497 if (condition == G_IO_IN)
1499 SysLog(NID_NET_HTTP, "====> [Event] Received the socket event(G_IO_IN).");
1501 else if (condition == G_IO_OUT)
1503 SysLog(NID_NET_HTTP, "====> [Event] Received the socket event(G_IO_OUT).");
1507 SysLog(NID_NET_HTTP, "====> [Event] Received the socket event(%d).", condition);
1510 _HttpMultipleConnectionInfo* pHttpMultipleConnectionInfo = static_cast< _HttpMultipleConnectionInfo* >(pUserData);
1511 int remainsConnection = -1;
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);
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);
1522 pHttpMultipleConnectionInfo->SetRemainsConnection(remainsConnection);
1525 SysLog(NID_NET_HTTP, "CURLM_OK: Called curl_multi_socket_action(%d)", action);
1529 _HttpUtility::PrintCurlMultiErrorCode(rc);
1532 pHttpMultipleConnectionInfo->CheckCurlMultiStatus();
1534 if (remainsConnection > 0)
1545 _HttpTransactionImpl::OnSocketOpened(int* pSocketFd, curlsocktype purpose, struct curl_sockaddr* addr)
1547 int socketFd = socket(addr->family, addr->socktype, addr->protocol);
1548 SysLog(NID_NET_HTTP, "SOCKET FD (%d)", socketFd);
1550 *pSocketFd = socketFd;
1556 _HttpTransactionImpl::OnHttpProgress(void* pUserData, double totalDownloadSize, double currentDownloadedSize,
1557 double totalUploadSize,
1558 double currentUploadedSize)
1560 _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1561 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1563 if (pHttpTransactionUserData->IsAbortedTransaction())
1565 SysLog(NID_NET_HTTP, "The HttpTransaction is already closed.");
1566 return _HTTP_NETWORK_ERROR;
1569 if (pHttpTransactionImpl->__pHttpProgressListener != null)
1571 long long donwloadTotalProgress = static_cast< long long >(totalDownloadSize);
1572 long long donwloadCurrentProgress = static_cast< long long >(currentDownloadedSize);
1574 long long uploadTotalProgress = static_cast< long long >(totalUploadSize);
1575 long long uploadCurrentProgress = static_cast< long long >(currentUploadedSize);
1577 SysLog(NID_NET_HTTP, "===> Progress UP(%lld/%lld) DOWN(%lld/%lld)", uploadCurrentProgress, uploadTotalProgress,
1578 donwloadCurrentProgress,
1579 donwloadTotalProgress);
1581 if (donwloadCurrentProgress != pHttpTransactionImpl->__donwloadCurrentProgress)
1583 _HttpResponseImpl* pHttpResponseImpl = _HttpResponseImpl::GetInstance(*pHttpTransactionImpl->__pHttpResponse);
1585 if (pHttpResponseImpl->IsCurrentBodyReceived())
1587 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_DOWNLOAD_PROGRESS)
1588 pHttpTransactionImpl->__pHttpTransactionEvent->FireHttpDownloadInProgressEvent(pHttpResponseImpl->GetCurrentBodyLength(), donwloadTotalProgress);
1590 pHttpResponseImpl->SetReceivedBody(false);
1591 pHttpResponseImpl->SetTotalBodyLength(donwloadTotalProgress);
1594 pHttpTransactionImpl->__donwloadCurrentProgress = donwloadCurrentProgress;
1597 else if (uploadCurrentProgress != pHttpTransactionImpl->__uploadCurrentProgress)
1599 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_UPLOAD_PROGRESS)
1600 pHttpTransactionImpl->__pHttpTransactionEvent->FireHttpUploadInProgressEvent(uploadCurrentProgress, uploadTotalProgress);
1601 pHttpTransactionImpl->__uploadCurrentProgress = uploadCurrentProgress;
1609 _HttpTransactionImpl::OnHttpHeaderReceived(void* pHeaderMsg, size_t size, size_t nmemb, void* pUserData)
1611 result r = E_SUCCESS;
1612 int bytesSize = size * nmemb;
1614 //SysLog(NID_NET_HTTP, "===> Received the header(Bytes: %d).", bytesSize);
1616 if (pHeaderMsg == null || bytesSize <= 0)
1618 SysLog(NID_NET_HTTP, "Invalid header was received.");
1622 byte* pBytes = static_cast< byte* >(pHeaderMsg);
1623 _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1624 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1625 _HttpResponseImpl* pHttpResponseImpl = null;
1627 String headerLine((char*) pBytes);
1629 if (pHttpTransactionUserData->IsAbortedTransaction())
1631 SysLog(NID_NET_HTTP, "The HttpTransaction is already closed.");
1635 pHttpResponseImpl = _HttpResponseImpl::GetInstance(*pHttpTransactionImpl->__pHttpResponse);
1636 r = pHttpResponseImpl->AddRawHeader(pBytes, bytesSize, false);
1639 SysLogException(NID_NET_HTTP, r, "[%s] Propagating.", GetErrorMessage(r));
1645 //Call back Function for curl.
1647 _HttpTransactionImpl::OnHttpBodyReceived(void* pBodyMsg, size_t size, size_t nmemb, void* pUserData)
1649 result r = E_SUCCESS;
1650 int bytesSize = size * nmemb;
1652 SysLog(NID_NET_HTTP, "===> Received the body(Bytes: %d).", bytesSize);
1654 if (pBodyMsg == null || bytesSize <= 0)
1656 SysLog(NID_NET_HTTP, "Invalid body was received.");
1660 byte* pBytes = (byte*) pBodyMsg;
1661 _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1662 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1663 _HttpResponseImpl* pHttpResponseImpl = null;
1665 bool isFullBuffer = false;
1666 int readBodySize = -1;
1668 if (pHttpTransactionUserData->IsAbortedTransaction())
1670 SysLog(NID_NET_HTTP, "The HttpTransaction was aborted.");
1674 pHttpResponseImpl = _HttpResponseImpl::GetInstance(*pHttpTransactionImpl->__pHttpResponse);
1675 pCurl = pHttpTransactionImpl->__pHttpCurl->GetCurl();
1677 if (!pHttpTransactionImpl->__isHeaderEventFired)
1679 SysLog(NID_NET_HTTP, "The header event will be fired in OnHttpBodyReceived()");
1681 r = pHttpResponseImpl->AddRawHeader(null, 0, true);
1684 SysLogException(NID_NET_HTTP, r, "[%s] Propagating.", GetErrorMessage(r));
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);
1692 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_HEADER_COMPLETED)
1693 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionHeaderCompletedEvent(pHttpResponseImpl->GetHeaderLength(), proxyAuth, httpAuth);
1695 pHttpTransactionImpl->__isHeaderEventFired = true;
1697 if (pHttpTransactionUserData->IsAbortedTransaction())
1699 SysLog(NID_NET_HTTP, "The HttpTransaction was aborted.");
1704 r = pHttpResponseImpl->AddRawBody(pBytes, bytesSize, isFullBuffer, readBodySize);
1707 SysLogException(NID_NET_HTTP, r, "[%s] Propagating.", GetErrorMessage(r));
1710 //Check if the Buffer is full.
1711 if (isFullBuffer && readBodySize > 0)
1713 //Fire the event(NET_HTTP_TRANSACTION_EVENT_READY_TO_READ)
1714 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionReadyToReadEvent(readBodySize);
1716 pHttpResponseImpl->SetCurrentBodyLength(readBodySize);
1717 pHttpResponseImpl->SetReceivedBody(true);
1724 _HttpTransactionImpl::OnHttpDebugReceived(CURL* pCurl, curl_infotype type, char* pChar, size_t size, void* pUserData)
1726 char logBuffer[_HTTP_DEFAULT_HEADER_SIZE];
1729 if (_HTTP_DEFAULT_HEADER_SIZE > static_cast< int >(size))
1735 logSize = _HTTP_DEFAULT_HEADER_SIZE - 1;
1738 if (type == CURLINFO_TEXT)
1740 strncpy(logBuffer, pChar, logSize);
1741 logBuffer[logSize] = '\0';
1742 SysLog(NID_NET_HTTP, "[DEBUG] %s", logBuffer);
1744 else if (type == CURLINFO_HEADER_IN || type == CURLINFO_HEADER_OUT)
1746 //Ignore the body message.
1747 if (size >= 2 && pChar[0] == 0x0D && pChar[1] == 0x0A)
1753 strncpy(logBuffer, pChar, logSize);
1754 logBuffer[logSize] = '\0';
1755 SysLog(NID_NET_HTTP, "[DEBUG] %s", logBuffer);
1763 _HttpTransactionImpl::OnHttpBodyReadyToWrite(void* pBodyMsg, size_t size, size_t nmemb, void* pUserData)
1765 result r = E_SUCCESS;
1766 int recommendedSize = size * nmemb;
1768 SysLog(NID_NET_HTTP, "===> Called(%d).", recommendedSize);
1770 _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1771 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1772 _HttpRequestImpl* pHttpRequestImpl = null;
1773 ByteBuffer* pBodyBuffer = null;
1776 if (pHttpTransactionUserData->IsAbortedTransaction())
1778 SysLog(NID_NET_HTTP, "The HttpTransaction was aborted.");
1779 return CURL_READFUNC_ABORT;
1782 pHttpRequestImpl = _HttpRequestImpl::GetInstance(*pHttpTransactionImpl->__pHttpRequest);
1783 pHttpRequestImpl->SetRecommendedSize(recommendedSize);
1784 if (pHttpRequestImpl->IsFirstChunkBody())
1786 SysLog(NID_NET_HTTP,
1787 "First chunk Body. Ignore to fire the event(OnTransactionReadyToWriteEvent) to send the first chunk");
1791 pHttpRequestImpl->SetReceivedTransactionReadyToWriteEvent(true);
1792 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_READY_TO_WRITE)
1793 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionReadyToWriteEvent(recommendedSize);
1796 pBodyBuffer = pHttpRequestImpl->GetSendingBuffer();
1797 if (pBodyBuffer == null)
1799 if (pHttpRequestImpl->IsLastChunkBody()) //Last chunk (ByteBuffer is an empty(0))
1801 SysLog(NID_NET_HTTP, "Sent the last chunk.");
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].");
1810 bufferSize = pBodyBuffer->GetRemaining();
1811 if (bufferSize > recommendedSize)
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].");
1817 pHttpRequestImpl->SetSendingBuffer(pBodyBuffer);
1818 SysLog(NID_NET_HTTP, "[bufferSize(%d) > recommendedSize(%d)] Sent the chunk(size: %d).", bufferSize, recommendedSize,
1820 return recommendedSize;
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);
1831 if (pHttpRequestImpl->IsFirstChunkBody())
1833 pHttpRequestImpl->SetFirstChunkBody(false);
1834 SysLog(NID_NET_HTTP, "Ended the first chunk body.");
1837 SysLog(NID_NET_HTTP, "[bufferSize(%d) <= recommendedSize(%d)] Sent the chunk(size: %d).", bufferSize, recommendedSize,
1842 SysLogException(NID_NET_HTTP, E_IO, "[E_IO] CURL_READFUNC_ABORT.");
1844 return CURL_READFUNC_ABORT;
1848 _HttpTransactionImpl::OnHttpSslHandshake(CURL* pCurl, SSL_CTX* pSslctx, void* pUserData)
1851 result r = E_SUCCESS;
1852 CURLcode curlCode = CURLE_OK;
1854 SysLog(NID_NET_HTTP, "Received OnHttpSslHandshake()");
1856 _HttpTransactionUserData* pHttpTransactionUserData = static_cast< _HttpTransactionUserData* >(pUserData);
1857 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionUserData->GetHttpTransactionImpl();
1859 if (pHttpTransactionImpl->__isAlreadyResumed || pHttpTransactionImpl->__certificateFlag == HTTP_CV_FLAG_IGNORED)
1861 SysLog(NID_NET_HTTP, "Resume the HttpTransaction. Ignore to verify the server cert.");
1865 if (pHttpTransactionImpl->__certificateFlag == HTTP_CV_FLAG_MANUAL)
1867 unique_ptr<_HttpSslInfo> pSSLInfo;
1869 SysLog(NID_NET_HTTP, "The certificate mode is HTTP_CV_FLAG_MANUAL");
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.");
1874 r = _HttpUtility::SetSslCertInfo(*pSSLInfo);
1875 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, CURLE_SSL_CERTPROBLEM, r, "[%s] Memory allocation failed.", GetErrorMessage(r));
1880 SSL_CTX_set_verify_depth(pSslctx, _HTTP_CERT_VERIFICATION_DEPTH_LIMIT);
1881 SSL_CTX_set_verify(pSslctx, SSL_VERIFY_PEER, _HttpTransactionImpl::OnHttpSslVerify);
1884 if (pHttpTransactionImpl->__certificateId >= 0)
1886 X509* pClientCert = null;
1887 EVP_PKEY* pClientKey = null;
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.");
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);
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.");
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);
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);
1910 SysLog(NID_NET_HTTP, "The subject of certificate is %ls.", clientCertString.GetPointer());
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);
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.");
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);
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);
1931 _HttpTransactionImpl::OnHttpSslVerify(int preverify_ok, X509_STORE_CTX* pX509ctx)
1933 result r = E_SUCCESS;
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);
1940 SysTryReturn(NID_NET_HTTP, pSsl != null, 0, E_SYSTEM, "[E_SYSTEM] The ssl must not be null.");
1942 socketFd = SSL_get_fd(pSsl);
1943 SysLog(NID_NET_HTTP, "The ssl socket is %d.", socketFd);
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);
1950 pExistSslInfo = _HttpUtility::GetSslCertInfo(socketFd);
1952 if (pExistSslInfo != null)
1954 SysLog(NID_NET_HTTP, "The SslInfo is existed.");
1956 bool certVerificationResult = false;
1958 _HttpTransactionEvent* pHttpTransactionEvent = pExistSslInfo->GetHttpTransactionEvent();
1959 SysTryReturn(NID_NET_HTTP, pHttpTransactionEvent != null, 0, E_SYSTEM, "[E_SYSTEM] pHttpTransactionEvent must not be null.");
1961 _HttpTransactionImpl* pHttpTransactionImpl = pHttpTransactionEvent->GetHttpTransactionImpl();
1962 SysTryReturn(NID_NET_HTTP, pHttpTransactionImpl != null, 0, E_SYSTEM, "[E_SYSTEM] pHttpTransactionImpl must not be null.");
1964 if (pHttpTransactionImpl->GetServerCertificateVerification() != HTTP_CV_FLAG_MANUAL)
1966 SysLog(NID_NET_HTTP, "The server certificate verification is not HTTP_CV_FLAG_MANUAL.");
1970 if (pHttpTransactionEvent->GetCertRequestedResult())
1972 SysLog(NID_NET_HTTP, "The certificate verification is already resumed.");
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)
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.");
1985 int numberOfCerts = pServerCertChain->stack.num;
1986 for (int i = numberOfCerts; i > 0; i--)
1988 pSrcServerCert = sk_X509_pop(pSrcServerCertChain);
1989 pServerCert.reset(pSrcServerCert);
1990 if (pServerCert != null)
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);
1996 SysLog(NID_NET_HTTP, "Count of Certs(%d), The subject of certificate is %ls[depth: %d].", numberOfCerts, serverCertString.GetPointer(), i -1);
1998 // Converter X509 to ByteBuffer.
1999 int bufferSize = -1;
2002 unique_ptr<X509Certificate> pX509Certificate;
2003 char* pSrcCertBytes = null;
2004 unique_ptr<char, _CharDeleter> pCertBytes;
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.");
2010 PEM_write_bio_X509(pNewBIoCert, pSrcServerCert);
2011 bufferSize = BIO_number_written(pNewBIoCert);
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.");
2017 len = BIO_read(pNewBIoCert, pSrcCertBytes, bufferSize);
2018 SysLog(NID_NET_HTTP, "The buffer size is %d.", len);
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.");
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.");
2026 r = pX509Certificate->Construct(buffer);
2027 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, 0, E_SYSTEM, "[E_SYSTEM] Failed to construct X509Certificate.");
2029 SysLog(NID_NET_HTTP, "Subject: %ls, Issuer: %ls", pX509Certificate->GetSubject().GetPointer(), pX509Certificate->GetIssuer().GetPointer());
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.");
2034 pX509Certificate.release();
2038 //Fire the event(_HTTP_TRANSACTION_EVENT_TYPE_CERT_VERIFICATION_REQUESTED)
2039 pHttpTransactionEvent->FireTransactionCertVerificationRequestedNEvent(pCertList.release());
2041 certVerificationResult = pHttpTransactionEvent->GetCertRequestedResult();
2042 if (certVerificationResult)
2044 _HttpSessionImpl* pHttpSessionImpl = pHttpTransactionEvent->GetHttpSessionImpl();
2045 pHttpSessionImpl->IgnoreSslVerification();
2049 return pHttpTransactionEvent->GetCertRequestedResult();
2056 SysLog(NID_NET_HTTP, "The SslInfo is not existed.");
2058 // The certificateFlag is HTTP_CV_FLAG_AUTOMATIC.
2059 if (error != X509_V_OK)
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)
2066 int numberOfCerts = pServerCertChain->stack.num;
2067 for (int i = numberOfCerts; i > 0; i--)
2069 pSrcServerCert = sk_X509_pop(pSrcServerCertChain);
2070 pServerCert.reset(pSrcServerCert);
2071 if (pServerCert != null)
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);
2077 SysLog(NID_NET_HTTP, "The subject of certificate is %ls[depth: %d].", serverCertString.GetPointer(), i -1);
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());
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.");
2090 r = _HttpUtility::SetSslCertInfo(*pSSLInfo);
2091 SysTryReturn(NID_NET_HTTP, r == E_SUCCESS, 0, r, "[%s] Memory allocation failed.", GetErrorMessage(r));
2107 _HttpTransactionImpl::OnHttpTransactionTimerExpiredEvent(gpointer pUserData)
2110 _HttpTransactionImpl* pHttpTransactionImpl = static_cast< _HttpTransactionImpl* >(pUserData);
2112 if (pHttpTransactionImpl->__pTimerSource != null)
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);
2119 if (!pHttpTransactionImpl->IsClosed())
2121 //Fire the event(NET_HTTP_TRANSACTION_EVENT_ABORTED) - E_TIMEOUT
2122 pHttpTransactionImpl->__pHttpTransactionEvent->FireTransactionAbortedEvent(E_TIMEOUT, true);
2129 } } } // Tizen::Net::Http