2009년 2월 26일 목요일
왜 OpenID를 주목하는가?
1. OpenID란 무엇인가?
위키피디아에서는 OpenID를 한마디로 "분산된 SSO (Single Sign On) 시스템" 이라고 정의하고 있다. 여기에서 1) “분산되어 있다”는 의미는 오픈아이디의 스펙만 준수할 경우 (특정 업체가 아니라) 누구나 OpenID를 만들어 공급해 줄 수 있다는 것 (ID Provider; 약자로 IdP) 이며, 2) “SSO”라는 의미는 하나의 ID와 패스워드로 OpenID 기능을 가지는 모든 시스템에 로그인할 수 있다는 것이다.
우리가 인터넷을 사용하면서 얼마나 많은 사이트에 회원 가입을 해 왔는지를 생각해보자.
인터넷을 제법 관심 있게 사용하는 분이라면 일주일에도 1~2개의 신규 사이트에 가입할 것이다. 회원 가입 시에 물어보는 정보는 아이디, 패스워드, 이메일 주소, 이름, 주민등록번호, 전화번호, 주소 등등 왜 이리 많은지 가입할 때마다 이런 반복 단순 작업을 언제까지 계속해야 하는 지 생각해 본 적이 많을 것이다.
OpenID를 이용하면 어떻게 될까요?
우선 최초에 단 한번 OpenID에 가입한다. 이때 아이디, 패스워드, 이메일 등의 필수정보와 입력을 원하는 기타 정보들을 입력하게 된다. 그리고 인터넷을 이용하면서 오픈아이디를 지원하는 사이트를 만나게 되면 더 이상 회원 가입할 필요 없이 기존에 만들어 놓은 나의 오픈아이디를 이용하여 로그인만 하면 된다. "편리하게 열리는 인터넷 세상"이 시작되는 것이다.
2. OpenID의 동작원리
홍길동님의 예를 살펴봄으로써 오픈아이디의 동작원리를 이해해 보도록 하겠다.
(1) 평소에 다양한 인터넷 서비스에 관심이 많은 홍길동님은 오픈아이디라는 것이 있다는 이야기를 듣고 아이디테일이라는 오픈아이디 제공 사이트에 가서 자신만의 오픈아이디를 발급받는다. 오픈아이디는 일반적인 인터넷 주소와 동일한 모양새를 가지고 있다: http://gildong.idtail.com
(2) 요새 나온 새로운 서비스 중에 Pumfit이라는 재미있는 서비스가 있다는 이야기를 들은 차에 방문해 보기로 한다.
(3) Pumfit 사이트에 있는 오픈아이디 로고를 보고 이 서비스에서 오픈아이디를 지원한다는 것을 발견한 홍길동님은 오픈아이디 로그인창에 자신의 오픈아이디를 입력하고 "로그인하기" 버튼을 누른다.
(4) 브라우저는 인증을 위해 IDtail의 인증 페이지로 이동하면서 홍길동님의 패스워드를 요구한다.
(5) 홍길동님은 자신의 패스워드를 입력한다.
(6) 인증이 정상적으로 이루어지면 IDtail에서는 Pumfit 서비스를 승인할 것인지 묻는다.
(7) 홍길동님이 승인하면 Pumfit 서비스에 대한 인증이 완료되면서 브라우저는 다시 Pumfit 사이트로 이동하고 로그인 상태가 된다.
글로 쓰니까 복잡해 보일 지 모르지만 실제로 홍길동님이 하는 것은 아이디 입력 -> 패스워드 입력 -> 승인 3단계 뿐이다. 또한 “승인”은 최초에 한번만 하면 다음부터는 하지 않아도 되는 과정이다. 복잡한 회원가입 대신에 간단하게 회원가입의 효과를 거둘 수 있게 된다.
3. OpenID의 유용성
오픈아이디의 정의에서 살펴 보았던 “분산된 시스템”이 의미가 있는 것은 내가 나의 오픈아이디제공자를 선택할 수 있다는 것이다. AOL, Sun, HP, Intel, Oracle 등이 주도하고 있는 Liberty alliance나 마이크로소프트의 Passport에서의 중앙 집중형 인증시스템에서는 물론이고 오픈아이디를 지원하지 않는 일반 서비스들에서 우리는 인증 관련하여 선택할 수 있는 것이 아무것도 없다. 그저 그들의 인증체계를 따를 뿐이다. 이때 우리는 그들을 신뢰할 수 있는 것일까? 신뢰를 할 수 있던 없던 간에 무조건 선택의 여지 없이 그들의 인증체계를 따라야 한다는 것은 문제가 있다. 하지만 오픈아이디와 같은 분산된 시스템에서는 나를 인증해 줄 수 있는 서비스를 내 마음대로 선택할 수 있다. 심지어는 내가 나만의 인증 서비스를 직접 만들 수도 있다. 분산된 SSO 시스템은 또 다른 장점도 가진다. 바로 SPOF (Single Point Of Failure) 를 방지하는 것이다. 일반적인 SSO 시스템에서는 해당 인증 시스템에 문제가 생길 경우 모든 사이트에서 인증받을 수 없게 되는 문제가 있다. 하지만 분산된 SSO에서는 delegation이라는 기능을 이용하여 블로그 또는 홈페이지 주소와 같은 나만의 URL을 나의 오픈아이디로 이용하면서 이에 연동되어 있는 하나의 오픈아이디가 문제가 생길 경우 다른 오픈아이디를 연동시킴으로써 특정 서비스에서 동일한 identity를 유지하는 것이 가능해진다. (Delegation을 수행하는 방법은 매우 간단하며 아래 6번에서 설명된다)
4. OpenID의 보안성
오픈아이디의 분산성은 보안에 대해서도 강점을 가진다. 오픈아이디의 스펙 자체에서는 보안에 대해 특별히 어떠한 강제 규정을 두고 있지는 않다. 하지만 우리는 오히려 다양한 인증 방법을 제공하는 다양한 오픈아이디 제공자를 만나보게 된다. 오픈아이디 제공자들은 가장 좋은 인증방법을 제공하기 위해 경쟁하게 될 것이며, 사용자들은 이중에서 자신이 적합하다고 생각하는 오픈아이디 제공자를 선택하면 된다.
SSL을 통한 로그인, 오픈아이디 지원 사이트에 로그인 하기 전에 오픈아이디 제공자 사이트에 우선적으로 로그인하고 시작함으로써 패스워드 입력이 필요 없게 만드는 것, 클라이언트 인증서의 설치, 마이크로소프트 비스타의 Cardspace 이용, 메신저를 통한 인증, OTP를 이용한 인증, Vidoop의 솔루션을 이용한 인증 등 다양한 방법이 가능하다.
5. OpenID를 지원하는 사이트는?
OpenID가 성공할 수 있는 가장 중요한 요소는 역시 OpenID를 지원하는 사이트가 얼마나 되는가 하는 것이다. 2006년 중반까지만 해도 극소수에 머물렀던 오픈아이디 지원 사이트 (Relying Party; 약자로 RP) 의 수는 2006년 말부터 폭발적으로 증가하고 있다. 오픈 커뮤니티나 블로그, 웹2.0 기반의 신규 서비스에서 주로 채택되던 오픈아이디가 이제는 AOL, Microsoft, Sun, VeriSign 등에서 도입되고 있으며 최근에는 IT기업이 아닌 리복 같은 회사의 사이트에서까지 오픈아이디를 도입하기 시작했다.
[그림 1] 오픈ID 지원 사이트(국외)
출처 : http://openid.net/pres/2007_Web2Expo_Implementing_OpenID-notes.pdf
국내의 경우에도 올해 들어 오픈아이디 지원 사이트가 많이 늘어나고 있어 설치형 블로그의 대표주자 태터툴즈, 미투데이, 이글루스, Pumfit 등에서 오픈아이디를 지원하며 그 수는 계속 증가하고 있는 추세이다. 대표적인 인터넷 포털인 다음에서도 오픈아이디를 준비하고 있다고 하니 그 영향력이 기대된다.
[그림 2] 오픈ID 지원 사이트(국내)
6. Delegation 하는 방법
메타태그를 삽입해 줌으로써 나의 블로그나 홈페이지 주소를 OpenID처럼 사용할 수 있다.
ID가 gildong인 경우의 예를 보면 다음과 같다.
(두번째/세번째 줄의 “gildong” 부분만 자신의 ID로 변경하면 된다.)
< link rel="openid.server" href="http://www.idtail.com/server" />
< link rel="openid.delegate" href="http://gildong.idtail.com/" />
< meta http-equiv="X-XRDS-Location" content="http://gildong.idtail.com/xrds" />
서비스형 블로그를 사용하시고 계신 경우에는 스킨에 위의 메타태그를 삽입할 수 있도록 블로그서비스 제공자가 허용해야 한다. 이글루스에서는 OpenID delegation 서비스 메뉴를 제공하고 있으며, 티스토리에서는 스킨 수정이 가능하기 때문에 사용자분께서 직접 위의 메타태그를 넣어주면 된다.
7. IDtail 서비스 소개
신뢰기반의 인터넷서비스를 제공하는 안철수연구소 사내벤처 고슴도치플러스에서는 지난 4월부터 오픈아이디 관련 서비스를 다음과 같이 제공하고 있다.
오픈아이디 제공 서비스: IDtail (http://www.idtail.com)
오픈아이디 지원 서비스: Pumfit (http://www.pumfit.com)
IDtail에서 자신만의 오픈아이디를 만들고 Pumfit에서 로그인하여 서비스를 이용해 보는 것만으로도 오픈아이디에 대한 이해를 한층 높일 수 있으리라 생각된다.@
안철수연구소 사내벤처TF팀 송교석 팀장
[안철수연구소 2007-05-14]
2009년 2월 10일 화요일
Sky IM-S410 (S410K) WHOOO 감성엔진을 달은 스카이 윈드(가칭)





스카이 윈드(가칭)이 나온단다...
입으로 바람을 불면 사진이 휘리릭~ 넘어가는 기능이....ㅎㅎ
네온사인2로도 불리우는데 네온사인폰이 U로 시작하는 모델명이었지만
이번에는 S로 시작하는 모델명이라는....
그만큼 슬림하다는거겠지...ㅎㅎ
감성엔진을 채택했다고 하니 기대해볼만한것 같다 ㅎㅎ
갖고싶다 ㅠㅠ
스타일이 돋보이는 디자인 11mm 초슬림 폴더
- 바람을 불어 사진을 넘기는 스카이 윈드 기능
- 상황에 따라 변하는 Matrix LED 탑재
<주요기능>
● 카메라-200만화소
● 2.6형 26만 컬러 WQVGA TFT
● 지상파 DMB
● 블루투스
● MP3
● 투폰!
● 외장메모리 대응
● 영상통화
● WCDMA + GSM
2009년 2월 8일 일요일
4대륙 피겨선수권 김연아선수의 연기장면(Nikon D90 동영상 테스트)
Nikon D90 동영상기능으로 촬영하였습니다.
급하게 녹화하느라 미처 풀HD로 설정은 못했습니다 ㅠ
혹시 D90의 동영상기능이 어느정도인지 궁금해 하시는분들이 계실까봐 올려봅니다 ^^
2009년 2월 7일 토요일
니콘 프리미엄팩 1
니콘 프리미엄팩2를 사용하고 있었으나 장비도 없는 헝그리 유저가 큰 가방을 갖고 있으니
참...방 한켠에 놓고 먼지만 쌓이게 되는게 현실이더군요....그래서 과감하게 프리미엄팩2를
팔고 프리미엄팩1을 샀습니다. 작고 아담한게 좋더군요..
저는 이 가방에 35/2 (35mm F2.0) 마운트상태의 D90+세로그립을 넣고 다닙니다.
저는 장비가 딸랑 이거밖에 없기 때문이죠 ㅎㅎㅎ 사실 불쌍하죠? ㅠㅠ
D90+35/2+세로그립을 렌즈가 가방 앞쪽을 보도록 넣고 파티션 나누는걸로 파티션을 나눈다음
나머지 공간에 파티션 또는 렌즈 한개정도를 더 넣을 수 있는 공간이 있습니다.
가방 사이즈가 크지 않습니다. 정말 저처럼 장비가 별로 없는분이거나 아니면 간단하게
필요한것만 갖고 나갈 때 사용하면 좋을 듯 합니다 ^^
구매를 계획하시는분들께 도움이 되고자 남깁니다 ^^
2009년 2월 1일 일요일
Active X에 대응한다! Fire Fox 플러그인 만들기(3)
들어는 봤나! Firefox PlugIn (3)
30줄도 안 되는 PlugIn을 작성해보자.
PlugIn SDK를 다운받으면 샘플 코드가 있습니다. 헌데, 샘플 코드 치고는 워낙 신중을 기했는지 샘플이 약간 어렵게 보입니다. 더 쉽게 작성할 수도 있는데 말 입니다. 그래서 최소한의 조건을 갖춘 Hello World 플러그인을 작성해보려고 합니다.
함수 3개로 이루어진 DLL 프로젝트 입니다. 쉽겠죠? 프로젝트 설정하는 부분의 분량이 좀 많아서 그렇지, 코드 내용은 상당히 가볍습니다. 가벼운 만큼 플러그인 코드를 이해하기 쉽겠죠? 자신만의 플러그인을 만들어 보세요!
Step 1 ) NPTest 프로젝트 생성
- Win32 Dynamic-Link Library를 만듭니다.
- A Simple DLL Project를 선택
- 주의! : FireFox는 파일명이 NP로 시작하는 것만 인식합니다.
Step 2 ) DLLMain 함수 삭제
- NPTest.cpp 에서 DLLMain 함수 삭제
- #include “npplat.h” 추가
Step 3 ) include 디렉토리 설정
- SDK 폴더에서 gecko-sdk와 sdk 폴더를 프로젝트 내에 include 폴더를 생성한 뒤 복사 합니다.
- Project Setting의 C/C++ 탭에서 Project 옵션 창에 다음 정보를 추가합니다.
/I ".\include\sdk\samples\include"
/I ".\include\gecko-sdk\plugin\include"
/I ".\include\gecko-sdk\nspr\include"
/I ".\include\gecko-sdk\java\include"
Step 4 ) 계속해서 Project Setting에서 C++/C 탭에 다음정보를 추가합니다.
- Preprocessor definition에 MOZILLA_STRICT_API,XP_WIN,_X86_ 항목을 추가한다.
Step 5 ) def 파일 생성
- NPTest.def 파일 추가 (파일 -> New -> C++ Source -> NPTest.def )
NPTest.def 파일의 내용을 다음과 같이 정의하세요.
LIBRARY NPTEST
EXPORTS
NP_GetEntryPoints @1
NP_Initialize @2
NP_Shutdown @3
Step 6 ) NPTest.cpp 에 함수 추가
NP_GetEntryPoints, NP_Initialize, NP_Shutdown 함수를 추가합니다.
NPTest.cpp 파일의 내용에 다음 내용을 추가하세요.
NPError OSCALL NP_Shutdown()
{
return NPERR_NO_ERROR;
}
NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs)
{
AfxMessageBox( "hi" ) ;
return NPERR_NO_ERROR;
}
NPError OSCALL NP_GetEntryPoints(NPPluginFuncs* aNPPFuncs)
{
return NPERR_NO_ERROR;
}
Step 7) Version 리소스를 생성합니다.
FireFox가 플러그인을 인식하기 위해서는 정확한 버전 정보를 생성해야 합니다. 이때 버전정보가 지켜야 할 규칙이 있는데 이를 명심하고 작성해야 합니다.
규칙1. 버전 정보는 English (US)로 설정되어야 합니다.
규칙2. Character Type은 Multilingual 로 설정되어야 합니다.
규칙3. FileEntents, MIMEType가 명시되어야 합니다.
리소스 추가 -> Version 을 한 뒤 Property 창에서 버전 정보를 English(US)로 설정합니다. 또한 프로젝트 세팅에서 Resource 탭에서 언어를 영어(미국)으로 설정합니다. 새로운 버전 블록을 추가할 때 English(US)로 설정하고 코드 페이지는 Multilingual로 설정합니다. 이 설정이 올바로 되어있는지 확인하기 위해서는 블록 코드가 "040904e4"로 설정되어 있는지 확인하면 됩니다.
FireFox가 플러그인을 인식하도록 하기 위해서는 MIME 타입을 반드시 버전 정보에 포함시켜야 하는데, 이는 NPTest.rc 파일을 직접 수정하는 과정을 거쳐야 합니다.
NPTest.rc 예제
BLOCK "040904e4"
BEGIN
VALUE "Comments", "\0"
VALUE "CompanyName", "ASP\0"
VALUE "FileDescription", "NPTest\0"
VALUE "FileExtents", "tst\0"
VALUE "FileVersion", "1, 0, 0, 1\0"
VALUE "InternalName", "NPTest\0"
VALUE "LegalCopyright", "Copyright ⓒ 2006\0"
VALUE "LegalTrademarks", "\0"
VALUE "MIMEType", "application/test-plugin\0"
VALUE "OriginalFilename", "NPTest.dll\0"
VALUE "PrivateBuild", "\0"
VALUE "ProductName", "ASP NPTest\0"
VALUE "ProductVersion", "1, 0, 0, 1\0"
VALUE "SpecialBuild", "\0"
END
Step 8) 플러그인을 로드하는 HTML 작성
<embed> 태그를 이용해서 플러그인을 로드 할 수 있습니다. 위 예제에서는 type 속성을 명시해줌으로써 플러그인을 로드 할 수 있습니다.
Test.html 예제
<html>
<body>
<center><h1>Basic Plugin Example for Mozilla Test Case</h1></center>
This test case is to demonstrate the Basic Plugin example. You should see the
plugin window with the black frame aroung it and the browser user agent string
which plugin draws inside the window.
<br><br>
<center>
<embed type="application/test-plugin" width=600 height=40>
</center>
</html>
</body>
Embed 태그의 type 속성을 버전에서 정해준 MIME 타입으로 설정해둔 것을 볼 수 있습니다. 위의 HTML 파일을 FireFox로 불러오면 플러그인이 로드된다. 테스트를 위해서 플러그인 로드시 MessageBox를 띄우는 코드를 작성한 후 테스트 합니다.
Step 9) FireFox에서 불러오기
NPTest.cpp 수정 부분
NPError OSCALL NP_Initialize(NPNetscapeFuncs* aNPNFuncs)
{
AfxMessageBox( "hi" ) ;
return NPERR_NO_ERROR;
}
NP_Initialize에 AfxMessageBox를 불러오는 코드를 작성해봅니다. MFC를 사용하기 위해서는 프로젝트 설정 정보에서 Using MFC로 설정해야 하며, 다음과 같은 헤더 정보를 포함해야 합니다.
MFC를 사용하기 위한 헤더 설정
#include <afxwin.h> // MFC 핵심 및 표준 구성 요소
#include <afxext.h> // MFC 익스텐션
#include <afxdisp.h> // MFC 자동화 클래스
이제 컴파일 한 후 결과 파일인 NPTest.dll 파일을 파이어폭스가 설치된 폴더에서 plugin 폴더에 복사한 후 위에서 작성한 test.html 파일을 불러오세요.
PlugIn이 실행되는걸 직접 확인하셨나요?
맨땅에서부터 정말로 실행되는 단계까지 직접 해보신 기분이 어떤가요? 플러그인 만드는 거 별거 아닌 것 같습니다. 여기에 자신의 아이디어를 적용시켜보세요!
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
Active X에 대응한다! Fire Fox 플러그인 만들기(2)
들어는 봤나! Firefox PlugIn (2)
PlugIn의 Life Cycle을 이해하자
Life Cycle이란 인스턴스가 처음으로 생성되는 시점에서부터, 인스턴스가 소멸할 때까지의 시점을 이야기 합니다. Standalone 어플리케이션 경우에는 인스턴스가 생성되고 소멸되는 시점이 프로그램 내부에서 조절 가능하기 때문에 중요하지 않지만, PlugIn 이나 Applet의 경우에는 인스턴스를 제어하는 주체가 브라우저이거나 다른 프로그램이기 때문에 Life Cycle을 이해하는 것이 중요합니다.
그림 1 PlugIn Runtime Model
EntryPoint?
위 테이블에 있는 함수의 실체는 어디에서 정의되는 것인가? 라는 것부터 확실히 하고 함수들의 역할을 이해해야 합니다. 위 함수들은 PlugIn이 가지고 있는 함수이며, 브라우저가 호출하는 함수들입니다. 이들을 EntryPoint 함수라고 하기도 합니다.
그림 2 EntryPoint?
눈치가 있는 사람이라면 윈도우에서 EntryPoint 구조를 가지려면 최소한 DLL 형태가 되야 된다는 사실을 알 수 있습니다. 그렇습니다. 윈도우에서 플러그인 파일은 DLL 입니다.
다시 Life Cycle로 돌아와서…
브라우저 내부에는 여러 개의 플러그인 인스턴스가 있을 수 있습니다. 같은 플러그인일지라도 여러 개가 로드 될 수 있습니다. 이런 경우에 가장 첫 플러그인 인스턴스가 생성되는 시점에 호출되는 함수가 NP_Initialize() 입니다. 이 후에 새로운 플러그인 인스턴스가 생성되어도 NP_Initialize() 함수는 다시 호출되지 않습니다. 이 함수에는 보통 플러그인들끼리 공유하는 전역 변수 등을 초기화 하는 코드가 들어갑니다. NP_Shutdown() 함수는 마지막 플러그인이 종료되는 경우에 호출됩니다.
NPP_New() 함수는 플러그인 인스턴스가 생성될 때마다 호출되는 함수 입니다. NPP_Destroy()는 플러그인 인스턴스가 소멸될 때마다 호출되는 함수 입니다.
최소한 PlugIn이 되기 위한 조건?
최소한 PlugIn으로 동작하기 위해서는 NP_Initialize()와 NP_Shutdown() 함수 2개만 정의되어 있으면 됩니다. DLL로 만들고 NP_Initialize(), NP_Shutdown() 함수들을 Export 시키면 최소한의 요건을 갖춘 PlugIn이 됩니다. 간단하죠?
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
Active X에 대응한다! Fire Fox 플러그인 만들기(1)
들어는 봤나! Firefox PlugIn
안녕하세요! Firefox PlugIn 이라고 합니다~
익스플로러에 ActiveX가 있다면, Firefox에는 PlugIn이 있습니다. 이들은 브라우저에서 돌아가는 로컬 어플리케이션입니다. 둘의 차이가 있다면 ActiveX는 윈도우 환경에서만 돌아가는 반면에 PlugIn은 Windows, Linux, Mac 을 지원한다는 차이가 있습니다. 하나의 PlugIn이 모든 OS에서 돌아간다는 이야기는 아니고, PlugIn 내부에 Windows 코드가 들어갈 수도 있고, Linux 코드가 들어갈 수도 있고, Mac 코드가 들어갈 수도 있다는 이야기가 되는 것이지요. 윈도우용 PlugIn은 윈도우에서만 돌아간다고 이해하면 됩니다. 대표적인 Firefox PlugIn으로는 Flash, 아크로밧 리더, 미디어플레이어, 리얼플레이어 등이 있습니다.
그림 1 Positioning PlugIn
브라우저는 원래 로컬 머신과 통신할 수 없습니다. 브라우저는 단지 웹 페이지를 열어서 보여주는 기능을 하는 것인데, 웹 페이지가 점점 다이내믹 해지면서 사용자와 더욱 능동적으로 소통하려고 하려고 하다가 결국, 웹 페이지에서 프로그램을 실행할 수 있으면 얼마나 좋을까? 하는 욕구가 생기고 그에 따라 ActiveX, Firefox PlugIn이 생겨나게 된 것입니다.
웹 페이지에서 채팅도 할 수 있고, 인터넷 뱅킹도 할 수 있고, 동영상도 볼 수 있고 이게 다 PlugIn이 있기 때문에 가능해진 기능들입니다. 근데 막강한 기능을 가진 PlugIn도 문제점은 있습니다. 바로 OS에 의존적이 된다는 점입니다.
그림 2 PlugIn의 OS dependency 문제
뭐 PlugIn의 특징을 생각해보면 어쩔 수 없는 결과이기도 하지만, 웹의 범용적인 특성을 고려해볼 때 썩 바람직한 모양은 아닌 것 같네요. 가상머신이든 플랫폼이되든… OS에 의존적이지 않은 플러그인이 결국은 나오지 않을까 생각하는데… 여러분은 어떤가요? (비슷한 개념으로 AJAX가 나오지 않았나 싶지만, 제 생각은 이걸로 웹이 대세가 될 것이라고 생각하는 것은 아직 이른감이 있는 것 같습니다.)
PlugIn 만들어 보시게요? 여기서부터 시작하세요.
Firefox PlugIn을 만들어 보시려면, 먼저 몇 개의 레퍼런스 사이트를 즐겨 찾기에 등록해 놓으면 좋을 것 같습니다. 처음에 아무것도 모르는 상태에서 시작한 필자는 처음에 많이 헤맸습니다. 요즈음 Firefox 때문에 Mozilla 사이트에 개발 내용과 같이 마케팅 컨텐츠가 섞이면서 혼란스럽기 그지 없습니다.
http://www.mozilla.com
FireFox 사이트입니다. (정확히는 Mozilla.com 이라는 영리단체입니다.) 이 사이트에 접속해서 FireFox 브라우저를 다운받은 후 설치할 수 있습니다.
http://developer.mozilla.org
Mozilla Development Center 라는 곳으로 PlugIn에 관련된 정보 이외에 Mozilla 프로젝트 개발 관련된 정보들을 볼 수 있는 곳입니다. FireFox 개발 관련 키워드를 얻고 싶으면 위 사이트를 참조하면 됩니다.
http://www.mozilla.org/projects/plugins/
PlugIn 개발에 관련된 페이지이다. SDK를 다운 받을 수 있는 링크나 여러 레퍼런스 매뉴얼들이 링크되어 있는 곳입니다. PlugIn 개발을 위해서 반드시 북마크 되어 있어야 하는 곳이기도 합니다.
http://web.archive.org/web/20040203041440/http://devedge.netscape.com/library/manuals/2002/plugin/1.0/
Mozilla 엔진인 Gecko에 대한 API 레퍼런스입니다.
SDK 다운 받기
http://www.mozilla.org/projects/plugins/GeckoPluginSDK-samplesWin32.zip
위 링크를 통해서 PlugIn API를 다운 받을 수 있습니다. SDK라고 하면 왠지 설치과정이 있을 것 같지만 이건 그냥 압축 풀고 바로 사용할 수 있습니다. SDK에는 샘플코드도 같이 포함되어 있습니다. 샘플은 VC++ 6 에서 바로 컴파일 할 수 있는 환경으로 구성되어 있기 때문에 쉽게 실행 할 수 있습니다.
PlugIn 샘플 실행하기
필자는 보통 SDK를 받으면 샘플부터 실행시켜 봅니다. 샘플 프로그램 컴파일해서 돌아가면 왠지 다 만든 것 같은 기분에 뿌듯합니다. 샘플 중에 가장 간단한 예제를 실행해봅시다.
1) Basic 샘플 경로 – sdk/samples/basic/windows
2) npbasic.dsw 을 VC++로 열기
3) Release 모드로 컴파일
4) FireFox가 설치된 경로의 plug-in 폴더에 생성된 dll 파일을 복사
5) sdk/samples/basic 경로에 있는 test.html 파일을 FireFox로 실행
안타깝게도 샘플을 돌려보려면 VC 6.0과 Mozilla Firefox가 설치되어 있어야 합니다. 컴파일하면 결과물이 DLL로 나옵니다. 이 파일을 Firefox가 설치된 폴더에서 plugins 에 복사하면 됩니다.
그림 3 샘플이 실행된 모습
브라우저의 버전 정보를 얻어와서 화면에 그려주는 예제입니다. 예제는 간단해 보이지만 실제 소스코드는 살짝쿵 복잡합니다. 제가 보기에는 더 쉽게 샘플 코드를 작성할 수 있을 것 같은데, 샘플에는 쓸데없는 코드가 좀 있어 보입니다. 다음은 다 걷어내고 핵심만 있는 PlugIn을 만들어 봅시다!
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
플러그인과 자바스크립트의 연동!
Firefox Plug-in – JavaScript 연동 (4)
JavaScript에서 Plug-in 내부의 함수를 호출하는 방법을 익혀 봅니다. 서로 다른 형태의 바이너리가 소통할 수 있는 이유는 XPCOM이라는 인터페이스 규약을 따르고 있기 때문입니다.
IDL 파일 생성
그림 1 Add 함수
지금 만들어 보려고 하는 형태는 위 그림에서 설명하는 것처럼 1 + 2를 호출하면 3을 반환하는 함수를 만들어 보려고 하고 있습니다. Function Call처럼 보이는 Add 함수는 Plug-in이 구현하고 있는 함수로서 JavaScript가 호출해서 반환 값을 얻어가고 있는 형태인데요. 바이너리 레벨에서 서로 통신하는 구조는 내부적으로 XPCOM 인터페이스 규칙을 따르고 있기 때문에 가능합니다.
간단해 보이는 Add 함수를 구현함으로써 크게 XPCOM 함수를 구현하는 방법, XPCOM 인터페이스를 구현하는 방법, 인자가 넘어오는 형태, 반환 값을 넘기는 형태 등을 배울 수 있습니다.
가장 첫 번째 단계로 IDL 파일을 만들어 봅시다. IDL 파일은 Interface Description Language로 인터페이스를 정의하는 파일이 되겠습니다. 인터페이스가 필요한 이유는 Add 함수가 어떤 형태로 구현이 되어 있던 간에 외부에서는 인터페이스만 보고 통신할 수 있도록 하기 위함입니다.
그림 2 nsIScriptableObject.idl
위 그림에 작성된 IDL 파일을 보면 #include 부분과 uuid 부분을 제외하면 Class 정의하는 것과 거의 차이가 없어 보입니다. Add 함수는 long 형 2개를 인자로 받고 long형을 반환하는 함수의 형태입니다. 위 내용을 그대로 작성해서 nsIScriptableObject.idl 파일로 저장합니다.
Type Header와 Type Library 파일 생성
앞서 배웠던 xpidl을 이용해서 Type Header와 Type Library를 생성합니다.
xpidl -m header -I .\gecko-sdk\idl nsIScriptableObject.idl
xpidl -m typelib -I .\gecko-sdk\idl nsIScriptableObject.idl
결과 파일로 nsIScriptableObject.h 와 nsIScriptableObject.xpt 파일이 생성됩니다.
Scriptable Object 구현 (XPCOM 프로그래밍)
nsIScriptableObject.h 파일에는 Add 함수에 대한 정의 부분만 들어가 있습니다. 내용을 잠시 보면
... 생략
/* Use this macro when declaring classes that implement this interface. */
#define NS_DECL_NSISCRIPTABLEOBJECT \
NS_IMETHOD Add(PRInt32 a, PRInt32 b, PRInt32 *_retval);
/* Use this macro to declare functions that forward the behavior of this interface to another object. */
#define NS_FORWARD_NSISCRIPTABLEOBJECT(_to) \
NS_IMETHOD Add(PRInt32 a, PRInt32 b, PRInt32 *_retval) { return _to Add(a, b, _retval); }
/* Use this macro to declare functions that forward the behavior of this interface to another object in a safe way. */
#define NS_FORWARD_SAFE_NSISCRIPTABLEOBJECT(_to) \
NS_IMETHOD Add(PRInt32 a, PRInt32 b, PRInt32 *_retval) { return !_to ? NS_ERROR_NULL_POINTER : _to->Add(a, b, _retval); }
… 생략
위 와 같은 내용으로 이루어져 있습니다. Xpild이 자동으로 생성해주는 부분이기 때문에 많은 부분 생략되었습니다. 중요한 부분은 NS_DECL_NSISCRIPTABLEOBJECT 이라고 선언되어 있는 매크로 입니다. Xpidl이 자동으로 헤더 파일을 생성할 때 개발자가 구현을 쉽게 할 수 있도록 몇가지 매크로를 만들어 주는데요. NSISCRIPTABLEOBJECT은 개발자가 구현해야할 함수 원형을 매크로로 선언해놓은 부분입니다. 본 예에서는 함수가 하나밖에 없기 때문에 불필요해 보일 수도 있지만 실제로 헤더에 선언된 매크로들은 많은 편리함을 제공해줍니다.
이 헤더파일의 구현부를 작성해보도록 합시다. 구현 파일의 이름은 nsScriptableObject.h와 nsScriptableObject.cpp로 하겠습니다.
Step 1. nsScriptableObject 클래스를 만들고
Step 2. xpidl이 생성한 nsIScriptableObject 를 상속받습니다.
Step 3. 그 다음에는 AddRef, Release, QueryInterface 함수를 구현해줍니다.
(이 3함수들을 XPCOM 규약에 따르는 형식입니다.)
Step 4. 그리고 마지막으로 Add 함수를 구현해줍니다.
nsScriptableObject.h 파일을 살펴보겠습니다.
#include "nsIScriptableObject.h"
class nsScriptableObject : public nsIScriptableObject
{
public:
nsScriptableObject();
virtual ~nsScriptableObject();
public:
// native methods callable from JavaScript
NS_DECL_NSISCRIPTABLEOBJECT
///////////////////////////////////////////////////////
// XPCOM Support
///////////////////////////////////////////////////////
// methods from nsISupports
NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr);
NS_IMETHOD_(nsrefcnt) AddRef();
NS_IMETHOD_(nsrefcnt) Release();
protected:
nsrefcnt m_nRefCnt;
};
NS_DECL_NSISCRIPTABLEOBJECT은 Add 함수의 원형이 들어있는 매크로 입니다. 그리고 아래는 AddRef, Release, QueryInterface 함수가 선언되어 있습니다.
nsScriptableObject.cpp 파일을 살펴보겠습니다.
// AddRef, Release and QueryInterface are common methods and must
// be implemented for any interface
NS_IMETHODIMP_(nsrefcnt) nsScriptableObject::AddRef()
{
++m_nRefCnt;
return m_nRefCnt;
}
NS_IMETHODIMP_(nsrefcnt) nsScriptableObject::Release()
{
--m_nRefCnt;
if (m_nRefCnt == 0)
{
delete this;
return 0;
}
return m_nRefCnt;
}
static NS_DEFINE_IID(kIScriptableIID, NS_ISCRIPTABLEOBJECT_IID);
static NS_DEFINE_IID(kIClassInfoIID, NS_ICLASSINFO_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
// here nsScriptablePeer should return three interfaces it can be asked for by their iid's
// static casts are necessary to ensure that correct pointer is returned
NS_IMETHODIMP nsScriptableObject::QueryInterface(const nsIID& aIID, void** aInstancePtr)
{
if(!aInstancePtr)
return NS_ERROR_NULL_POINTER;
if(aIID.Equals(kIScriptableIID)) {
*aInstancePtr = static_cast<nsIScriptableObject*>(this);
AddRef();
return NS_OK;
}
if(aIID.Equals(kIClassInfoIID)) {
*aInstancePtr = static_cast<nsIClassInfo*>(this);
AddRef();
return NS_OK;
}
if(aIID.Equals(kISupportsIID)) {
*aInstancePtr = static_cast<nsISupports*>(static_cast<nsIScriptableObject*>(this));
AddRef();
return NS_OK;
}
return NS_NOINTERFACE;
}
NS_IMETHODIMP nsScriptableObject::Add(PRInt32 a, PRInt32 b, PRInt32 *_retval)
{
int nResult = a + b ;
*_retval = nResult ;
return NS_OK;
}
AddRef, Release, QueryInterface 함수는 위 내용대로 구현하면 됩니다. 자세한 내용은 추후에 알아보도록 합니다.
Add 함수 구현부를 보면 인자로 a, b , _retval 이 있습니다. a와 b는 idl에서 선언해준 그대로의 형태로 되어 있으며, 반환값은 정수형 포인터로 _retval 로 지정되어 있는 것을 볼 수 있습니다. 일반 Function Call과 약간은 다른 형태로 보입니다.
nsIClassInfo 구현
JavaScript에서 Plug-in 함수를 호출을 허용하기 위해서는 nsIClassInfo를 상속받아야 합니다.
// We must implement nsIClassInfo because it signals the
// Mozilla Security Manager to allow calls from JavaScript.
#include "nsIClassInfo.h"
class nsClassInfoMixin : public nsIClassInfo
{
// These flags are used by the DOM and security systems to signal that
// JavaScript callers are allowed to call this object's scritable methods.
NS_IMETHOD GetFlags(PRUint32 *aFlags)
{*aFlags = nsIClassInfo::PLUGIN_OBJECT | nsIClassInfo::DOM_OBJECT;
return NS_OK;}
NS_IMETHOD GetImplementationLanguage(PRUint32 *aImplementationLanguage)
{*aImplementationLanguage = nsIProgrammingLanguage::CPLUSPLUS;
return NS_OK;}
// The rest of the methods can safely return error codes...
NS_IMETHOD GetInterfaces(PRUint32 *count, nsIID * **array)
{return NS_ERROR_NOT_IMPLEMENTED;}
NS_IMETHOD GetHelperForLanguage(PRUint32 language, nsISupports **_retval)
{return NS_ERROR_NOT_IMPLEMENTED;}
NS_IMETHOD GetContractID(char * *aContractID)
{return NS_ERROR_NOT_IMPLEMENTED;}
NS_IMETHOD GetClassDescription(char * *aClassDescription)
{return NS_ERROR_NOT_IMPLEMENTED;}
NS_IMETHOD GetClassID(nsCID * *aClassID)
{return NS_ERROR_NOT_IMPLEMENTED;}
NS_IMETHOD GetClassIDNoAlloc(nsCID *aClassIDNoAlloc)
{return NS_ERROR_NOT_IMPLEMENTED;}
};
#include "nsIScriptableObject.h"
class nsScriptableObject : public nsIScriptableObject ,
public nsClassInfoMixin
{
.. 생략
위 같이 nsClassInfoMixin 클래스를 작성해주시고, 구현한 nsScriptableObject 클래스에 상속을 시켜주세요. 이제 JavaScript에서 Plug-in에 있는 함수를 호출할 때 사용할 함수에 대한 구현이 완료되었습니다. 다음은 plug-in에서 ScriptableObject를 Firefox 브라우저에 넘겨주는 코드가 작성되어야 합니다.
CleanSample에서 GetValue 함수 추가 구현
이전에 작성하였던 CleanSample에서는 GetValue함수가 구현이 되어 있지 않습니다. 이 함수를 구현해야 Firefox 브라우저에게 ScriptableObject를 넘길 수가 있고, 그제서야 JavaScript에서 Plug-in 내부의 함수를 호출 할 수 있게 됩니다.
가장 먼저 fillPluginFunctionTable 함수에서 GetValue 함수 포인터를 넘겨주는 코드를 수정합니다.
static NPError fillPluginFunctionTable(NPPluginFuncs* aNPPFuncs)
{
if(aNPPFuncs == NULL)
return NPERR_INVALID_FUNCTABLE_ERROR;
// Set up the plugin function table that Netscape will use to
// call us. Netscape needs to know about our version and size
// and have a UniversalProcPointer for every function we implement.
aNPPFuncs->version = (NP_VERSION_MAJOR << 8) | NP_VERSION_MINOR;
aNPPFuncs->newp = NPP_New; // 플러그인 인스턴스가 생성될때마다 호출된다.
// aNPPFuncs->destroy = NPP_Destroy; // 플러그인 인스턴스가 소멸될때마다 호출된다.
aNPPFuncs->setwindow = NPP_SetWindow; // 플러그인의 윈도우 상태가 변경될때마다 호출된다.
// aNPPFuncs->newstream = NPP_NewStream;
// aNPPFuncs->destroystream = NPP_DestroyStream;
// aNPPFuncs->asfile = NPP_StreamAsFile;
// aNPPFuncs->writeready = NPP_WriteReady;
// aNPPFuncs->write = NPP_Write;
// aNPPFuncs->print = NPP_Print;
// aNPPFuncs->event = NPP_HandleEvent;
// aNPPFuncs->urlnotify = NPP_URLNotify;
aNPPFuncs->getvalue = NPP_GetValue;
// aNPPFuncs->setvalue = NPP_SetValue;
return NPERR_NO_ERROR;
}
그리고 다음으로 NPP_GetValue 함수를 구현합니다. 함수 내용은 대략적으로 Firefox가 ScriptableObject의 인스턴스를 요청처리와 Interface 요청 처리하는 코드로 구성되어 있습니다.
NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value)
{
if(instance == NULL)
return NPERR_INVALID_INSTANCE_ERROR;
NPError rv = NPERR_NO_ERROR;
if (variable == NPPVpluginScriptableInstance)
{
// addref happens in getter, so we don't addref here
nsScriptableObject * scriptablePeer = getScriptablePeer();
if (scriptablePeer)
{
*(nsScriptableObject **)value = scriptablePeer;
}
else
{
rv = NPERR_OUT_OF_MEMORY_ERROR;
}
}
else if (variable == NPPVpluginScriptableIID)
{
static nsIID scriptableIID = NS_ISCRIPTABLEOBJECT_IID;
nsIID* ptr = (nsIID *)NPNFuncs.memalloc(sizeof(nsIID));
if (ptr)
{
*ptr = scriptableIID;
*(nsIID **)value = ptr;
}
else
{
rv = NPERR_OUT_OF_MEMORY_ERROR;
}
}
return rv ;
}
작동개시!
ㅋ ㅑ ~ 에러없이 컴파일이 되는데 성공하셨나요? 저는 여기까지 오는데 무수한 삽질을 했습니다;; 마지막으로 Firefox에서 돌려보면서 결과를 보는 일만 남았습니다. 아래와 같은 HTML 페이지를 작성하신 다음에 %Firefox 설치 폴더%plugins 폴더에 NPPlugIn.dll 파일과 NPPlugIn.xpt 파일을 복사하신 다음 HTML 페이지를 Firefox로 열어보세요.
<embed id=sample type="application/sample-plugin" width=600 height=40>
<script>
var obj = document.getElementById( "sample" ) ;
var result = obj.Add( 2 , 1 ) ;
alert( result ) ;
</script>
후후후! Alert 창으로 1 + 2 = 3 의 결과 창이 뜨는 것이 보이시나요? 이제 plug-in 뭐 별거냐 싶으시죠?
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
XPCOM의 시작 XPConnect의 Type Library(IDL)
XPCOM을 본격적으로 시작하기에 앞서 type library, xpidl compiler와 interface에 대해서 알아보도록 합시다.
Type Library
XPCOM은 기본적으로 다른 언어로 작성되어 있는 모듈 사이를 이어주는 기술입니다. XPCOM을 이용하면 C++로 작성이 되어 있다고 해도 JavaScript에서 호출이 가능한 형태를 구현할 수 있습니다. 이러한 기능은 type library가 있기 때문에 가능합니다.
Type library는 외부에서 접근 가능하도록, 일관적인 데이터 형식을 가지고 있습니다. 또한 인터페이스를 통해서 외부와 일관된 방식으로 소통이 가능합니다. 인터페이스를 정의함으로써 멀티 플랫폼에서 다양한 언어로 작성된 모듈간의 통신이 가능하게 되는 것이지요.
C++로 작성된 모듈에 인터페이스가 있다는 것은, 자바스크립트로 된 모듈이 이 인터페이스에 접근하여 데이터를 주고 받을 수 있다는 것을 의미합니다. 바꿔 말하면 자바스크립트에서 C++로 작성된 모듈 내의 함수를 호출할 수 있다는 것이지요.
정확히 말하면 XPConnect가 이러한 역할을 해주는 것 인데요. XPConnect는 XPCOM을 기반으로 만들어진 것으로써, C++객체와 자바스크립트를 연결해주는 계층을 구현하고 있습니다. 서로 다른 객체간의 연결을 Marshal 이라는 단어를 써서 표현하기도 합니다. XPConnect는 자바스크립트와 C++객체간의 Marshal을 담당하는 계층입니다. 최근에는 XPConnect에 Python에 대한 지원 기능이 추가되고 있다고 합니다.
정리하면, 서로 다른 객체간의 연결은 공통된 인터페이스를 노출함으로써 가능해지는데, 인터페이스를 노출하기 위해서는 type library가 필요하다는 것이 주요 포인트가 되겠습니다.
Interface description
특정 개체에 인터페이스를 달기 위해서는 Type library가 필요하다는 것을 알았습니다. 그렇다면 type library는 어떻게 만들어 지는 것일까요? Type library는 Interface Description Language(IDL)을 정의하면 만들어 지게 됩니다.
IDL 이라고 하는 이 언어는 MSCOM에서 사용되는 IDL과 약간 다르고 CORBA에서 말하는 IDL과도 약간씩 다른 형태를 띄고 있습니다. 이러한 이유로 XPCOM은 전용 컴파일러인 XPIDL을 가지고 있습니다. IDL 파일을 정의하고 이를 컴파일 하기 위해서는 XPIDL 컴파일러가 필요한 것이지요.
XPIDL의 가장 큰 역할을 말하자면 바로 type library를 만들어 주는 기능입니다. IDL 언어로 작성한 파일을 XPIDL로 컴파일 하면 *.xpt 확장자를 가지는 파일이 생성됩니다. 이것이 바로 type library 인 것이지요.
IDL 작성의 예
#include "nsISupports.idl"
[scriptable, uuid(f728830e-1dd1-11b2-9598-fb9f414f2465)]
interface nsIScreen : nsISupports
{
void GetRect(out long left, out long top, out long width, out long height);
void GetAvailRect(out long left, out long top, out long width, out long height);
readonly attribute long pixelDepth;
readonly attribute long colorDepth;
};
위는 IDL로 작성한 예 입니다. 대체로 C++ 언어와 비슷한 형태를 띄고 있는 것을 볼 수 있습니다. 위 예에서는 두 개의 메소드와 두 개의 속성이 정의되어 있습니다.
참조
http://www-128.ibm.com/developerworks/webservices/library/co-xpcom2.html
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
XPCOM이란 무엇인가?
XPCOM이 무엇이냐고 물어보신다면…
XPCOM은 C/C++, JavaScript로 작성될 수 있고, C/C++, JavaScript에서 사용될 수 있습니다. 머지않아 Perl과 Python에서도 사용할 수 있을 것으로 보입니다. 필자가 보기에 XPCOM의 가장 매력적인 부분은 C++ 컴파일러가 구동되는 어떠한 환경에서도 작동한다는 점 입니다.
XPCOM은 오픈소스 프로젝트입니다. 흔히 오픈소스이면 안정성에 문제가 있지 않을까 걱정하게 되지만, XPCOM은 현재 Mozilla Firefox 브라우저에서 사용하고 있으며, Adobe Acrobat에서도 사용하고 있는 것을 보면 상당히 안정적일 것이라는 인상을 받을 수 있습니다. 또한 소스가 오픈 되어 있기 때문에 언제든지 구조나 원리를 알고 싶을 때는 소스를 열람해서 해결 할 수 있다는 커다란 장점을 가지고 있습니다. 문서가 지원해줄 수 없는 가장 확실한 지원임이 분명합니다.
Microsoft COM과 XPCOM의 차이점이라면?
코드를 작성하는 관점에서 MSCOM과 XPCOM은 거의 비슷해 보입니다. 둘 다 인터페이스 기반이기 때문에 QueryInterface, AddRef, Release라는 함수를 가지고 있습니다. 형태는 비슷하지만 MSCOM과 XPCOM은 서로 호환되지 않습니다. 또 MSCOM과의 차이점이라고 말할 수 있는 것은 XPCOM은 Remote Object에 접근하는 기술이 제공되지 않는 다는 것이 있습니다. 서로 개념과 코드의 형태는 비슷하지만 바이너리 레벨에서 서로 호환이 되지 않는 다고 생각하면 될 것 같습니다.
XPCOM을 익히기 위해 필요한 지식은?
XPCOM의 코드는 MSCOM의 형태와 거의 비슷하기 때문에 COM 개발 경험이 있으면 많은 도움이 될 수 있습니다. 또 Interface Definition Language(IDL)로 작성하는 방법을 익히고 있어야 합니다.
앞으로 필자는 완성된 XPCOM을 작성하기 위해서 한 단계씩 진행해 보려고 합니다. XPCOM을 이해하면 개발을 하는데 있어서 굉장히 넓은 시야를 가지게 해줄 것 같습니다. 자바스크립트와 C++간을 이어준다는데… 도대체 어떻게 그렇게 되는지 궁금하지 않으세요?
참조
http://www-128.ibm.com/developerworks/webservices/library/co-xpcom.html
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
Fire Fox의 역사(3)
Mozilla Application Suite
모질라는 1998년에 오픈소스가 된 이후에 모질라를 이용한 많은 어플리케이션이 만들어 졌다. 대표적으로 모질라를 기반으로 한 브라우저는 Epiphany, Galeon, K-Meleon등이 있는데 넷츠케이프와 파이어폭스도 마찬가지로 이들과 같은 위치에서 모질라를 기반으로 한 브라우저라고 볼 수 있다.
그림 1 모질라 기반의 또다른 브라우저, Epiphany
모질라 기반의 어플리케이션은 브라우저가 대부분인데 그럼 모질라 소스코드는 단지 브라우저 코드인가? 아니다! 모질라 프로젝트가 가지고 있는 코드에는 렌더링 엔진 Gecko, XML기반 UI엔진 XUL, 네트워크 엔진 Necko등 이 외에도 굉장히 많은 프로젝트의 집합으로 구성되어 있다. 이들은 공통적으로 모든 OS에서 돌아갈 수 있는 호환성을 제공하고 어플리케이션 개발의 관점에서 보면 거진 프레임웍 수준의 기능을 제공한다는 것을 알 수 있다. 이러한 특성 때문에 모질라 프로젝트를 Mozilla Application Suite라고 부른다.
Mozilla Application Suite를 통해서 만들어진 대표적인 제품들이 브라우저가 대부분이라서 브라우저 관련 프로젝트라는 인상을 지우기가 힘들지만 Mozilla Application Suite를 이용해서 만든 문서 편집기도(Composer) 있고 채팅 프로그램(Chatzilla)도 있고 메일/뉴스 클라이언트(ThunderBird)도 있고 정말 많은 종류의 어플리케이션의 모질라를 기반으로 하고 있다.
비스타라는 마이크로소프트의 차기 OS와 Mozilla Application Suite를 비교해 보면 굉장히 많은 부분에서 유사성을 보인다. 플랫폼으로서 모질라의 가능성을 볼 수 있는 부분이다. 뭐 보는 관점에 따라 다를 수 있는 거지만, 어떻게 보면 마이크로소프트가 모질라를 베끼지 않았나 싶을 정도로 구조적으로 많이 유사하다.
Nigel McFarlane이 쓴 글 중 Longhorn and Mozilla: Birds of a Feather이라는 글은 비스타와 모질라를 비교한 글이다. 이 글을 통해서 모질라는 이미 어플리케이션 플랫폼으로서의 역할을 충분히 하고 있다는 걸 알 수 있다.
그림 2 Mozilla = Vista?
Soooo~ What!
비스타와 구조적으로 비슷하다고 뭐 더 좋다는 말은 아니다. 필자가 하고 싶은 얘기는 모질라가 단순히 브라우저를 만들기 위한 프로젝트는 아니라는 말이다. 모질라가 Mozilla Application Suite라고 불릴 수 있는 이유에 대해서 설명하고 있다는 것이 포인트이다.
그림 3 멋있지? 이게 Mozilla Application Suite로 만든 프로그램이래~
위 그림은 SongBird라는 어플리케이션이다. 모질라를 기반으로 한 Application Framework for Development of Cross-Platform Internet Client Applications…(휴우~) ß 이러한 모토를 달고 나온 프로그램이라서 의미가 큰 어플리케이션이라고 할 수 있겠다.
Mozilla, Netscape, Firefox
여기까지 조사하면서 3가지의 키워드를 얻을 수가 있었다. 모질라, 넷츠케이프, 파이어폭스가 그것이다. 파이어폭스와 넷츠케이프와의 관계를 풀기 위해서는 모질라를 알아야 했고, 모질라를 좀 알아보니 이것이 엄청 무시무시한 놈이었다는 것을 알 수 있었다.
그림 4 Mozilla, Netscape, Firefox의 삼각관계
위 그림을 보면 3개의 키워드 간의 관계를 알 수 있다. Mozilla가 Framework을 내놓으면 Firefox와 Netscape가 해당 프레임웍을 가지고 각자의 철학에 맞는 제품을 개발하는 것이다. 필자가 궁금했던 것 중에 하나는 Mozilla 팀에서는 Firefox도 개발하고 있는데 그럼 모질라 브라우저는 출시되지 않느냐는 것이다. 정확히 말하면 Mozilla Foundation에서는 Mozilla Suite라는 이름으로 브라우저를 출시하고 있으며, Firefox는 Mozilla Corporation에서 개발하고 출시하고 있다. Mozilla Corporation 은 영리 단체로서 모질라 재단의 자회사이다. 결국 엄격히 말하면 Mozilla Suite와 Firefox는 서로 다른 회사에서 나오는 제품인 것이다.
그림 5 Mozilla.com의 마케팅 사이트 로고
참고 자료
Mozilla Corporation : http://www.mozilla.or.kr/zine/?p=518
Identity of Firefox
필자는 도대체 Firefox는 뭘까?로 시작한 Identity의 탐구 목적의 조사가 이렇게 진지하게 진행될 줄은 상상도 못했다. 그리고 이렇게 복잡할 줄이야! 초기에 예측한 조사시간은 4시간이었지만 Mozilla 기사를 읽는 시점에서 8시간으로 늘어났고 지금 마지막 문단을 쓰고 있는 시점에서 예측 조사 소요시간은 12시간이다.
멀쩡히 모질라 브라우저를 만들고 있는 모질라 재단이 있는데, 도대체 무슨 이유로 파이어폭스라는 걸 또 만들게 되었을까? 파이어폭스의 첫 이름은 피닉스였다. 피닉스 프로젝트는 모질라 1.0이 나오는 시점 즈음해서 시작하는데, 그 당시 모질라 1.0은 너무 느려터졌다고 한다. 그래서 모질라 브라우저 보다 2배이상 빠르고 가벼운 브라우저를 만들고자 하는 의도에서 피닉스라는 프로젝트가 시작되었다. 피닉스는 당시 1메가 정도되는 크기의 브라우저면서 굉장히 빠르게 동작하는 브라우저였다. 파이어폭스라는 이름은 피닉스->파이어버드->파이어폭스 순으로 변하면서 얻어진 이름이다. 이름이 바뀐 이유는 피닉스는 이미 있는 회사이름과 겹치는 문제가 있었고, 파이어버드는 오픈소스 데이터베이스 프로젝트명과 같았기 때문이다.
그림 6 Firefox Top 10 Product 안에 들다!
맥락을 이해하는 방법으로 파이어폭스의 아이덴디티를 찾아봤는데, 필자는 조사과정 중에 이것저것 읽어본 것도 많고 들은 것도 좀 있고 해서 지금 대충 감이 오는 것 같다. 이 글을 쭈욱 읽었던 사람도 같은 심정이었으면 좋겠지만 워낙 복잡하다 보니 더 헷갈리는 건 아닌지 모르겠다. 작고 간편하게 돌아가는 브라우저가 더 인기를 끄는걸 보니 개발자인 필자는 많은 부분 충격을 받았다. 더 많은 기능에 이것저것 다 되는 제품이 더 좋은 것이 아닌가? 라는 마인드를 가지고 있었는데, 음… 왠지 내 생각은 옳은 게 아닐 수도 있겠다는 생각이 번쩍 든다. 누군가가 “마케팅에는 절대 개발자가 참여해서는 안 된다” 라는 말을 듣고 울컥했던 기억이 나는데, 역시 맞는 말 인가? ㅠ_ㅠ
참고자료
The History of Mozilla Firefox: From Phoenix, to Firebird, to Firefox
http://www.flexbeta.net/main/articles.php?action=show&id=89
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
Fire Fox의 역사(2)
Mozilla Foundation, 회사야? 뭐야?
앞서 Netscape와 Firefox를 돌려본 결과 Mozilla Foundation이라는 공통점을 발견했다. Mozilla Foundation 도대체 무엇을 하는 곳일까? Mozilla Foundation에 관련된 정보를 얻기 위해서 mozillazine 이라는 웹진을 뒤져봤다.
http://www.mozilla.or.kr/zine/
그림 1 Mozilla 웹진
뉴스를 처음부터 뒤지다가 원하는 정보가 들어있는 뉴스를 찾고야 말았다.
넷스케이프는 1998년 독립할 당시 강력한 웹검색 기술을 만들기 위해 공개소스 프로젝트인 모질라 계획을 수립했다. 그 당시는 넷스케이프가 시장 점유율을 놓고 MS와 치열한 경쟁을 하던 시기였다. 넷스케이프는 MS와 경쟁하는데 도움이 되도록 개발자를 끌어들이기 위해 자사 커뮤니케이터 브라우저 소스코드를 공개하는 모험을 걸었다.
모질라 1.0 출시,「브라우저 전쟁 재개되나?」, http://www.mozilla.or.kr/zine/?p=10
모질라는 오픈소스 프로젝트였던 것이었다. MS에 밀리는 와중에 Netscape가 살아남기 위한 해결책으로 나온 전략임을 알 수 있다. 근데 이건 그냥 모질라 프로젝트잖아? Mozilla Foundation을 말하는 것 같지는 않다. 모질라의 어원도 상당히 궁금하지만 일단은 Mozilla Foundation에 대한 정보를 얻기 위해서 계속해서 뉴스를 뒤지기 시작했다.
뉴스를 읽으면서 참… 넷츠케이프도 고생이 많다 싶었다. 계속해서 실패하고 사원들 짤리고 새 제품 내놓으면 계속 욕먹고 그 와중에도 꿋꿋이 운영하는 모습이 참 힘들어 보였다.
모질라랑 넷츠케이프랑 다른거야?
Mozilla에서 새로운 버전을 릴리즈 하면 Netscape도 해당 모질라 버전을 기반으로 한 제품이 나왔다. 모질라에서 마일스톤 18 버전이 나오니까 그 버전을 기반으로 넷츠케이프 6 프리뷰 버전 3가 출시되고, 모질라 1.0이 나오니까 넷츠케이프 7.0이 발표된다.
그림 2 이러면 같은거 아냐?
뉴스를 계속 읽으면서 계속 헷갈리는 내용은 모질라와 넷츠케이프는 무슨 관계냐? 왜 모질라가 제품을 출시하면 넷츠케이프도 따라서 출시가 되는 것일까? 이럴 바에야 모질라 1.0 이라고 하지 말고 애초부터 넷츠케이프7.0이라고 하지 않는 이유가 뭘까?
구분하고는 있지만 크게 차이가 있는 건 아니다.
필자가 정말 알고 싶은 건 Mozilla나 Netscape나 둘 다 제품이름인 것 같은데 정말 크게 차이가 있느냐 하는 것이다. 위에서 첨부한 뉴스를 끝까지 읽다 보면 이런 내용을 볼 수 있다.
AOL 타임워너가 자사 AOL 버전과 다른 소프트웨어에서 모질라 기술을 테스트하면서 과연 3500만 네티즌이 기본 브라우저로 채택한 MS IE를 내몰 수 있을 것인지 관심이 높아지고 있다. 지난 달 출시된 넷스케이프의 일반 소비자용 브라우저인 넷스케이프 7.0 베타버전은 모질라 1.0과 같은 소스코드를 기반으로 제작되었다.
모질라 1.0 출시,「브라우저 전쟁 재개되나?」, http://www.mozilla.or.kr/zine/?p=10
넷스케이프는 모질라의 일반 소비자용 버전이었던 것이다. 모질라는 개발자를 위한 브라우저 혹은 숙달된 사용자를 위한 브라우저라고 한다. 결국 같은 소스코드에서 제작된 크게 차이가 없는 제품이지만 구분을 위한 것이라고 한다. 사람 헷갈리게 뭐냐고-_-)+ 뭐 누가 다르다고 하면 할말 없지만, 쩝… 참기름이나 들기름이나 내가 보기에는 똑같고마~
What a pity, Mozilla Foundation!
Mozilla Foundation은 무엇인가? 이쯤에서 결론을 정리해야 할 것 같다.
About Mozilla Foundation : http://www.mozilla.org/about/
위 사이트에 가면 Mozilla Foundation에 대한 이야기가 나와있다. 사실 필자도 뉴스를 보기 아주 오래 전부터 이 사이트를 가서 About Mozilla Foundation을 읽어봤다. 하지만 아무리 읽어도 너무 추상적인 이야기들이라 궁금증을 해소하기에는 무리가 있었다. 그래도 최소한 어떻게 만들어졌는지는 알아냈으니 수확은 있었다.
필자가 알아본 바로는 Mozilla Foundation은 2003년도에 AOL의 Netscape 부서의 지원으로 만들어진 비영리 재단이다. 이 재단에 이전까지 AOL에서 사용하던 모질라 트레이드마크와 로고를 그대로 인계하였기 때문에 이전부터 있던 모질라 프로젝트와 계속 연계가 되어서 운영이 될 수 있었다.
그림 3 2003년 Mozilla Foundation 설립
Mozilla Foundation이 출범한 이유는 상당히 참담하다. AOL이 그 당시에 MS와 IE 독과점에 관련된 소송을 하고 있었는데, 희한한 결론으로 소송이 끝나버렸다. 7억5000 달러의 배상금을 받고, AOL은 7년간 자신의 회원들에게 IE를 사용하게 하는 라이센스를 받아버린 것이다. 헉… 회사에서 열심히 넷츠케이프 개발하고 있는데 정작 옆에 사람들은 다들 IE를 쓰고 있는 희한한 경우가 된 것이다. 결국 얼마 안 있어 AOL은 넷츠케이프 부서의 구조조정을 이유로 50명을 해고하고 Mozilla를 비영리 단체로 만들어 버린다.
그림 4 AOL 결국 못 견디고 Netscape 개발자 50명 짜르다!
기부금으로 운영되는 비영리 단체라 초기에는 Fund 문제로 힘들어 보였다. 하지만 넷츠케이프 개발자들은 AOL을 나와서 IBM이나 Sun에서 스카우트 되거나 Mozilla 관련 컨설팅 업체를 세우는 등, 비영리 단체가 된 이후에도 핵심 개발자들은 Mozilla 프로젝트를 계속 수행하게 되고 현재의 Firefox를 개발하는 단체로 발전하게 된다.
이번 조사에서 알 수 있는 Fact
1. Netscape는 모질라 소스코드를 기반으로 하고 있다.
2. Mozilla는 오픈소스 프로젝트이다.
3. Mozilla Foundation은 비영리 단체이다.
본 글의 출처는 다음과 같습니다.
작성자 : 이은규
홈페이지 : http://unkyulee.net
작성일 : 2006-02-20
06. 들어는 봤나! Firefox PlugIn (3).doc
Clean PlugIn Sample.zip