WebDAV 라는 기술은 나온지 어느정도의 시간이 흐르긴 했다.
처음에는 편의성은 우수했지만, 보안적인 문제점들이 많아 사용 기피가 된적도 많았다.

그런데, HTTPS 즉 SSL/TSL 기반의 암호화를 하고, 아이폰 등의 휴대폰이나 각종 원격 동영상/음악 플레이어들이 WebDAV 기반으로 제작되는 케이스들이 늘어나면서 생각보다 많은 사용자가 생겼다.
필자의 경우 많은 파일들이 있는데, 이 파일들을 원격에서 노트북으로 확인하고 정리할 수 있는 방법이 필요했고, 그에 제일 만만한 이 WebDAV 기술로 적용해보려 했다.


1. 기본적인 준비
제일 먼저 해야 하는 것은 서버를 결정해야 한다.
그리고 운영체제는 당연히 Windows 여야 하며, 최소 Pro 버전이상이 있어야 한다.
(Windows Server는 상관없고, Windows 7, 8, 10의 경우 Pro 버전 이상이 필요)
또한 상시 켜져 있고, 상시 연결될 수 있는 유선 네트워크도 필요하다.(무선랜도 되기야 하겠지만.. 한계가.)
그리고 공유기 같은게 있다면, 일단 포트 포워딩이라는 기술을 이용해 노출도 해야 한다.

2. IIS 구성
서버가 구성되었다면, IIS를 설치해야 한다.
"Turn Windows features on or off"를 실행한다.
그리고 항목 중에, Internet Information Service를 선택한다.

각 구성요소 중 필수적으로 아래와 같은 항목이 선택되어 있는지 체크하도록 한다.

  • WebDAV Publishing - 보통은 안켜져 있는데, 꼭 체크해서 넣는다.
  • Basic Authentication - 기본인증이라고 부르며, 이 기능이 있어야 아이디/패스워드를 입력할 수 있다.
    보통 휴대폰이나 3th-Party 제품의 경우 로그인 방식이 이 기본 인증방식이 많기 때문에 꼭 선택해야 한다.
  • IIS Management Consol - 보통은 선택되어 있는데, 이거 없으면 설정이 매우 어려우니 꼭 체크해놓는다.

그외의 것은 필요하면 설치해야 겠지만, 굳이 필요하지 않는다.
웹서버로 쓰는게 아니라, WebDAV 서버로만 쓸 것이기 때문에, 굳이 무겁게 설정할 필요는 없다.
(필자는 개인적으로 테스트해봐야 되는게 있어서... 이것 저것 선택하여 설치함)


3. SSL 구성
Windows 기능 중 원격에 있는 파일들을 연결해 볼 수 있는 기능이 있다.
윈도우 탐색기로 내 컴퓨터에서 오른쪽 버튼을 눌러 "Add a network location"(한글로 네트워크 위치 추가?)를 하면 원격에 위치한 파일을 마치 하드 디스크 붙이듯 연결할 수 있다.
WebDAV로 연결할 수도 있는데, 다만, Windows 7인지, Vista인지, 이 WebDAV로 연결할 때 반드시 SSL로 연결해야 한다는 단서가 붙는다.
그래서 SSL 구성이 필요하다.
개인적으로는 이게 제일 난해 했다.
일단 인증서를 만들어야 하는데, 유료로 제공하는 것은 비싸고, 그렇다고 IIS 안에 있는 Self-Sign 즉 자체 사설 인증서로는 Windows Explorer를 이용한 연결 자체가 안된다. ( 이 역시 편법은 있지만.. )

일단 인증서 확보가 제일 관건.
OpenSSL 이라는 프로그램을 이용해서 생성하는 다양한 방법들이 제시되는데, Linux 가 좀 필요하다
(Windows 나 Mac 버전도 있음). 다만, 이 부분은 필자도 잘 몰라서 해본적은 없다. - 구글사마의 도움이.......필자는 pfSense 라는 방화벽 겸, 라우터 겸 사용하는 솔루션을 통해서 인증서를 생성했다.
Root 인증서와 서버용 인증서, 그리고 해당 서버용 인증서의 키를 확보했다.
( root.crt, server.crt, server.key )

그런데 IIS 에서는 이 인증서를 가져올 때 pfx 형식의 인증서만 받는다. - 짐작컨데 개인키 부터 루트인증서 정보까지 담고 암호로 잠긴 형태로 알고 있다. 문제는 crt 파일과 key 파일로 pfx 파일로 만들려면 OpenSSL을 이용해 믹스를 해야 하는데, 이것도 수월치 않았다.
필자는 그냥 포기했고, 대신 사이트에서 제공하는 도구를 이용해 등록했다.

사이트는 https://www.sslshopper.com/ssl-converter.html 이고 이 위치에서 서버용 crt와 key 파일로 pfx 파일을 생성했다.


위와같이 해서 최종 pfx 파일을 만들면 끝이다.


3. IIS 내에 인증서 등록

inetmgr 이라는 프로그램을 실행한다.
왼쪽 트리에서 최상위 항목을 선택한 뒤, "Server Certificates"를 선택한다.

회면이 전환 되었으면 오른편에 있는 "Import"를 선택한다.


작은 팝업이 뜨는데, 앞서 제작한 pfx 파일을 선택하고, 만들 때 넣었던 암호를 넣고, Web Hosting으로 선택한 뒤 "OK" 버튼을 누르면 닫히면서 리스트가 하나 추가된다.


4. IIS 내 https 구성
자동으로 구성 된 Web Server를 쓸수 있고, 아니면 새로 만들어도 된다.
어쨌던 사이트 부분를 클릭해서 선택 한 후 Bindings... 를 클릭한다.

일반적으로 80 포트로 연결할 수 있는 사이트가 하나 있는데, 무시하고, Add.. 를 클릭해서 나오는 팝업에 정보들을 입력한다.

먼저 http 라고 된 부분을 https 로 선택한다.
포트는 자신이 원하는 포트로 선택한다.(공유기나 라우터에서 정의한 포트를 적으면 된다.)
Host name에는 원격으로 들어올 때 사용하는 URL을 사용한다.
SSL certificate 에서는 앞서 Import 한 인증서를 선택한다. (만약 없다면 3번 혹은 2번 부터 작업해야 할 수 있다. )
마지막으로 Require Server Name Indication이 체크되어 있으면 끈다.


5. Web Application 설정

다음은 사이트 동작용 웹어플리케이션 부분이다.
다시 Feature View 창에서 Basic Settings... 를 선택한다.

그냥 직관적으로 만들면 Application pool 이 아마도 Default AppPool로 되어 있을 것이다. 그냥 써도 무방하지만, 기왕이면 새로운 Application pool을 만들어 적당히 이름을 짓는다. 만들 때 로그인 계정은 자신의 PC의 관리자 권한을 갖고 있는 계정을 넣는다. 보통 자신이 PC에 로그인할 때 쓰는 계정을 넣는다.
(만약 암호가 없는 계정이면 계정부터 새로 만들거나, 암호를 생성해야 한다. )

WebDAV로 연결할 때, 일종의 광장 역할을 하는 경로를 Phisycal path에 넣는다. 그리고 반드시 Test Settings.. 를 눌러 잘 연결되는지 테스트 한다. 만일 새로 생성한 Application pool에 담긴 계정으로 처리가 안된다면, Connection As.. 에 들어가 계정을 입력해도 되기는 한다. 하지만, 가급적이면 Application Pool에 계정을 넣는게 좋다. (보안으로는 좀 취약 )

6. WebDAV Authoring Rule 설정
여기서 수행하는 내용은 WebDAV의 설정이다.
외부에서 WebDAV에 접속했을 때, 현재 구성된 내용 중 WebDAV에 접속가능한 권한들과, WebDAV 활성화 및 세부 설정들을 수행하게 된다.
서버 화면에서 WebDAV Authoring Rules를 클릭하면 된다.

그리고 나오는 화면에서 사용자를 먼저 설정한다.
오른쪽의 메뉴에서 Add Authoring Rule... 을 클릭하면 된다.
일종의 회원 관리하는 형식 정도로 이해하면 된다.
아무나 들랄달락 할 수 있게 할지, 특정 그룹에 해당하는 인원에게 할지, 그리고 각 대상자들의 읽기/쓰기 권한등을 설정한다.

그리고 오른쪽 메뉴에 Enable WebDAV를 선택한다
(만약 이미 Enable이 되어 있으면 Disable WebDAV라고 표시되므로, 이 경우는 그냥 놔두면 된다.)


마지막으로 WebDAV Settings가 있다.
다만, WebDAV의 특성을 잘 이해하고 있다면, 이 내용에 대한 설정을 수행하면 되지만,
잘 모른다면 기본값으로 두는 것을 권장한다.



6. 하위 폴더 구성하기.
웹서버 항목 위에서 오른 쪽 버튼을 눌러 "Add Virtual Directory"를 클릭한다.
Alias에는 WebDAV 상에서 표시할 이름을 적고
Physical path에는 로컬 디스크 내용은 "..." 버튼을 넣어 입력하고, NAS 등 외부 공유 폴더를 걸 때는
\\서버이름 등을 입력해서 연결한다.
파일이 제대로 연결되는지 Test Settings.. 를 눌러 확인하도록 한다.
만일 제대로 연결되지 않는다면, Connect as.. 를 눌러 들어가 권한이 충분한 아이디와 암호를 입력해서 저장한다.

필요한 폴더 만큼 생성한다.


7. 인증 설정.
원격에서 연결할 때, 아이디 패스워드를 물어볼지, 만약 물어본다면 어느 방식으로 물어볼지에 대한 내용이다. 이 설정은 웹서버 혹은 전체 서버 설정으로 구성할 수 있다.
범위에 따라 선택 한 뒤, Authentication을 더블 클릭해서 들어간다.

앞서 설치한 내역 만큼 내용이 보이게 되는데, 이 중 Basic Authentication을 제외한 나머지는 모두 Disable로 만든다. 만드는 방법은 해당 항목을 선택 한 뒤, 오른쪽에서 enable 혹은 disable을 선택하면 된다.

로컬에서만 접근하면 Windows Authentication이 좋기는 한데, 인터넷 상에서 연결한다면, 반드시 Basic Authentication으로 하는게 좋다. 특히 모바일(휴대폰 혹은 패드 등)으로 접근할 때는 Basic 밖에는 답이 없다.


8. 정리하며....

사실 WebDAV 설정을 하는 것에는 큰 무리가 없으나 이놈의 SSL 연결이나, 기타 UI 기반으로 만들어진 숨겨진 설정들을 찾아 조립하는게 문제가 있었다.
그리고 공유 폴더를 연결할 때 오류가 있었는데, 확인해보니 Windows Authentication이 켜진 경우 문제가 있었다. 끄니 깔끔하게 연결된다.

원격에서 마치 탐색기로 연든 나오는 화면은 굉장히 매력적으로 생각이든다.
파일관리에 대해서 애로사항이 매번 꽃을 피웠는데, 이 도구를 이용하면 더 쉬워질 것 같다.
그리고 동영상 플레이도 이젠 단순 세팅으로 해결을 볼 수 있을 것 같다.

728x90

Open Source기반의 EDM을 찾다가, 발견한 제품인 Alfresco. Java로 된 솔루션인데, 이미 상용화 서비스를 제공하고 있어서 인지, 제품의 완성도가 상당히 높았다.
그래서 이 Aflresco를 Windows에 설치 한 뒤, 다양하게 사용해 봤는데, 괜찮았다. 그래서 아예 서버를 분리해서 Alfresco 전용 서버를 구축하기로 마음먹고, 성능 향상을 위해 x64기반의 Ubuntu Server 위 에 설치했다.

그리고 현재 잘 사용하고 있다.

 

그런데, 예전에 설치해서 사용할 때는 Office 계열 문서의 경우 자체적으로 PDF로 변환을 해서, 이를 웹상에 바로 노출되었는데, 이게 제대로 동작하지 않고 있다. 즉, 진짜 바이너리 파일 처럼 문서가 계속 Word, Excel 등으로만 뜨고, Preview 화면이 제대로 표시되지 않는 문제가 계속 되었다. 처음에는 변환에 시간이 걸려서 그런가 했는데, 애석하게도 그렇지는 않은 듯 싶다.

 

구글링을 해보니 이런 글(http://www.simonbuckle.com/2007/06/06/converting-to-pdf-with-alfresco/) 이 걸렸다.

" lsof -i | grep 8100 " 라고 입력하면 Office 파일 변환 서비스가 떠 있어야 된다는 의미인데, 애석하게도 실행해본 결과 아무것도 나타나지 않았다. 결국 이 Office 파일 변환 서비스가 제대로 떠있지 않다라는 결론이 나고, 좌절을 맛볼 수 밖에 없었다.

 

마음을 다 잡고 다시 차근 차근 구글링을 시도했고, 이 문제를 해결 하기 위한 답을 찾았다.
이 문제를 해결 하기 위해 아래의 링크들을 참고했다.
https://forums.alfresco.com/forum/end-user-discussions/alfresco-share/cannot-preview-ms-office-files-03122012-1400

https://forums.alfresco.com/forum/installation-upgrades-configuration-integration/configuration/document-preview-broken-42b#p139371

 

문제 현상.

문제가 된 현상은 다음과 같다.


보면 모든 문서들이 단순 아이콘으로만 뜨고 있다. 더욱이 해당 문서 안으로 들어가면, 내용을 보여주는 Preview 화면 조차 없다.

 

그러다가, Tomcat 내부에 있는 catalina.out 이라는 로그 파일을 관찰했고, 문서를 읽을 때마다, 다음과 같은 오류를 뱉는 것을 확인했다.

ERROR [extensions.webscripts.AbstractRuntime] [http-8080-39] Exception from executeScript 
- redirecting to status template error: 02120007
The content node was not specified so the content cannot be streamed to the client:
classpath*:alfresco/templates/webscripts/org/alfresco/repository/thumbnail/thumbnail.get.js org.springframework.extensions.webscripts.WebScriptException: 02120007
The content node was not specified so the content cannot be streamed to the client:
classpath*:alfresco/templates/webscripts/org/alfresco/repository/thumbnail/thumbnail.get.js at org.alfresco.repo.web.scripts.content.StreamContent.execute(StreamContent.java:183) at org.alfresco.repo.web.scripts.RepositoryContainer$2.execute(RepositoryContainer.java:400)

그래서

Exception from executeScript - redirecting to status template error

로 검색을 했고, 위의 문제 해결 링크를 찾았다.

 

 

문제 분석

최초로 찾은 글에서는 몇몇 답변들이 있었지만, 별 의미는 없었다. 하지만, 맨 끝자락에 있는 "TTownsend"라는 분이 글을 남겼고, 그 분이 문제 해결에 대한 Thread를 남겼는데, 그게 결정적이였다. ( Thanks TTownsend! )

 

같은 문제인지 확인해 보려면, /alfresco/libreoffice/scripts Directory로 이동 한뒤, openoffice_ctl.sh 를 실행해 본다. 그러면 콘솔 창에 "openoffice did not start" 라는 메시지가 뜨면 바로 이 해결 방법으로 처리할 수 있는 문제이다.

 

그러면 이제 openoffice_ctl.sh 가 어떻게 실행되는지 확인한다.

 

먼저 openoffice_ctl.sh 파일을 열고 그 안에서 SOFFICE로 시작되는 모든 변수 값을 가져온다.


소스의 맨 윗부분인데, 이 내용을 메모장 같은 곳에 복사해서 각 변수들 값을 조합하여 직접 실행 시킬 수 있는 명령 줄을 만든다.

#!/bin/sh

# Open Office
SOFFICE_PATH="/alfresco/libreoffice/program"
SOFFICE_PORT="8100"
SOFFICEBIN=/alfresco/libreoffice/program/soffice.bin
SOFFICE="$SOFFICEBIN --nofirststartwizard --nologo --headless --accept=socket,host=localhost,port=$SOFFICE_PORT;urp;StarOffice.ServiceManager"
SOFFICE_STATUS=""
이 내용을
/alfresco/libreoffice/program/soffice.bin --nofirststartwizard --nologo --headless --accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager
로 만든다.

 

명령줄이 준비되었으면 실행해본다.

root@testserver:/alfresco/libreoffice/scripts# /alfresco/libreoffice/program/soffice.bin --nofirststartwizard --nologo --headless --accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager
/alfresco/libreoffice/program/soffice.bin: error while loading shared libraries: libXrender.so.1: cannot open shared object file: No such file or directory
No command 'urp' found, did you mean:
 Command 'unp' from package 'unp' (universe)
 Command 'burp' from package 'burp' (universe)
 Command 'arp' from package 'net-tools' (main)
 Command 'rup' from package 'rstat-client' (universe)
urp: command not found
StarOffice.ServiceManager: command not found
root@docsvr:/alfresco/libreoffice/scripts# apt-file search libXrender.so.1
libxrender1: /usr/lib/x86_64-linux-gnu/libXrender.so.1
libxrender1: /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
libxrender1-dbg: /usr/lib/debug/usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0

결론을 내자면, 이 문제의 모든 원인은 바로 Open Office 를 실행하기 위한 필수 라이브러리가 제대로 설치되어 있지 않아 발생되는 문제였다. Open Office 자체가 X11과 같은 X-Windows용 프로그램이다 보니, Linux Server와 최소 설치형태로 제공되는 시스템은 당연하게 X-Windows 라이브러리가 없었고, 그 결과 Open Office 프로그램을 실행할 수 없는 문제가 발생하는 것이다.

 

서버 내에 X-Windows 라이브러리가 없어서 발생되는 문제였으므로, 이 문제를 해결 하려면, 역시 X-Windows를 설치하면 해결 된다. 하지만, 고작 이 Open Office 서비스를 실행하기 위해서 X-Windows를 설치하는 것은 배보다 배꼽이 큰 결과로 봐도 무방한다. GUI 없이 시스템 자원을 확실하게 사용하려고 서버를 깔았는데 말이다.

 

그러므로, 거대한 X-Windows 구성요소 중, Open Office가 실행될 수 있는 최소 필수 라이브러리만 설치하도록 한다.

 

이를 하기 위해서는 준비 작업을 먼저 해야 한다.

 

 

준비 작업

특별히 준비할 것은 없지만, 현재의 문제를 정확히 파악하려면, 패키지 관리 도구를 업데이트 해야 한다.

문제 분석은 현재 설치되어 있는 라이브러리들을 파악해야 한다. 그 라이브러리는 어떤 패키지에 속해 있는지를 알아야 하는데, 그 작업을 하기 위해서는 apt-file 이라는 패키지가 필요하다. (이미 구성되어 있을 수도 있다.)

apt-get install apt-file

apt-file update
먼저 apt-file 패키지를 설치한다. 그리고 apt-file을 업데이트하도록 한다.

그러면 문제의 파일이 어느 라이브러리에 속하는지 알 수 있게 된다.

 

 

해결 방법

앞서 실행해 봤던 명령 줄을 실행한다.

그러면 아래처럼 결과가 나오는데, 그 중 굵게 표시한 부분을 주목하자. libXrender.so.1 이라는 라이브러리를 읽어오는데 문제가 발생했다는 것이다.
/alfresco/libreoffice/program/soffice.bin: error while loading shared libraries: libXrender.so.1: cannot open shared object file: No such file or directory
No command 'urp' found, did you mean:
No command 'urp' found, did you mean:
 Command 'unp' from package 'unp' (universe)
 Command 'burp' from package 'burp' (universe)
 Command 'arp' from package 'net-tools' (main)
 Command 'rup' from package 'rstat-client' (universe)
urp: command not found
StarOffice.ServiceManager: command not found
root@docsvr:/alfresco/libreoffice/scripts# apt-file search libXrender.so.1
libxrender1: /usr/lib/x86_64-linux-gnu/libXrender.so.1
libxrender1: /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
libxrender1-dbg: /usr/lib/debug/usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0

문제의 라이브러리가 속한 패키지를 파악한다.

apt-file search libXrender.so.1

라고 입력한다. 그러면 다음과 같은 결과를 돌려준다.

libxrender1: /usr/lib/x86_64-linux-gnu/libXrender.so.1 
ibxrender1: /usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
libxrender1-dbg: /usr/lib/debug/usr/lib/x86_64-linux-gnu/libXrender.so.1.3.0
결과를 보면 libxrender1 이라는 패키지에 구성된 파일임을 알 수 있다.

 

이 패키지를 다시 설치한다.

 apt-get install libxrender1
그러면 패키지와 연계되어 아직 설치되지 않았던 패키지들이 실행된다.
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다
상태 정보를 읽는 중입니다... 완료
다음 새 패키지를 설치할 것입니다:
  libxrender1
0개 업그레이드, 1개 새로 설치, 0개 제거 및 22개 업그레이드 안 함.
20.9 k바이트 아카이브를 받아야 합니다.
이 작업 후 88.1 k바이트의 디스크 공간을 더 사용하게 됩니다.
받기:1 http://kr.archive.ubuntu.com/ubuntu/ raring-updates/main libxrender1 amd64 1:0.9.7-1ubuntu0.13.04.1 [20.9 kB]
내려받기 20.9 k바이트, 소요시간 1초 (13.5 k바이트/초)
Selecting previously unselected package libxrender1:amd64.
(데이터베이스 읽는중 ...현재 83473개의 파일과 디렉터리가 설치되어 있습니다.)
libxrender1:amd64 패키지를 푸는 중입니다 (.../libxrender1_1%3a0.9.7-1ubuntu0.13.04.1_amd64.deb에서) ...
libxrender1:amd64 (1:0.9.7-1ubuntu0.13.04.1) 설정하는 중입니다 ...
libc-bin에 대한 트리거를 처리하는 중입니다 ...
ldconfig deferred processing now taking place

이 작업을 앞에서 Open Office를 실행하기 위한 명령 줄 "/alfresco/libreoffice/program/soffice.bin --nofirststartwizard --nologo --headless --accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager"를 실행하면서 오류가 발생하지 않을 때 까지, apt-file search 하고, apt-get install 을 해서 찾는다.

 

그러면 어느 순간부터는 실행 했을 때, 더 이상 입력되지 않고, 무언가가 계속 실행된 상태가 유지되는 것을 볼 수 있다. 필자의 경우 아래와 같이 되고, 실행된 상태로 계속 유지 되었다.

root@testserver:/alfresco/libreoffice/scripts/alfresco/libreoffice/program/soffice.bin --nofirststartwizard --nologo --headless --accept=socket,host=localhost,port=8100;urp;StarOffice.ServiceManager
Fontconfig warning: "/alfresco/libreoffice/share/fonts/truetype/fc_local.conf", line 13: Having multiple  in  isn't supported and may not work as expected

이제 Ctrl + C로 빠져 나오고, ./openoffice_ctl.sh start 명령을 입력한다.

그러면, "./openoffice_ctl.sh : openoffice started at port 8100" 라는 메시지가 나오고 종료된다.

 

그러면 성공!

 

이제 alfresco 서버를 다시 시작하면 정상적으로 동작하는 것을 볼 수 있다.

 



 

결론

X-Windows 라이브러리와 같은 기초 동작 라이브러리만 잘 구성해서 추가해주면 아주 부드럽게 잘 동작한다. 문서 Preview도 잘 되고, 화면도 팍팍 표시된다. 문제는 단순했지만, 역시 잘 모르면, 해결하기 그렇게 쉽지는 않다. 하지만, 전세계를 대상으로 검색해보면, 나와 같은 고민에 빠진 사람들을 쉽게 찾아볼 수 있고, 또, 그 문제를 접근하고, 해결하는 방법들이 잘 나와 있어 얼마나 다행인지 모르겠다. (아직도 NavXX 마수에 빠지신 분은 이 해결 방법 그렇게 쉽게 찾지는 못 할 듯! ㅋ )

 

어쨌던, 이 솔루션 생각보다 훌륭하다. 상당히 안정적이며 빠르다.

물론 설정이나, 구성 방법은 그렇게 쉽지만은 않지만, 그래도 성능 하나 만으로 이 모든 문제를 상쇄할 만큼 훌륭한 제품인 것 같다. 개인적인 문서 / 사진 라이브러리 구축을 위해 사용하고 있지만, 작은 규모의 팀이나, 회사에서도 충분히 활용 할만 하다. ( 아 아직 한글은 지원하지 않는다. 현재 필자가 개인적으로 번역 작업을 해보고 있다. ㅋ )

 

( Alfresco 한글화 구성 사이트 : http://crowdin.net/project/alfresco/ko )

728x90

요즘 SharePoint 관련된 업무를 하지 않다보니, SharePoint가 벌써 2013이 나왔다는 사실은 몇 일 전에 알았습니다. Windows Server 2012가 나와서 이번에 개인적으로 사용하는 Windows Server 를 업그레이드 해봤다가, 문서 저장용 서버로 SharePoint로 이용하기 위해 SharePoint 2013을 설치했습니다.처음에는 익숙했던 SharePoint 2010 을 설치하려고 했는데, 호환성 이슈가 있어서, 결국 쓰지 못하고, 대신 SharePoint 2013을 사용하게 되었습니다.

기왕 설치하는 것이라는 마음에 RBS(Remote BLOB Storage : SQL의 FILESTREAM 기법을 활용한 원격 BLOB 저장 기법)까지 적용해봤습니다.

이런 저런 우여곡절은 있었지만, 간신히 설치해봤고, 띄워봤는데, 약간 느린점만 빼면, UI는 정말 깔끔하고, 자바스크립트도 훌륭하게 정리된 것 같습니다.

2

일단 파일 업로드가 간편해졌습니다. "또는 여기로 파일 끌어 놓기" 라는 위에 아무 파일이나 Drag & Drop을 하는 순간 업로드가 됩니다. 매번 파일 업로드를 하기 위해 Submit Form을 띄워서 처리할 필요가 없어졌습니다.

5

3

그리고 SharePoint 2010에서 제공한 리본 메뉴도 정리가 되어 이젠 완전히 Office 처럼 되었습니다. 얼핏 보았을 때는 뭔가 있어보이고, 깔끔하게 가려져서 괜찮은듯 싶지만, 이 부분은 호불호가 갈릴듯 싶습니다.

6

웹 파트도 간단하게 넣고 편집할 수 있습니다. 드디어 Contents Management의 끝을 Javascript로 완성한 듯 싶습니다. 일정한 틀 내에 문자열을 추가/삭제/편집 해서 원하는 디자인을 뽑아내고, 등록된 웹파트들을 넣고 빼기가 더욱 쉬워졌습니다. 물론 윈도우 내에 설치용 프로그램만큼의 성능을 제공하지는 않지만, 간단한 편집이나, 관리에서는 빼어난 능력을 제공합니다.

진짜 웹파트만 잘 구성해서 제공해도 SharePoint에서 사용하는 것에 불편함이나 문제가 없어보입니다.

7

 

아직은 개인 문서 관리 차원에서 사용하기 위해 설치를 한 상태라 파일 업로드 정도로만 올려봤습니다.
아직까지는 무슨 기능이 어떻게 동작하는지는 모르겠지만, 차근 차근 하나씩 밟아 보려고 합니다.

예전 SharePoint Foundation 2010과 같이 Windows Server에 무료로 제공하는 버전도 있을텐데, 아직 설치해보지는 않았습니다. 만일 단순한 기능의 팀사이트 정도라면 그 정도 레벨로 다른 곳에 설치를 한 뒤 리포팅을 해볼 예정입니다.

728x90

Google 에서 제공되는 서비스들은 거의 대부분 API를 제공하고 있다.
ATOM - 우리가 보통 말하는 SOAP과 같은 형태로 규격화된 XML로 구성된 형태와 JavaScript에서 쓰기 편한 JSON 형태들, 결과값도 다양한 형태로 제공한다.
(우리나라 포털은 이런 것과는 전혀 반대로 가고 있다. 뭐 다음이나, 네이버에는 개발자 들이 많으니, 외부 개발자들이 끼어들 필요가 없어서 그런듯... 애플 앱스토어 같은 성공 모델도, 이들에게는 큰 감흥이 없는 것 같다.)

이 중 Google Calendar 값을 가져와서 편집하려는 .NET 기반 툴을 만들려고 생각 중이였다.

 http://code.google.com/apis/calendar/data/2.0/developers_guide_protocol.html

난 맨처음 ATOM 기반의 데이터를 보았기 때문에, XMLDocument Reader로 읽어서 원하는 값들을 뽑으려고 했다.
하지만, 내용이 너무 방대하고 많아서 이 내용들을 정리할 생각에 뒷목이 뻣뻣함이 느껴졌는데,
알고보니까, 언어별로 이미 패키지화 해버렸다.
패키지는 다음 URL에서 받으면 된다.

http://code.google.com/p/google-gdata/downloads/list

MSI 파일로 설치를 하면 기본 경로로 C:\Program Files\Google\Google Data API SDK 위치에 설치된다.
Calendar 뿐만 아니라, Google 에서 제공하는 각종 기능들을 다룰 때 사용하는 대부분의 기능들을 담은 패키지를 제공한다.

그 중 완벽 정리된, .NET 코드로 작성하는 방법은 아래의 URL에서 참고하면 된다.

http://code.google.com/apis/calendar/data/2.0/developers_guide_dotnet.html

거의 완벽 정리. ( 문제는 언어 장벽! ㅠ.ㅠ )

각종 Open API 기반 서비스는 Google 기반으로 동작하게 할 수 밖에 없을 것 같다.
다음도, 네이버도 결국 이런 서비스를 제공하는 것은 요원한 일이 될테니..

구글 서비스나 잘 구성해서 써야 겠다.

 

Google Calendar 내용을 모두 열어 보는 코드를 간단하게 짜보면 아래와 같다.


Google.GData.Client.GDataCredentials m_credential 
= new Google.GData.Client.GDataCredentials("구글아이디", "구글암호");

Google.GData.Calendar.CalendarService svc = new Google.GData.Calendar.CalendarService("지금 만들고 있는 프로그램의 이름");
svc.Credentials = m_credential;

Google.GData.Calendar.EventQuery query
= new Google.GData.Calendar.EventQuery(http://www.google.com/calendar/feeds/default/private/full);

query.StartDate = DateTime.MinValue;
query.EndDate = DateTime.MaxValue;
Google.GData.Calendar.EventFeed feed = svc.Query(query);

foreach (Google.GData.Calendar.EventEntry entry in feed.Entries)
{
     if (entry.Times.Count > 0)
     {
            entry.Times[0].AllDay;  // 종일 이벤트인지?
            entry.Times[0].StartTime;  // 시작일
            entry.Times[0].EndTime;   // 종료일
      }
      entry.Title.Text; // 이벤트 제목
}

저 코드면 맨 마지막에 나오는 값들로 표시를 하거나 정리를 할 수 있게 된다.

그런데 특이한 점은 일정에서 날짜와 시간이 반드시 들어갈 줄 알았는데, 알고 보니까,
외부에서 파일을 import 해서 넣은 일정들은 저 entry.Times 값이 없는 경우가 있다.
그래서 entry.Times 에서 갯수를 파악한 뒤 내용을 꺼냈다.  - 주의가 필요 -

728x90

댓글을 이용해서 pjyoung 님께서 질문을 남겨주셨는데요.( http://www.hind.pe.kr/805#comment6147213 )
내용을 읽어보다가, 잠시 대기라는 느낌이 들어 글을 남김니다.

지금 OBJECT 태그를 이용하시는 것까지는 맞는데요. CODEBASE 부분의 Tag 부분이 잘못된 것 같습니다.
CODEBASE라는 부분의 의미는 Object 태그가 들어간 페이지를 브라우저를 통해 띄울 때,
해당 ActiveX가 없을 때 어디서 받아가지고 오는 것인지 알려주는 부분입니다.

은행권 사이트를 예를 들어볼께요.(ActiveX 범벅이라 참 좋은 예제 같습니다 -_-;;; )
먼저 한번도 들어가본적이 없는 은행권 사이트에 접속을 합니다.
그 은행권에서 사용하는 보안용 ActiveX의 GUID가 33e6b301-a928-438d-b3b1-733bfc68ccdb 라고 하죠.
그 은행권 사이트에 접속하는 IE에서는 자신의 컴퓨터 안에 저 위의 GUID에 해당하는 ActiveX가 있는지 검색합니다.
당연히 있으면 띄우고 없으면 CODEBASE에 설정된 정보를 따라 들어가 다운로드 받고 설치합니다.
그 때 IE에서 보면 주소바 아래쪽에 노란색 바 같은게 뜨잖아요?
바로 그 행동을 한다고 사용자에게 알려주는 부분입니다.
그러나 여기서 잠시… 이 CODEBASE에 담기려면, 인증서가 배포 파일 안에 있어야 됩니다.
공인인증서 같은 것인데, 프로그램 배포용 공인인증서 입니다.
그거 안들어가면 IE에서 설치 못합니다.
(바이러스 따위로 인지해버린다는 거죠.)

아래의 링크를 보시면 알겠지만, 그 CODEBASE에 관련된 내용이 자세히 나와있습니다.

.http://digitalangelmaster.wordpress.com/2008/02/15/기존-activex-control-업그레이드/

 

그런데 위의 내용은 어떻게 보면 실험용이라기보다는 실전용의 의미에 가깝습니다.

만일 그냥 웹페이지에 띄우는 실험이나 자체적인 연습이라고 한다면 다르게 접근하시면 됩니다.
먼저 CODEBASE 부분을 삭제하시구요.
다음은 그 ActiveX를 띄우는 PC에 ActiveX를 강제적으로 설치하는 것입니다.

C:\Windows\Microsoft.NET\Framework\v2.0.50727\regasm /codebase “xxxxxxxx/form.dll”

저 위의 명령이 바로 그 ActiveX를 강제적으로 설치하는 것입니다.
아예 미리 PC 안에 설치되어 있으면 IE 에서는 군말 없이 띄웁니다. 즉 위의 명령을 써서, 직접 PC에 인스톨을 하는 것입니다. 그러면 특별한 코드상의 문제만 없다면 화면에 뜰 것입니다.

한번 확인해보세요.
(제가 해보고 싶었지만, 지금 밀린일이 좀 많아서 테스트는 안해봤어요 -_- ;;;)

728x90

MOSS 2007 기반으로 개발을 하거나, 기타 웹 어플리케이션을 만들면 꼭 들어가는 코드가 바로 JavaScript 이다.특히나 동적 웹을 구현을 하려면 특히 자주 활용하게 된다.
하지만, 그 Javascript의 동작이 올바른지 올바르지 않은지에 대한 판단을 하는 모습을 보면, 상당히 원시적으로 하는 경우를 많이 보게 된다. 일단 동작하는 화면을 보고, 그 결과물을 보고 현재 구성된 Javascript를 보고, 일부 수정하거나 MessageBox를 띄우고 결과물 보고..
이렇게 Javascript를 수정하는 경우 경험이 많은 개발자야 짐작과 동시에 문제점을 찾기라도 하지만, 웹 개발에 익숙치 않거나, 아예 문법 오류로 인해 Javascript 자체가 실행 안된 경우라면, 거의 좌절이다. 게다가, 웹 페이지 내에 직접 박아 넣은 Javascript라면 그럭저럭 짐작이라도 하는데, 다른 Javascript 소스를 include 한 경우라면, 이야기가 점점 꼬이기 시작한다. 뭐가 문제인지 짐작도 되지 않는다.
다행이, FireFox나 Google Chrome과 같은 웹브라우저에서는 자체적으로 혹은 외부 플러그인을 통해 디버깅이 가능하며 그 기능은 상상을 초월한다. 훌륭하다 못해 멋지기 까지 할 정도로 정확하게 값을 뽑아오며, 정확히 어느 파일의 어느 위치에 오류가 있는지 알려주며,  현재 상태 값을 보면서 정확한 오류 내용을 파악할 수 있다.

그러나, 우리나라 환경에서 개발하는, 그것도 새로 개발도 아니고, 기존 코드를 수정하는 입장인 경우, Javascript를 까보면, FireFox나, Chrome에서는 동작하지도 않는 경우가 허다하다. 특히나 ActiveX 같은 X 같은 플러그인 꽂은 곳은 아예 Gothem! 레벨. 결국 IE로 띄워 뭔가 디버깅을 시도해야 된다는 슬픈 일이 닥친다.

하지만, MS 기반, IE 온리 개발하는 곳에서는 일반적으로 Visual Studio를 이용한 .NET 개발이 주로 발생되는데, 이 경우 라면 해피하다. 여기서는 이 해피한 경우에 대처하는 좋은 방법을 알려드리려 한다.

1. IE 설정.

IE가 6.0으로 쫑 날 줄 알았으나, FireFox와 Chrome, 사파리 등의 웹 브라우저의 등장으로 위기감의 고조와 함께, 그 동안 계속되었던 6.0의 버그, 속도 문제등의 이유로 결국 7.0을 내 놓았다. 그러나, 7.0을 탑재한 Vista의 처절한 실패로 인해 Windos 7과 함께, 등장한 8.0 으로 업그레이드 되었다.

즉, 이제 IE는 6.0, 7.0, 8.0 이 혼재된 모습을 보이기 시작했다.

일단, 8.0을 기준으로 설명하며, 7,0이나, 6.0은 다른 곳을 찾아보거나, 짐작해서 옵션을 변경해야 할 것 같다.
IE를 실행 한 뒤, 인터넷 옵션을 띄우고, 인터넷 옵션에서 “고급”탭을 클릭해서 연다.

여러가지의 항목들 중 “스크립트 디버깅 사용 안함(기타)”, “스크립트 디버깅 사용 안함(Internet Explorer)”에 체크 되어 있는 것을 끄도록 한다.

2. 에러 페이지까지 가기.

Visual Studio가 깔린 PC에서 IE를 통해 먼저 에러가 발생하는 페이지까지 접근하도록 한다. 지금 필자에게는 마땅히 띄울 UI가 담긴 Page가 없으므로 에러가 발생하는 페이지를 띄우도록 할 것이다.

에러가 발생했다. 그러면 에러 페이지가 뜨는데, 여기서 체크 박스들을 없애고 “예(Y)”를 클릭한다.

위의 팝업이 안뜨면 브라우저의 왼쪽 아래에 있는 경고 표시를 클릭하면 볼 수 있다.

일단 “예(Y)”를 하면, IE에 등록된 Javascript 디버거들의 목록이 뜬다.

현재 필자는 변변한 디버거라고는 Visual Studio 정도지만, Office 2003~2007 을 전체설치하는 경우 Javascript 디버거가 별도로 설치될 수 있다. 또는 3rd Party 제품이 뜰 수도 있다. 다른 제품들은 각 제품의 설명을 보도록 하고, 여기서는 Visual Studio로 선택하도록 한다.

혹여 Visual Studio일지라도 이미 떠 있는 Visual Studio를 선택할 수 있는데, 가급적이면, 새 인스턴스 Visual Studio를 선택하도록 한다.

3. Visual Studio 에서 디버깅.

“새 인스턴스 Visual Studio XXXX”를 선택하고 “Y”를 클릭하면 Visual Studio가 뜬다. 이 때 디버깅을 하는 것은 iexplore.exe 자체. 무슨 프로세스를 걸던 간에 일단 띄워보면, 정확한 오류 메시지를 알려준다.

 
오류 보시고, 이번엔 “중단(B)” 버튼을 클릭한다.
그러면 소스가 보일 것이고, 어디서 오류가 났는지 볼 수 있다.

왼편에는 지금 오류가 난 페이지와 관련된 각종 Javascript 소스들과 Html 소스들이 쭉 나래비가 펼쳐질 것이고,
오른편에는 해당되는 소스가 보인다. 여기서 부터는 Visual Studio 만의 디버그 UI를 활용함으로써 충분한 기능을 발휘할 수 있다.

소스 자체에서 커서를 위로 올리면 인텔리센스의 또다른 기능인, 변수 값들을 볼 수 있으며, 조사식, 콜스택, 지역 변수 값들을 모두 보면서 진행할 수 있다. 한단계씩 실행할 수도 있다.

4. 고급 디버깅 - 중단점

꼭 오류가 나기 이전 단계에서 디버그를 시작하고 싶은 경우에는 중단점을 이용하면 된다.
자신이 원하는 곳에다 중단점을 걸고 진행하면 되는데, 이를 위해서는 항상 동일한 위치에서 오류가 발생해야 쉽게 적용 가능하다. 방법은 아래와 같다.

1. 자신이 원하는 위치에 중단점을 건다.(Visual Studio 버전에 따라 중단점을 걸게 되는 조건이 조금씩 다르다.)
  
2. 디버그를 끝까지 진행시킨다.(디버그에서 계속 버튼 – 디버깅이 멈춰진 곳에서 계속 진행하도록 하는 버튼)을 누르거나 선택하면 된다.)
   
3. 경고창으로 뜨는 메시지에 예외를 iexplore로 보내겠다는 메시지에 예(Y)를 선택한다.
  
4. 브라우저로 돌아와서, 다시 Refresh를 한다.

5. 그러면 자신이 중단점을 건 위치에 커서가 멈춰 있게 된다.
  

 

5. 줄이며.

사실 Visual Studio의 기능은 막강한 편이다. 최초 5.0, 6.0 같은 경우 Windows 기반 Application 제작에 비중이 실렸다면, Visual Studio 2003 부터 조금씩 조금씩 웹 쪽에 대한 기능이 실리기 시작했다. 특히 Visual Studio 2005 부터는 ASP 개발에 있어 그 편리성은 혁신에 가깝게 진행되었다.

최소한 위의 디버그 모드에 대한 기능은 2003보다는 2005가, 2005 보다는 2008에서 더 정확하게 확실하게 동작함을 알 수 있다. 다소 툴이 무거워 쉽게 접근하는건 무리겠지만, 웹 표준에 제대로 맞지도 않는 웹 개발을 특히나 유지보수를 하려고 한다면, IE를 쓰고, Visual Studio를 쓰는 강수를 노려야 되니… 뭐 억지로라도 쓰도록 한다.
일단 쓸 수 있는 환경(CPU나 RAM이나.. 개발자 PC의 성능 문제가 대부분)이라면, 나름 장점이 많은 도구이니, 활용하는데 큰 무리가 없으리라 본다.


UPDATE:

저 위의 방법은 Javascript가 오류가 난다는 가정하에서 하나씩 거는 방법이다. 만일 Javascript의 오류가 나지 않을때, 디버그를 걸어 확인하고 싶을 때까 있다.

그런 경우에는 소스 내에 "debugger;" 라는 줄을 추가하면 된다.

그러면 debugger 라고 적힌 줄에서 에러가 난 것 처럼 표시되고, 위의 방법대로 진행이 가능하다.

728x90

블로그 내 필자를 관리하는 방법을 설명합니다.

 

일단 scmaid.org의 관리자 페이지에 들어갑니다.

들어가는 방법은 아래 메뉴에 표시된 위치를 클릭하면 들어가집니다.

 

 

다음은, 관리자 화면으로 넘어갈때, ID/Password를 묻는데, (안 묻는다면 일단 Logout을 하시고 다시 들어기시기 바랍니다.) 그 안에 관리자 아이디와 암호를 넣습니다.
(아이디와 암호 부분은 이정호 선임을 통해 전달 받거나 하시면 됩니다.)

 

 

이제 관리자 화면을 볼 수 있는데, 그 중, 네트워크 –> 필진 목록을 클릭해주세요.

(만일 IE 8.0에서 메뉴가 제대로 보이지 않으면 주소 줄 옆의 호환성 보기 아이콘( )을 클릭하세요!)

 

 

필진 목록을 클릭하면 필진 목록이 보이는데, 여기에 모든 기능이 담겨 있습니다.

직접 페이지를 띄워서 테스트를 하셔도 되고, 화면을 보시면서 익혀도 됩니다.

 

 

1. 필진 초대하기.

팀 블로그이기 때문에, 필자가 1인이지 않습니다. 여러 사람이 동시에 글을 올릴 수 있습니다. 그러나 공개 게시판과 같은 형식이 아니기 때문에, 특정 인에 대해서만 필진으로 등록하게 됩니다. 여기서 중요한 것은 필진의 이메일 주소가 반드시 필요합니다. 또한 이메일 주소 자체가 ID이기 때문에, 반드시 올바른 이메일 주소여야만 합니다.

먼저 관리자는 초대장 부분에 있는 “받는 사람” 필드에 E-Mail 주소를 넣습니다.

그 외의 부분은 필요한 만큼만 채우시면 됩니다. 그리고 초대장을 발송하세요.

 

그러면 받는 사람에게 다음과 같은 메일이 옵니다.  메일 안에 “블로그 바로가기”라는 링크를 클릭하시면 됩니다.

클릭하면 아래와 같은 화면이 뜹니다.(자동으로 생성된 암호로 로그인됩니다.)

 

필명에다가 자신의 별명이나 이름을 씁니다. 저 이름으로 글 쓸 때마다 박히니, 가명을 쓰셔도

되고, 진명을 쓰셔도 되고, 별명을 쓰셔도 무방합니다.  그리고 그 아래의 “저장하기” 버튼 클릭하시구요.

 

다음은 비밀번호 있는 부분에 있는 부분에서 “새로운 비밀번호” “비밀번호 확인” 부분에 자신만의 암호를 넣어주세요.

만일 이 부분을 안채우시면 암호를 알 길이 없습니다.(자동으로 만들어진 비밀 번호이여서, 관리자도 알 수 없습니다.)

입력 후 “저장하기” 버튼을 클릭하세요.

 

나머지는 그대로 두세요!

 

 

이렇게 필진을 등록하시면 됩니다.

 

2. 필진 관리하기.

필진 관리는 관리자 권한에서만 가능합니다.

관리로는 필진의 권한 설정과 필진 삭제 정도의 기능이 있습니다.

그 모든 처리는 표 안에서 다 됩니다.

필진 관리를 하기 위해서는 관리자 페이지에서 네트워크 –> 필진 관리로 일단 들어갑니다.

 

 

권한 부분의 설정은 관리자, 글관리가 있는데,

이중 최소한 글 관리에 체크를 해주시기 바랍니다.

체크하는 순간 알아서 저장 적용됩니다.

 

마찬가지로 필진을 빼고 싶은 경우 사용자 제외를 클릭하시면 됩니다.

(삭제된 필진의 글은 모두 관리자로 넘어가게 됩니다.)

728x90

지금까지 2003 IIS만 주로 쓰고 있다가, 2008로 넘어오면서 나름 적응을 했다고 생각했다.

그런데, 2008 R2에서는 시스템 성능 및 보안 등등 여러가지를 손 본듯 싶었다.

 

이번에 지원 프로젝트건이 있어 잠시 나왔다.

ClearQuest 7.1.1 과 IIS간의 연동 부분이 있는데, ClearQuest에서 제공하는 COM 과 연결하는 작업이 반드시 필요한 내용이였다.

로컬 및 자체 Staging 서버(애석하게도 여기는 2008이였지, 2008 R2가 아니였다.)에서는

잘 돌다가, 갑자기 운영서버에 올라가니 다음과 같은 오류를 뿜었다.

 

'/' 응용 프로그램에 서버 오류가 있습니다.
--------------------------------------------------------------------------------

80040154 오류로 인해 CLSID가 {94773112-72E8-11D0-A42E-00A024DED613}인 구성 요소의 COM 클래스 팩터리를 검색하지 못했습니다.
설명: 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 스택 추적을 검토하여 발생한 오류 및 코드에서 오류가 발생한 위치에 대한 자세한 정보를 확인하십시오.

예외 정보: System.Runtime.InteropServices.COMException: 80040154 오류로 인해 CLSID가 {94773112-72E8-11D0-A42E-00A024DED613}인 구성 요소의 COM 클래스 팩터리를 검색하지 못했습니다.

소스 오류:

줄 19: ....

 

처음에는 COM이기 때문에, 해당 서버에 저 COM이 제대로 등록되어 있지 않았나 싶었다.

그래서 구성 요소 서비스에 들어가, 해당 Component가 이상한가 봤는데,

애석하게도 내가 다루고 있던 COM은 서버형이 아니므로 전혀 무관계.

이번에는 RegEdit 를 띄운 뒤, 저 CLSID를 검색하는데,

잘 걸린다. 위치도 제대로 되어 있고, 모든 설정은 OK! 였다.

.NET Framework 문제인가? 3.5가 아닌 2.0 기반의 Classic .NET 설정의 문제인가.

아니면 내가 코드를 짤 때 레퍼런스 설정이 잘못된 것인가?

여러가지 의문점들을 하나씩 수정하면서 체크해봤다.

대략 1시간 정도 시간을 보내고 났다.

그러나 방법은 모르겠고.....

 

그러다가, 현재 동작 중인 응용 프로그램 설정에서 다음을 보았다.

3264compotableproblem

 

저게 x64 형태의 서버에서만 설정하는 부분인 것 같다.

성능상의 Issue를 최소화 시키기 위해 x86기반의 응용 프로그램 제외 모드가 있는 것 같다.

그런데, 애석하게도 저 옵션이 Default 값이 False인듯.

True로 바꾸자 모든게 매끄럽게 진행이되었다.

728x90

+ Recent posts

728x90