allow_url_fopen off 일때, proxy 구현 방법.

jQuery에 관심이 생기면서, javascript 만으로 RSS 리더기를 만들어 보기로 했다.
jQuery가 워낙에 많은 Plugin들을 지원하고 있어서, rss Parser도 금방 찾을 수 있었다.
jFeed 라는 것인데, 소스도 간단하고.. 복잡한 기능이 필요없는 용도로는 적당했다.

그런데, 예상치도 못한 문제가 있었다.
Ajax에서 다른 도메인의 페이지를 읽기 위해 proxy를 구현 해야 하는데..
셈플 소스에 포함된 것이 정상적으로 동작하지 않는 것이다.

셈플 소스에 포함된 코드는 아래와 같다.
<?php
header('Content-type: application/xml');
$handle = fopen($_REQUEST['url'], "r");

if ($handle) {
    while (!feof($handle)) {
        $buffer = fgets($handle, 4096);
        echo $buffer;
    }
    fclose($handle);
}
?>

원인은 호스팅을 받고 있는 cafe24 에서는 보안상의 이유로 php.ini 파일에서 fopen 함수의 사용을 막아 놓은 것이다.



업체에서 제안하는 방법은, fsockopen 이용하는 방법으로 셈플 소스는 아래와 같다.
function get_url_fsockopen( $url ) {
	$URL_parsed = parse_url($url);

	$host = $URL_parsed["host"];
	$port = $URL_parsed["port"];
	if ($port==0)
		$port = 80;

	$path = $URL_parsed["path"];
	if ($URL_parsed["query"] != "")
		$path .= "?".$URL_parsed["query"];

	$out = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";

	$fp = fsockopen($host, $port, $errno, $errstr, 30);

	if (!$fp) {
		echo "$errstr ($errno)<br>\n";
	} else {
		fputs($fp, $out);
		$body = false;
		while (!feof($fp)) {
			$s = fgets($fp, 128);
			if ( $body )
			$in .= $s;
			if ( $s == "\r\n" )
			$body = true;
		}

		fclose($fp);
		echo $in;
	}
}

하지만,  이방법도.. connection, write는 성공하지만, read 부분에서 데이터를 가져오질 못했다.
업체 문의 결과, www 폴더안에 ".htaccess" 파일을 만들고 파일 내용으로, 
php_flag allow_url_fopen 1

를 넣어 주면 된다고 한다. 단, 취약점을 통한 보안적 위험에 대한 책임을 보장할 수 없단다.
왠지 찝찝하다. 

좀 더 뒤져보니, curl 이란 php 라이브러리가 있다. 이넘이 물건이다. 좀 잡다한 기능들이 많아 무거워 보이긴 한데.. 일단 동작은 잘 된다.

curl 라이브러리를 이용한 소스는 아래와 같다.
<?php

function get_url_content($url) {

	$ch = curl_init();

	curl_setopt($ch, CURLOPT_URL, $url);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
	curl_setopt($ch, CURLOPT_HEADER, true);
   
	$html = curl_exec($ch);  
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);  
  
  	$inc=1;
	while ($http_code == 301 || $http_code == 302)
	{
		$header = curl_getinfo($ch, CURLINFO_HEADER_OUT);
		curl_close($ch);

		list($header, $html) = explode("\n\n", $html, 2);
		preg_match('/Location: (.*?)\n/', $header, $matches);
		$url = $matches[1];
		if (strlen(trim($url)) <= 0 )
			return "[".$http_code."] forwarding error, not found url.<br/>";

		$ch = curl_init();
		curl_setopt($ch, CURLOPT_URL,$url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
		$html = curl_exec($ch);
		$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);

		if ( $inc++ > 5 ) {
			curl_close($ch);
			return "to many forwarding...<br/>";
		}
	}

	curl_close($ch);

	return substr($html, strpos($html, '<?xml'));;
}

echo get_url_content( $_REQUEST['url'] );

?>

소스의 기능은 아래와 같다.
   
    1. HTTP CODE가 301, 302의 Forwarding 관련된 것이면 해당 URL로 이동.
        : CURLOPT_HEADER 옵션, while문 안의 해더 파싱 부분.
    2. Forwaring이 5번 이상이면, 에러 처리.
        : while문 안의 if문 
    3. HTTP 해더 부분 제거.
        : return 전의 substr 구문. rss 리더를 위한 proxy 이므로 필요 하다.

마지막 소스를 이용해 proxy 문제를 해결 했다.

JQuery를 이용한 둥근 테두리 테이블 만들기

웹눈 님의 Round Table 소스를 JQuery를 이용하는 소스로 수정해봤습니다.

JQuery를 요 몇일 보고 있는데, 재미있네요..
이제 막 시작한 단계로 더 깔끔하게 다듬을 수 있을 것도 같은데..
아직은 내공이 부족하네요.

좋은 방법 있으면 공유 해주시면 고맙겠습니다.

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script>
function roundTable(objID) {
	var $obj = $("table#" + objID);
	var s, r;
	var y, x, MAX;
	var w, h;

	r = parseInt($obj.attr('radius'));
	if (r == null || r < 1) r = 1;
	else if (r > 6) r = 6;

	MAX = r * 2 + 1;

	$obj.before("<TABLE id='tmpRoundTbl'></TABLE>")
	$("table#tmpRoundTbl")
		.attr("cellSpacing", 0)
		.attr("cellPadding", 0)
		.append("<TBODY></TBODY>");

	for (y=0; y < MAX; y++) {
		$("table#tmpRoundTbl TBODY").append("<TR></TR");
		s = Math.abs(y - parseInt(r));
		for (x=0; x < MAX; x++) {
			
			$("table#tmpRoundTbl TBODY TR:eq("+y+")")
				.append("<TD></TD>");

			w = '1px'; h = '1px';
			if (x == 0 || x == MAX - 1) h = null;
			else if (y == 0 || y == MAX - 1) w = null;
			else if (r > 2) {
				if (Math.abs(x - r) == 1) w = '2px';
				if (Math.abs(y - r) == 1) h = '2px';
			}

			if (w != null) 
				$("table#tmpRoundTbl TBODY TR:eq("+y+") TD:eq("+x+")")
					.css("width", w);
			if (h != null) 
				$("table#tmpRoundTbl TBODY TR:eq("+y+") TD:eq("+x+")")
					.css("height", h);

			if (s == x || s == MAX - x - 1) 
				$("table#tmpRoundTbl TBODY TR:eq("+y+") TD:eq("+x+")")
					.css("backgroundColor", $obj.attr('rborder') );
			else if (x > s && s < MAX - x - 1) 
				$("table#tmpRoundTbl TBODY TR:eq("+y+") TD:eq("+x+")")
					.css("backgroundColor", $obj.attr('rbgcolor') );
		}
	}

	$("table#tmpRoundTbl TBODY TR:eq("+s+") TD:eq("+r+")").append( $obj );
}
</script>


<table id="ta" width="300" height="100" border="0" 
    radius="3" rborder="#999999" rbgcolor="#F8F8F8">
<tbody><tr>
<td valign="top">테스트입니다</td>
</tr>
</tbody></table>
<span>
<script>roundTable("ta");</script>
</span>



[ 참고 ] 

한글 변환기 ( Chrome Extensions )

크롬 확장 프로그램을 만들었습니다.
예전에 만들어준 한글 변환기 스크립트를 이용하여 만들었습니다.

한글 입력기가 설치되지 않은 환경에서 한글 입력이 가능 합니다.
1시간 미만으로 뚝딱 만든 건데, 대부분 시간이 아이콘 만드는 시간이었네요. ^^;

* History 
2010-04-23  한글 키보드 레이아웃 이미지 추가 ( 옵션에서 출력 여부 결정 )



prototype을 이용한 Ajax 멀티 request

prototype을 이용해 비동기 방식의 요청을 여러건 해서 순서 상관없이 응답을 받아 처리하는 부분을 구현해 봤다. 

원래 목적은 fund 정보를 웹에서 관리하기 위해 만들려 한것인데...
미완성 프로젝트다..
엑셀에선 간단하던 수식들을 웹으로 옮기려니 만만치 않더라 ㅡㅡ;

소스에는 포함된 내용들은 아래와 같다.
   - Prototype Javascript Lib 사용
   - Javascript Calendar Javascript Lib 사용(한국어 처리 부분 소스 약간 수정)
   - 멀티 Ajax 요청 처리
   - 요청 처리중일때 모래 시계 보여주기
   - Msg 출력을 동적으로
   - select Object에 요청 받은 내용 동적으로 append


common.js 보기



list.html 보기

url
http://www.panghosting.net/~newtype/fund/list.html

다음 자동 로그인 주소 변경..

다음 자동 로그인 주소가 바뀌었다.
기존 자동 로그인 주소를 입력하면,
아이디, 비번 뿐 아니라..  그림 문자까지 넣으란다  ㅡㅡ;

바뀐 다음 자동 로그인 주소는 아래와 같다.
https://logins.daum.net/Mail-bin/login.cgi?id=아이디&pw=비번&enpw=비번

참고로 몇가지더..

네이버 자동 로그인 주소
https://nid.naver.com/nidlogin.login?id=네이버 아이디&password=비밀번호&url=http://naver.com


투데이즈피피시 이너서클 자동 로그인 주소
http://www.todaysppc.com/mbzine/bbs/login_check.php?s_url=/index.php&user_id=아이디&password=비번&group_no=1



한글변환기

영어 상태로 입력된 문장을 한글로 변환 해주는 Javascript 함수를 만들어 봤다.

나중에 지를(ㅡㅡ;) 아이팟 터치에서 한글 입력 기능이 없단다.
떠도는 얘기를 들어보니 별도 SDK가 없이 javascript로 개발을 한다고 해서
자료를 찾아보지도 않고 무작정 코딩부터 했다. 흐흐..

테스트는
http://newtype.myi.cc/tools/hangle.html
http://panghosting.net/~newtype/tools/hangle.html
http://host.newtype.pe.kr/tools/hangle.html
여기서 해보면 된다.

테스트는 IE6, IE7, FF2 에서 해보았다.

스크립트 용량을 줄여보겠다고 바둥바둥했는데..
그래도 2KB (1,971 바이트) 란다.
발로 코딩하니 한계가 있는 듯...

부디 유용하게 쓸 수 있기를..
어째뜬 아이팟 터치 기대 만땅이다.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-

2007.12.26
호스팅이 중단되어 페이지 연결이 되지 않습니다.
빠른 시일내에 복구 하겠습니다.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-

2007.12.30
복구 하였습니다.
URL이 좀 복잡해 졌네요.

=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-

2008.03.10
Native SDK가 발표되었네요.


=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--=-=-=-

2010.12.27
URL을 다시 복구 하였습니다.

GoogleGear Sample source


얼마전 구글에서 GoogleGear라는 것을 배포 했다.
처음엔 어떤것인지도 몰랐는데..
최근에 알게된 사실로는 오프라인에서도 웹서핑을 도와준다고 한다.

자세히 내용을 살표보니 SQLite를 이용해 웹에 있는 자료들을 미리 읽어들어 저장해 두고,
오프라인 일 때도 써먹는 다는 내용이였다.

사실, IE의 "오프라인으로 작업"등 비슷한 기능은 이미 있었다.
하지만, 역시 구글이다.
개발자들이 편하게 접근할 수 있도록 GoogleGear API를 열어두었다.

그럼, 코드로 만나보자.

1. GoogleGear를 사용하기 위해서는 먼저 설치가 되어있어야 한다.
   처음 발표되었을때, 뭔지도 모르고 미리 설치는 해두었다 ^^;

2. gears_init.js 파일을 html안에 포함 해야한다.
<script src="gears_init.js"></script>
  gears_init.js 파일을 미리 받아 놓고 위 코드를 html에 포함 해도 되고,
  gears_init.js 파일의 내용 전부를 html 파일에 포함 시켜도 된다.

3. 설치 여부 체크
  html 파일이 열리면, GoogleGear가 설치되어 있는지 체크 하는 부분이 있어야 한다.
  if ( !window.google || !google.gears ) 
  {
      alert('GoogleGear를 먼저 설치하세요.');
      return;
  }

4. DB파일을 생성한다.
SQLite는 파일 하나로 Database를 로칼 컴퓨터에 생성 한다.
FireFox에서는 C:\Documents and Settings\<사용자명>\Application Data\Mozilla\Firefox\Profiles\<임시이름>.default\urlclassifier2.sqlite 라는 파일이 생성되었다.
  try {
    db = google.gears.factory.create('beta.database', '1.0');
  } catch (ex) {
    alert('Database를 생성할 수 없습니다: ' + ex.message);
  }

5. 테이블을 만든다.
  if (db) {
    db.open('address');
    db.execute('create table if not exists ntAddress' +
               ' (name varchar(255), phone varchar(255), email varchar(255) , Timestamp int)');

    display();
  }
  소스를 보면 알겠지만, 자바스크립트에서 쿼리를 직접 날린다. @.@

6. 쿼리를 날린다.
   이렇게 쉽게 사용이 가능하다.
   try {
    db.execute('insert into ntAddress values (?, ?, ?, ?)', [oName.value, oPhone.value, oMail.value, currTime]);
  } catch (e) {
    alert(e.message);
    throw new Error(e.message);
alert (e.message);
   }

   이제까지 Google API가 그러했듯이 엄청 간단하다.
   우리가 잘 아는 쿼리를 직접 날리고,
   무거운 작업의 경우 WorkPool을 이용해 백그라운드로 돌릴 수도 있다.
   LocalServer를 이용해 서버 정보를 간단하게 캐쉬로 만들어 저장하는 할 수도 있는 듯하다.
   Google에서 제공하는 샘플 소스 및 툴 을 받아보자

   손가락이 근질근질 하지 않은가. 흐흐흐흐흐...
 

address.html 전체 소스 보기



덧글,
샘플 코딩하면서 삽질을 했다.
innerHTML 스크립트가 IE7에서 먹지 않는 것이다.
한참 삽질을 하다가 IE7 관련 자료에서 이런 문구를 발견 했다.
IE does not support when setting a div’s innerHTML property
div 테그를 span으로 바꾸고 간단히 해결했다.
신버전은 구버전과 호환 되게 해달라고!!!  버럭



티스토리 스킨


제 블로그에서 사용하는 티스토리 스킨을 올려둡니다.
완전히 개인적인 용도입니다.

제 계정의 구글애드센스, 구근애널리틱스가 포함된 스킨 입니다.





간단한 Ajax Sample 코드

먼저 파일 구조를 설명하면..
전체 파일 구성은 아래와 같습니다.

    - ./index.php : XMLHttpRequest를 이용 정보를 요청
    - ./list.php : ./sheet/ 서브 디렉토리에서 skin파일과 db파일을 읽어서 보여줌
    - ./sheet/*.html : skin 파일
    - ./sheet/*.txt: csv형식의 db파일

중요 부분을 설명하겠습니다.

먼저 index.php파일을 보면..

    if (window.XMLHttpRequest)
    {
        HTTPRequestObject = new XMLHttpRequest();
    }
    else if (window.ActiveXObject)
    {
        HTTPRequestObject = new ActiveXObject("Microsoft.XMLHTTP");
    }

여기서 Internet Explorer냐 FireFox냐를 구분해 HTTPRequestObject 인스턴스를 생성합니다.

    function doSubmit(sheet)
    {
        var url = "http://" + location.host + "/list/list.php?sheet=" + encodeURIComponent(sheet);
       
        HTTPRequestObject.open("GET", url, true);
        HTTPRequestObject.onreadystatechange = HTTPRequest;
        HTTPRequestObject.send(null);
        document.getElementById("result").innerHTML = "Requesting data ...";
    }   

submit 이벤트 발생시 HTTPRequestObject를 이용해 서버에 요청 합니다.
GET 방식이기 때문에 일부 브라우저 설정에 따라 인코딩 형식이 바뀌기 때문에
encodeURIComponent() 함수를 사용해 UTF-8형식으로 강제 변환 했습니다.

그리고, 응답이 들어오면 수행할 콜백 함수를 HTTPRequest로 지정했습니다.

    function HTTPRequest()
    {
        if (HTTPRequestObject.readyState==4)
        {
            if (HTTPRequestObject.responseText.indexOf('invalid') == -1)
            {    
                document.getElementById("result").innerHTML = HTTPRequestObject.responseText;
            }
            else
            {
                document.getElementById("result").innerHTML = "Error requesting data.";
            }
        }
    }

응답이 들어오면 HTTPRequest() 함수에서 내용을 뿌려 줍니다.

list.php는 별 내용이 없습니다.
인코딩 형식을 변환 하기 위해

       mb_convert_encoding()

함수를 사용했습니다.


테스트 페이지

전체 소스 다운은 아래를 클릭 하세요.


JSP 만으로 오라클 접속


서블릿을 사용하지 않고 JSP만 이용
commit, rollback 지원 하지 않고 단순 조회용

접속 정보와 쿼리를 날릴 Index.jsp


쿼리 결과를 조회할 result.jsp