썰렁한 엔지니어

Adventures of Bilbo Baggins

못생긴 PHP create_function

2008/07/16 19:01  |   장난하기  |   최호진
PHP의 lambda function 제조기는 create_function 이라는 함수 입니다. 대략 이렇게 사용하죠.

<?php
$times = 5;
$yourarray = array_map( create_function( '$item', "return \$item * $times;" ), $myarray );
?>
실시간으로 만들어지는 함수를 map 함수에 집어 넣는 전형적인 예입니다. 그런데 너무 못생기지 않았나요? 그런데 딱히 PHP 구문에 맞추면서 근사한 뭔가도 만들기 쉽진 않아 보입니다. 위의 예에서 함수 본체에 해당하는 "return \$item * $times;"는 모두 문자열이기 때문에 런타임 파싱의 오버헤드가 있는데, 이것을 컴파일타임으로 올리고, 변수의 스코프만 적절히 만들어주면, 굳이 문자열로 가지 않고도 대략,

<?php
$times = 5;
$yourarray = array_map( function ( $item ) { extern $times; return $item * $times; }, $myarray );
?>

이렇게 하면 되지 않을까 싶은데, 이정도면, $times를 런타임에서 패싱해야하므로, 내부적으로는 global 키워드 취급해서 스코프 체인을 현 스택에서부터 뒤지는 것으로 가면되지 않을까 싶은데...

이러면, 컴파일타임으로 많은것을 끌어 올릴 수 있지 않을까...

크리에이티브 커먼즈 라이센스
Creative Commons License
2008/07/16 19:01 2008/07/16 19:01

다른 도메인간의 자바스크립트 장난질2

2008/07/01 20:21  |   장난하기  |   최호진
지난 글에 이어 생각해 볼만한 문제 회피 방법을 소개할까합니다. domain이 다른 상황에서 데이터를 요구하거나 전송하고자할 때 사용하는 방법으로 script tag 삽입(dynamic script tag)이라는 기법이 사용됩니다. (참고 1: 구글 책 검색) (참고2)

www.example.com: main.html
<script>
function draw( result )
{
    if( result ) { alert("성공"); } else { alert("실패"); }
}

function addComment( id, comment )
{
    var scr = document.createElement( "SCRIPT" );
    scr.src = "http://external.example.net/api/get_tags?article_id="+
id+"&comment="+encodeURIcomponent(comment)+"&callback=draw";
    document.body.appendChild( scr );
}
</script>
위 스크립트는 도메인이 www.example.com에 있으면서, external.example.net이라는 외부 도메인의 글에 댓글을 달 수 있는 방법에 대한 하나의 예시입니다. 전형적이죠.

위 방법의 단점이 있으니 그것은, 위 방법은 GET 방식을 통해 이루어지는 URL 길이 제한에 걸린다는 것입니다.

검색 결과를 참고해봐서 인용하자면,
IE: 2083, FF: 65,536, Safari: 8,000, Opera: 190,000
Apache: ~4,000 IIS: 16,384
http://www.boutell.com/newfaq/misc/urllength.html
정도입니다.
아쉽게도 IE의 경우 2083자 정도이고, 이것은 UTF8의 경우 URL에서 한글 인코딩은 한 글자당 9byte를 소비하므로, 호스트명이나 변수명등을 제외하면, 200자정도로 제한 되는 것을 알 수 있습니다.

따라서, POST를 쓸 수 밖에 없습니다만, 이 경우 script 태그를 통한 방법으로는 GET만 가능하므로 어렵습니다. 숨겨진 IFRAME을 만들고, 이 녀석 안에서 FORM을 만들어 전송하는 방법으로 해야겠습니다.

다음과 같은 방법을 소개합니다.

example.com: main.html
<script>
var request = {};
var requestCount = 0;
function addComment( id, comment )
{
    request[requestCount] = {id:id, comment:comment};
    var irf = document.createElement( "IFRAME" );
    ifr.src = "post.html#"+ requestCount;
    requestCount++;
    document.body.appendChild( ifr );
}
</script>
example.com: post.html
<html>
<head><meta http-equiv="Content-Type"
content="text/html; charset=utf-8" /></head>
<body>
<script>
var request = window.parent.request[document.location.hash.substr(1)];
var form = document.createElement( 'FORM' );
var key = document.createElement( 'INPUT' );
var value = document.createElement( 'INPUT' );

form.action =
"http://external.example.net/api/addComment?callback=dummy";

form.method = "post";
key.name = "article_id";
key.value = request.id;
value.name = "comment";
value.value = request.comment;

document.body.appendChild( form );
form.appendChild( person_id );
form.appendChild( key );
form.appendChild( value );
form.submit();
</script>
</body>
</html>

/* Dynamic script tag technique has limitation of URL max length */
원리는 간단합니다. 숨겨 있는 IFRAME에서 자기의 주소 뒤에 오는 fragment (#) 부분을 해석하여, 부모 프레임에 숨겨 있는 개체에 접근합니다. 주소에 넣기 싫다면, 숨겨 있는 frame을 만들때 name에 넣어주고, window.name으로 접근해도 됩니다.

간단하죠? 단,iframe을 사용할 경우, iframe이므로 /api/addComment의 결과는 text/html과 같이 브라우져 안에서 해결할 수 있는 MIME 형식이어야합니다. 또한 callback이 동작하지 않습니다. FORM이 전송되고 나면, iframe은 더이상 www.example.com이 아닌 external.example.net 소속이 되므로, 부모에 접근할 수 없게 됩니다. 꼭, callback을 호출하고 싶을 때는 api의 결과창이 다시 redirect되어 상위에 접근할 수 있도록 바뀌어야합니다. 이것은 숙제로 남겨 둡....니다.
크리에이티브 커먼즈 라이센스
Creative Commons License
2008/07/01 20:21 2008/07/01 20:21

텍스트큐브 MMS 기반 모바일 로그

2008/07/01 19:54  |   장난하기/Textcube  |   최호진
텍스트 큐브 1.7 확장팩으로 들어가 있는 모바일 플러그인을 설계할 때, 몇가지 번쩍인 생각들에 대해 공유하고 자 합니다.

전화번호

다른 모바일 블로그와 달리 이 기능은, 전화번호 인증을 하지 않습니다. 사실, 제 휴대폰이 IM-7400 SKY 폰인데, 여기에 설치되어 있는 컬러메일 기능은 전화번호를 보내오지 않습니다. 그래서 처음부터 전 모든 MMS에서 휴대폰 번호가 올라오지 않는 줄 알았습니다. 그러다가 테스트해 본 다른 폰에서는 올라오기도 하는 것이었습니다.

잘 찾아보면 MMS 규격을 찾을 수 있겠지만, 기본적으로 Email MIME 형식만으로 만들 수 있기 때문에 Email blog 형식으로 바로 진행하였습니다. 모바일에서 올라오는 특성들이 표준을 모두 준수해서 올라올 것이 아니겠더군요.

이메일 서버

이메일 서버를 돌려야 MMS 메시지를 받을 수 있습니다. 그러나, 수많은 Textcube 사용자에게 이메일 서버를 돌리라는 것은 사실 무리입니다.

이것의 대안으로, textcube.org 메일 서버를 MMS 수신용도로 돌려서, 블로그에 쏴주는 방법도 있겠습니다만, 저희가 서버 운영을 하기에는 설치형 블로그에서 부담스러운 일이 될 것입니다.

따라서, 외부 메일 서버를 사용하고 POP3를 이용하기로 결정하였습니다. 따라서, 메일을 받은 즉시 처리할 수 있는 실시간성을 포기하고, 5분정도의 간격으로 처리하는 방법을 사용합니다.

주기적인 작업

위에서 말한대로, POP3의 경우 주기적으로 메일이 왔는지 확인해야 합니다. 그러면, 누가 그 5분을 계산해서 명령을 수행한단말입니까? 웹서버만 있는 환경에서 주기적인 작업을 실행하기 위해서는 UNIX계열의 cron이나 Window 계열의 AT 명령을 이용해야하는데, 사실상의 많은 호스팅 업체에서는 잘 허락해주지 않습니다.

이를 위해서, Referer 없이 들어오는 없는 페이지에 대한 요청 로그였습니다. Referer가 있을 경우 페이지상의 잘못된 링크로 인한 css, image등일테니 페이지 렌더링에 영향을 줍니다만, referer가 없는 경우 웜 같은 경우가 많을 것이라 판단하여, 이들의 404 not found page 뒷부분에 cron 작업을 실행해야할지 판단합니다.


크리에이티브 커먼즈 라이센스
Creative Commons License
2008/07/01 19:54 2008/07/01 19:54

다른 도메인간의 자바스크립트 장난질

2008/06/07 01:57  |   장난하기  |   최호진
브라우저에서 사용되는 자바스크립트는 잘 알고 있다시피, DOM 구조상 document 개체의 domain이 다르면 접근할 수 없는 것으로 알려져 있습니다. (참고) 그 규칙에 따라서, 브라우저 제작사들은 적절한 접근제한을 가하고 있습니다.

몇가지 상황에서 우회로를 뚫어 보겠습니다.


세션키 전달


같은 데이터베이스를 사용하지만, TLD나 1차 도메인 명이 다른 두 개의 다른 도메인으로 운영되되는 사이트를 운영할 때는 싱글사인온 같은 문제가 발생합니다. 한가지 팁으로 사용되는 방법으로는 현재의 window.name에 값을 저장하고 도메인이 달라지는 다음 페이지에서 window.name을 조사하여 전달하는 방식을 iframe에 응용하는 것입니다.

example.com: main.html
<html><body>
<iframe src="http://example.net/othersite.html" name="SESS_12345678"></iframe>
</body></html>
example.net: othersite.html
<html><head>
<script>if( document.cookie.indexOf( 'SESSION' ) < 0 && window.name.substr(0,4) == 'SESS' ){
    document.cookie = "SESSION="+window.name.substr(5);
    document.location.href = document.location.href; /* 다시 로드 */
}
</script>
</head></html>

변화하는 값 전달

위의 예는 페이지가 로드될 때 한 번 일어날 수 있는 상황에서 사용됩니다. 다음 소개하는 예는 IE에서만 동작하는 팁입니다.

example.com: main.html
<html>
<body>
<iframe width="300px" height="1024px" src="http://example.net/othersite.html" name="other"></iframe>
<script>
setInterval( function() {
    window.frames['other'].name = (new Date()).getTime();
}, 1000 );
</script>
</body></html>
example.net: othersite.html
<html><body>
<span id="display"></span>
<script>
setInterval( function() {
    document.getElementById('display').innerHTML = window.name;
}, 1000 );
</script></body>
</html>
IE에서만 동작하는 이유는 window.frames['other'].name 속성이 접근가능하기 때문입니다. 분명히, 다른 도메인인데도 불구하고, 해당 윈도우의 속성을 변경할 수 있게 되고, 그것을 통해서 두 도메인간 데이터를 교환할 수 있는 방법이 존재하는 것입니다. IETester를 이용해서 확인한 결과 5.5~8Beta1까지 모두 사용이 가능하더군요.

FF, Opera, Safari에서는 위 코드가 모두 접근 오류를 일으키고 실행되지 않습니다.


크리에이티브 커먼즈 라이센스
Creative Commons License
2008/06/07 01:57 2008/06/07 01:57
이올린 태그검색올블로그 태그검색티스토리 태그검색, 이올린 태그검색올블로그 태그검색티스토리 태그검색

쵝오 만들기

2008/06/05 12:01  |   장난하기  |   최호진
한글 초,중,종성 분리 코드를 만든 딱 한가지 이유는, 채팅체로 많이 쓰이는 형식, "쵝오(최고)"! 와 같은 방식으로 기존 문서를 바꾸는 툴을 만들고 싶은 생각에서 였습니다.

배고픈데 밥이나 먹죠 -> 백호픈데 밥인하 먹죠

뭐 이런 식이죠. http://coolengineer.com/files/choik-o/ 에서 즐기실 수 있습니다.

사용자 삽입 이미지

크리에이티브 커먼즈 라이센스
Creative Commons License
2008/06/05 12:01 2008/06/05 12:01

한글 초성,중성,종성 분리 PHP 코드

2008/06/05 11:40  |   장난하기  |   최호진
Python의 CJKCodec에 들어 있는 disjoint, conjoint의 PHP 버전을 만들어 보았습니다. 막연하게 어려울 것이라 생각했었는데, Perky님을 만났을때 힌트를 얻어, 살짝 구현해본 것을 조금 다듬어 공개합니다.

소스는, http://coolengineer.com/files/hangul/hangul.php.txt 이고, 테스트를 해보실 수 있는 링크는 다음과 같습니다.

http://coolengineer.com/files/hangul/testhangul.php
http://coolengineer.com/files/hangul/testhangul.php.txt

한글가지고 놀아 봐야겠죠?

크리에이티브 커먼즈 라이센스
Creative Commons License
2008/06/05 11:40 2008/06/05 11:40

경고! ssh-vulnkey 로 확인하세요.

2008/05/14 10:23  |   장난하기  |   최호진
출근하여 우분투 업데이트를 해보니, 뭔가 심각한 메시지가 뜬다.
특정 OpenSSL 라이브러리 버전으로 만들어진 ssh key가 일정한 패턴이 있는 것인지, 반드시 테스트해야할 경고가 뜬다.

으윽...

$ ssh-vulnkey
Not blacklisted: 2048 7b:1f:5f:7a:c6:.....  /etc/ssh/ssh_host_rsa_key
Not blacklisted: 1024 d9:42:47:92:d6:.... /etc/ssh/ssh_host_dsa_key
COMPROMISED: 2048 7e:17:d2:36:.... /home/pynoos/.ssh/id_rsa.pub

아. 주로 사용하는 public key가 블랙리스트에 있단다.
리모트 서버의 public key가 블랙리스트에 있는지 확인하는 방법으로는 다음과 같다.
$ ssh-keyscan -t dsa,rsa 172.16.11.25 | ssh-vulnkey -
# 172.16.11.25 SSH-1.99-OpenSSH_3.5p1 FreeBSD-20030924
# 172.16.11.25 SSH-1.99-OpenSSH_3.5p1 FreeBSD-20030924
Not blacklisted: 1024 4c:4e:e1:fe:.... 172.16.11.25

다행이 회사에서 사용하는 다른 서버들의 public key는 안전한듯. 다들 점검하세요.
크리에이티브 커먼즈 라이센스
Creative Commons License
2008/05/14 10:23 2008/05/14 10:23

Windows에서 DNS 설정 스크립트

2008/05/10 21:30  |   장난하기  |   최호진
Automating TCP/IP Networking on Clients라는 재밌는 스크립트 모음 Tech note가 있습니다.
귀찮은 DNS 설정을 이제 Visual basic script</