투케이2K

489. (kotlin/코틀린) [유틸 파일] requestGetSslCertificateDownloadHttp : 웹뷰 로드 및 ssl 인증서 다운로드 수행 본문

Kotlin

489. (kotlin/코틀린) [유틸 파일] requestGetSslCertificateDownloadHttp : 웹뷰 로드 및 ssl 인증서 다운로드 수행

투케이2K 2024. 4. 23. 20:21

[개발 환경 설정]

개발 툴 : AndroidStudio

개발 언어 : Kotlin

 

[소스 코드]

 

        // -----------------------------------------------------------------------------------------
        // TODO [SEARCH FAST] : [GET] : [SslCertificate] : [HTTP] : requestGetSslCertificateDownloadHttp
        // -----------------------------------------------------------------------------------------
        // TODO [호출 방법 소스 코드]
        // -----------------------------------------------------------------------------------------
        // TODO [참고 및 로직 동작] :
        // TODO [1] : HTTPS 특정 주소 웹뷰를 사용해 로드 수행
        // TODO [2] : 정상 로드 완료 시 SslCertificate 인증서 다운로드 수행
        // TODO <uses-permission android:name="android.permission.INTERNET" />
        // -----------------------------------------------------------------------------------------
        /*
        try {

            // [URL 주소 선언]
            val url = "https://naver.com"

            // [헤더 생성]
            val header: MutableMap<String, Any> = HashMap()

            // [http 요청 수행]
            N_AsyncHttp.requestGetSslCertificateDownloadHttp(A_Intro@this, "SSL 인증서 다운로드 수행", url, header)
                .subscribeOn(AndroidSchedulers.mainThread()) // [Observable (생성자) 로직을 IO 스레드에서 실행 : 백그라운드]
                .observeOn(Schedulers.io()) // [Observer (관찰자) 로직을 메인 스레드에서 실행]
                .subscribe(
                    { value ->
                        S_Log.ltw("================================================")
                        S_Log.cnt("[" + ACTIVITY_NAME + " >> requestGetSslCertificateDownloadHttp :: onNext]")
                        S_Log.cnt("-----------------------------------------")
                        S_Log.cnt("[VALUE :: $value]")
                        S_Log.lbw("================================================")
                    },
                    { error ->
                        S_Log.lte("================================================")
                        S_Log.cnt("[" + ACTIVITY_NAME + " >> requestGetSslCertificateDownloadHttp :: onError]")
                        S_Log.cnt("-----------------------------------------")
                        S_Log.cnt("[ERROR :: " + error.message.toString() + "]")
                        S_Log.lbe("================================================")
                    }
                )
                {
                }

        }
        catch (e: Exception){
            S_Log._printStackTrace_(null, S_FinalMsg.LOG_BUG_STATE, null, e);
        }
        // */
        // -----------------------------------------------------------------------------------------
        fun requestGetSslCertificateDownloadHttp(mContext: Context, tag: String, url: String, header: Map<String, Any>): Observable<SslCertificate> {

            // [로직 처리 실시]
            return Observable.create { subscriber: ObservableEmitter<SslCertificate> ->
                try {

                    // ------------------------------------------------------
                    // TODO [URL 변수 선언 실시]
                    // ------------------------------------------------------
                    val urlData = url

                    if (C_Util.stringNotNull(urlData) === false) {
                        S_Log._F_(mContext!!, "requestGetSslCertificateDownloadHttp :: [Error] :: URL Data Is Null", null)

                        subscriber.onError(Throwable("[Error] :: URL Data Is Null"))
                        subscriber.onComplete()
                        return@create
                    }
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [HTTPS 포함 체크 실시]
                    // ------------------------------------------------------
                    if (urlData.startsWith("https") == false) {
                        S_Log._F_(mContext!!, "requestGetSslCertificateDownloadHttp :: [Error] :: Url StartsWith Https Need", null)

                        subscriber.onError(Throwable("[Error] :: Url StartsWith Https Need"))
                        subscriber.onComplete()
                        return@create
                    }
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [요청 로그 출력 실시]
                    // ------------------------------------------------------
                    S_Log._F_(mContext!!, "requestGetSslCertificateDownloadHttp :: SSL 인증서 다운로드 수행 실시", arrayOf(
                        "TAG :: $tag",
                        "URL :: $urlData",
                        "HEADER :: $header"
                    ))
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [웹뷰 생성 및 기본 값 지정 수행]
                    // ------------------------------------------------------

                    val mWebview = WebView(mContext)
                    mWebview.clearCache(true) // [디스크 및 쿠키 데이터 모두 지움]
                    mWebview.clearHistory() // [웹뷰 히스토리 지움]
                    mWebview.settings.cacheMode = WebSettings.LOAD_NO_CACHE // [웹뷰 로드 캐시 모드 지정]
                    mWebview.settings.javaScriptEnabled = true // [자바스크립트 허용]
                    mWebview.settings.javaScriptCanOpenWindowsAutomatically = true // [자바스크립트 윈도우 오픈 허용]
                    mWebview.settings.domStorageEnabled = true // [자바스크립트 웹 스토리지 허용]
                    mWebview.settings.mediaPlaybackRequiresUserGesture = false // [비디오 자동 재생 지원 설정]
                    mWebview.settings.defaultTextEncodingName = "UTF-8" // [인코딩 설정]

                    if (Build.VERSION.SDK_INT >= 21) {
                        mWebview.settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW // [HTTPS 이미지 표시]
                    }

                    // [스케일 확대, 축소 관련]
                    mWebview.setInitialScale(8)
                    mWebview.scrollTo(0, 0)
                    mWebview.settings.loadWithOverviewMode = true
                    mWebview.settings.useWideViewPort = true
                    mWebview.settings.builtInZoomControls = true
                    mWebview.settings.setSupportZoom(true)
                    mWebview.settings.displayZoomControls = false
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [웹뷰 클라이언트 지정]
                    // ------------------------------------------------------
                    val errorFlag = booleanArrayOf(false)

                    mWebview.webViewClient = object : WebViewClient() {

                        // [로딩이 시작될 때]
                        override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
                            super.onPageStarted(view, url, favicon)
                            S_Log._W_(S_FinalMsg.LOG_Loading_Start, arrayOf("URL :: $url"))
                        }
                        // [로딩이 완료됐을 때 한번 호출]
                        override fun onPageFinished(view: WebView, url: String) {
                            super.onPageFinished(view, url)
                            S_Log._W_(S_FinalMsg.LOG_Loading_End, arrayOf("URL :: $url"))

                            // TODO [웹뷰 인증서 반환 수행]
                            try {
                                if (errorFlag[0] == false) { // [정상 로드 된 경우 만]

                                    // [SSL 인증서 확인]
                                    val sslCertificate = view.certificate

                                    // [리턴 반환]
                                    if (sslCertificate != null){
                                        subscriber.onNext(sslCertificate)
                                        subscriber.onComplete()
                                        return
                                    }
                                    else {
                                        subscriber.onError(Throwable("[Error] :: [onPageFinished] :: sslCertificate Is Null"))
                                        subscriber.onComplete()
                                        return
                                    }

                                }
                            } catch (e: Exception) {
                                subscriber.onError(Throwable("[Exception] :: [onPageFinished] :: " + e.message.toString()))
                                subscriber.onComplete()
                                return
                            }
                        }
                        // [SSL 인증서 에러]
                        override fun onReceivedSslError(view: WebView, handler: SslErrorHandler, error: SslError) {
                            // [E/chromium: [ERROR:ssl_client_socket_impl.cc 에러 해결 위함]
                            S_Log._E_(S_FinalMsg.LOG_Error_State, arrayOf(
                                "TIME :: " + S_FinalMsg.LOG_NOW(),
                                "URL :: " + view.url.toString(),
                                "Error Sort :: " + "onReceivedSslError",
                                "Error Description :: " + "http 요청 SSL 인증서 에러"
                            ))

                            // [플래그 값 변경]
                            errorFlag[0] = true

                            // [리턴 반환]
                            subscriber.onError(Throwable("[Error] :: [onReceivedSslError] :: http 요청 SSL 인증서 에러"))
                            subscriber.onComplete()
                            return
                        }
                        // [오류가 났을 경우 응답 콜백 부분]
                        override fun onReceivedHttpError(view: WebView, request: WebResourceRequest, errorResponse: WebResourceResponse) {
                            S_Log._E_(S_FinalMsg.LOG_Error_State, arrayOf(
                                "TIME :: " + S_FinalMsg.LOG_NOW(),
                                "URL :: " + view.url.toString(),
                                "Error Sort :: " + "onReceivedHttpError",
                                "Error Description :: " + "Http 통신 에러",
                                "Error Code :: " + errorResponse.statusCode.toString(),
                                "Error Header :: " + errorResponse.responseHeaders.toString(),
                                "Error Response :: " + errorResponse.data.toString()
                            ))

                            // [플래그 값 변경]
                            errorFlag[0] = true

                            // [리턴 반환]
                            subscriber.onError(Throwable("[Error] :: [onReceivedHttpError] :: Http 통신 에러"))
                            subscriber.onComplete()
                            return
                        }
                    }
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [웹뷰 로그 수행]
                    // ------------------------------------------------------
                    mWebview.loadUrl(urlData)
                    // ------------------------------------------------------

                } catch (e: Exception) {

                    // ------------------------------------------------------
                    // [로그 출력]
                    // ------------------------------------------------------
                    S_Log._printStackTrace_(
                        mContext, S_FinalMsg.LOG_BUG_STATE, arrayOf(
                            "requestGetSslCertificateDownloadHttp :: SSL 인증서 다운로드 [EXCEPTION] 확인",
                            "TAG :: $tag",
                            "EXCEPTION :: " + e.message.toString()
                        ), e
                    )
                    // ------------------------------------------------------


                    // ------------------------------------------------------
                    // TODO [리턴 데이터 반환]
                    // ------------------------------------------------------
                    try {
                        subscriber.onError(Throwable("[EXCEPTION] : [requestGetSslCertificateDownloadHttp] : " + e.message.toString()))
                    } catch (ex: Exception) {
                        ex.printStackTrace()
                    }
                    // ------------------------------------------------------
                }
            }
        }

 

반응형
Comments