RSS구독하기:SUBSCRIBE TO RSS FEED
즐겨찾기추가:ADD FAVORITE
글쓰기:POST
관리자:ADMINISTRATOR
윈도우의 파일을 ftp나 기타 등등으로 utf-8 시스템의 리눅스에 올리면 한글이 다 깨진다.
이것을 해결 할 수 있는 방법은 여러가지이다.

시스템을 euc-kr로 쓰거나 기타등등 방법은 여러가지이다.

이것 때문에 구글링을 해 보았고, kldp 포럼에서 몇가지 방법을 찾아 낼 수 있었다.

1. ftp upload 시 적절한 케릭터 셋을 이용하는 법.
  lftp, filezilla, gftp 패치등이다.
  이중에서 lftp는
  set encoding=utf-8
  set fileencodings=utf-8,euc-kr
  이런식으로 세팅해서 이용 할 수 있다.

2. file system 마운트시 codepage 와 iocharset 을 명시
  ex) -o codepage=949,iocharset=utf8
  fstab에서 지정 해주면 편하게 이용이 가능 하다.

3. 자동 변경 쉘 스크립트.
   쉘스크립트로 그냥 변경 해버린다.
   만들까 했으나... KLDP에서 다른 분들의 글을 읽던 중 이미 만들어 놓은것을 발견 했다.
   recypace + musiphil 두분이 만들었다. 한분이 만들고 다른분이 버그 수정.
   내가 만든것이 아니므로, 원 저작자를 밝혔다.(또한 원자작자가 삭제를 원하면 지울것이다.)

  ----------------------------------------------------------------------
  $ cat char_convert.sh
  #!/bin/sh

  # mv2utf gets at least one filename

  if [ $# -eq 0 ]

   then
       echo "Usage : $0 filename1 [filename2] .....";
       exit 0
   fi
   # Rename euc-kr filename to utf-8 filename

   for filename

   do

       utfname=`echo "$filename" | iconv -f euc-kr -t utf-8`;

       err=$?;

       if [ $err -eq 0 ]

       then

               if [ "$filename" = "$utfname" ]

               then

   # if the filename is english file name

                       echo "$filename is not euc-kr (may be in english)"
               else
   # if the filename is euc-kr

                       echo "rename $filename : $utfname";
                       mv "$filename" "$utfname"
               fi
       else

   # if the filename is not euc-kr
               echo "$filename is not euc-kr"
       fi
   done
  ----------------------------------------------------------------------

4. iconv와 convmv
convmv --notest -f euckr -t utf-8 -r DIRECTORY

5. vi  에서
  set encoding=utf-8
  set fileencodings=utf-8,euc-kr
  
상황에 따라 적절한 방법을 선택해서 이용 하면 된다.
최고의 방법이란 없다. 언제나 사황에 따른 최선의 방법이 있을 뿐이다.
2007/10/25 13:14 2007/10/25 13:14
이 글에는 트랙백을 보낼 수 없습니다
Linux
=====
 
 .bash_profile 또는 .bashrc에서
export PATH=$JAVA_HOME/bin을 지정
 
#설치 위치 : /usr/local/j2sdk1.4.2_02/ (/usr/local/jdk 로 심볼릭 링크)
#export JAVA_HOME=/usr/local/jdk
#export CLASSPATH=$JAVA_HOME/classes12.zip:/root/j2sdk1.4.2_02/lib
#export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/lib
 
 
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
 . ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin
BASH_ENV=$HOME/.bashrc
USERNAME="root"
export USERNAME BASH_ENV PATH
export PATH=$PATH:$usr/java/j2re1.4.2_06/bin/
 
 
 

 

 
FreeBSD
========
 
/etc/profile 또는 $HOME/.bash_profile $HOME/.bashrc, .cshrc
(env 명령으로 쉘을 확인한 후 어떤 쉘을 쓰는지 확인)
 
# tcsh 쉘의 설정(.cshrc)
----------------------
# alias
alias l  ls -alF
alias ns netstat -nr
alias pp ps -aux
 
# path
set path = (/sbin /bin /user/sbin /usr/bin /usr/local/sbin /usr/local/bin /usr/X11R6/bin)
set path = ($path $HOME/bin)
 
# 환경변수
setenv LANG ko_KR.EUC
 
# 쉘 프롬프트
set prompt = "$user %c2> "
set prompt = "$user $cwd> "
set prompt = "`hostname -s`> "
 
# jdk
setenv JDK /usr/local/jdk1.1.8
set path = ($path $JDK/bin)
setenv CLASSPATH $JDK/lib/classes.zip:.
setenv LD_LIBRARY_PATH $JDK/lib/i386
 
# stty
stty erase ^H

 
# Bourne Shell의 설정(.profile)
-----------------------------
# alias
alias l='ls -alF'
 
# 로케일
LANG="ko_KR.EUC"; export LANG
 
#path
PATH=/sbin:/bin:/usr/sbin:/usr/bin:$HOME/bin; export PATH
 

 
Windows
========

도스창을 열고 set path=...... 명령을 넣으면 그 도스창을 띄운 프로세스에만 적용
 
autoexec.bat에 아래 내용 추가후 Rebooting
예) set path=%path%;c:JDK설치위치bin
설명 ) path라는 변수를 셋팅하는데 "기존의 path 변수에 있는 설정값"을 가져오고(%path%) , 추가로(;) "c:j2sebin"라는 폴더를
패스를 잡아서 어디서든지 그 안에 있는 명령어들을 쓸수있게 한다
 
환경변수를 아래와 같이 수정
예) '시작' > '설정' > '제어판' > '시스템' 으로 가서... '고급'tab > '환경변수' 버튼 클릭
     > '시스템 변수'에 "path" 더블 클릭 >  ;c:JDK설치위치bin 내용 추가
2007/10/25 00:37 2007/10/25 00:37
이 글에는 트랙백을 보낼 수 없습니다

1. 클래스의 호출 순서

제목 : 자바에 대한 개념을 흔들어 놓는 소스다...

db책은 시간이 없어서 그냥 와우북에서 보고 영진껄루 사서 보았다....전체적인 개념잡기는 쉬운데...책 두께에 비해 깊은 내용이 없더군....하여간 엽기적인 소스를 만난 덕에 또 이렇게 글을 띠운다....

class A {
  static
  {
  System.out.println("A클래스 스태틱 로딩");
 
  }
  A() {
     System.out.println("A()");
  }
}

class ClassInitTest {
  static int monthNum=12;
  static int monthDays[];
  static
  {
     monthDays = new int[monthNum];
     monthDays[ 0] = 31; monthDays[ 1] = 28;
     monthDays[ 2] = 31; monthDays[ 3] = 30;
     monthDays[ 4] = 31; monthDays[ 5] = 30;
     monthDays[ 6] = 31; monthDays[ 7] = 31;
     monthDays[ 8] = 30; monthDays[ 9] = 31;
     monthDays[10] = 30; monthDays[11] = 31;
     
     System.out.println("static int monthDays[];...");
  }
   
  A a;
  {
     a = new A();
     System.out.println("A a;");
  }
  ClassInitTest() {
     this(0);
     System.out.println("ClassInitTest()");
  }
  ClassInitTest(int x) {
     System.out.println("ClassInitTest(int x)");
  }

  public static void main(String args[]) {
     new ClassInitTest();    //내생각엔 여기서 생성자를 호출해서 저기 아래로 이동해야 될 것 같은데 a객체를 생성하면서  a클래스로 가버리네...이해할 수 없다...5분만 투자하거라...늘그막이 고생하는 친구를 위해...(엉아라는 표현을 이젠 자제한다)

     System.out.println("new ClassInitTest();");
  }  
}

실행한 결과다....
static int monthDays[];...
A클래스 스태틱 로딩
A()
A a;
ClassInitTest(int x)
ClassInitTest()
new ClassInitTest();


답변: 자바 버츄얼머신 스펙을 참조...
 
덕분에 썬 사이트에 가서 자바 버츄얼머신 스펙을 꼼꼼히 읽어보았다.
클래스를 초기화 할때 즉 생성하면 생성자가 제일 먼저
불리우는 것이 아니었다.
간단하게 말을 하겠다.

그래야 잊지 않고 나도 기억하기 쉬우니까.
비록 정확한 대답은 아니라고 해도 전혀 틀린 것도 아니니까.

이건 만은 기억하자.

1. static을 초기화한다.
2. field를 초기화한다.
3. 생성자를 호출한다.

그러니까 소스에서는 ClassInitTest를 생성하면
1. 이 클래스내의 static을 초기화한다.
출력: static int monthDays[];...

2. 다음은 필드를 초기화한다.
필드 A a; 가 있으므로 클래스 A를 생성할 것이다.
이 클래스에도 static이 있기 때문에 이를 초기화한다.
출력: A클래스 스태틱 로딩

3. 그리고, A() 생성자를 호출한다.
출력:A()

4. 다음행 실행
출력:A a

5. 다음은 ClassInitTest의 생성자를 호출.
생성자에서 this(0)이라는 인자 있는 생성자를 호출하므로
출력:ClassInitTest(int x)

6. 다음행 샐행
출력:ClassInitTest()

7. 다시 다음행 실행
출력:new ClassInitTest()

아휴~ 힘들다. 1000자 넘기지 않으려고 말을 짧게 썻다.
이해해라.


 

2. 텍스트 필드에 저장할 수 있는 문자열의 최대 길이

먼저 질문부터 하겠습니다.

Form의 method방식을 get으로 지정했을 경우에 전달할 수 있는 최대 문자열의 길이는 ?

HTTP 데이터 전송 방식에는 get과 post 방식이 있습니다. get방식은 URL에 "이름=값"의 형식으로 데이터를 전송합니다. 쉽게 설명하자면 우리가 많이 사용하고 있는 인터넷 익스플로러를 잘 관찰하시면 다음과 같은 주소를 보시게 될 겁니다.

folderselect=639096&rand=9935556036482

이름과 값을 위와 같은 형식으로 서버에 전달하는 것입니다. 이렇게 get 방식으로 전달할 수 있는 스트링의 길이는 도대체 얼마나 될까 알아보았습니다.

알파벳과 한글 모두 2047문자까지 들어가더군요. 하지만 엄밀히 따지면 앞에 주소도 있고 기다 경로를 제외하면 조금 작아지겠지요. 그런데 실제 데이터를 get 방식으로 전달해 보면 그 보다 훨씬 미치지 못하는 길이만이 넘아갔습니다. 한글로 대략 340문자까지만 전송이 되었습니다[필자가 해보니깐 정말 변수명을 어떻게 하느냐에 따라 틀리고 사파리는 한글이 안된다;;;; 머 어쩌라구]. (+- 오차는 10문자 정도) 이를 post 방식으로 다시 전송하였더니 2000자 이상이 거뜬이 전송되었습니다.

이로써 get 방식과 post 방식의 또 다른 차이점을 알았습니다. 님들도 많은 양의 데이터를 전송할 때는 post 방식을 사용하세요. 무심코 get방식을 사용한다면, 왜 데이터가 제대로 전송이 되지 않는지 그 이유를 찾는데 한참을 보내야 할 겁니다.


 

3. 각종 데이터 타입의 최대값

  • MS Access의 MEMO 데이터 형 : Up to 65,535 characters
  • 유닉스의 IPC중 메시지큐 : 메시지의 최개크기 (4096), 큐의 최대 크기(16384)
  • 자바 자료형의 최소/최대값

유형

크기

최소값

최대값

byte

8bit

-128

127

short

16bit

-32768

32767

int

32bit

-2147483648(20억)

2147483647(20억)

long

64bit

-9223372036854775808

9223372036854775807


4. 네트워크 바이트 순서

바이트 오더(byte order)에는 두 가지가 있다. little endian과 big endian이다.

  • little endian : 작은 수를 끝에 놓는다.
  • big endian : 큰 수를 끝에 놓는다.

little endian은 56이란 수를 56으로 표현하고, big endian은 56을 65로 나타낼 수 있다는 말이다.

네트워크 상의 byte order은 big endian이다. 가령 little endian 머신에서 little endian머신으로 데이터를 전송한다면 문제가 없다 거꾸로 big endian에서 big endian으로도 마찬가지다. 문제는 다른 방식의 두 머신이 통신을 할 때이다.

일단 네트워크로 데이터를 전송할 때는 네트워크 바이트 순서로 바꿔준 다음 데이터를 수신한 쪽에서 자신의 머신에 맞게 순서를 다시 조정하면 된다. 소켓에선 이런 일을 도와주는 함수가 있으며 htonl, htons, ntohl, ntohs와 같은 것들이 바로 이런 일들을 한다.

참고로 SUN, IBM들은 big endian형식이고 Intel은 little 엔디안 형식이라고 한다. 왜 이렇게 두 가지 방법이 있어서 번거롭게 하는지 모르겠다. 한가지밖에 없다면 아무 신경 쓰지 않고 통신을 하면 될텐데...


5. JAVA 기초 문법 중에서

  • 같은 파일 안에 public class는 단 하나만 존재할 수 있으며 클래스는 파일이름과 같아야 한다.
  • float 형의 유효 데이터는 소수점이 있는 숫자로 끝에 F 또는 f가 붙은 숫자이어야 한다.
    float f = 1.3 -> ( X )
    float f = 1.3f -> ( O )
    소수점만 있을 경우에는 double형으로 인식된다.
  • 같은 클래스내에서 메소드를 overloading할 때
    리턴타입은 상관없이 메소드의 인자만 다르면 된다.

class Test
{
     boolean method( int arg ) { return true; }

     boolean method( long arg ) { return true; }

     boolean method( int arg1, int arg2 ) { return true; }

     void method( ) { }     //신기하지만 자바에서는 이것도 가능하다.

     // 컴파일 에러 발생( 메소드 이름과 인자가 같으면 안된다. )
     void method( int arg ) { return true; }    

}

  • 헷갈리는 overloading과 overriding 구분하기

"overloading : 짐을 너무 많이 싣다. "
( 같은 클래스에 이름이 같은 메소드를 여러번 정의할 수 있다. )

class Test
{
     void method( int arg ) {}     // load

     void method( int arg1, int arg2 ) {}     // load ( overload )
}

 

"overriding : 짓밟다. 무시하다. "
( 부모로부터 상속받은 메소드를 재정의할 수 있다. )

class SuperClass
{
     void method( int arg ) { System.out.println( "SuperClass : " + arg ) }
}

class SubClass extends SuperClass
{
     void method( int arg ) { System.out.println( "SubClass : " + arg ) }
}


2007/10/24 12:06 2007/10/24 12:06
이 글에는 트랙백을 보낼 수 없습니다

I. 자바 웹스타트 소개
-------------------------------

  자바 웹스타트는 2001년 초에 소개된 기술로 한번 클릭으로 자바 애플리케이션을 쉽게
수행 시킬 수 있는 환경으로 자바가 추가하던 사상 즉 "언제 어디서나 같은 코드로서
쉽게 접근하고 강력한 기능을 발휘하는 언어" 라는 강점을 유감 없이 발휘할 수 있는 
기술이다.

  자바 웹스타트는 기존의 웹 환경의 한계점을 뛰어넘어 네트웍으로 자유롭게 풍부하고
강력한 응용프로그램을 실행 시킬 수 있으며, 버젼 및 배포 관리를 자동으로 수행하는 
JNLP(Java Network Lanunching Protocol)을 기반으로 하여 관리함으로서 기존의 클라이언트
윈도우즈 프로그램의 문제점을 극복하고 새로운 파라다임을 제시한다.

자바 웹스타트의 장점을 요약하면 다음과 같다.

1. 바탕화면이나 웹화면의 아이큰을 단 한번 클릭함으로서 자동 다운로드 및 캐쉬를 사용한
   응용 프로그램이 구동되어 빠르고 쉽게 자바 응용 프로그램을 실행할 수 있다.

2. Linux, Mac, Windows 등 다양한 플랫폼에서 동일한 User Interface로 실행됨으로 
   OS로 부터 독립적인 환경을 제공한다.

3. 웹 환경의 단순한 HTML 및 JavaScript로 구현되던 User Interface를 보다 강력한 자바
  UI 기술인 AWT/Swing을 이용하여 구현할 수 있다.

4. 응용프로그램이 자동적으로 캐쉬되고 업데이트 됨으로 첫번째 구동 이후에는 매우 
  빠른 속도록 응용프로그램이 시작된다.

5. Java 2의 보안 모델 Signed Application 및 "sand box" 모델이 적용됨으로
  사용자들은 보다 안전한 환경에서 강력한 UI를 사용할 수 있다.


자바 웹스타트를 좀더 잘 이해 하기 위하여는 Client/Server 아키텍쳐 맥락에서 Client를
크게 Thin Client (가벼운 클라이언트) 와 Rich Client(강력한 기능의 클라이언트)로 나누어 보고
이 둘의 장단점을 비교해보면 서로의 성격을 좀더 확실히 이해할 수 있다.

Thin Client란 Web Browser와 같이 이미 사용자 환경에 Client가 설치되어 있고, 서버로부터
가벼운 HTML과 같은 화면 정보를 받아 화면을 매번 그려주는 체계를 말한다.

- 가벼운 클라이언트 환경 (web browser) 장점

    . Browser 만 있으면 언제 어디서나 가볍게 화면을 접속하여 볼 수 있다.
    . 화면 자체를 간단히 HTML 로 구성할 수 있다.
    . Hyper link 를 이용하여 화면 Navigation을 할 수 있다.
    . SessionLess 처리를 이용하여 짧은 트렌젝션을 많이 처리하는데 적합하다.
    . 문서 등을 보여주는 (Browsing) 하는데 효과적이다.

- 가벼운 클라이언트 환경 (web browser) 단점

    . HTML의 한계 때문에 복잡한  UI 또는 기능성 있는 입출력 구조를 처리하기 어렵다.
    . JavaScript 나 Dynamic HTML은 Language 자체가 유동성이 많고
      환경 오류의 가능성이 높다.
    . JavaScript 또는 Dynamic HTML은 완전한 Language 또는 객체 지향적 Language가
      아니라 유지 보수성 및 생산성이 떨어진다.
    . 전송된 자료가 쉽게 Browser를 통하여 노출되기 때문에 보안성이 떨어진다.
    . HTML의 한계 때문에 다량의 자료 처리가 쉽지 않다.
    . 옵션 및 환경이 Browser에 의존적이기 때문에 사용자 환경마다 처리될 때도 있고
      처리가 않 될 수도 있다.
    . 트렌젝션 마다 Image + HTML + Data 가 함께 내려 옮으로써 처리 속도가 저하된다.


Rich Client(강력한 기능의 클라이언트) 란 기존의 C/S 시스템 또는 전용 Browser 나 
Windows 프로그램과 같이 특정 업무에 맞도록 화면을 개발하고, 메뉴, 아이콘, 테이블, 트리,
드래그드랍등 다양하고 강력한 사용자 화면과 인터페이스를 구성하는 것이다. 

Browser와 같이 이미지 디자인 같은 작업이 별도로 필요 없는 대신에 Excel 처럼 필드 위주의
강력한 기능을 구현할 수 있는 것이 특징이다.


- Rich Client의 장점

    . 강력하고 기능성 있는 GUI 를 제공한다. (Spread Sheet, DeskTop, Tree, Drag and Drop 등등)
    . Browser에 의존하지 않고 개인 PC의 화면에서 바로 실행 가능하다.
    . Remote 환경 뿐만 아니라 Local 환경, DB, Network 처리, File 처리 등이 자유롭다.
    . 서버와 데이타 만 주고 받기 때문에 속도가 빠르다.
    . 다량의 데이타를 local 과 서버 작업으로 분산 처리가 가능하기 때문에 다량 처리에 적합하다.
    . Browser 의존적이 아니기 때문에 PC 자체의 환경 문제가 적다.
    . 객체 지향적 모델로 GUI를 만들기 때문에 유지 보수성이 뛰어 나다.
    . 전송되는 자료가 쉽게 노출되지 않으므로 보안성이 우수하다.

- Rich 클라이언트의 단점
   
    . 프로그램 설치가 필요하여 초심자가 설치할 시에 오류가능성이 있다.
    . 설치된 프로그램이 다른 요인으로 손상될 수 있다.
    . 반드시 모듈이 설치된 PC에서만 작동한다.
    . 프로그램 변경 또는 Version Up이 발생하면 다시 배포해야 한다. (Version 문제 가능성)
    . 대부분 MicroSoft Windows 환경이기 때문에 Windows 버젼 및 환경 때문에 
      오류 발생 가능성이 있다.


Java Web Start는 Thin Client와 Rich Client의 장점을 동시에 수용하고 각각의 단점을 서로
보안할 수 있도록 통합시킨 기술이다.

  Java Web Start 기술을 채용하면 Thin Client 처럼 어디서나 쉽게 접근하여 가볍게 사용할 수
있을 뿐만 아니라 Rich Client와 같은 강력한 기능을 구현할 수 있어 웹 기술과 C/S 기술을
동시에 채용하여 비용 대비 성능이 가장 우수하다.

 - Java Web Start 는 Thin Client 의 장점과 Rich Client의 장점을 통합한 기술이다.

      . web 환경과 같이 언제 어디에서든 손쉽게 사용할 수 있다. (아이콘 클릭으로 시작)
      . plug-in 이 자동으로 설치되며 일단 설치되면 다시 설치할 필요 없다. (웹으로 시작 가능)
      . Application 모듈이 local 에 cache 되어 자동으로 버젼을 체크하여,
        download 시간이 대폭 축소된다.
      . C/S 환경이 갖고있는  강력하고 다양한 GUI 기술이 Swing을 통하여 구현되며, 
        독립 데스크 탑 환경으로 갈 수 있다.
      . Web Version 이나 Client Server 버전을 따로 개발할 필요가 없다. Web Start 가
        두개의 환경을 단일 코드로 지원한다.
      . JavaScript, DHTML 등에 의존하지 않고, 독립환경의 단일 기술로 이루어짐으로서
        오류 가능성이 적다.
      . 결국 손쉽게 접근할 수 있는 Thin Client 의 장점과 강력한 GUI 및 작업 기능의 
        Rich Client 의 장점을 동시에 구현하는 것이다.


Java Web Start 환경적 특징을 살펴보면 다음과 같다.

- Java Web Start 환경은 새로운 기술이라기 보다는 Java 기술의 최종 완성된 형태이다.

- Web Version 이나 Client Server 버전을 따로 개발할 필요가 없다.

- JVM Version 1.4는 자동으로 Install 된다.

- XML, Security, Messaging 등 최신 기술 Component 가 같이 포함되어 있다. (미래가 있다.)

- Web Start 는 자동으로 Caching 을 하여 빠르다.

- Web Browser 나 MS Windows 환경에 독립적이다.

- 따로 Desktop 환경을 구성할 수 있다.


II. 웹스타트 실행하기
-----------------------

  자바 웹스타트가 어떤것인가를 가장 직관적으로 알 수 있는 방법은 실제로
웹스타트로된 시스템을 실행해보는 것이다.  웹스타트는 앞에서도 설명했듯이
언제 어느 곳에서나 쉽게 실행해 볼 수 있다는 장점을 가지고 있다.  따라서
여러분들이 지금 일반적인 네트웍 환경과 PC 환경을 가지고 있다면 직접 
웹스타트 시스템을 실행해 보는 것이 자바 웹스타트를 가장 빨리 이해하는
지름길 이다.

  본 강좌에서는 자바 웹스타트로 된 시스템을 실행해보기 위하여 JComtech에서
개발한 "JDMS"를 예제로 하겠다.  JDMS는 통신 판매(Direct Marketing) 회사들을
위한 판매관리 ASP 시스템으로, 현재 몇개 회사가 JDMS를 공동으로 사용하고 있다.
상용 시스템임으로 테스트 사용시 무리한 트렌젝션을 발생시키지 않기를 바란다.

  JDMS에 접근하려면 우선 웹브라우져에서 http://jdms.jcomtech.co.kr로 가서
홈페이지를 방문한다.  홈페이지에는 JDMS에 관련된 소개 및 사용법, 사용자 게시판
으로 구성되어 있다. 이러한 내용들은 업무관련 내용임으로 간단히 읽고 참고하기
바란다.

  자바 웹스타트로 JDMS를 실행하려면 홈페이지 좌측 상단에서 "Application"이라는
메뉴를 찾아 클릭한다.  이 메뉴를 클릭하면 우선 사용자 브라우져에 JRE 1.4 버젼이
설치되어 있는가를 검사한다.  만일 설치가 되있지 않다면 자동으로 Plug-in을 설치
하도록 되어 있다.  만일 JRE 1.4를 설치하겠냐고 묻는 화면이 나오면 "예"를 눌러
설치하도록 한다. 설치하는데는 다소 시간이 걸린다. 하지면 처음 실행시 한번만
실행하면 된다.

  자바 웹스타트는 자바 1.2 버젼부터 소개되었지만  1.4 버젼에서는 설치 및 운용이 
자동으로 되기 때문에 더욱편리하다.  따라서 본 강좌는 자바 1.4 버젼을 전제로
진행 하겠다.

  JRE 1.4가 모두 설치되었다면 브라우져 화면에 자바 로고와 "JDMS Web start [시작]"
라는 메뉴가 나온다.  이를 클릭하면 자바 웹스타트 로고가 나오면서 프로그램이
설치되어 있는 웹서버로부터 자바 클레스 화일들을 다운로드 받는 화면들이 진행된다.
처음 실행할 때는 웹서버로부터 JDMS를 실행하기위하여 필요한 모든 화일들을 다운로드
받겠지만 다음번 부터는 버젼이 변경된 부분만 다운로드 받기 때문에 속도가 매우
빨라진다.

  자바 프로그램 다운로드가 성공적으로 이루어지면 즉시 프로그램이 실행되면서 JDMS
로그인 화면이 나오게 된다.  로그인 아이디와 암호는 jcom/jcom으로 한다.  아이디와
암호가 맞으면 스윙으로 구성되 단독 윈도우가 실행되며, 드디어 JDMS 시스템 화면이
나오게 된다.  화면에 있는 메뉴들을 한번씩 실행해보며 시스템이 어떻게 실행되는지
경험해보기 바란다. 구체적인 JDMS은 업무 구성이나 사용법은 본 강좌에서 생략하도록 
한다.  

  JDMS를 한번 둘러보았다면 화면을 종료하고 브라우져도 닫기 바란다.  그러한 후에
여러분 PC에서 윈도우 바탕화면에서 Java Web Start 아이콘을 찾아보기 바란다.
정상적인 경우라면 JRE 1.4를 설치하면서 바탕화면에 "Java Web Start" 아이콘을 만든다.
이 아이콘은 웹스타트 설치를 관리할 수 있는 "Java Web Start 응용프로그램 관리자"를
실행하는 아이콘이다.

  Java Web Start 응용프로그램 관리자에는 PC에서 실행된 적이 있는 응용프로그램과
SUN에서 제공하는 몇가지 예제 프로그램을 실행할 수 있는 아이콘이 있어 웹브라우져를
통하지 않고도 직접 자바 프로그램을 실행할 수 있다.  웹브라우져에서 실행한 적이 
있는 JDMS로 아이콘으로 직접 실행할 수 있을 것이다.  Java Web Start 응용프로그램
관리자를 이용하지 않고 직접 JDMS를 바탕화면에 등록하여 사용할 수도 있는데 이는
프로그램 실행시 등록 여부를 물어서 아이콘 등록을 하게된다.

  이렇게 JRE 1.4 Plug-in을 설치하고 JDMS를 실행하였다면, 여러분은 자바 응용프로그램
시스템인 JDMS를 웹페이지에서도 실행할 수 있고, 직접 바탕화면에서도 실행할 수 있게
된다.  그러고 처음 실행할 때문 프로그램 다운로드 시간이 걸리겠지만 두번째 부터는
프로그램이 빠르게 실행된다는 것을 느낄 수 있을 것이다.  프로그램 Caching 및 버젼
관리는 웝스타트 환경이 자동으로 해주기 때문이다.

  JDMS를 다시 웹에서 실행해보고 또 다시 바탕화면에서 번갈아 실행해봄으로서 사용자들이
어떠한 환경에서 사용하게되고 어떠한 장접이 있는지 직관적으로 알게될것이다.

  개발자 입장에서 이러한 환경을 잘 분석해보면 응용 프로그램은 자바가 제공하는 AWT 및
Swing으로 만든 윈도우 환경이라는 것을 알게될 것이다. 결국 웹스타트 환경에서 응용
프로그램을 잘 개발하려면 자바 순수 프로그램 및 자바 UI 프로그램(AWT/Swing)기술이 
기본적으로 있어야 하면 웹스타트의 서버 환경은 웹서버 설치후 자바 클레스를 묶은 jar
화일및 jnlp 프로토콜 mine 타입을 지정하면 된다. 이러한 서버 설정 방법은 이 후에 
다루도록 한다.


III. 간단한 프로그램 만들기 
------------------------------
자바 웹스타트 환경을 만들려면 우선 그 환경에서 실행될 응용 프로그램이 필요하다. 
비교적 간단한 프로그램으로 자바 웹스타트의 다양한 측면을 테스트 하기 위하여 자바 Swing으로 
간단한 편집기를 만들어 보겠다. 간단한 편집기의 클래스 명은 SimpleEditor로서 다음과 같은 
화면으로 구성되어 있다.
  
[소스보기 - 파일첨부 참조] 소스를 살펴보면 우선 buildGUI() 메소드에서 
메뉴와 화면을 만들며 그리고 이벤트 처리를 위한 리슨너 등을 추가하고 있다. 
주요 기능 및 메소드를 살펴보면 다음과 같다. 
- buildGUI() 화면의 필드와 메뉴를 만들며, 이벤트 처리가 가능하도록 각각의 컴퍼넌트에 
ActionListener 및 DocumentListener를 추가하고 있다. 
- checkUpdate() 테스트 필드에 변경이 있으면 이를 화일에 저장할지를 묻고, 
사용자가 "예"를 선택하면 이를 화일에 저장한다. 
그리고 "취소" 버튼을 누르면 취소를 true 값으로 리턴한다. 
- newFile() 화면을 clear하고 상태를 초기 상태로 바꾸어 새로운 화일을 편집할 수 있도록 한다. 
- open() FileChooser를 이용하여 기존의 테스트 화일을 열고 이를 테스트 필드에 보여주는 
기능을 한다.
- close() 편집하던 화일을 닫는 기능을 수행한다. 
- save() 편집하던 화일을 저장하는 기능을 수행한다. 만일 화일명이 없으면 FileChooser를 
이용하여 화일명을 지정하도록 한다.
- exit() 편집하던 화일이 있으면 저장하고 편집기 프로그램을 종료한다. 
 위의 메소드들은 각각의 메뉴 선택시에 actionPerformed 메소드에서 실행되면 
 
현재 화일 문서가 변경되었는가의 여부는 DocumentListener를 사용하여 이벤트 처리한다. 
이 프로그램을 실행하려면 SimpleEditor.class 화일을 JRE가 설치된 PC에 복사하고 
단지 "Java -classpath . SimpleEditor" 라는 명령어를 치면 실행되어 아무런 문제 없이
 Local Computing 환경에서 사용할 수 있다. 하지만 다음 문제는 이 프로그램을 여러사람이
 자바 웹스타트를 이용하여 네트웍 환경으로 여러사람이 사용할 수 있게하는 것이다. 
이러한 환경은 응용 프로그램에 추가적인 고려 사항이 필요하며 또 자동 배포를 수행할 수 있는
 웹 서버가 필요한데 자세한 내용은 본 SimpleEditor 프로그램을 예제로 다음 장에 계속하여
 설명하겠다. 

 

 

IV. 웹스타트 응용프로그램
-------------------------


기본적으로 웹스타트 응용프로그램은 SimpleEditor에서 보았듯이 Java2 개발 방법을 사용하며 public static void mina(String[] arg)의 메인 함수에 의하여 실행된다.  하지만 이러한 응용프로그램을 웹스타트와 같이 자동 다운로드 환경에서 사용하려면 보안 및 공유 환경때문에 다음과 같이 몇가지 고려해야 할 사항이 있다.

- 자바 class화일들은 다운로드가 용이할 수 있도록 모두 JAR 화일로 묶어야 한다.

- 그림 화일이나 추가적인 화일 및 자원을 사용한다면 이 모든 것을 JAR로 묶어야 한다.

- SandBox 보안 모델을 사용함으로 다음과 같이 Local 시스템 자원을 사용하지 못한다.

  . local disk 및 native libarary를 사용하지 못한다.
  . Network 자원은 자신이 download된 서버로부터 뿐이 사용하지 못한다.
  . Security Manager을 설치할 수 없으며, 시스테 프로퍼티를 제한적으로 사용한다.

- 이러한 보안상 제약점을 넘으려면 signed JAR 화일을 사용해야 한다.



그럼 SimpleEditor.class를 이러한 사항을 고려하여 배포 준비를 해보도록한다.

우선 SimpleEditor.class를 다음과 같은 JAR 커멘드를 이용하여 .jar 화일로 묶는다.

-----------------------------------
prompt> jar cvf editor.jar *.class
-----------------------------------

이렇게 하면 배포할 수 있는 editor.jar 화일이 생성된다. 만일 클레스 화일 또는 이미지,
리소스 등 화일이 여러개라면 jar 커멘드를 이용하여 같은 화일에 묶도록한다.

SimpleEditor 프로그램은 화일을 읽거나 저장하기 위하여 local 디스크를 접근한다.
하지만 일반 jar 화일로는 SandBox 보안 모델 때문에 local 디스크를 접근할 수 없다.
따라서 local disk에 접근할 수 있는 권한을 부여하기 위하여 다음과 같이 jar 화일에 keytool 및 jarsigner를 이용하여 인증서 sign을 할 필요가 있다. (keytool 및 jarsigner는 JDK1.2 이상 버젼에 포함되어있는 툴이다.)


1. 다음과 같이 keytool 커멘드를 이용하여 teststore 화일에 test 라는 별명으로 새로운 키를 만든다.

----------------------------------------------------------
prompt> keytool -genkey -keystore teststore -alias test

keystore 암호를 입력하십시오:  test12345
이름과 성을 입력하십시오.
  [Unknown]:  editor
조직 단위 이름을 입력하십시오.
  [Unknown]:  editor
조직 이름을 입력하십시오.
  [Unknown]:  editor
구/군/시 이름을 입력하십시오?
  [Unknown]:  editor
시/도 이름을 입력하십시오.
  [Unknown]:  editor
이 조직의 두 자리 국가 코드를 입력하십시오.
  [Unknown]:  editor
CN=editor, OU=editor, O=editor, L=editor, ST=editor, C=editor이(가) 맞습니까?
  [아니오]:  y

<test>에 대한 키 암호를 입력하십시오
        (keystore 암호와 같은 경우 RETURN을 누르십시오):  test
키 암호가 너무 짧습니다. 여섯 글자 이상이어야 합니다.
<test>에 대한 키 암호를 입력하십시오
        (keystore 암호와 같은 경우 RETURN을 누르십시오):  test12345
--------------------------------------------------------------------


2. 생성된 keystore 화일과 그 화일에 생성된 키를 이용하여 자체 signed 인증서를 생성한다

----------------------------------------------------------
prompt> keytool -selfcert -alias test -keystore teststore

keystore 암호를 입력하십시오: test12345
----------------------------------------------------------


3. keystore 화일 teststore에 저장된 키 정보를 보려면 다음과 같이 명령을 주고 암호를 입력한다.

------------------------------------------
prompt> keytool -list -keystore teststore
------------------------------------------


4. 최종적으로 만들어진 인증서를 이용하여 다음과 같이 jarsigner를 이용하여 jar 화일에 sign한다.
   암호를 물으면 teststore 생성시 사용된 암호를 입력한다.

------------------------------------------------------
prompt> jarsigner -keystore teststore editor.jar test
------------------------------------------------------


이렇게서 만들어진 signed-jar 화일인 editor.jar는 최종적으로 자바웹스타트를 통해서 배포할 수 있는 화일이다.  웹스타트를 통하여 배포되는 화일이 local 자원이나 network 자원을 이용하려면 모두 이렇게 signed-jar를 만들어야 한다.

이렇게 JAR화일을 준비하면 응용프로그램은 배포 준비가 완료된 것이다.  하지만 이렇게 응용 프로그램만 준비한다고 해서 모든 과정이 끝난 것은 아니다.  

우선 이 프로그램이 어떤 것이고 어떻게 배포될지를 기술하는 XML 문법으로 이루어진 jnlp 화일이 필요하고, jar와 jnlp을 적절이 설정된 웹서버에 올리는 과정이 필요한다.

이러한 내용은 다음 장에서 다루도록 한다.




V. JNLP 화일 및 웹서버 설정 
-----------------------------

JNLP(Java Network Launching Protocol) 화일은 자바 웹스타트에서 자동 배포될 모듈에대한
정보 및 어떻게 배포될 것인 가에 대한 정보를 기술해주는 화일로 웹서버에서는 우선 이
화일부터 호출 되고 이 화일에 기술된 대로 JAR 화일을 다운로드하여 프로그램이 실행되도록
되어 있다.

JNLP 화일은 기본적으로 XML 문법 체계를 가지고 있으며, 모든 테그에 대한 정보를 자세히 
보려면 SUN site에서 JNLP Spec v1.0을 참고하도록 한다.  여기서는 JNLP에대한 기본적인 사항을
예제 위주로 살펴보겠다.

다음은 SimpleEditor.jar를 배포할 수 있도록 만들어진 simple.jnlp 화일의 내용이다.


================================= 
file : simple.jnlp
================================= 

<?xml version="1.0" encoding="utf-8" ?>
<jnlp spec="1.0+" codebase="http://www.javanuri.com/jaws/apps" href="simple.jnlp">

  <information>
    <title>Simple Editor Demo</title>
    <vendor>JavaNuri</vendor>
    <description>Simple Editor Demo Program</description>
    <description kind="short"> Simple Editor</description>
    <icon href="images/editor.jpg" />
    <offline-allowed />
  </information>
  
  <security>
    <all-permissions />
  </security>

  <resources>
    <j2se version="1.4" />
    <jar href="editor.jar" />
  </resources>

  <application-desc main-class="SimpleEditor" />

</jnlp>


본 simple.jnlp 예제에서 첫라인은 본 문서가 XML이고 encoding이 utf8로 되어 있음을 
기술하는 것이고 다음부터 나오는 JNLP 주요 태그 내용은 다음과 같다. 

- jnlp tag : <jnlp spec="1.0+" codebase="http://www.javanuri.com/jaws/apps" href="simple.jnlp">
  본 내용이 jnlp에 관련된 내용임을 기술하며 문서의 끝에 </jnlp>로 닫힌다.

  . spec 속성은 jnlp 1.0 버젼 이상임을 정의한다.
  . codebase 속성은 본 문서의 모든 화일의 기본 URL을 정의한다.
  . href 는 본문서 화일 이름을 정의한다.

- information tag : <information> ... </information>
  각종 하위 태그로 본 프로그램에 관한 제목, 제작사, 설명, 아이콘 등을 기술하고 있으며, 
  이는 배포 및 실행될 때 사용자가 화면을 통해 볼 수 있는 아이콘 및 설명으로 사용된다.

- security tag : <security> ... </security>
  이 태그는 프로그램에 실행될때 주는 local 자원에 대한 권한을 기술한다.

- resource tag : <resource>... </resource>
  이 태그는 하위 태그를 이용하여 j2se 버젼 및 사용되는 jar 화일들을 기술하여
  실행환경에 대한 정보를 담고 있다.

- application-desc tag :   <application-desc main-class="SimpleEditor" />
  이 태그는 플로그램 실행시 필요한 사항을 기술하며 특히 main-class 는 반드시
  지정되어야할 속성으로 자바 프로그램의 main 메소드가 있는 클래스명을 써준다.



여러분이 여기까지해서 JAR 및 JNLP 화일을 만들었다면 이를 적절하게 배포해줄
웹서버 환경이 필요하다.  자바 웹스타트는 기본적으로 HTTP 프로토콜을 사용하며 클래스가
실려있는 JAR화일 및 이 내용을 기술하고 있는 JNLP화일은 결국 웹서버의 서비스 디렉토리에
복사되어야 한다.


웹서버는 다양한 종류가 있으며, 기본적인 환경설정은 해당 웹서버 제품의 메뉴얼에 
따라야할 것이다.  

본 강좌에서는 가장 많이 쓰이고 있는 Apache 웹서버를 예제로하여 환경을 설정할 것이다. 
다른 웹서버도 크게 차이는 없으리라 생각된다. 

따라서 www.apache.org 사이트를 방문하여 windows, linux, solaris 등 여러분의 환경에 맞는 
apache웹서버를 다운로드하여 메뉴얼이 지시하는데로 설치하도록 한다. 
본 강좌에서는 웹서버 설치에 관해서 다루지는 않겠다.


웹서버를 설치한 후에 가장 먼저 해주어야 할일은 jnlp 확장자 화일에 관한 mime type의
설정이다.  

mime type의 설정은 웹서버로 하여금 jnlp 확정자를 갖은 화일은 어떠한 컨테츠로 취급할 
것인지를 알려준다. 
아파치 웹서버의 경우는 설정 디렉토리에서 mime.types 화일에 다음과 같이 한 라인만 
추가해 주면 된다.

   application/x-java-jnlp-file JNLP


추가한 후에는 반드시 웹서버를 다시 시작해야 한다.

이렇게 웹서버 설정이 끝났다면 지금까지 만들었던 jar 화일과 jnlp 화일을 웹서버의 
document root 에 적절히 복사해놓는 것이다. 이것은 마치 웹서버에 html 화일을 복사해놓는
것과 마찬가지이다. jar 및 jnlp 화일과 함께 복사하여야 할 것은 simple.jnlp에서 
지정한 아이콘 화일인 images/editor.gif이다. (첨부 File 이용)

아래에 첨부된 file을 다운로드하여 images 디렉토리에 복사하기 바란다.

simple.jnlp 화일은 경우는 반드시 jnlp 테스의 codebase 속성에 기술되어 있는 주소를
반드시 여러분의 웹서버 설치 주소로 변경해야한다. 그렇지 않으면 다운로드시 오류가 발생할 것이다.

여기까지 하면 SimpleEditor를 자바 웹스타트를 이용하여 실행할 준비가 모두 끝난 것이다.
실제 실행 및 실행시 유의 사항등은 다음 장에서 다루도록 한다.




VI. 예제프로그램 웹스타트로 실행하기 
---------------------------------------

 
웹스타트 응용프로그램 개발 과정을 다시한번 정리해보면 다음과 같다.

1. 실행될 응용프로그램을 AWT/Swing으로 개발한다.
2. 개발된 응용프로그램을 배포할 수 있도록 jar로 묶는다.
3. Local 자원을 사용할 수 있도록 jar에 sign을 하여 signed-jar를 만든다.
4. 배포 실행될 응용프로그램에 대한 내용을 jnlp 화일을 만들어 xml로 기술한다.
5. web 서버에 JNLP mime type을 설정한다.
6. web 서버의 적절한 디렉토리에 singed-jar, jnlp 화일 및 이미지 화일을 복사한다.

여기까지의 사항이 완료되었다면 일단 웹브라우져에서 웹스타트 응용프로그램을
실행할 수 있는 웹서버 환경이 갖추어진 것이다.

 실제 예제로 만들어진 editor.jar 와 simple.jnlp를 브라우져에서 실행하려면
웹서버를 실행하고 단순히 다음과 같이 simple.jnlp를 호출하는 URL을 치면 된다.

 http://www.javanuri.com/jaws/apps/simple.jnlp

  브라우져에 jre1.4가 정상적으로 설치되었으면 먼저 "Web Start Logo"화면이 뜨고
보안을 위해 jar에 sign된 내용이 나타나면서 승인 여부를 묻는 화면이 나온다.
여기에서 "예"를 선택하면 즉시 editor 프로그램이 실행될 것이다.
그리고 두번째로 웹에서 실행할 때는 바탕화면에 아이콘 생성 여부를 물을 것이다.
여기에서 "예"를 선택하면 바탕화면에 아이콘이 생성되면서 다음 부터는 웹브라우져를
통하지 않고 바탕에 있는 아이콘을 단순히 클릭함으로써 응용프로그램이 시작될 것이다.

  이제까지 만들어왔던 SimpleEditor 예제에 대한 관련 jar, jnlp, jpg 화일들은
example.zip에 묶어 첨부되어 있다. 이를 다운로드 받아 압축을 풀고 웹서버에 설치하고
실행시켜보기 바란다. 단 실행시 jnlp화일에 있는 codeBase 속성은 여러분의 웹서버 주소에
맞도록 수정해야 한다.

  서버 설정은 이제까지 설정한데로 하면 보통은 이상없이 환경이 설정된다. 하지만
클라이언트 즉 브라우져 환경은 사용자에 따라 웹스타트가 설정되어 있을 수도 있고, 아닐수
도 있다. 따라서 이러한 브라우져 환경을 통제하려면 html 및 javascript를 이용할 필요가
있다.
    
  사용자 브라우져를 체크해 웹스타트를 실행할 수 있는 방법은 여러가지가 있을 수 있지만
대체로 다음 세가지 방법이 있다.
    
1. 자바스크립트를 이용해 웹스타트 설치여부를 체크한 다음 설치돼지 않았을 경우
   설치하라는 메시지 링크를 주는 방법
   
2. 웹스타트 버젼1.2의 자동 설치 기능을 이용하는 방법
    
3. 간단한 JRE1.4를 이용한 Applet을 이용하는 방법
    

  첫번째 방법인 자바웹스타트 설치여부를 체크하는 방법은 우선 웹브라우져 종류를 파악해야 하는데,
이방법은 "Java Web Start Developers's Guide"에서 사용한 자바스크립트인 xbDetectBrowser()를 사용하여
할 수 있다. xbDetectBroser.js는 본 글에 첨부 하였다.
    
  다음 예제는 "Java Web Start Developers's Guide"에 나오는 예제를 응용하여 이해하기 쉽게 변경한
것으로서 스크립트를 실행시키면 Java Web Start 가 설치되었을 경우는 해당 프로그램을 실행할 수 있는
URL 링크가 나오고, 설치되어 있지 않을 경우는 Java Web Start를 설치하라는 메시지가 나오는 예제이다.

Simple1.html
=====================================================================================================
<HTML>
<HEAD><TITLE>Java Web Start Page</title>
<!----------------------------------------------------------------
  xbDetectBrowser() 함수를 이용하여 브라우져 환경에 관한 정보 생성
------------------------------------------------------------------>
<SCRIPT LANGUAGE="JavaScript" SRC="xbDetectBrowser.js"></SCRIPT>

<!----------------------------------------------------------------
  Web Start 설치 여부, 브라우져가 IE 인지 여부 설정 
------------------------------------------------------------------>
<SCRIPT LANGUAGE="JavaScript"> 

    var javawsInstalled = 0; 
    isIE = "false"; 

    if (navigator.mimeTypes && navigator.mimeTypes.length) { 
       x = navigator.mimeTypes['application/x-java-jnlp-file']; 
       if (x) javawsInstalled = 1; 
    } else { 
       isIE = "true"; 
    } 

</SCRIPT>

<!----------------------------------------------------------------
  브라우져가 IE일 경우 Web Start 설치 여부 결정하는 VBScript
------------------------------------------------------------------>

<SCRIPT LANGUAGE="VBScript"> 
    on error resume next 
    If isIE = "true" Then 
      If Not(IsObject(CreateObject("JavaWebStart.IsInstalled"))) Then 
            javawsInstalled = 0 
      Else 
            javawsInstalled = 1 
      End If 
    End If 
</SCRIPT>

<!----------------------------------------------------------------
 insertLink 함수 정의 :
   웹스타트가 설치되었을 경우는 응용 프로그램 실행 링크를 보여주고
   그렇지 않을 경우는 설치 필요 메시지 보여줌
  (설치 필요 메시지를 수정하여 download URL 링크로 만들 수 있음)
------------------------------------------------------------------>

<SCRIPT LANGUAGE="JavaScript"> 
    function insertLink(url, name) { 
    if (javawsInstalled || navigator.family == 'gecko') { 
          document.write("<a href=" + url + ">"  + name + "</a>"); 
       } else { 
          document.write("Java Web Start 설치가 필요합니다."); 
       } 
    } 
</SCRIPT>

<!----------------------------------------------------------------
  웹스타트 응용프로그램 실행 링크를 insertLink 함수를 통하여 만듬
------------------------------------------------------------------>

<SCRIPT LANGUAGE="Javascript"> 
    insertLink("http://www.javanuri.com/jaws/apps/simple.jnlp", "웹스타트 응용프로그램 시작"); 
</SCRIPT>

<BODY>    
</BODY>
</HTML>
    
=====================================================================================================
    
 두번째 방법인 자동 설치 기능을 이용하는 방법은 썬의 자바 사이트에서 제공하는 Web Start자동 설치
기능을 수행하는 ActiveX를 호출하는 것이다. Java Web Start만을 자동 설치하는 OBJECT 테그 및 URL은

<OBJECT CODEBASE="http://java.sun.com/products/javawebstart/autodl/jinstall_javaws-1_2-windows-i586.cab" 
CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>
이며

자바 1.4 버전을 자동 설치할 수 있는 OBJECT 테그 및 URL은

<OBJECT CODEBASE="http://java.sun.com/products/plugin/autodl/jinstall-1_4_1-windows-i586.cab" 
CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>

이다.

  이왕 자동 설치 기능을 사용하려면 web start만 설치하는 것 보다는 응용프로그램 환경이 더 좋은
자바 1.4버전을 설치하는 것이 좋다.

  다음 예제는 위의 예제와 같이 기존에 web start설치 여부를 체크하고 없으면 자동설치 되도록 자바 
스크립트 및 HTML을 작성 예를 보여주고 있다. ( Developer's Guide 참조 )

Simple2.html
=====================================================================================================

<!----------------------------------------------------------------
  브라우져가 Netscape일때 web start 설치 여부를 설정한다.
------------------------------------------------------------------>

<SCRIPT LANGUAGE="JavaScript">
var javawsInstalled = 0;
var javaws12Installed = 0;

isIE = "false";

if (navigator.mimeTypes && navigator.mimeTypes.length) {
  x = navigator.mimeTypes['application/x-java-jnlp-file'];
  if (x) {
     javawsInstalled = 1;
     javaws12Installed=1;
  }
} else { 
  isIE = "true";
}
</SCRIPT>

<!----------------------------------------------------------------
  브라우져가 IE일때 web start 설치 여부를 설정한다.
------------------------------------------------------------------>

<SCRIPT LANGUAGE="VBScript">
on error resume next
If isIE = "true" Then
  If Not(IsObject(CreateObject("JavaWebStart.isInstalled"))) Then
     javawsInstalled = 0
  Else
     javawsInstalled = 1
  End If
  If Not(IsObject(CreateObject("JavaWebStart.isInstalled.2"))) Then
     javaws12Installed = 0
  Else
     javaws12Installed = 1
  End If
End If
</SCRIPT>

<!----------------------------------------------------------------
  xbDetectBrowser.js를 이용하여 navigator.family를 설정한다.
------------------------------------------------------------------>
<SCRIPT LANGUAGE="JavaScript"
SRC="xbDetectBrowser.js">
</SCRIPT>

<!----------------------------------------------------------------
  gecko 방식이거나 이미 web start가 설치된 경우는 
  http://www.yyy.zzz/app.jnlp를 실행할 수있는 link를 보여준다.

  그렇지 않다면
  썬에서 제공하는 PluginBrowserCheck를 실행시킬수 있는 link를 제공한다.
  PluginBrowserCheck는 브라우져가 IE일 경우 "pass"파라미터에 있는
  자동 설치 URL인 http://www.yyy.zzz/download.html로 가고 아닐경우는
  플랫폼에 따라 설치 안내문이 나오도록 "fail"파라미터에 있는
  http://java.sun.com/cgi-bin/javawebstart-platform.sh로 간다.

------------------------------------------------------------------>

<SCRIPT LANGUAGE="JavaScript">
if (javawsInstalled ||  navigator.family == 'gecko') {
    document.write("<a href=http://www.yyy.zzz/app.jnlp>프로그램 실행</a>");
} else {

  document.write("<a href=http://dlres.java.sun.com/PluginBrowserCheck?");
  document.write("pass=http://www.yyy.zzz/download.html&");
  document.write("fail=http://java.sun.com/cgi-bin/javawebstart-platform.sh>");
  document.write("설치 및 응용프로그램 실행</a>");

}
</SCRIPT>

=====================================================================================================

download.html
=====================================================================================================
<!----------------------------------------------------------------
웹스타트 자동 설치 ActiveX프로그램을 호출하고 설치후에는 
http://www.yyy.zzz/app.jnlp로 링크되도록 한다.
만일 이미 설치돼었다면 곧바로 웹스타트가 실행된다.
------------------------------------------------------------------>

<HTML>
<BODY>
<OBJECT CODEBASE="http://java.sun.com/products/javawebstart/autodl/jinstall_javaws-1_2-windows-i586.cab" 
CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>
<PARAM NAME="app" VALUE="http://www.yyy.zzz/app.jnlp">
<PARAM NAME="back" VALUE="true">
<!-- Alternate HTML for browsers which cannot instantiate the object -->
<A HREF="http://java.sun.com/cgi-bin/javawebstart-platform.sh?">
Download Java Web Start</A>
</OBJECT>
</BODY>
</HTML>
=====================================================================================================

이 방법은 결국 썬에서 제공하는 설치 ActiveX를 이용하는 것이고 그렇기 때문에 IE에서만 작동한다.
그리고 설치가 않될 경우는 플랫폼에 따라 설치 메뉴얼이 있는 페이지로 이동하게 된다. 이 방법을
잘 파악하려면 다음과 같이 썬에서 제공하는 각종 URL을 잘 이해하고 있어야 한다.

- http://dlres.java.sun.com/PluginBrowserCheck 
  pass와 fail파라미터가 있어 브라우져가 IE일 경우 pass에서 준 URL로 링크되고 아닐 경우는
  fail에서 준 URL로 링크된다.  파라미터가 없을 경우 플랫폼에 따라 JRE를 설치할 수 있는
  메뉴얼 페이지로 간다.

- http://java.sun.com/cgi-bin/javawebstart-platform.sh
  플렛폼에 따라 자바 웹스타트를 설치할 수 있는 메뉴얼 페이지로 이동한다.

- <OBJECT CODEBASE="http://java.sun.com/products/javawebstart/autodl/jinstall_javaws-1_2-windows-i586.cab" 
  CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>
  자바 웹스타트를 자동 다운로드 및 설치하는 ActiveX를 구동한다. "app"파라미터는 설치후 자동 링크되는
  URL 값이다.


- <OBJECT CODEBASE="http://java.sun.com/products/plugin/autodl/jinstall-1_4_1-windows-i586.cab" 
  CLASSID="clsid:5852F5ED-8BF4-11D4-A245-0080C6F74284" HEIGHT=0 WIDTH=0>
  JRE1.4를 자동 다운로드 및 설치하는 ActiveX를 구동한다. 웹스타트는 자바 1.4버젼에 포함되어 있다.


  자동 설치 및 실행의 세번째 방법은 간단하게 시작 버튼을 가진 Applet을 만들고 Applet실행을 
JRE 1.4로 할 수 있도록 요구하는 것이다.  이렇게 하면 Applet이 실행되면서 JRE 설치 버젼을
체크해 자동으로 JRE1.4가 설치되며 자바웹스타트도 자동 설치된다.
 
  Applet을 조금더 응용하면 Applet에 실행버튼을 만들어 웹스타트 응용 프로그램을 바로 실행할 수 있도록
하는 것이다. 다음은 그러한 버튼을을 갖은 예제 Applet 및 실행 HTML이다.

StartApplet.java
=====================================================================================
import java.awt.*;
import java.awt.event.*;
import java.net.*;

/**
 * StartApplet
 *
 */
 
public class StartApplet extends java.applet.Applet implements ActionListener {

    // start button
    Button btStart        = new Button("응용프로그램 시작");
    
    // url
    String url;
    
    //--------------------------------
    // init
    //--------------------------------
    public void init() {
        
        btStart.addActionListener(this);
        add(btStart);
        
        url = getParameter("url");
        
    }
    
    //----------------------------------------
    // action performed
    //----------------------------------------
    public void actionPerformed(ActionEvent e) {
    
        try {
            getAppletContext().showDocument(new URL(url));
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        
    }
    
}

==============================================================================

StartApplet.html
==============================================================================

<html>
<body>

<OBJECT    name="StartApplet"  classid="clsid:8AD9C840-044E-11D1-B3E9-00805F499D93"  WIDTH=150 HEIGHT=30
  codebase="http://java.sun.com/products/plugin/autodl/jinstall-1_4_0-win.cab#Version=1,4,0,0">
  <PARAM NAME=CODE VALUE="StartApplet.class">
  <PARAM NAME="type" VALUE="application/x-java-applet;version=1.4">
  <PARAM NAME="url" VALUE="<a href=http://www.yyy.zzz/app.jnlp>">

  <COMMENT>
   <EMBED invokeURLs=false type="application/x-java-applet;jpi-version=1.4" CODE="StartApplet.class" WIDTH=150 HEIGHT=30
    pluginspage="http://java.sun.com/products/plugin/index.html#download">
    scriptable=false
     <NOEMBED invokeURLs=false></NOEMBED invokeURLs=false>
   </EMBED invokeURLs=false>
  </COMMENT>
</OBJECT>    

</body>
</html>

================================================================================

  StartApplet은 url 파라미터를 받아들이고 시작 버튼을 누르면 브라우져의 링크를 url 파라미터가
지정한데로 가도록 되어 있다. 따라서 실행하고 싶은 JNLP 파일을 url 파라미터에 주면 웹스타트가
자동 실행된다.

  StartApplet.html은 StartApplet 클레스를 자바 플러그인 형태로 실행 시키며, 자바 플러그인이
설치되어있지 않으면 자동 설치되도록 되어 있다. 위의 예제에서 <a href=http://www.yyy.zzz/app.jnlp> 부분만
원하는 URL로 바꾸어주면 자동 설치 및 웹스타트 시작페이지로 사용할 수 있을 것이다.

  이 방법은 간단한 Applet이 필요하기는 하지만 가장 간단하고 쉬운 방법이 아닌가 생각한다.



VII. Jar 자원 활용 및 JNLP API 이용
-----------------------------------


  자바웹스타트 응용 시스템을 만들다 보면 때로는 클레스와 함께 jar 화일에 묶여있는
이미지 화일이나 프로퍼티 화일, 자료 화일 등이 필요할 경우가 있다.  이러한 경우에는
java.lang.ClassLoader로 부터 해당 자원을 얻을 수 있다. 

다음은 jar화일에 묶여있는 이미지 화일로부터 Icon 객체를 생성해내는 예제이다.

ClassLoader loader = this.getClass().getClassLoader();
Icon myIcon = new ImageIcon(loader.getResource("imgs/myImg.gif"));

이 밖에도 java.lang.ClassLoader의 getResourceAsStream(String name) 메소드를 이용하면
다양한 자원을 InputStream을 통하여 얻을 수 있다.

  
  자바웹스타트 환경에서는 Java 2 SE API에서 제공하지 않는 추가적인 기능을 하는 API를
제공한다. 이것은 JNLP API라고 한다. JNLP API를 이용하여 개발할 경우는 jnlp.jar가
필요한데 이러한 파일은 JNLP Developer's Pack에 포함 되어 있다. 다음은 Developer's Pack을
다운로드 할 수 있는 URL이다.

http://java.sun.com/products/javawebstart/download-jnlp.html

  JNLP API가 추가적으로 제공하는 클레스는 javax.jnlp package로 묶여 있으며
BasicService, ClipboardService, DownloadService, FileOpenService, FileSaveService, 
PrintService, PersistenceService 등이 있는데 이들은 ServiceManager 클레스를 통하여
사용할 수 있다. 각각의 기능은 다음과 같다.

- javax.jnlp.BasicService

BasicService는 웹스타트의 환경적인 면이나 브라우져를 통제하기 위한 API를 제공하는데
자바 애플릿의 경우 AppletContext와 비슷한 역할을 한다. 다음 예제는 웹스타트 환경에서
웹브라우져로하여금 특정 URL로 가도록 하는 것이다.

import javax.jnlp.*;
.....

BasicService bs = (BasicService)ServiceManager.lookup("javax.jnlp.BasicService");
bs.showDocument(new URL("http://www.javanuri.com"));



- javax.jnlp.ClipboardService

ClipboardService는 시스템에서 사용하는 클립보드에서 복사 객체를 가져오거나 클립보드로
복사하는 서비스를 제공한다. 자바웹스타트는 이 기능을 사용할 때 보안을 위하여 경고창을
보여준다. 다음은 간단한 스트링을 클립보드에 복사하는 예제이다.

import javax.jnlp.*;
.............

ClipboardService cs = (ClipboardService)ServiceManager.lookup("javax.jnlp.ClipboardService");
StringSelection ss = new StringSelection("Hello Web Start");
cs.setContents(ss);


- javax.jnlp.DownloadService

DownloadService는 자신의 자원을 Cache에 저장, 삭제등 Cache를 통제할 수 있는 서비스 API를
제공하는 클레스이다. 다음은 myapp.jar를 Cache에서 확인하고 있으면 삭제한후 다시 Cache에
저장하는 예제이다.

import javax.jnlp.*;
...........

DownloadServicd ds = (DownloadService)ServiceManager.lookup("javax.jnlp.DownloadService");
URL url = new URL("http://www.javanuri.com/jws/myapp.jar");
boolean isCached = ds.isResourceCached(url, "1.0");
if(isCached) {
  ds.removeResource(url, "1.0");
}

DownloadServiceListener dsl = ds.getDefaultProgressWindow();
ds.loadResource(url, "1.0", dsl);


- javax.jnlp.FileOpenService

FileOpenService는 권한이 제약된 환경에서도 이를 사용자에게 알리고 화일을 열 수 있는
다이얼로그 윈도우를 열어주는 서비스이다.  다음 예제는 FileOpenService를 이용하여 화일을
여는 예제이다.

import javax.jnlp.*;
..............

FileOpenService fo = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fc = fo.openFileDialog(null, null);

- javax.jnlp.FileSaveService


FileSaveService는 권한이 제약된 환경에서도 local disk에 화일을 저장할 수 있는
기능을 제공하는 서비스 클레스이다. 이는 FileOpenService의 경우와 반대인 기능을 제공하는
클레스이다.  다음은 FileOpenService를 이용하여 화일을 연 후에 FileSaveService를
이용하여 화일을 저장하는 예제이다.

import javax.jnlp.*;
.....................

FileOpenService fo = (FileOpenService)ServiceManager.lookup("javax.jnlp.FileOpenService");
FileContents fc = fo.openFileDialog(null, null);
FileContents newfc = fss.saveFileDialog(null, null, fc.getInputStream(), "newfile.txt");

- javax.jnlp.PrintService

PrintService는 권한이 제약된 웹스타트 환경에서도 프린트를 가능하게 해주는 API 를 갖고 있는
서비스 클레스이다.  이 API를 이용하여 프린트를 요청하면 사용자에게 허가할 것인가를 묻는
다이얼로그가 나타난다. 다음은 PrintService를 이용한 프린트 요청 예제이다.

import javax.jnlp.*;
.....................

PrintService ps = (PrintService)ServiceManager.lookup("javax.jnlp.PrintService");

// default page format
PageFormat pf = ps.getDefaultPage();

// customizing page format
PageFormat npf = ps.showPageFormatDialog(pf);

// print
ps.print(new Doc());


// printable class
class Doc implements Printable {

 ....
 public int print(Graphics g, PageFormat fm, int idx) {
  ....
 }

}

}


- javax.jnlp.PersistenceService

PersistenceService는 브라우져의 쿠키와 마찬가지고 사용자의 클라이언트에 간단한 자료를 
저장할 때 사용된다. 저장되는 형태는 url형태로 자장된다.
다음은 간단한 url을 저장하고 내용을 읽어들이는 예제이다.


import javax.jnlp.*;
.....................

PersistenceService ps = (PersistenceService)ServiceManager.lookup("javax.jnlp.PersistenceService");

String addr = "www.javanuri.com/some.txt";
java.net.URL = new URL(addr);

// create
ps.create(url, 1024);
FileContents fc = ps.get(url);
OutputStream os = fc.getOutputStream(false);
os.write(...);

// read
fc = ps.get(url);
InputStream in = fc.getInputStream();

in.read(...);

.......


- javax.jnlp.FileContents

FileContents 는 FileOpenService, FileSaveService, PersistenceService와 같은 서비스에서 
input과 output을 처리할 수 있도록 만들어진 클레스이다. 일반적인 File 클레스와 비슷하게
생각하면 된다.  보안과 자료 저장 형태 등이 일반 File 클레스와는 다르다.



출처 : http://www.javanuri.co.kr, 유용근

2007/10/24 11:22 2007/10/24 11:22
이 글에는 트랙백을 보낼 수 없습니다
자바스크립트(JavaScript)에서는 다음의 함수들로, HTML 페이지 주소를 인코딩/디코딩합니다.

encodeURI() / decodeURI()
최소한의 문자만 인코딩합니다.
; / ? : @ & = + $ , - _ . ! ~ * ' ( ) #
이런 문자는 인코딩하지 않습니다.
http:// ... 등은 그대로 나옵니다.


encodeURIComponent() / decodeURIComponent()
알파벳과 숫자 Alphanumeric Characters 외의, 대부분의 문자를 모두 인코딩합니다.
http:// ... 가 http%3A%2F%2F 로 됩니다.



escape() / unescape()
예전부터 있던 오래된 함수입니다. encodeURI() 와 encodeURIComponent() 의 중간 정도의 범위로 문자를 인코딩합니다.


encodeURI, encodeURIComponent, escape 함수 사용 예제


<html>

<body>

<script type="text/javascript">
  var s;

  s = encodeURI('http://www.google.co.kr/소 설.html');
  document.write('<p>' + s + '<p>');
  // 출력 결과: http://www.google.co.kr/%EC%86%8C%20%EC%84%A4.html


  s = encodeURIComponent('http://www.google.co.kr/소 설.html');
  document.write('<p>' + s + '<p>');
  // 출력 결과: http%3A%2F%2Fwww.google.co.kr%2F%EC%86%8C%20%EC%84%A4.html


  s = escape('http://www.google.co.kr/소 설.html');
  document.write('<p>' + s + '<p>');
  // 출력 결과: http%3A//www.google.co.kr/%uC18C%20%uC124.html
</script>

</body>
</html>




어떤 함수든 "공백 문자" 즉 스페이스는 %20 으로 치환합니다. 그러나 주소의 공백은 없어야 합니다.


2007/10/23 15:27 2007/10/23 15:27
이 글에는 트랙백을 보낼 수 없습니다
Linux  2007/10/18 13:49
이것때문에 다시 리눅스 밀지 마시길

zlib 설치
Download : http://www.gzip.org/zlib/

[root:/usr2/src] tar xvfz zlib-1.1.4.tar.gz
[root:/usr2/src] mv  zlib-1.1.4 /usr/local/zlib
[root:/usr2/src] cd /usr/local/zlib
[root:/usr/local/zlib] ./configure -s // libz.so 관련모듈생성
[root:/usr/local/zlib] make
[root:/usr/local/zlib] ./configure // libz.a 생성
[root:/usr/local/zlib] make test
[root:/usr/local/zlib] make install
[root:/usr/local/zlib] ls -al libz.so*
lrwxrwxrwx    1 root     root           13 Jul  5 08:01 libz.so -> libz.so.1.1.4
lrwxrwxrwx    1 root     root           13 Jul  5 08:01 libz.so.1 -> libz.so.1.1.4
-rwxr-xr-x    1 root     root        60880 Jul  5 08:01 libz.so.1.1.4
[root:/usr/local/zlib] cp libz.so* /usr/local/lib
[root:/usr/local/zlib] cd /usr/local/lib
[root:/usr/local/lib] ls
libz.a  libz.so  libz.so.1  libz.so.1.1.4
[root:/usr/local/lib] rm -rf libz.so
[root:/usr/local/lib] rm -rf libz.so.1
[root:/usr/local/lib] ln -s libz.so.1.1.4 libz.so
[root:/usr/local/lib] ln -s libz.so.1.1.4 libz.so.1
[root:/usr/local/lib] vi /etc/ld.so.conf
/usr/local/lib // 구문 추가 ( rpm 설치시 lib 는 /usr/lib 이기에 )
[root:/usr/local/lib] ldconfig
2007/10/18 13:49 2007/10/18 13:49
이 글에는 트랙백을 보낼 수 없습니다

다음글은 하이텔  MFC소모임의 시삽이신 권정혁님의 글을 정혁님의 허락하에
다음과 같이 기재합니다. 허락해주신 정혁님께 감사드립니다.
****************************************************************************
이 글은 Mike Blaszczak 의 책 "Professional MFC" 의 Appendix D 에 들어있는
내용을 번역한 글입니다. 제 허락없이는 다른 어떤게시판에도 옮기실수 없습니
다. 물론 글의 원 소유자는 Mike 입니다.

                                            MFC&T 사용자 모임 시삽 권정혁

============================================================================
MFC 헤더와 라이브러리 설명 (The Foundation Classes Headers and Libraries) #1

1. Header Files

아래 테이블은 모든 MFC 헤더 파일들과 사용 목적, 그리고 어떤 파일전에 어떤
파일들이 Include 될수 있는지에 대해 나와있습니다. 거의 모든 헤더들이 다른
헤더들에 의해 Include 된다는 것을 주의하십시오.
당신의 코드에서 직접 Include 하는것은 약 4-5개 정도입니다.

----------------------------------------------------------------------------
헤더 (Header)설명
----------------------------------------------------------------------------

Afx.h       Windows 를 사용(?)하지 않는 MFC 프로그램을 작성할때 Include
            하는 Main Header 파일입니다. 콘솔용 MFC 응용프로그램을 작성할때
            이 헤더만 있으면 됩니다. 이것은 Windows 외에서 사용될수 있는
            콜렉션 클래스와 Application Framework 클래스들를 포함한 모든
            클래스를 선언합니다. 콘솔용 프로그램을 작성한다면 다른 MFC 헤더
            들을 Include 하기전에 이 파일을 Include 하여야 됩니다.
            만약 윈도우용 프로그램을 작성한다면, 이 파일대신 Afxwin.h 를
            사용하십시오.

Afxcmn.h    이 파일은 윈도우의 공용 컨트롤(Common Control)에 대한 Definition
            들을 가지고 있습니다. Afxwin.h 를 Include하지 않았다면 이 파일을
            사용할수 없습니다.
           
Afxcoll.h   이 파일은 MFC 컨테이너 클래스들에 대한 Declaration(선언)을
            가지고 있습니다. 이 파일은 Afx.h 의 내용에 의존합니다.
            Afxcoll.h 는 CObject-style 과 type-safe 콜렉션에 대한
            Definition 을 포함하고 있습니다. 템플릿 콜렉션 클래스들은
            Afxtempl.h 안에 있습니다.

Afxctl.h    이 파일은 ActiveX 컨트롤을 작성하는데 필요한 클래스와 선언들을
            가지고 있습니다. 컨트롤 작성 프로젝트에서는 이 파일을 Afx.h 나
            Afxwin.h 대신에 Include 해야 합니다.

Afxcview.h  이 파일은 Tree 와 List 공용 컨트롤을 기초로 하는 CView 파생
            클래스들에 대한 Definition 들을 가지고 있습니다. 이 파일은 좀더
            작고 효율적인 링킹을 위해 Afxwin.h 와 Afxcmn.h 파일로부터
            분리되었으며, 이것은 좀더 작고 빠른 실행화일을 생성할수 있도록
            해줍니다. 만약 CTreeView 나 CListView를 사용한다면 Afxwin.h 파일
            다음에 이것을 Include 하여야 합니다.
           
Afxdao.h    이 파일은 DAO 에 기반한 데이터 억세스를 지원하기 위한 클래스들
            (CDaoDatabase 와 CDaoRecordset 같은)을 담고있습니다. 이 헤더가
            필요하다면 Afxwin.h 와 Afxdisp.h 다음에 Include 하여야 합니다.
           
Afxdb.h     이 파일은 ODBC 에 기반한 데이타 베이스 프로그램을 개발하기 위한
            클래스들(CDatabase 와 CRecordset 같은)을 담고 있습니다.
            이 파일은 또한  "RFX_*" 와 같은 [레코드 필드 교환 명령]들 같은
            데이터베이스 프로그램 개발에 필요한 전역 함수들을 정의하고
            있습니다. 데이터베이스 클래스를 사용하려면 먼저 Afx.h 와
            Afxwin.h 를 Include 한다음 이 파일을 Include 하여야 합니다.

Afxdb_.h    이 파일은 ODBC 와 DAO 에 공통적인 definition 들과 클래스들을
            포함하고 있습니다. 이 파일은 전혀 Include 할 필요가 없습니다.
            이것은 Afxdb.h 나 Afxdao.h 를 Include 할때 따라오게 됩니다.
           
Afxdd_.h    이 파일은 다이알로그 데이타 교환(DDX) 함수들에 대한 선언들을
            포함하고 있습니다. 끝이 _ 로 끝나는 다른 화일들과 마찬가지로,
            이 파일도 직접 Include 할 필요가 없습니다.
            이것은 Afxwin.h 에 의해 포함됩니다.

Afxdisp.h   이 파일은 COM dispatch인터페이스에 대한 선언과 정의들을 포함하고
            있윱求?이것은 CCmdTarget에 의해 처리되는 Automation을 작성하기
            위한 모든 확장들과 MFC 가 COM 프로그램을 쉽게 하기위해 제공하는
            모든 자료형들, Wrapper 클래스들을 포함하고 있습니다.
            COM 을 사용할때만 이 파일을 Include 하십시오. 만약 그렇지 않으면
            필요치 않은 런타임DLL들에 연결되게 되며,이것은 작성된 프로그램의
            시작을 느리게 할것입니다. 이 파일은 Afxwin.h 뒤에 Include 되어야
            합니다. 만약 Afxcmn.h 를 사용하고 있고, OLE 클래스들을 사용할
            필요가 있다면 이 파일을 Include하십시오

Afxdlgs.h   MFC 의 확장 다이알로그 클래스들이 이 파일에 선언되어 있습니다.
            이 클래스들은 CPropertySheet와 CPropertyPage를 포함하여 윈도우의
            공통 대화상자(Common Dialog)에 대한 MFC Wrapper 들입니다.
            이 파일은 Afxext.h 에 의해 포함되게 됩니다.
           
Afxdllx.h   이 파일은 MFC 확장DLL을 작성할때 소스 모듈들에 포함되는 소스코드
            를 포함하고 있습니다.(ExtRawDllMain)
           
Afxdll_.h   이 파일은 MFC 가 확장 DLL 에 대한 정보를 관리하도록 도와주는
            클래스들을 포함하고 있습니다.
            이 파일은 당신의 프로그램이 _AFXDLL Precompiler플래그를 사용하여
            작성될때 Afxwin.h 에 의해 포함됩니다.

Afxext.h    Afxext.h 화일은 '확장' MFC클래스들을 선언합니다.
            이것은 CStatusBar와 CToolBar같은 진보된 User-Interface클래스들을
            포함하고 있습니다. 이 클래스들을 사용한다면, 먼저 Afxwin.h 를
            포함하십시오.

Afxinet.h   CHttpConnection 같은 클래스들을 선언합니다. 이 파일에 선언된
            클래스들을 인터넷 클라이언트 프로그램을 작성가능하게 합니다.

Afxisapi.h  ISAPI 인터페이스를 사용하는 인터넷 서버 프로그램 작성용 클래스들
            선언입니다.

Afxmsg_.h   이 파일은 간접적으로 Afxwin.h에 의해 참조됩니다. 따로 Include 할
            필요는 없습니다. 메시지맵 항목들에 대한 정의를 포함하고 있습니다

Afxmt.h     Multithreaded Application 을 위한 동기화(Synchronization) 객체를
            포함하고 있습니다. 이 클래스들은 Console 프로그램에서도 사용이
            가능하며, 먼저 Afx.h 를 Include 해야 합니다.

Afxodlgs.h  이 파일은 MFC 에서의 OLE 대화상자 구현을 위한 클래스 선언들을
            포함하고 있습니다. 만약 이 대화상자들 사용하거나 서브클래싱 할
            경우에는 이 파일을 직접 Include 하여야 합니다.
            물론 먼저 Afxwin.h 가 Include 되어야 합니다.

Afxole.h    이 파일은 OLE를 위한 핵심 클래스들을 선언하고 있습니다.
            이 클래스들은 COleDocument 기반의 클래스들과 OLE 아이템들 그리고
            그들과 같이 사용되는 Drag-and-Drop 지원을 포함합니다. 프로그램이
            OLE 를 사용한다면 Afxwin.h 다음에 이 파일을 포함해야 합니다.

Afxplex_.h  이 파일은 MFC 에서 CObject기반의 콜렉션 클래스들 구현에 사용되는
            CPlex 클래스를 구현하고 있습니다.

Afxpriv.h   이 파일은 MFC 구현에 필요한 내부적인(사적인) 것을을 포함하고
            있습니다. 만약 안을 들여다본다면, 당신의 일을 도와줄수 있는
            깔끔한 자료구조나 클래스들을 찾을수 있을겁니다.
            하지만, 조심해서 사용하십시오. 이 파일에 있는 것들은 MFC 버젼이
            바뀌면 예고없이 바뀔수도 있습니다.
            이런것을 인지한 다음에 직접 Include 하여 사용하십시오.

Afxres.h    이 파일은 MFC 프로그램을 위한 Resource Script(.rc 파일) 에 의해
            사용됩니다.(Include 됩니다.)
            이 파일은 Afxwin.h 에 의해 간접적으로 참조됩니다.
            이 파일은 거의 직접 참조될 필요가 없습니다. 이 파일은 미리
            정의된 모든 MFC 리소스들에 대한 Preprocessor Symbol Definition
            들을 포함합니다.

Afxrich.h   이 파일은 CRichEditCtrl 과 관련된 약간의 클래스들에 대한 정의를
            포함하고 있습니다. 만약 Rich Edit컨트롤을 사용한다면 Afxcmn.h와
            Afxwin.h 다음에 이 파일을 Include 해야 합니다. 또한 Afxole.h
            파일도 Include 되어야 합니다.Rich Edit 컨트롤은 매우 강력합니다
            이것은 완벽하게 OLE 를 지원합니다.

Afxsock.h   CSocket 과 CAsyncSocket 클래스에 대한 정의를 포함하고 있습니다.
            이 클래스들은 Windows Sockets API(네트워크 기반의 통신 API)를
            감쌉니다.(Wrapping)

Afxstat_.h  이 파일은 동작중인 프로그램에 대해 MFC 가 관리하는 상태정보
            저장용 구조체들을 정의합니다. 이 상태정보는 MFC 에 의해
            사용되며 프로그램이 어떻게 동작해야 할지를 알수 있게 합니다.
            이 파일은 직접적으로는 참조되지 않으며, Afx.h에 의해 Include
            됩니다.

Afxtempl.h  이 파일은 MFC 콜렉션 클래스들에 대한 템플릿 기반의 구현들을
            포함하고 있습니다. Afx.h 뒤에 Include 되어야 합니다.  

Afxtls_.h   MFC 가 각 어플리케이션별 또는 쓰레드별 상태정보를 관리하기 위한
            Thread-Local Storage 매크로 들을 포함합니다. 이 매크로들은
            Afxstat_.h 에 있는 많은 구조체들에 의해 사용되며, 이 파일은
            직접적으로 참조되지 않습니다. Afx.h 에 의해 참조됩니다.

Afxver_.h   이 파일은 MFC 프로그램이 만들어질때(Build) 여러가지 설정을 위해
            사용되는 많은 Preprocessor macro 들을 가지고 있는 중요한 파일
            입니다. 당신이 MFC 어플리케이션을 Build 할때 이 헤더는 당신의
            프로그램이 정확하게 MFC 에 링크되는지를 확인하는 약간의 설정도
            추가하게 됩니다. 이 파일은 전혀 직접 참조할 필요가 없으며,
            실제로 이 파일을 읽어볼 필요도 없습니다. 이 파일은 아주
            저수준(Low-Level)의 매크로와 내부구현들로 가득차 있기때문입니다.

Afxv_cfg.h  이 파일은 한가지의 일을 합니다: 이것은 _AFX_PORTABLE 이란
            플래그에 의해 동작됩니다. 만약 당신이 MFC 를 Build 하기위해
            제작되지 않은 컴파일러(Watcom 이나 Symantec 등)를 사용한다면
            Preprocessor 심볼인 _CUSTOM 을 정의하여 이 파일이 Include되도록
            해야 합니다. 이 파일은 절대로 어플리케이션에 의해 직접적으로
            참조되지 않으면, 일반적인 상황에서는 MFC 에 의해 전혀 사용되지
            않습니다.

Afxv_cpu.h  Afxver_.h 에 의해 참조되며,이 파일은 Macintosh,Power PC,MIPS,
            Alpha용 MFC 에 대한 약간의 설정을 합니다. 이 파일은 절대로
            어플리케이션에 의해 직접적으로 참조되지 않습니다.

Afxv_dll.h  이 파일은 DLL 기반의 MFC Build 에 대한 설정을 하기위해
            사용됩니다. 이 파일은 DLL Build에 대한 많은 특수심볼을 정의하여
            DLL 의 Segment Layout 을 최적으로 만듭니다. 이것은 Afxver_.h 에
            의해 참조되며 절대로 어플리케이션에 의해 직접적으로 참조되지
            않습니다.

Afxv_mac.h  이 파일은 Macintosh용 MFC 에 대한 여분의 설정변경을 가지고
            있습니다. 이것은 Afxver_.h에 의해 참조되며 절대로 어플리케이션에
            의해 직접적으로 참조되지 않습니다.

Afxv_w32.h  이 파일은 Win32 용 MFC 를 설정합니다. 이것은 항상 Include 되며,
            이것은 MFC 가 Win32 의 변형들(Win32s,Win32c..) 상에서 동작될때도
            마찬가지입니다. 이 파일은 시스템관련, 표준 C, C++ Include 파일을
            참조하게됩니다.이 파일이 Windows.h와 그 친구들을 불러오는
            파일입니다. (또한 Tchar.h 나 String.h 같은 헤더도 포함됩니다.)

Afxwin.h    이 파일이 윈도우 상에서 동작하는 MFC 어플리케이션에 대한 주 헤더
            (Primary Header) 파일입니다. Windows 용 프로그램을 작성한다면
            Afx.h 후에 이 파일을 Include 하십시오. 콘솔 프로그램을 만든다면
            이 파일을 사용하지 마십시요.
            이 파일은 CWnd 와 CWnd의 파생 클래스와 같은 기본클래스들을 정의
            합니다.

Winres.h    이 파일은 MFC 어플리케이션에 의해 사용되는 Resource Identifier
            들에 대한 부분집합을 정의합니다. 이것은 Afxres.h에 의해 참조되며
            Windows의 헤더가 일반적으로 정의하는 것들의 부분집합을
            제공합니다. MFC 어플리케이션에서 직접 참조되지 않습니다.

다음글은 하이텔  MFC소모임의 시삽이신 권정혁님의 글을 정혁님의 허락하에
다음과 같이 기재합니다. 허락해주신 정혁님께 감사드립니다.
****************************************************************************

이 글은 Mike Blaszczak 의 책 "Professional MFC" 의 Appendix D 에 들어있는
내용을 번역한 글입니다. 제 허락없이는 다른 어떤게시판에도 옮기실수 없습니
다. 물론 글의 원 소유자는 Mike 입니다.

                                            MFC&T 사용자 모임 시삽 권정혁

============================================================================
MFC 헤더와 라이브러리 설명 (The Foundation Classes Headers and Libraries) #2

2. 런타임 라이브러리 (Run-time Libraries)

이 테이블은 Visual C++ 과 함께 제공되는 라이브러리와 Pre-Compiled Object 들의
기능에 대한 짧은 설명을 보여줍니다.

------------------------------------------------------------------------------
런타임 라이브러리 (Run-time Libraries)
------------------------------------------------------------------------------

파일설명

Advapi32.lib  레지스트리나 보안 관련 API 같은 진보된 API 서비스 들에 대한
              임포트 라이브러리 입니다. 이 임포트 라이브러리와 링크하는 것은
              당신의 프로그램에서 Advapi32.dll에 포함된 함수들을 사용가능하게
              합니다.

Atl.lib       MS의 Active Template Library에 대한 라이브러리입니다.

Binmode.obj   이 모듈과 링크하면 C 런타임 라이브러리에 의해 오픈되는 화일들이
              기본적으로 Binary 모드로 열리도록 만듭니다.

Cap.lib       Call Attributed Profiler 에 대한 인터페이스 입니다.
              이 툴은 함수 호출 패턴(Function Call Patterns)을 분석함으로써
              Win32 어플리케이션을 튜닝하게 해줍니다.

Chkstk.obj    런타임용 Stak-Depth 체킹 모듈입니다.
              이 모듈은 모든 함수 호출전에 스택의 크기(Depth)를 체크함으로써
              Stack Overflow 가 났는지 체크하는 것을 도와줍니다.
              Windows NT 에서는 프로그램의 스택 세그먼트를 조심스레 체크하며,
              스택 오버플로우가 난다면 프로그램을 깨끗히 종료시켜주므로
              이 파일은 거의 필요가 없습니다.

Comctl32.lib  윈도우 공용 컨트롤(Windows common controls)에 대한 라이브러리
              입니다.

Comdlg32.lib  윈도우 공용 대화상자(Windows common dialogs)에 대한 라이브러리
              입니다. 이 라이브러리는 표준 화일오픈,화일저장,폰트선택,프린트
              ,컬러 선택 다이얼로그에 대한 인터페이스를 제공합니다.

Commode.obj   전역적인 File Commit Flag 값을 Commit 으로 설정합니다.
              이 파일과 링크하는것은 오픈되는 모든화일이 기본적으로 Commit
              모드에서 열리도록 합니다.

Compmgr.lib   컴포넌트에대한 임포트 라이브러리입니다.

Ctl3d32.lib   3차원(Three-D) 컨트롤에대한 지원 라이브러리입니다.
              이 라이브러리는 다이알로그와 컨트롤이 3차원으로 보이도록 합니다.
              이 파일은 거의 안쓰입니다. 단지 이전버젼과의 호환을 위해
              제공됩니다.

Ctl3d32s.lib  Win32s 용 프로그램에대한 Ctl3d 라이브러리 입니다.

D3drm.lib     Direct3D 렌더링 모델(Rendering Model) API에 대한
              라이브러리입니다.

Daouuid.lib   DAO 객체들에 대한 UUID 값을 가지고 있는 라이브러리입니다.

Ddraw.lib     DirectDraw API용 라이브러리입니다.

Dflayout.lib  Compound Document File(복합문서파일)에 대한 저장소 관리
              (Storage Management)를 하는 OLE 함수들에 대한 임포트
              라이브러리입니다.

Dlcapi.lib    DLC 3270 연결을 위한 라이브러리 입니다.

Dplay.lib     DirectPlay API용 라이브러리 입니다.

Dsound.lib    DirectSound API용 라이브러리입니다.

Fp10.obj      이 모듈과 링크하는것은 프로그램이 기본적으로 53비트 대신 64비트
              부동소수점(Floating-Point Precision) 형식으로 알고리즘을
              사용하게 합니다.

Gdi32.lib     Windows GDI 임포트 라이브러리 입니다. 이 라이브러리와 링크하는
              것은 프로그램이 Windows 의 Graphic Device Interface 에 있는
              SelectObject(),CreateFont(),LineTo() 와 같은 루틴을 호출하여
              디스플레이나 프린터에 그리기를 수행할수 있도록 합니다.

Glaux.lib     OpenGL 보조 함수 라이브러리 입니다. 거의 모든 프로그램에서
              사용되지 않으나, 이것은 OpenGL의 핵심(Core) 라이브러리의 기능을
              향상시키도록 합니다. Opengl32.lib도 참조하십시오.

Glu32.lib     OpenGL 그래픽의 핵심 함수 라이브러리 입니다.
              Opengl32.lib도 참조하십시오.

Hlink.lib     IHlink 와 관련 인터페이스 지원용 라이브러리 입니다.
              이 인터페이스들은 ActiveX 객체가 일반적인 하이퍼링크 스타일
              (Hyperlink-Style)의 이동을 구현하는것을 도와줍니다.

Imagehlp.lib  디버거 같은 시스템 툴들이 다른 프로세스를 관리하고 디버그
              정보를 추출하도록 하는 루틴이 들어있는 라이브러리 입니다.

Imm32.lib     Input Method Editor(IME)의 사용에 라이브러리입니다.
              IME는 조그만 팝업윈도우창으로 보이며,다른나라 글자를 선택하도록
              해줍니다. (한글윈도우 사용자는 다들 아시죠..? )

Kernel32.lib  Windows Kernel 의 임포트 라이브러리입니다. 이 라이브러리와
              링크함으로써 Windows kernel 안에 들어있는 루틴의 호출이 가능해
              집니다. Windows Kernel 에는 CreateSemaphore() 나 GlobalAlloc()
              같은 함수들이 포함되어 있습니다.

Largeint.lib  수학계산용 Large Interger지원 라이브러리입니다. 이 라이브러리는
              단지 호환목적으로 제공됩니다. Visual C++ 의 컴파일러는
              기본적으로 64Bit Integer 를 지원합니다.

Libc.lib      표준 C Runtime 라이브러리입니다. 이 라이브러리는 sprintf() 나
              strcpy() 같은 함수들이 포함되며,프로그램에 정적으로 링크됩니다.
              이것은 멀티쓰레드나 재진입(re-entrant) 프로그램에는 안전하지
              못합니다.

Libcd.lib     표준 C Runtime 라이브러리의 Debug 버젼입니다. Debug 빌드에선
              Libc.lib 대신 이것을 사용합니다. 이것은 프로그램에 정적으로
              링크됩니다.

Libci.lib     표준 C 라이브러리입니다.이 라이브러리는 Libc.lib 와 비슷하지만,
              이것은 이전 버젼의 Visual C++ 에서 제공된 표준 라이브러리에서
              지원된 표준 iostream 라이브러리와의 호환성을 제공합니다.
              (iostream이 구형이라는 얘기죠..) 이것은 프로그램에 정적으로
              링크됩니다.

Libcid.lib    구형 iostream 버젼이 포함된 표준 C 라이브러리의 Debug버젼입니다.
              역시 프로그램에 정적으로 링크됩니다.

Libcimt.lib   구형 iostream 버젼이 포함된 표준 C 라이브러리의 멀티쓰레드에
              안전한 버젼입니다. 역시 프로그램에 정적으로 링크됩니다.

Libcimtd.lib  구형 iostream 버젼이 포함된 표준 C 라이브러리의 멀티쓰레드버젼의
              Debug 빌드입니다. 역시 프로그램에 정적으로 링크됩니다.

Libcmt.lib    멀티쓰레드 프로그램이나 재진입 프로그램에서도 사용이 안전한
              sprintf() 나 strcpy() 같은 함수들이 포함된 C 런타임 라이브러리의
              멀티쓰레드 버젼입니다. 역시 프로그램에 정적으로 링크됩니다.

Libcmtd.lib   바로위의 Libcmt.lib의 디버그 버젼입니다.
              역시 프로그램에 정적으로 링크됩니다.

Libcp.lib     표준 C++ 런타임 라이브러리 입니다. 이것은 호출하는 프로그램에
              정적으로 링크되며, 멀티쓰레드나 재진입 프로그램에 안전하지
              못합니다.

Libcpd.lib    표준 C++ 런타임 라이브러리의 Debug 버젼입니다.
              역시 프로그램에 정적으로 링크됩니다.

Limcpmt.lib   표준 C++ 런타임 라이브러리의 멀티쓰레드 버젼입니다.
              역시 프로그램에 정적으로 링크됩니다.

Libcpmtd.lib  멀티쓰레드 C++ 표준 라이브러리의 디버그 버젼입니다.
              역시 프로그램에 정적으로 링크됩니다.

Loadperf.lib  이 임포트 라이브러리는 Performance Counter 에 관련된 레지스트리
              값들의 초기화를 지원하는 루틴들을 포함합니다.
              이 라이브러리는 보통 인스톨 프로그램들에 사용됩니다.

Lz32.lib      Lempel-Ziv압축해제 루틴 라이브러리입니다. 보통 인스톨 프로그램에
              의해서 사용됩니다. 이 라이브러리는 압축루틴이 없으며,
              단지 압축해제루틴만 들어있습니다.

Mapi32.lib    Microsoft Mail API 라이브러리 입니다..

Mfcapwz.lib   Custom Wizard의 개발을 가능하게 해주는 클래스와 함수들이 포함된
              라이브러리입니다.

Mfcclwz.lib   Custom Wizard의 개발을 가능하게 해주는 클래스와 함수들이 포함된
              라이브러리입니다.

Mfcuia32.lib  OLE 공통 사용자 인터페이스(Common User Interface)에 대한 MFC 의
              구현부분이 들어있습니다. Oledlg.lib 와 비슷하지만 Unicode 대신
              ANSI 인터페이스를 지원합니다.

Mgmtapi.lib   SNMP(Simple Network Management Protocol) Management API입니다.

Mpr.lib       연결관리(Connection Management)를 위한 LAN Manager 스타일의
              네트웍 API 가 들어있습니다. 이 API 들은 Windows 상에서 Connect와
              DIsconnet 를 가능하게 합니다.

Msacm32.lib   Microsoft Audio Compression Manager API(오디오 압축 관리자 API)
              입니다. 이것은 Audio Waveform 데이타를 압축하고 해제하는
              유틸리티들입니다.

Msconf.lib    Microsoft ActiveX Conferencing API 에 대한 라이브러리입니다.

Mslsp32.lib   License Service API 에 대한 임포트 라이브러리입니다.

Msvcirt.lib   구형 iostream 버젼이 포함된 표준 C 라이브러리의 DLL Build에 대한
              임포트 라이브러리 입니다. 이 라이브러리는 Libci.lib 라이브러리의
              DLL 버젼에 대한 임포트 라이브러리입니다.

Msvcirtd.lib  Mscvirt.lib 라이브러리의 디버그 버젼에 대한 임포트 라이브러리
              입니다.

Msvcprt.lib   표준 C++ 라이브러리의 DLL Build 에 대한 임포트 라이브러리입니다.
              이것은 Libcp.lib 라이브러리의 DLL 버젼에 대한 임포트 라이브러리
              입니다.

Msvcprtd.lib  Msvcprt.lib 라이브러리의 디버그 버젼에 대한 임포트 라이브러리
              입니다.

Msvcrt.lib    표준 C 라이브러리의 DLL Build 에 대한 임포트 라이브러리입니다.
              이것은 Libc.lib 라이브러리의 DLL 버젼에 대한 임포트 라이브러리
              입니다.

Msvcrtd.lib   Msvcrt.lib 라이브러리의 디버그 버젼에 대한 임포트 라이브러리
              입니다. Retail Build 에서 Msvcrt.lib 를 사용한다면 Debug Build
              에서 이것을 사용하십시오.

Mswsock.lib   Windows Sockets 2 API 에 대한 Microsoft 의 특정 확장부분
              (MS-Specific Extension)에 대한 임포트 라이브러리입니다.

Mtx.lib       Microsoft Transaction Server(MTS) 프로그래밍 인터페이스
              라이브러리입니다.

Mtxguid.lib   MTS 에 의해 지원되는 객체들의 Guid 들을 가지고 있는
              라이브러리입니다.

Nddeapi.lib   Network DDE API 입니다. DDE 스타일의 서비스를 네트웍을 통하여
              시스템간에 사용가능하도록 해줍니다.

Netapi32.lib  LAN Manager API Interface 입니다. 이 라이브러리는 MS 의 NOS
              (Network Operation System)에 의해 제공되는 저수준의 기능들을
              사용하도록 해주는 함수들을 포함하고 있습니다.

Newmode.obj   당신의 Application 이 malloc() 함수 호출에 실패했을때 new
              연산자의 에러 처리 메커니즘을 사용하도록 하여줍니다. 기본적으로,
              이것이 동작하지는 않습니다: malloc() 이 실패한다면, NULL 을
              리턴하지 예외를 발생시키지(Throw) 않습니다.              
              이 모듈과 링크하는것은 malloc() 호출 실패시 new 연산자의 에러
              처리루틴을 호출하는 것으로 C 런타임 라이브러리의 동작을
              변경합니다.

Ocx96.lib     OCX 96 스펙(Specification)에 명시된 인터페이스들에 대한
              UUID들이 포함된 라이브러리입니다.

Odbc32.lib    ODBC API 라이브러리입니다. 이 라이브러리는 데이터베이스
              응용프로그램에 대한 하부 독립적인 API 들을 제공합니다.
              이 라이브러리는 MFC 에 의해 다시 추상화 됩니다.

Odbccp32.lib  ODBC control panel applet(제어판에 등록되는 응용프로그램) 에
              관한 인터페이스가 포함된 라이브러리입니다.

Oldnames.lib  "Kernighan and Ritchie C" 와 호환되는 이름을 가진
              표준 C 런타임 라이브러리 함수들입니다. 이 라이브러리는 K&R-C의
              execv() 같은것을 ANSI-C 의 같은 함수인 _execv() 에 매핑(Mapping)
              해줍니다.

Ole32.lib     32-bit OLE 지원을 위한 Core 라이브러리입니다.

Oleaut32.lib  32-bit Automation interface에 대한 라이브러리입니다.

Oledlg.lib    OLE 공통 사용자 인터페이스(Common User Interface)에 대한 System
              Implementation입니다. OleUiEditLinks() 나 OleInsertObject()와
              같은 함수들을 포함합니다.

Olepro32.lib  OLE Property Frame API 입니다. 또한 OLE Font (IFont) 나 Picture
             (IPicture) 프로퍼티 들에 대한 구현도 포함하고 있습니다.

Opengl32.lib  OpenGL 의 Core 함수 라이브러리입니다.
              OpenGL 은 Silicon Graphics에 의해 정의되고 Microsoft 에 의해
              Win32 용으로 구현된 Graphic Rendering Language 입니다.
              Glu32.lib 와 Glaux.lib 도 참조하십시오.

Pdh.lib       Performance Data 헬퍼함수들에 대한 임포트 라이브러리 입니다.
              이 Win32 API의 부분들은 프로세스에대해 Performance Counter 들을
              작성하고,질의하고,갱신하는것을(Create,Query,Update) 도와주는
              쉬운 인터페이스들을 포함하고 있습니다.

Penwin32.lib  Pen Computing 용 Windows에 대한 확장 라이브러리입니다.

Pkpd32.lib    Pen Windows 의 커널함수들입니다.

Rasapi32.lib  클라이언트용 Remote Access Service(RAS) API 입니다.
              이 라이브러리에 있는 함수들은 모뎀이나 그 비슷한 저속회선 연결을
              통해 원격지 컴퓨터에 연결하도록 해줍니다.

Rasdlg.lib    RAS 응용프로그램에 대한 Common User Interface 요소들을 포함하고
              있는 라이브러리입니다.

Rassapi.lib   RAS 서버쪽 API 들입니다.

Rpcndr.lib    Remote Procedure Call(RPC) Helper Function API 들입니다.

Rpcns4.lib    RPC Name Service 함수들 입니다.

Rpcrt4.lib    RPC Windows run-time 함수들 입니다.

Scrnsave.lib  화면보호기(Screen saver) 에 대한 인터페이스입니다.

Setargv.obj   이 모듈과 링크하는 것은 콘솔 프로그램이 Wildcard(*,?) 를 사용한
              Command Line Parameter들을 실제 파일이름들로 지정하도록 확장하여
              줍니다. 각 파일은 main() 의 argv 인자에 들어가게 됩니다.
              윈도우에서 사용하려면 Wsetargv.obj 를 살펴보십시오.

Setupapi.lib  파일 설치와 삭제에 관련된 함수들입니다. 셋업프로그램에서
              사용됩니다.

Shell32.lib   Windows Interface Shell API 들입니다. 이 API 들은 예를 들어
              Norton Desktop for Windows와 같은 프로그램에 사용된 실행파일에서
              아이콘을 추출하거나 Command Line Parameter 를 사용해 다른
              프로그램을 실행하는등의 기능을 제공합니다.

Snmpapi.lib   Simple Network Managerment Protocol(SNMP)에 관련된 주 API 함수들
              입니다. TCP/IP 네트웍에 대해 이 프로토콜은 Gateway 나 연결될
              네트웍들을 모니터링하는데 사용됩니다. Mgmtapi.lib 와 연관되어
              있습니다.

Svrapi.lib    Inter-Server Communication 에 관한 Network API 들입니다.

Tapi32.lib    Microsoft Telephony API(TAPI) 라이브러리입니다. lineOpen() 과
              같은 telephony API 들을 구현합니다.

Th32.lib      32-bit Toolhelp 라이브러리입니다. 이 라이브러리는 Debugger 나
              저수준의 툴을 작성할때 도움을 주는 함수들을 제공합니다.
              예를들어 이 라이브러리의 루틴들을 윈도우상에서 프로세스나
              쓰레드들을 Enumerate 하게 해줍니다.

Thunk32.lib   Thunk 컴파일러의 런타임 지원 루틴들입니다.
              (Thunking 이 뭔지 아시죠?)

Url.lib       이 파일은 URL 을 Parsing 하거나 MIME 헤더를 해석하는데 사용하는
              루틴입니다. 이 라이브러리에 있는 함수들은 현재 문서화가 되어있지
              않으며, 이것은 Win32 SDK 의 이후 버젼이나 Visual C++ 의 이후버젼
              에서 더 정제되고, 무리없게 지원될것입니다.

Urlmon.lib    URL 모니커(moniker)의 런타임 지원 라이브러리에 대한 임포트
              라이브러리입니다.

User32.lib    윈도우즈의 USER.EXE 에 대한 임포트 라이브러리 입니다.
              이 라이브러리와 링크하는 것은 프로그램이 Windows 의 UI 부분을
              사용할수 있도록 해줍니다. 이 라이브러리는 CreateDialog() 나
              CreateWindow() 같은 함수를 포함합니다.

Uuid.lib      Stock(내장된) OLE 객체에 대한 표준 UUID 들입니다.

Vdmdbg.lib    이 라이브러리에 있는 함수들은 NT VDM 안에서 디버깅 하는것에
              관련된 기능들을 지원합니다.

Version.lib   GetFileVersion() 과 같은 버젼 확인 API 들입니다.

Vfw32.lib     Video for Windows API 들입니다. 이 라이브러리에 있는 함수들은
              Multimedia 비디오와 오디오를 재생,녹음,수정,저장 하는것을
              가능하게 합니다.

Webpost.lib   WebPost API 임포트 라이브러리입니다. 이 라이브러리는 ISP
              (internet Service Provider)에 의해 제공되는 웹 사이트에 사용자의
              컴퓨터에서 데이타를 올리는것이 가능하도록 도와줍니다.

Win32spl.lib  Win32 spooler API 입니다. 이 파일에 있는 루틴들은 다른 프로그램
              이나 컴퓨터들로부터 Print Spooler Status에 접근하는것을 가능하게
              해줍니다.

Wininet.lib   Windows Internet Client API 들입니다.

Winmm.lib     Windows Multimedia API 들입니다. Multimedia Device Management,
              Timer, Wave 파일, Multimedia I/O 제어함수 같은 것을 포함합니다.

Winspool.lib  The Win32 spooler API 입니다. 이 라이브러에 보이는 루틴들을
              프로그램이 프린트 하는 동안 Windows Print Spooler 의 기능을
              사용하도록 해줍니다.

Winstrm.lib   Windows NT의 TCP/IP interface들 입니다. 이 파일은 TCP/IP Routing
              함수같은 것들을 제공합니다.

Wintrust.lib  ActiveX 객체에 대한 Trust Verification(신용확인) 에 관한 API들의
              임포트 라이브러리입니다. 이것은 WinVerifyTrust() 같은 함수들을
              사용가능하도록 합니다.

Wow32.lib     이 라이브러리는 16-Bit 와 32-Bit 객체간에 핸들을 변형하도록 하는
              Generic Thunking 메커니즘에 의해 사용됩니다. 이 라이브러리는
              또한 16 Bit 프로세스에서 32-Bit 메모리를 관리하도록 하는것을
              도와줍니다.

Ws2_32.lib    Windows Sockets 2.0 API 입니다.

Wsetargv.obj  이 모듈과 링크하는 것은 Windows 프로그램이 Wildcard(*,?) 를
              사용한 Command Line Parameter 들을 실제 파일이름들로 지정하도록
              확장하여 줍니다. 각 파일은 main()의 argv 인자에 들어가게 됩니다.
              콘솔 프로그램에 사용하려면 setargv.obj 를 살펴보십시오.

Wsock32.lib   Windows Sockets APIs.

Wsock32.lib   Windows Sockets API 입니다.

Wst.lib       Working Set Tuner DLL 에 대한 인터페이스 입니다.
              Working Set Tuner DLL 은 프로그램을 조사하여 프로그램의
              Working Set 을 최소화하도록 도와줍니다.

=============================================================================

참고할점은 주 API 들과, 헤더 파일 그리고 라이브러리들의 요약이 Lib 디렉토리에
있는 Win32api.csv 에 들어있다는 것입니다. 이 파일은 Comma Separated Variable
File(*.csv) 이며,  엑셀같은 스프레드쉬트 프로그램에서 읽어들일수 있습니다.

2007/10/16 10:57 2007/10/16 10:57
이 글에는 트랙백을 보낼 수 없습니다

<<< RPC(Remote Procedure Call)의 역사 >>>

1980년대에 여러 회사들에 의하여 다양한 RPC가 구현되었다. 그들 중에는 SUN 마이크로 시스템즈의 오픈 네트워크 컴퓨팅(ONC)과 Apollo 컴퓨터의 네트워크 컴퓨팅 구조(NCA)가 있었다. 오늘날, 휴렛 팩커드의 HP-UX, IBM의 AIX, SUN 마이크로 시스템즈의 SUN OS 4.1.X, 그리고 산타크루즈 오퍼레이션의 SCO UNIX와
같은 대부분의 상업용 UNIX 시스템들은 모두 ONC 기법을 기반으로 RPC를 구현 하였다.

그러나, SUN의 Solaris 2.x 운영체제와 UNIX 시스템 V.4는 수정된 ONC 기법을 기반으로 RPC를 구현하였다. 두 기법은 매우 비슷하다. 즉, 그들은 모두 네트워크를 통하여 데이터를 전송하기 위한 외부 데이터 표현(XDR) 형식을 사용하고, RPC 응용들의 생성을 간단히 하기 위하여 rpcgen 컴파일러를 제공한다. 그러나 두 기법은 ONC 기반 RPC API들이 소켓에 기초를 하고, 반면에 시스템 V.4 RPC API들은 소켓이나 TLI를 기초로 할 수 있다는 점에서 차이가 있다.

<<< RPC 프로그래밍 인터페이스 계층 >>>

RPC 프로그래밍 인터페이스는 다양한 계층이 있다. 그들의 범위는 C 라이브러리 함수들(예를 들면, printf)을 호출하는 것과 같은 방법으로 사용자들이 시스템이 제공하는 RPC 함수들을 호출하는 최상위 계층으로부터, RPC API들을 사용하여 사용자들이 RPC 프로그램을 생성하는 하위 계층까지 있다. 이 다양한 프로그래밍 인터페이스 계층들은 이 장의 나머지 부분에서 자세히 설명한다.

최상위 계층에는 원격 시스템의 정보를 수집하기 위하여 사용자들이 직접호출할 수 있는 시스템이 제공하는 RPC 함수들이 있다. 이 함수들은 일반적으로 C 라이브러리 함수처럼 사용될 수 있다. 단지 그들을 사용하기 위해서는 특별한 설정이 필요하다. 즉, (1) 함수의 원형들을 선언하는 특정한 헤더 파일들과 (2) 컴파일된 프로그램은 -lrpcsvc 스위치와 함께 링크되어야 한다. librpcsvc.a 라이브러리는 이 RPC
라이브러리 함수의 목적코드들을 포함한다.

RPC 라이브러리 함수들의 장점은 쉽게 사용할 수 있고 프로그래밍 부담이 적다는 것이다. 그러나, 시스템에서 정의된 RPC 라이브러리 함수들은 많지 않다. 그러므로, 이 함수들에 대한 응용은 제한이 있다.
RPC 프로그래밍의 두 번째 계층은 RPC 클라이언트와 서버의 스터브(stub) 루틴을 자동적으로 생성하기 위하여 rpcgen 컴파일러를 사용하는 것이다. 사용자들은 단지 클라이언트와 서버 프로그램을 생성하기 위한 클라이언트의 main 함수와 서버의 RPC 함수들만 작성한다. 또한 rpcgen 컴파일러는 클라이언트와 서버 사이에 데이터를 전송하기 위하여사용자가 정의한 어떠한 데이터 유형이든지 XDR 형식으로 변환하는 XDR 함수들을 생성할 수 있다. rpcgen 컴파일러를 사용하여 얻는 장점은 사용자들이 RPC 함수들과 클라이언트의 main함수를 작성하는데 주력할 수 있다는 것이다. 즉, 하위 계층의 RPC API들에 대해 알 필요가 없다. 이는 프로그래밍 노력을 절약하고 오류 발생 가능성을 줄이게 한다. 그러나, 이러한 접근 방식의 결점은 rpcgen이 생성한 클라이언트 서버프로그램에 의하여 사용되는 네트워크 트랜스포트의 어떤 자세한 속성들에 대하여 제어하기 어렵다는 것이다. 또한 이러한 클라이언트 서버는 XDR 함수들에 의하여 사용되는 동적 메모리를 관리할 수 없다.
RPC 프로그래밍 인터페이스의 최하위 계층은 RPC 클라이언트와 서버 프로그램들을 생성하기 위하여 RPC API들을 생성하는 것이다. 이것의 장점은 사용자들이 프로세스에 의하여 사용되는 네트워크 트랜스포트와 XDR 함수에 있는 동적 메모리 관리를 직접 제어할 수 있다는 것이다. 그러나, 이는 사용자 부분에서의 더 많은 프로그래밍 노력이 필요하게 된다

출처 : Tong - forestcamp님의 [솔라리스]통

2007/10/16 10:51 2007/10/16 10:51
이 글에는 트랙백을 보낼 수 없습니다

1. 사용자 인증의 단일 창구 SSO

 가. SSO(Single Sigh On)의 개념

  - 사용자가 한 개의 ID, PASSWORD로 여러 응용시스템을 접근할 수 있는 기술

 나. SSO가 필요한 이유

  - 기업내 다양한 응용시스템 도입 및 운영에 따른 ID, PASSWORD 관리 복잡

  - 중앙집중적인 ID관리 및 시스템 권한관리를 통한 업무의 순화 및 표준화 실현


2. SSO의 요소기술과 EAM의 비교

 가. SSO의 특징

   1) 특징 : 단일의 ID, PASSWORD를 통한 다양한 시스템 접근 제공

   2) 구성요소 : 클라이언트/서버 Agent, SSO 인증서버, LDAP

   3) 주요기능 : 단일 로그인, 표준화된 인증 접근방법, 중앙집중식 접근관리 가능

   4) 구현방식 : 쿠키방식, 웹방식, PKI인증서 이용방식


 나. EAM(Enterprise Access Management)와 SSO의 비교

비교항목 EAM SSO
목적 ID관리와 권한, 자원정책의 결합 중앙집중식 ID 관리
장점 자원접근시 권한까지 제어
개별응용레벨의 권한제어
단일 ID 로 사용의 편리성
인증정책과 권한설정이 용이
단점 사용자/자원별 권한관리 어려움
고가 및 구현의 복잡성
ID, PASSWORD노출시 전체시스템 위험
자원별 권한관리 미비


3. SSO 적용시 고려사항 및 활용

 가. 단일 ID, PASSWORD 사용으로 노출시 기업전체의 보안위협이 되므로 개인의 철저한 ID,

       PASSWORD관리와 병행하여 ONE-TIME PASSWORD 정책이 필요함

 나. PKI 기반의 SSO 단순성 탈피위해 PMI(Previlege Management Infrastructure) 의 AC(Attribute

       Certificate) 인증서 사용하고 , 향후 EAM 도입이 필요함.

EAM 시스템과 요구 사항

연·재·목·차

제1회 EAM 시스템과 요구 사항
제2회 SSO 모델과 보안 기술
제3회 SSO·RBAC 표준화 동향


기업의 IT 인프라와 자산에 대한 통합화 및 관리 그리고 통제에 대한 관심이 증대되고 있다. 단순한 사내망에 불과하던 기업 IT 인프라가 직원, 고객, 파트너 등으로 사용자가 확대되면서 다양한 서비스를 요구받기 때문이다. 모든 기업들은 회사의 자원을 보호하고 자원에 대한 접근 권한을 관리함으로써 이러한 복잡한 문제들을 해결하길 바라고 있다. 이러한 기업의 요구에 부합하는 기술적 트렌드를 3회에 걸쳐 연재한다.

강신범 | 소프트포럼 기반기술개발실장


EAM(Extranet Access Management) 시스템은 인트라넷·익스트라넷 서비스를 동시에 수행하는 현재의 기업 IT 인프라 시스템을 안전하게 구성하고 효율적인 관리를 수행할 수 있는 환경 제공을 목적으로 한다.

EAM 시스템에 대한 이해를 돕기 위해 먼저 기업 내 IT 인프라를 EAM 시스템으로 통합하는 시나리오를 간단히 기술하고, 이 시나리오에 근거해서 EAM 시스템의 요구사항을 보안 a기술 측면에서 살펴본다.


EAM 시스템

현재 그룹웨어, 인사관리(HR) 시스템 그리고 전사적자원관리(ERP) 시스템을 운영하고 있는 회사의 경우 각 애플리케이션 별로 각각의 사용자 계정과 권한 관리를 위한 자원이 투입돼 운영된다. 이는 부가적인 관리를 필요로 함은 물론이고 획일적이고 통합되지 않은 상태의 시스템 운영으로 인한 다양한 부작용 및 보안적 결함을 드러내게 된다. 이와 같은 고민에 빠진 회사는 규모의 증대와 IT 인프라 확산에 비례해 보안적 결함이 점차 증가하게 된다. 또한 일정 시일 이후에는 EAM 시스템 도입 비용을 상회하는 기존 시스템의 운영비용으로 인한 손실분을 안게 되는 최악의 상황에까지 몰리게 된다.

이같은 회사가 EAM 시스템을 도입하게 되었을 경우에 회사 내부에서 사용되는 그룹웨어, HR, ERP를 EAM 시스템으로 통합하고 각 애플리케이션별로 개별적으로 관리되던 사용자 계정, 권한관리시스템까지도 단일화된 EAM 시스템에서 통합 관리하게 된다. 이 작업으로 인한 회사의 IT 인프라는 다음과 같이 변경된다.

우선 사내 직원은 사용자 인증을 최초로 한번 받고, 각 애플리케이션을 SSO(Single Sign-On) 기술에 의해 추가 인증없이 사용할 수 있다. 또한 각 애플리케이션은 개인화 서비스를 통해 인증된 사용자의 정보를 얻어 동작에 적용한다.

개별 애플리케이션은 통합된 인가·접근제어 정책에 따라 사용자의 접근을 제어한다. 사내 IT 인프라 관리자는 EAM 관리시스템을 통해 각 애플리케이션별로 접근권한을 사용자에게 제어할 수 있다. 사용자가 통합 인증을 받고 각 애플리케이션에 접근하는 모든 감사정보를 EAM 시스템이 관리해 개별적으로 관리되던 감사정보를 통합해 관리할 수 있게 된다.


EAM 시스템의 요구사항

EAM 시스템은 적어도 다음과 같은 6가지 요구사항 항목을 가진다.

△인증(Authentication):

시스템에 접근하는 사용자를 확인한다. 일반적으로 ID/PWD 방식이 가장 널리 사용되며 보안성을 강화하기 위해 암호, PKI 기술들이 이용된다.

△SSO:

통합 인증된 사용자가 개별 애플리케이션에 추가적인 인증 요구 없이 사용할 수 있어야 한다.

△인가·접근제어(Authorization):

개별 애플리케이션의 각 자원 및 서비스에 대한 인가·접근제어 권한을 관리 툴로 설정하고, 설정된 인가·접근제어 권한이 개별 애플리케이션 동작에 적용이 돼야 한다.

△개인화(Personalization):

통합 인증된 사용자가 개별 애플리케이션에 접근할 때, 접근하는 사용자의 아이덴티티(Identity)와 사용자의 정보를 확인할 수 있는 기술이 제공돼야 한다.

△관리(Administration):

통합 인증을 위한 사용자 계정, 개별 애플리케이션의 인가·접근제어, 개인화를 위한 정보제공의 범위, 감사기능 등을 편리하게 관리할 수 있는 기능이 제공돼야 한다.

△감사(Auditing):

전체 시스템에 접근해 통합 인증을 받고 SSO으로 개별 애플리케이션에 접근, 인가·접근제어가 수행되는 모든 과정이 감사 기록으로 남아야 한다.

<그림> Extranet Computing 환경


인증(Authentication)

EAM 시스템의 요구사항에서 사용자 인증에 관련된 보안 기술은 전체 시스템의 보안성에 매우 중요한 부분을 차지한다. 이와 관련해 EAM 시스템에서 사용될 수 있는 다양한 인증방법 기술에 대해서 소개한다.

인증방법은 기본적인 ID/PWD 방식과 보안성이 상대적으로 높은 X.509 인증서, OTP(One Time Password), 생체인식으로 나뉘어 진다. 아래에서 설명하고 있는 인증 방법들은 일반적인 EAM 시스템에서 웹 환경에 적용하기 적합한 기술들이다.

△Basic ID/PWD:

HTTP/HTTPS 프로토콜의 BASIC Authentication 방법을 이용해 ID와 패스워드로 사용자를 인증한다. 이 인증 방법은 HTTP 프로토콜을 사용하는 경우 사용자가 입력한 ID와 패스워드가 네트워크를 통해 암호화되지 않고 전송된다. HTTPS 프로토콜을 이용하는 경우에는 암호화돼 전달된다.

△Digest Authentication:

HTTP/HTTPS 프로토콜의 Digest Authentica-tion 방법을 이용해 ID와 패스워드로 사용자를 인증한다. 이 인증방법은 패스워드가 평문으로 전달되지 않아 Basic ID/PWD 인증보다 향상된 보안 서비스를 제공하지만, 패스워드가 저장될 때 반드시 패스워드 원본 혹은 복호화될 수 있는 정보로 저장돼야 하기 때문에 서버에서의 패스워드 관리에 각별한 주의가 요구된다.

△Form Based Authentication:

Customized Form(HTML/JSP/ASP etc.)을 이용해 사용자를 확인한다. 폼에 입력되는 인증 정보는 사용자 ID/PWD 만으로 구성될 수도 있고 사용자 ID/PWD 이외의 다른 정보, 예를 들어 사용자 주민등록번호 등을 추가적으로 포함해 사용할 수 있다. 전달되는 정보의 암호화를 위해서는 HTTPS 프로토콜이나 기타 암호 제품을 사용할 수 있다.

△X.509 Client Certificate over SSL:

HTTPS 프로토콜의 사용자 인증서 인증 프로토콜을 이용해 인증한다. 인증서의 폐기 여부 확인을 위해 CRL 검증과 OCSP 검증 방법을 사용할 수 있다.

△One Time Password 인증:

한 번만 사용될 수 있는 패스워드를 이용해 사용자를 인증한다. 사용자에게 미리 전달된 OTP Token을 이용하여 사용자를 인증한다.

△생체 인식:

사용자의 지문이나 홍채 등을 이용해 사용자를 인증한다. 아직은 널리 사용되고 있지 않으나 지문 인식의 경우 그 영역이 확대되고 있는 추세이다.

지금까지 기업의 IT 인프라 관리를 위해 효율성과 보안성을 모두 만족시킬 수 있는 EAM 시스템에 대한 개념과 요구사항을 살펴봤다. 기업의 다양한 IT 시스템 운영에 있어서 보다 안전하고 저비용의 운영 방식을 원한다면 각 애플리케이션 별로 분산돼 있는 인증과 권한 관리 부분을 통합시켜 전사적인 관리가 가능한 EAM 시스템 도입을 고려해 봐야 한다.



연재/EAM·SSO 기술과 표준화 동향 ②

SSO 모델과 보안 기술

강신범
소프트포럼 기반기술개발실장

연·재·목·차

제1회 EAM 시스템과 요구 사항
제2회 SSO 모델과 보안 기술
제3회 SSO·RBAC 표준화 동향

SSO 모델

일반적으로 사용되는 SSO 시스템은 두 가지 모델로 구분된다. SSO 대상 애플리케이션에서 사용되는 사용자 인증 방법을 별도의 SSO 에이전트가 대행해주는 Delegation(인증 대행) 방식과 SSO 시스템과 신뢰관계를 토대로 사용자를 인증한 사실을 전달받아 SSO를 구현하는 Propagation(인증정보 전달) 방식으로 구분된다.

<그림 1> SSO Delegation Model

△Delegation 방식: 대상 애플리케이션의 인증 방식을 변경하기 어려울 때 많이 사용된다. 대상 애플리케이션의 인증 방식을 전혀 변경하지 않고, 사용자의 대상 애플리케이션 인증 정보를 에이전트가 관리해 사용자 대신 로그온 해주는 방식이다. 즉 Target Server 1을 로그온 할 때 User1이 alice/alice라는 ID/ PWD가 필요하다면, 에이전트가 이 정보를 가지고 있고, User1이 Target Service 1에 접근할 때 에이전트가 대신 alice/alice ID/PWD 정보를 전달해서 로그온 시켜준다. △Propagation 방식: 통합 인증을 수행하는 곳에서 인증을 받아 대상 애플리케이션으로 전달할 토큰(Token)을 발급 받는다. 대상 애플리케이션에 사용자가 접근할 때 토큰을 자동으로 전달해 대상 애플리케이션이 사용자를 확인할 수 있도록 하는 방식이다. 웹 환경에서는 쿠키(Cookie)라는 기술을 이용해 토큰을 자동으로 대상 애플리케이션에 전달할 수 있다. 이러한 웹 환경의 이점으로 웹 환경에서의 SSO는 대부분 이 모델을 채택하고 있다.

<그림 2> SSO Propagation Model

△Delegation & Propagation 방식: 웹 환경이라고 하더라도 Propagation 방식이 모두 적용될 수는 없다. 특히 웹 애플리케이션의 변경이 전혀 불가능하고 사용자 통합이 어려운 경우 Delegation 방식을 사용하게 된다. 또한 대상 애플리케이션들이 많이 있고 애플리케이션의 특성들이 다양한 경우 각 애플리케이션에 Delegation 방식과 Propagation 방식을 혼용해서 전체 시스템의 SSO을 구성한다.

△Web 기반 One Cookie Domain SSO: SSO 대상 서비스와 응용 애플리케이션들이 하나의 Cookie Domain안에 존재할 때 사용된다. 일반적인 기업 내부의 컴퓨팅 환경이다. 통합인증을 받은 사용자는 토큰을 발급받게 되고, 이 토큰은 Cookie Domain에 Cookie로 설정되어 Cookie Domain 내의 다른 서비스로 접근할 때 자동으로 토큰을 서비스에 제공하게 된다. 서비스에서 동작되는 SSO 에이전트는 토큰으로부터 사용자 신원을 확인하고 요청된 자원에 대한 접근을 허가 해준다.

Web 기반 Multi Cookie Domain SSO

SSO 대상 서비스와 응용 애플리케이션들이 여러 도메인으로 분산돼 있을 경우다. Multi Domain 환경인 경우에는 사용자 인증 및 토큰의 발행을 위한 마스터 에이전트가 존재한다.
마스터 에이전트는 각 서비스 에이전트의 사용자 인증을 위임받아 수행한다. 인증된 사용자에게는 토큰을 발급하고 각 서비스 에이전트에게 안전하게 전달한다. 또한 에이전트가 해당 토큰을 자신의 Domain에서 Cookie로 저장해 사용할 수 있도록 한다. 각 서비스 에이전트의 신뢰도 및 SSO 시스템의 보안 레벨에 따라 다음과 같이 두 가지 방식으로 서비스될 수 있다.

<그림 3> One Token for All Multi Cookie Domain

△One Token for All Multi Cookie Domain: 모든 도메인이 하나의 토큰을 공유한다. 모든 시스템은 서로 신뢰관계를 가져야 한다. 토큰이 하나만 사용되므로, 마스터 에이전트는 사용자 인증 및 각 도메인에 대한 토큰 제공에 대해서만 수행하게 돼 에이전트들의 관리 및 구성이 매우 간단하다. 하지만 모든 도메인들이 서로 신뢰관계를 가져야 한다는 제약사항으로 인해 적용대상이 제한적이다. 일반적으로 하나의 기업에서 운영하는 다중 도메인 서비스들을 SSO로 구성할 때 많이 사용된다.

<그림 4> One Token form each cookie domain & One Token for Master Agent

△One Token for each cookie domain & One Token for Master Agent: 마스터 에이전트와 각 도메인들이 각각 토큰을 가진다. 마스터 에이전트는 각 도메인의 에이전트들과 신뢰관계를 가지며, 각 도메인의 에이전트들 사이는 신뢰관계를 가지지 않는다. 마스터 에이전트는 각 도메인의 에이전트에게 전달할 사용자 토큰을 발행하므로, 에이전트들의 레벨이나 속성에 따라 토큰에 저장되는 사용자 정보의 양을 조절할 수 있다. 토큰이 각 도메인 별로 발행되므로, 도메인별 Replay Attack 등에 대한 취약성이 전체 시스템에 영향을 주지 않는다.

SSO 보안 기술

토큰은 쿠키를 통해 전달되므로 외부에 노출되는 정보이다. 완벽한 보안을 위해서는 토큰이 네트워크에서 노출되어서는 안되지만, 비용 및 관리상의 이유로 허용되고 있다. 하지만 토큰을 통해 토큰이 포함하고 있는 정보까지 외부에 노출하는 것은 심각한 결함을 제공한다. 토큰의 네트워크 구간에서의 정보 노출 및 위·변조를 방지하기 위해 다음과 같은 보안기술이 사용된다.

△Data Confidentiality: 토큰은 주요 암호 알고리즘(AES, SEED)과 128bit 이상의 키로 암호화돼 보호되어야 한다. △Data Integrity: 토큰은 MAC

(Message Authentication Code) 등을 포함해 데이터의 무결성을 보장해야 한다. △Replay Attack Protection: 토큰은 사용자와 대상 애플리케이션 사이에 전달되는 인증 정보이다. 일반적으로 토큰은 네트워크에 노출되며, 노출된 토큰을 사용해 다른 사용자가 인증을 받고 들어올 수 있다(Replay Attack). 특히 웹 환경에서 이러한 문제점이 중요한 이슈로 등장하고 있다. 이러한 문제점을 근본적으로 해결하기 위해서는 토큰을 네트워크에 노출시키지 않아야 한다.
토큰을 네트워크에 노출시키지 않기 위해서는 항상 사용자와 대상 애플리케이션 사이에 암호 채널을 형성해야 하며, 이 채널을 통해 토큰을 전달해야 한다. 그러나 SSL과 같은 채널 암호를 사용하는 데에는 매우 많은 비용이 요구되어 실제로 많이 사용되고 있지는 않다.
SSL과 같은 암호채널을 사용하지 않으면서 Replay Attack이 발생할 수 있는 상황을 줄일 수 있도록 다음과 같은 보안 기술들이 사용된다.

△사용자 주소 제한: 토큰이 발행될 때 접속한 사용자 주소 정보를 토큰 내부나 토큰을 발행한 서버에서 기억함으르써 Token이 제출된 사용자 주소와 최초 발행시 기억된 주소를 비교하여 접속한 곳 이외에서의 접속을 제한할 수 있다. 사용자 주소가 업무진행 중에 자주 변경되지 않는 시스템일 경우 유효하다. 예를 들어 회사내의 인터넷 환경일 경우 사용될 수 있다. 인터넷 환경의 경우에는 사용자 주소가 특정 범위에서 자주 바뀔 수 있는 환경도 있기 때문에 불특정 다수를 위한 일반적인 인터넷 서비스에 사용하기에는 부적합하다.

△유효시간 제한: 토큰의 유효시간을 매우 짧게 줌으로써 Replay Attack에 사용될 수 있는 시간을 제한한다. 유효시간내에 임계시간(예: 유효시간의 1/2)을 넘으면 자동으로 토큰을 재 발행하여 사용자는 의식하지 못하고 서비스를 계속 사용하게 한다. 지금까지 사용자가 각 애플리케이션별로 별도의 인증을 받지 않고, 한번의 통합 인증만으로 각 애플리케이션들을 사용할 수 있도록 하는 SSO 기술에 대해 살펴보았다. 대상 애플리케이션의 수정을 최소화할 수 있는 Delegation 모델과 토큰을 생성해 통합 인증 서비스를 제공하는 Propagation 모델 그리고 양자의 장점을 조합한 Delegation & Propagation 방식을 이해한다면 현재 도입 대상 기업의 IT 인프라와 진행중인 서비스 및 애플리케이션의 특성에 적합한 EAM 시스템 도입을 결정하는데 도움이 될 것이다.

EAM·SSO 기술과 표준화 동향

제3회 SSO·RBAC 표준화 동향

2007/10/11 16:27 2007/10/11 16:27
이 글에는 트랙백을 보낼 수 없습니다

예전부터 궁금했던 cross-domain 의 한계를 극복하는 방법을 찾았습니다. 2005년 자료이지만 근본적으로는 상관 없을듯  합니다. 원문의 내용을 나름 번역을 하였는데 최대한 빠르게 번역을 해보고자 하였기 때문에 어색한 부분이 많습니다. 그런 부분은 원문에 직접 가서 보는게 좋겠습니다.

원문 : http://fettig.net/weblog/2005/11/28/how-to-make-xmlhttprequest-connections-to-another-server-in-your-domain/

Updates to this post

이 기술문서의 업데이트된 버전(firefox 1.5에서 작업한)을 여기에서 볼 수 있다.

The problem

XmlHttpRequest(이하 XHR) 객체는  다른 서버의 데이터 접근으로부터 해당 데이터를 보호하기 위해 브라우저의 same origin security policy으로 둘러싸여져 있다. 이것은 Ajax 개발자에게 심각한 한계에 부딪히게 한다: 당신은 뒷단에서 server에 호출하기 위해 XHR을 사용할수 있을 것이다. 하지만 그것은 현재 페이지와 같은 서버에서 진행되어야만 한다. 이러한 한계점을 해결할수 있는 대안으로 알려진 것으로는 server-side reverse proxyingbypassing XmlHttpRequest entirely이 있다. 나의(원문 필자)의 경우 이러한 접근들 어느쪽도 실무와 연결되지 않았다. 나는 LivePage  (Divmod에서 Donovan Preston 과 다른 훌륭한 해커들에 의해 개발되어진 live-update 프래임워크)를 사용하길 원했다. LivePage는 동시에 많은 장기유지(long-lasting)되는 네트워크 연결을 핸들링하는데 좋은 Twisted를 사용하였기 때문에잘 작동되었다. 많은 long-lasting 연결을 핸들링하는데 아파치가 좋지 않게 됨에 따라 Twisted server의 앞단에 아파치 reverse proxy를 넣는 것은 performance와 scalibility를 손상시키는 주된 요인이될 것이다. 그리고 LivePage가 XHR에 제약을 받게됨에 따라 나는 궁극적으로 non-XHR를 사용할수가 없었다.

JotSpot과 함께 우리의 접근방식은 Twisted server가 모든 페이지의 요청과 XHR 호출을 핸들링하게 하였다. 그것은 JotSpot이 웹사이트 전용으로 standalone일때까지는 좋았다. 그러나 우리의 고객들이 요구하는 것은 보통 xxx.jot.com 사이트에서 Live-style의 실시간 업데이트를 할 수 있는 능력이었다. 그리고 우리는 우리의 도메인에 있는 모든 사이트의 앞단에 Twisted server를 넣는것을 원치 않았다. 따라서 나는 우리의 도에인의 모든 페이지에서도 XHR을 통해 live.jot.com과 통신할수 있게 할 수 있도록 하는 방법을 찾기 시작하였다. 결론적으로, 그것은 가능했다. 하지만 어떤 hoops를 뛰어넘어야만 한다. 여기 있는 예제들에 대해서 두가지를 알아둬라:

  • 나는 실제로 두개의 다른 server를 사용하지 않았다. 나의 예제에서, http://fetting.net/에 있는 페이지는 http://www.fetting.net/.에 XHR호출생성을 시도할 것이다.사실은 나의 아파치가 동일한 가상호스트를 만드는 것이 브라우저에게는 다르지 않게 보인다. 그것들이 같은 hostname을 가지고 있지 않다고 하더라도,그리고 두개의 다른 내용을 가지고 있는 다른 사이트라고 하더라도 다르지않게 취급되어진다. 만약 내가 ajax.fetting.net서버에 그것의 IP주소와 함께 XHR호출을 한다면 결과는 다르지 않다.
  • 나는 getUrl 한수를 제공해주는 간단한 XHR wrapper library를 사용하였다. getUrl은 URL과 callback 함수를 취하고, URL로 XHR연결을 열어준다, 그리고, 결과와 함께 함수를 호출한다. 만약 이것이 흥미롭다면 여기에서 full code를 볼 수 있다.
  • 내가 XHR호출을 만드는 서비스는 간단한 PHP페이지(ajaxdata.php)로 server에서의 편재 UNIX 시간을 출력한다 : 실제로는 그리 유용하지 않지만 테스트를 목적으로 하기에는 충분히 좋다.

첫번째 시도 : 고지식한 접근방식

여기 내가 시도한 첫번째 방식이 있다 :

다른 subdomain의 페이지의 full URL과 함께하는 XHR. 나는 이것은 동작하지 않을 것이라 확신했지만, 나는 이것을 검증해보고 싶었다 :

  1. <html>
    1. <head>
      1. <script type=”text/javascript” src=”xmlhttp.js”></script>
      2. <script type=”text/javascript”>
        1. var AJAX_URL=”http://www.fettig.net/playground/ajax-subdomain/ajaxdata.php”;
        2. function getTime(){
          1. getUrl(AJAX_URL, gotTime);
        3. }
        4. function gotTime(status, headers, result) {
          1. document.getElementById(’time’).innerHTML = result;
          2. setTimeout(getTime, 1000)
          3. }
        5. window.onload = getTime;
      3. </script>
    2. </head>
    3. <body>
    4. <div id=”time”>
    5. </div>
    6. </body>
  2. </html>
이 페이지는 fetting.net으로부터 전달되어졌고, www.fetting.net으로 XHR 호출을 생성하려하고 있다. 실제로는, 이러한 것들이 같은 server겠지만, browser는 그것을 알지 못한다. 놀랄것도 없이, 이것은 어떤 브라우저에서도 동작하지 않는다. 당신은 다음과 같은 security error를 받을 것이다(firefox로 부터) :
  1. uncaught exception : Permission denied to call method XMLHttpRequest.open
당신은 여기서 그것을 해볼 수 있다.

두번째 시도 : iframe과 document.domain 사용하기

나의 최근 JotSpot 사무실로의 방문에서 Alex는  iframe과 document.domain 프로퍼티를 가르쳐주었다. iframe은 다른 페이지로부터 현재의 페이지에 데이터가 로드되는 것은 XHR과 유사하다. 그러나 iframe은 그것들이 포함하고 있는 페이지들과 동일한 웹서버로부터 당겨오는 페이지에 한계가 없다 - 그들은 그 어떤 URL도 로드할 수 있다. cross-site 보안문제를 예방하기 위해서 브라우저는 javascript object model에 same origin policy를 강요한다:한 frame에서 동작하는 script는 각각의 페이지가 동일한 서버에서 온 것이라 할 지라도, 다른 어떤 iframe 안에 있는 객체에도 접근을 할 수 없다. 그러나, 이러한 규칙에도 예외가 있다. 만약 각각의 페이지가 동일한 parent domain으로 부터 왔고, 각각의 document.domain프로퍼티에 동일한 parent domain을 가리키도록 설정하면, 각각의  iframe에서 동작하나는 script는 각각 서로간에 통신을 허용할 것이다.

예를 들어, http://www.example.com/http://ajax.example.com/을 iframe에 로드한다고 하자. 각각의 페이지가 example.com 도메인에 있는 한, 만약 각각의 document.domain이 "example.com"으로 설정되어 있다면 그것들은 서로간의 데이터에 접근을할 수 있게된다.

그럼, 당신은 iframe과 document.domain을 XHR 연결에 사용할 수 있는 것인가? 두가지의 제약사항과 함께 가능하다.

  1. iframe은 반드시 당신이 XHR호출을 하는 서버로부터 와야 한다.
  2. 반드시 document.domain을 설정하기 전에 XHR 연결(open)을 해야만 한다.

여기 내가 사용한 코드가 있다. 첫번째로, test2.html :

  1. <html>
    1. <head>
      1. <script type=”text/javascript”>
        1. document.domain=”fettig.net”;
        2. function gotTime(result) {
          1. document.getElementById(’time’).innerHTML = “Server timestamp: ” + result;
        3. }
      2. </script>
    2. </head>
    3. <body>  
      1. Single XmlHttpRequest. Works in all modern browsers.
      2. <div id=”time”></div>
      3. <iframe src=”http://www.fettig.net/playground/ajax-subdomain/test2-iframe.html”>    </iframe>
    4. </body>
  2. </html>
이 페이지의 script는  document.domain을 설정하고, XHR 호출의 결과를 핸들링하는 gotTime 함수를 정의한다. 모든 XHR 덩어리들은 iframe에서 일어난다. 여기에 test2-iframe.html코드가 있다 :
  1. <html>
    1. <head>
      1. <script type=”text/javascript” src=”xmlhttp.js”></script>
      2. <script type=”text/javascript”>  
        1. var AJAX_URL=”http://www.fettig.net/playground/ajax-subdomain/ajaxdata.php”;    function gotResult(status, headers, result) {
          1. document.domain = “fettig.net”; // set d.d before talking to parent frame      window.parent.gotTime(result);
        2. }
        3. getUrl(AJAX_URL, gotResult);
      3. </script>
    2. </head>
  2. </html>

test2-iframe.html은 www.fetting.net에 XHR호출을 만든다. 그것은 www.fetting.net으로 부터 왔기때문에 가능한 것이다. 따라서 그것은 단지 그것의 원천 서버에 요청을 하것 뿐이다. 그것이 한번 응답을 받으면, 그것은 parent frame의 document.domain과 매칭시키기 위하여  document.domain을 fetting.net으로 설정한다.이제 그것은 javascript를 사용하여 parent frame에 요청을할 수 있다. 따라서 그것은 window.parent.gotTime을 하는것이 가능하다.

이것을 하기 위한 중점은 올바른 요청에 있다. 당신이 한번 document.domain을 설정하면 당신은 XHR 호출을 만들 수 잇는 능력을 잃게 된다. 따라서 당신은 document.domain을 설정하고 parent frame과 통신을 가능케 하기 전에 당신의 XHR 작업에 신경을 써야할 것이다.

Konq이러한 규칙을 따르면 잘 작동할 것이다. 이 기술들은 현대의 모든 브라우저에 잘 작동되어진다(나는 IE6, Firefox1.0.7, Safari 1.3, Opera8.5, 그리고ueror 3.4에서 테스트를 해보았다)
당신은 여기에서 그것들은 테스트해볼수 있다.

세번째 시도 :  XmlHttpRequest 반복하기

나는 우리의 도메인에 있는 다른 서버로 한개의 XHR을 생성하는 방법을 해결하여 기뻤다.  그러나 현시점에서 이 기술은 거의 심각한 한계를 가지고 있다.:당신은 XHR호출을 당신이 document.domain을 설정한 시점에서만 할 수 있다. 당신이 한번 그렇게 하면, 당신은 parent frame과 통신할 수 있는 능력을 얻게 되지만, 앞으로 XHR 호출을 할수있는 능력은 잃게 된다. 계속적으로 서버에 XHR 호출을 생성하고 결과를 핸들링해야하는 능력이 필요한 LivePage에게는 이것은 좋지 못한 방법이었다. 나는 iframe이 server(XHR를 사용하여)와 parent frame(document.domain을 설정해야지만 할 수 있는)과의 통신 모두를 할 수 있는 방법이 필요했다.

이로서 질문한가지를 떠오르게 하였다 : document.domain 프로퍼티를 한번만 설정할수 있는가? 혹은 fly에서 그것을 switch할 수 있는가? 만약 그 변경을 앞으로 혹은 뒤로 되돌릴수 있다면, 그것을 앞으로 뒤로 바꾸는 것은 가능할 것이다. 여기에 iframe의 수정된 버전인 test3-iframe.html이 있다.

  1. <html>
    1. <head>
      1. <script type=”text/javascript” src=”xmlhttp.js”></script>
      2. <script type=”text/javascript”>  
        1. var AJAX_URL=”http://www.fettig.net/playground/ajax-subdomain/ajaxdata.php”;
        2. function gotResult(status, headers, result) {
          1. var oldDomain = document.domain;
          2. document.domain = “fettig.net”;
          3. window.parent.gotTime(result);
          4. document.domain = oldDomain;
          5. setTimeout(getTime, 1000);
        3. }
        4. function getTime(){    
          1. getUrl(AJAX_URL, gotResult);
        5. }
        6. getTime();
        7. </script>
      3. </head>
    2. </html>
결과는 test2-iframe.html에서와 비슷하게, test3-iframe.html에 있는 gotResult 함수는 document.domain을 fetting.net(parent frame에 접근을 가능케 하기 위해)로 설정하고 window.parent.gotTime을 호출한다. 그러나 첫번째로 해당 페이지가 전송되어진 호스트를 디폴트로 하는 현재의 document.domain값을 저장해놓는다. 그것은 parent와의 작접을 끝낸 후, 그것은 document.domain을 원래의 값(XHR 을 생성할 수 있는 처음에 저장한 domain주소)으로 바꾸어 설정한다.  그런다음 그것은 다른 XHR 호출을 설정하기 위하여 setTimeout을 사용한다. 결과는 main page에서 timestamp가 계속해서 갱신되어져야만 한다.
당신은이 동작을 여기서볼수 있다.
이 페이지는 iframe이 각 시간마다 parent page에 있는 함수를 호출하고 XHR을 반복적으로 생성해내고 서버로부터 결과를 얻어낸다 . 불행하게도 이 기술은 IE,Safari,Knqueror에서는 잘 작동되지만 Mozilla와 Opera에서는 작동하지 않는다. 첫번째 XHR은 동작을 하지만, document.domain을 원래의 값으로 바꾸려고 할때 오류가 발생할 것이다. Firefox에서는 다음과 같은 error message를 발생시킨다.
  1. Error: [Exception... "Illegal document.domain value"   code: “1009″  nsresult: “0×805303f1 (NS_ERROR_DOM_BAD_DOCUMENT_DOMAIN)”   location: “http://www.fettig.net/playground/ajax-subdomain/test3-iframe.html  Line: 13″]
Mozilla와 Opera는 document.domain의 값에 대해서 더욱 엄격하다 - 그것은 오직 현재의 값이나 더 상위 레벨의 도메인으로만 설정이 가능하다.예를 들어서 만약 호스트가 aaa.bbb.example.com이라면, 나는 document.domain을 bbb.example.com으로 바꿀수 있다. 이러한 점에서 나는 그것을 다시 example.com으로 바꿀수 있었지만, 다시 aaa.bbb.example.com으로 되돌릴수는 없었다. 한번 당신이 상위레벨의 도메인으로 옮겼다면 다시는 하위레벨로 수정할수가 없어서 곤경에 빠질 것이다.

네번째 시도 : Mozilla에서 동작하게 하기

나는 Opera없이 살 수 있지만 Mozilla없이는 살 수 없다. 따라서 나는 그 문제를 해결할 수 있는 방법을 찾아내야 했다. 잠시동안 그것에 대해서 생각해본뒤 나는 의문이 생기기 시작하였다 : frame들간에 통신에 있어서 보안상의 제한이 단지 어떻게 엄격하게 규정되어지는가? 우리는 브라우저들이 해당 frame의 document.domain이 같은 값을 가지고 있지 않은 이상은 다른 프레임으로의 접근을 하지 못하도록 한다는 것을 알고 있다. 따라서 child frame들의 document.domain을 설정이 parent의 그것과 같지 않다면 child에서 window.parent.foo에 접근하는 것은 불가능 하다. 그러나 만약 당신이 parent frame에 있는 함수를 지시할수 있도록 childframe에 있는 attribute를 설정할 수 있다면, 그리고 document.domain을 바꿀 수 있다면 어떤가? child frame은 여전히 함수를 호출할수 있을까? 대답은 "그렇다"이다. 그리고 그것은 내가 Mozilla에서 작업하는데 있어서 필요로 하는 것을 충족시켜주었따. 방법은 두개의 frame을 사용하는 것:

  1. parent window  bridge iframe  child iframe
bridge iframe과 child iframe은 모두 당신이 XHR 호출을 만들고자 하는 서버로부터 존성되어졌다. parent apge 코드는 위에서의 예제와 동일하다 :그것은 XHR의 결과를 핸들링하는 함수를 정의하고, iframe을 로딩한다. 여기서는 bridge code를 보자 :
  1. <html>
    1. <head>
      1. <script type=”text/javascript” src=”xmlhttp.js”></script>
      2. <script type=”text/javascript”>  
        1. function gotTime(result) {    
          1. window.parent.gotTime(result); // pass result up to the parent  
        2. }  
        3. window.onload = function(){
          1. var subframe = document.createElement(’iframe’);      document.body.appendChild(subframe);
          2. subframe.src = “test4-iframe.html”;
          3. subframe.contentWindow.bridgeGotTime = gotTime;
          4. document.domain = “fettig.net”;
        4. }
      3. </script>
    2. </head>
    3. <body>
    4. </body>
  2. </html>

이 frame이 로드될때, 그것은 다른 frame 그 안에 로드한다. child frame이 bridge frame과 동일한 서버로부터 로딩되어지는 한, bridge frame은 script를 통해서 child frame의 객체에 접근할 수 있다.bridge frame은 그것만의 gotTime에 subframe.contentWindow.bridgeGotTime를 설정한다. 다음으로 bridge frame은 그것의 document.domain을 그것의 parent widnow의 그것과 매칭시켜 변경한다.이 시점에서 bridge frame은 그들의 document.domain 프로퍼티가 매칭되지 않을때까지 child frame에 직접적으로 통신할수 있는 능력을 잃게 된다. 그러나 child frame은 처음에 설정해놓았던 bridgeGotTime 함수를 통해서 bridge frame과 통신을할수 있는 능력을 유지할수 있게된다. 그리고 bridge frame의 document.domain이 parent의 document.domain과 매칭되는한, bridge와 parent는 자유롭게 통신할수 있다. 나의 제한적인 테스팅에서는,이 기술은 오직 Mozilla-based 브라우저에서만 작동하는것처럼 보였다. (나는 Opera에 대한 방법을 찾지 못했지만, 여기에 시간을 많이 소비할 생각은 없다).

나의 마지막 예제에서는 document.domain을 switching하고, 만약 당신이 document.domain을 재설정하려고 할때 브라우저가 에러를 발생시킨다면 bridge-iframe에 의지할 수 있는 hybrid적인 접근방식을 사용하였다. 여기 main page code가 있다 :

  1. <html>
    1. <head>
      1. <script type=”text/javascript”>
        1. document.domain=”fettig.net”;
        2. function gotTime(result) {
          1. document.getElementById(’time’).innerHTML = “Server timestamp: ” + result;
        3. }
      2. </script>
    2. </head>
    3. <body>
      1. <div id=”time”></div>
      2. <iframe src=”http://www.fettig.net/playground/ajax-subdomain/test4-iframe.html”></iframe>
    4. </body>
  2. </html>
여기까지는 iframe이  test4-iframe.html으로부터 로드되어져 온다는 것을 제외하고는 모든것이 동일하다. 여기 그 페이지의 코드가 있다 :
  1. <html>
    1. <head>
      1. <script type=”text/javascript” src=”xmlhttp.js”></script>
      2. <script type=”text/javascript”>  
        1. var AJAX_URL=”http://www.fettig.net/playground/ajax-subdomain/ajaxdata.php”;    function getTime(){
          1. getUrl(AJAX_URL, gotTime);
        2. }
        3. function gotTime(status, headers, result) {
          1. var oldDomain = document.domain;
            1. if (window.bridgeGotTime) {
              1. window.bridgeGotTime(result);    
            2. } else {
              1. document.domain = “fettig.net”;      
              2. window.parent.gotTime(result);    
            3. }
            4. try {
              1. document.domain = oldDomain;
              2. setTimeout(getTime, 1000);    
            5. } catch(e) {
              1. // denied access to switching the domain, use bridge instead        document.location.replace(”test4-bridge.html”);    
            6. }  
          2. }  
          3. getTime();
          4. </script>
        4. </head>
      3. </html>

이 코드는 XHR서버와 parent frame 각각에 대하여 통신할 필요가 있을때마다 document.domain을 전 후로 변환하는 것을 시도한다. 그러나, 만약에 이것이 실패한다면  그것은 대신하여 bridge iframe을 로드할 것이다. 두개의 다른 페이지가 동일한 일을 하게 하기 위하여,이 페이지는 bridge frame의 child로서도 수행되어진다. 만약 그것이 widnow.bridgeGotTime 어트리뷰트를 보게 되면 그것은 bridge iframe의 아래에서 수행되어진다는 것을알수 있을 것이고, 따라서 그것은 직접적으로 widnow.parent를 요청하는 대신에 window.bridgeGotTime를 요청할 것이다.

당신은 이 액션을 test4.html에서 볼 수 있다. 그것은 Opera를 제외한 최근 모든 브라우저에서 작동한다.

Update : test5.html를 사용하라(갱신되었음). 자세한 내용은 여기 참고

결론 :  당신의 도메인에서 다른 서버에 XHR호출을 만드는 것은 가능하다. 만약 당신이 약간의 설정상의 오버로드를 감안할 의지가 있다면 당신은 반복적으로 호출할 수도 있다. 이것은 여러가지의 이점을 가지고 있다 :
  1. 만약 페이지의 주요 컨텐츠가 아파치나 다른 어떤 웹서버로부터 불러져온다면 그동안 LivePage 요청은을 핸들링하는 전용 Twisted server 를 가질 수 있다.
  2. XHR을 포함하는 웹서비스를 핸들링할수 있는 전용 서버를 가질 수 있다.
  3. two-max-connection이라는 브라우저의 한계로부터 DNS에서 자유롭게 XHR를 사용할 수 있다. 브라우저는 당신이  한번에 두개가 넘은 연결을 할수 없게할 것이다-만약 당신이 JotSpot Live와같은 어플리케이션을 사용하고 한번에 한개가 넘는 탭으로 이동하려고 한다면 뒤죽박죽이 되어질 수 있다. 그러나 만약 XHR이 같은 서버에서 호출되지 않아도 된다면, 당신은 wildcard DNS를 사용할 수 있고,
2007/10/09 13:51 2007/10/09 13:51
이 글에는 트랙백을 보낼 수 없습니다
웅쓰:웅자의 상상플러스
웅자의 상상플러스
전체 (379)
게임 (5)
영화 (2)
기타 (23)
맛집 (5)
영어 (2)
대수학 (3)
형태소 (5)
Hacking (9)
Linux (112)
HTML (48)
Application_developing (48)
Web_developing (102)
Window (11)
«   2007/10   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
  1. 2016/01 (1)
  2. 2015/12 (3)
  3. 2015/10 (3)
  4. 2015/03 (2)
  5. 2015/01 (4)