Entries Tagged as 'Railo'



Installing Railo 3.1.2.001-resin-3.1.9 on Ubuntu Server 9.10 64bit
Category : Railo , Ubuntu & Linux/Unix Comments : 댓글쓰기 Posted by 장창학 at 10:39 AM

어제 서버이전을 했습니다. 그동안 사용했던 Cafe24의 VPS상품(가상서버)중에 CentOS버전을 이용했었는데, 기간도 만료되어가고 이번에 Ubuntu상품이 출시되어서 새로이 변경을 했습니다. Ubuntu의 간결한 시스템(서버전용버전이라 상당히 간결합니다.)과 APT의 편리함, 그리고 무엇보다 경험상 J2EE기반 WAS의 메모리 관리는 Ubuntu가 더 나은 듯하여 옮기기를 주저없이 결정했습니다.

실제로 전체 2GB의 시스템 RAM메모리 중 CentOS의 경우 90%이상 늘 풀로 차있던 반면, Ubuntu는 50%대에서 안정적으로 보여주고 있어 만족하고 있습니다. 물론 Ubuntu가 좀 더 경량화된 Server전용OS이긴 하지만요. 제 CentOS는 초기의 Cafe24상품이라 그런지 OpenOffice까지 깔려 있었던 가상이미지 였습니다.

각설하고, 이번에 Ubuntu 64Bit 9.10 Server Edition에  railo-3.1.2.001-resin-3.1.9-without-jre버전을 깔면서 엄청난 삽질을 했습니다. 이전의 설치방법으로는 거의 100% 오류발생이 일어날 것입니다. 우선 Apache + PHP + MySQL이 설치되지 않은 순수 OS만 설치된 Ubuntu에서 시작합니다. Cafe24.com의 Ubuntu상품은 APM은 본인이 알아서 설치해야 합니다. OS만 설치되는 상품입니다.(사실 이게 제일 맘에 들었습니다. Ubuntu에서 APM설치하기란 정말 딱 5초면 알아서 설치되는 APT관리자가 있으니까요.) 그럼 설치순서를 정리해 보겠습니다. 참고로 PHP는 저는 필요치 않아 설치하지 않았습니다.

 

1. Install SunJDK 1.6

sudo apt-get install sun-java6-jdk

위와 같이 설치를 합니다. 설치를 마치면 JRE의 경로는 /usr/lib/jvm/java-6-sun/ 가 됩니다. java -version을 입력하여 정상적으로 구동되고 있는 지 확인합니다. 이 부분에서 정상적인 설치가 안되는 경우, 나중에 Railo를 설치하고 난뒤 시작하기 위하여 httpd.sh를 구동하면 "exec: 40: -jar: not found" 와 같은 에러메시지를 출력합니다. (If Java path is wrong, it makes error "exex:40:-jar: not found" messege.)

 

2. Java Path

이제 시스템 환경변수에서 Java의 경로를 지정해야 합니다. 예전 Railo버전을 Ubuntu에 설치할 때는 굳이 강제로 지정하지 않아도 잘 되었는데 이번 3.1.2.001부터는 Resin버전이 3.1.9로 변경되어 그런지 반드시 지정을 해야 Resin이 구동되더군요. /etc/profile에 다음을 추가합니다.(vi /etc/profile)

JAVA_HOME=/usr/lib/jvm/java-6-sun/
export JAVA_HOME
export PATH=$PATH:/usr/lib/jvm/java-6-sun/bin

참고로 /usr/lib/jvm/java-6-sun/bin 경로는 SunJDK1.6을 APT로 설치하였을 경우의 경로입니다. 직접 JDK파일을 받아서 설치한 경우는 본인의 경로로 바꾸어 주세요. 추가한 다음 source /etc/profile를 해주어 profile를 업데이트 해 줍니다.

 

 3. Install Apache 2, MySQL 5

이제 apache와 mysql를 설치합니다. 다음과 같이 설치하면 됩니다. 설치 후의 apache 가상호스트 설정이나 mysql설정은 이전 설치설명 4번, 5번을 참조 주세요.

sudo apt-get install apache2 libapache2-mod-auth-mysql build-essential apache2-threaded-dev mysql-server mysql-client

모든 설치가 끝나면, Apache의 경우 /etc/apache2 가, MySQL의 경우 /etc/mysql이 기본 경로가 됩니다. 나머지 설정은 이전 설치설명을 참조하세요.

 

4. Install Railo (railo-3.1.2.001-resin-3.1.9-without-jre.tar.gz)

이제 Railo를 설치합니다. railo-3.1.2.001-resin-3.1.9-without-jre.tar.gz파일을 /opt/ 아래로 업로드 합니다. 그런다음 압축을 풉니다.

tar xvf railo-3.1.2.001-resin-3.1.9-without-jre.tar.gz /opt/

그런 후 railo설치 디렉토리로 이동합니다.

cd /opt/railo-3.1.2.001-resin-without-jre/

다음과 같이 설치옵션을 주어 설치합니다. 여기서가 중요합니다.(Very Important!!) 이것 때문에 엄청 고생을 했는데요. Railo의 Resin은 사실 Resin Professional버전이라 정상적인 라이센스가 없는 경우 설치에 문제가 있습니다. 따라서 Railo의 디렉토리안의 다음 두 파일의 이름을 변경해 줍니다. (Rename each files!)

Makefile.in → Makefile.in.bak
Makefile.am → Makefile.in

즉, Makefile.in파일은 .bak를 붙혀 Backup을 해놓고, Makefile.am파일을 Makefile.in으로 변경합니다. 그런다음 아래와 같이 컴파일하여 설치합니다.

sudo ./configure --with-apxs=/usr/bin/apxs2 --with-java-home=/usr/lib/jvm/java-6-sun/
sudo make
sudo make install

설치가 끝난 후 /opt/railo-3.1.2.001-resin-without-jre/bin 안의 httpd.sh를 실행합니다.

./httpd.sh start

정상적으로 구동이 되면, /etc/apache2/httpd.conf파일에 다음과 같은 내용이 들어가 있을 겁니다.

#
# mod_caucho Resin Configuration
#
LoadModule caucho_module /usr/lib/apache2/modules/mod_caucho.so
ResinConfigServer localhost 6800
CauchoConfigCacheDirectory /tmp
CauchoStatus yes

 

5. ETC

남은 Apache의 Vhost설정이나, Resin의 Vhost설정 등은 이전 설치 설명중 4번, 5번을 참조하시면 됩니다. 


Image를 Resize할때 정사각형 비율로 Resizing하기
Category : ColdFusion , Railo Comments : 2 Comments Posted by 장창학 at 10:54 PM

Square Image ResizeColdFusion에서 이미지를 Resize하는 방법은 imageResize() 함수를 쓰게 되면 쉽게 가로사이즈를 변경할 수 있습니다. 물론 함수는 Adobe ColdFusion 8 또는 Railo 3이상의 환경에서 지원합니다. 그런데 이미지를 리사이징하다보면 가로가 더 길거나 세로가 더 긴 직사각형 이미지가 대부분입니다. 그리고, HTML이나 ColdFusion에서 사이즈를 줄 일 경우 대부분 Width값만 조절하면 Height값은 비율에 따라 자동으로 조절됩니다. 하지만 Design의 특성상 또는 Twitter에서의 Profile 사진처럼 정사각형으로 이미지를 보여야 하는 경우가 있습니다.

그런데 사용자가 업로드하는 이미지는 언제나 가로가 더 길던, 세로가 더 긴 직사각형 이미지이고, 업로드시 사용자가 Photoshop등에서 미리 정사각형으로 조절하여 업로드 할 수 있지만 매번 그러라고 할 수 도 없는 노릇입니다. 그리고 가로가 길던, 세로가 길던 정사각형으로 리사이즈 하는 경우 이미지의 비율을 찌그러뜨리지 않고(홀쭉이가 되거나 뚱댕이 되는 것이 아닌), 원본 비율대로 사이즈만 조절되어야만 한다면 어떻게 해야 할까요? LearnCF에서의 간단한 예제를 통해 가로세로 비율이 정사각형이 아닌 이미지를 어떻게 정사각형 이미지로 비율 맞추어 리사이즈하는지 알아 봅시다. 먼저 예제를 미리 보시길 바랍니다.

Demo View : http://www.nooree.com/samples/cfimage/square_thumnail.cfm

<cfimage>를 이용해서 특정 이미지의 정보를 읽어 온 다음, squareThumbnail()이라는 사용자 정의 함수(UDF)에 Arguments(여기서는 이미지정보와 리사이즈하고자 하는 목표 사이즈) 를 전달하면, 실행됩니다. 목표 사이즈값은 가로세로의 동일한 값이겠죠? 그리고 다음의 세가지 조건에 따라 프로세싱을 달리 합니다. 첫번째는 가로사이즈가 더 큰 이미지인 경우, 두번째는 세로사이즈가 더 큰 이미지인 경우, 마지막으로 정사각형이미지인 경우로 나누어 처리합니다. 모든 이미지의 정보에서 가로와 세로의 길의 절반값을 계산합니다. 가령 400px*300px 크기의 이미지라면 가로의 절반값은 200px이고, 세로의 경우 150px이 됩니다. 그렇다면 이 이미지의 중심점의 좌표는 X좌표는 200. Y좌표는 150이 됩니다.

그런다음 imageCrop()함수를 이용해서 이 중심좌표를 기준으로 원하는 목표 사이즈 만큼만 가로세로 잘라내면 되겠죠. imageCrop()함수의 기본 사용법은 ImageCrop(name, x, y, width, height) 이므로 X값과 Y값을 지정해 주고, width와 height는 목표 리사이즈 값이므로 동일한 값입니다. 다음의 코드를 보고 X, Y값을 구해보세요. 간단하게 imageResize()함수와 imageCrop()함수를 써서 정사각형 이미지 리사이즈를 구현해 보았습니다.

 

<cffunction name="squareThumbnail" access="private" returntype="void">
	<!--- 함수로 넘어온 Argument정의 --->
	<cfargument name="image" required="true" />
	<cfargument name="size" required="true" />
	<!--- 이미지의 사이즈의 절반을 구함. 전체 사이즈의 2분의 1--->
	<cfset var half = int(arguments.size / 2) />
	<!--- X, Y의 초기값 정의 --->
	<cfset var fromX = 0 />
	<cfset var fromY = 0 />
	<!--- 세로가 더 긴 경우 --->
	<cfif arguments.image.height gt arguments.image.width>
		<cfset imageResize(arguments.image, arguments.size, '') />
		<cfset fromX = arguments.image.Height / 2 - half />
		<cfset imageCrop(arguments.image, 0, fromX, arguments.size, arguments.size) />
	<!--- 가로가 더 긴 경우 --->
	<cfelseif image.width gt image.height>
		<cfset imageResize(arguments.image, '', arguments.size) />
		<cfset fromY = arguments.image.Width / 2 - half />
		<cfset imageCrop(arguments.image, fromY, 0, arguments.size, arguments.size) />
	<cfelse>
		<cfset imageResize(arguments.image, '', arguments.size)>
		<cfset imageCrop(arguments.image, 0, 0, arguments.size, arguments.size)>
	</cfif>
	<!---정사각형으로 리사이즈된 이미지 출력--->
	<cfimage action="writetobrowser" source="#arguments.image#" />
</cffunction>

<h2>김태희 - 정사각형 이미지 리사이즈</h2>

<!---이미지 정보를 읽어옴--->
<cfimage action="read" name="image" source="#expandPath('./kimtaehee.jpg')#" />
<!--- 읽어온 이미지를 화면상에 출력--->
<cfimage action="writetobrowser" source="#image#" />
<!--- squareThumbnail 사용자 함수에 이미지를 대입하여, 정사각형 이미지로 변환--->
<cfset squareThumbnail(image, 150) />

 


RemoteObject를 이용한 Railo와 Flex의 연동 - Blog의 제목을 DataGrid에 뿌려보기
Category : ColdFusion , Flash/RIA , Railo Comments : 댓글쓰기 Posted by 장창학 at 7:24 AM

아.. 정말이지 이 예제를 만들어 보면서 끙끙댔습니다. Flex에 대한 지식도 매우 얇거니와 그나마 안한지 3년이 넘어가서 간단한 것(?) 하나 만들기 정말 힘드네요.ㅋㅋ 집에 쳐박혀 있던 Flex책들을 다시 꺼네여 좀 읽어 본 후 한번 만들어 봤습니다. 사실 ColdFusion에서야 CFC(ColdFusion Component)를 만드는 것이야 일도 아닙니다만, 젠장.. Flex로 Client 꾸미는 것이 일이네요.(그래서 제가 Flex나 Flash와 같이 Actionscript에 흥미가 없나 봅니다. ㅠㅠ)

암튼 지난 Railo에서 Flex시작!! 이란 포스트에서 처음으로 Flex와 Railo를 연동해봤는데요. Adobe ColdFusion의 경우 이미 MX버전부터 Flash Remoting을 지원하고 있었고, 버전 8부터는 아예 LCDS를 내장해버려(물론 라이센스를 별도로 구매해야 쓸 수 있습니다) Flex와의 연동 뿐만 아니라 그냥 mxml컴파일까지 ColdFusion서버에서 처리하면 되었습니다. Railo의 경우 버전 3.1부터 BlazeDS를 내장해서 mxml컴파일까지 지원하길 바랬는데 그냥 Flash Remoting만 지원하고 있습니다. 물론 Railo 역시 이미 버전2부터 Flash Remoting을 지원했었고요. 다만 3.1부터 BlazeDS엔진이 일부 추가되었다는 이야기 입니다. 결론은 Railo나 Adobe ColdFusion이나 (성능상의 문제는 일단 노외로 하고..) Flex에서 모두 RemoteObject를 쓸 수 있었다 뭐~ 그런 이야기입니다. ㅋ(참고로 Open BlueDragon에서도 BlazeDS를 이용하려면 다음의 링크를 참조하세요. BlaseDS의 내부 jar파일과 OpenBDAdoptor를 이용하는 예제인데 Query Object를 리턴받을 수 없는 기능제한이 있군요. http://wiki.openbluedragon.org/wiki/index.php/OpenBD_and_BlazeDS)

쳐벅혀 있던 Flex책과 씨름해서 겨우 만든 것이지만 간만에 Flex해보니 재밌네요.ㅋ 예제는 아래의 URL에서 확인해 볼 수 있습니다. 간단하게 블로그의 DB에서 게시글의 테이블의 URL주소로 쓰이는 name이란 칼럼과 title이란 칼럼을 구해와서 Datagrid에 Binding하고 링크를 걸어주는 예제입니다. ColdFusion CFC를 이용해서 Database 쿼리결과를 Array로 반환하여(물론 ColdFusion에서는 쿼리결과를 배열뿐만 아니라, 목록, 구조 등으로도 반환받을 수 있습니다. 이 부분은 ColdFusion기술문서를 참조하세요.) 리턴해주면 Flex에서 데이터를 바인딩하는 초간단 예제이므로 그냥 그런가보다 해 주시길 바랍니다. ColdFusion이라면 모를까 Flex에 대해 여쭤보시면 저는 아마도 궁색한 변명을 늘어놀지도.. ㅎㅎㅎ

Demo View : http://www.nooree.com/samples/railoflexblog/nooreeBlogEntry.html

Sample File Download

blogRemoteService.cfc

<cfcomponent hint="My blog entries">
	<cffunction name="blogQuery" access="remote">
		<cfquery name="qGetEntry" datasource="DSN이름">
			SELECT name, title
			FROM blog테이블명
			ORDER BY last_modified DESC
			LIMIT 30
		</cfquery>
		<cfreturn qGetEntry />
	</cffunction>
</cfcomponent>

 

nooreeBlogEntry.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="myBlog.blogQuery()" >

	<mx:Style>
		Alert {
		titleStyleName: "alertTitle";
		messageStyleName: "alertMessage";
		}		  
		.alertTitle {
		fontSize: 12;
		}		  
		.alertMessage {
		fontSize: 12;
		}
	</mx:Style>
	
	<mx:Script>
		<![CDATA[
			import mx.collections.ArrayCollection;
			import mx.rpc.events.FaultEvent;
			import mx.rpc.events.ResultEvent;
			import mx.controls.Alert;
			import mx.events.ListEvent;
			
			[Bindable]
			private var myArrayCollection:ArrayCollection;
			 
			private function queryResultHandler(evt:ResultEvent):void {
				myArrayCollection = evt.result as ArrayCollection;	
				myDataGrid.visible = true;
			}
			 
			private function faultHandler(evt:FaultEvent):void {
				mx.controls.Alert.show("오류발생:" + evt.fault.faultDetail)	
			}

			private function itemClickEvent(evt:ListEvent):void {				
			  if(evt.rowIndex >= 0) {
			     var url:URLRequest = new URLRequest("/blog/post.cfm/" + evt.currentTarget.selectedItem.name); 
 	             navigateToURL(url,'_blank');
			  }		
			}			
			
		]]>
	</mx:Script>

    <mx:RemoteObject id="myBlog" destination="ColdFusion" source="samples.railoflexblog.cfc.blogRemoteService" endpoint="http://www.nooree.com/flex2gateway" showBusyCursor="true">  
    	<mx:method name="blogQuery" result="queryResultHandler(event)" fault="faultHandler(event)"/>
    </mx:RemoteObject>

    <mx:DataGrid id="myDataGrid" dataProvider="{myArrayCollection}" visible="true" width="850" height="100%"  fontSize="12" itemClick="itemClickEvent(event)">
    	<mx:columns>
			<mx:DataGridColumn headerText="주소" dataField="name" width="300" />
			<mx:DataGridColumn headerText="제목" dataField="title" width="500" />
		</mx:columns>
    </mx:DataGrid>
	
</mx:Application>

 

source="samples.railoflexblog.cfc.blogRemoteService"의 부분은 CFC의 위치경로입니다. 위 예제에서 CFC의 위치는 웹루투/samples/railoflexblog/cfc/blogRemoteService.cfc 입니다.


Adobe ColdFusion, BlazeDS(Railo), LCDS(FDS) 보안업데이트(Security Updates)
Category : ColdFusion , Flash/RIA , Railo , Securities Comments : 댓글쓰기 Posted by 장창학 at 1:54 AM

Adobe에서 보안패치가 배포되었습니다. Flex와 관련있는 BlazeDS, LCDS, FDS, LiveCycle을 비롯해서 Flex엔진이 내장된 ColdFusion 7,8,9버전 모두 해당됩니다. 매우 심각한 보안패치이니 관련 제품 사용자는 업데이트 하시길 바랍니다. 다행이 저는 ColdFusion엔진이 Railo라서 상관은 없지만 BlazeDS는 영향을 받겠네요. Railo에 내장된 BlazeDS에도 적용이 될련지 확인해 보고 관련이 있다면 Posting하겠습니다. 현재 적용해 본 결과 일부 Railo서버에서는 문제가 있네요.(For some, Railo server error occured.)  최근에 Railo를 설치한 경우라면 문제는 없는 것 같은데.. 만약 최근에 설치하였거나 일단 적용해 보고자 한다면 다음의 경로에 BlazeDS의 보안데이트가 적용된 flex-messaging-core.jar 파일을 덮어 씌우세요.(미리 flex-messaging-core.jar를 백업하시길 바랍니다. 문제 발생시 원본으로 대체하면 정상적으로 작동합니다.)

Windows환경에서는 C:\Program Files\{Railo설치디렉토리}\lib\ 이며, Linux환경에서는 일반적으로 /opt/railo/lib 가 되겠습니다. 동일한 파일이 기존에 있으므로 덮어 씌우면 되는데, 문제가 발생하는 환경이 있으므로 Railo자체의 보안업데이트를 기다리는 것이 나을 듯 합니다. Railo Team에서도 관련내용을 확인했다고 합니다. (http://groups.google.com/group/railo/browse_thread/thread/a2883c03b99526d4) 만약 강제로 적용하여 Railo를 재시작해도 문제가 발생한다면 원래 설치된 버전의 Railo설치파일을 다운로드 받아 압축을 푼 후 flex-messaging-core.jar만 다시 복원해 주면 됩니다.


IsImageFile 함수를 이용한 보안(Security) Tip
Category : ColdFusion , Railo Comments : 댓글쓰기 Posted by 장창학 at 3:19 PM

가끔이기는 하지만 간혹 파일업로드가 가능한 게시판을 구축하여 운영하다보면 꼭 파일의 확장자를 강제로 바꾸어 업로드를 시도하는 분들이 있습니다. 가령 실제 파일은 delete.sh이나 delete.exe파일인데(둘다 각각 서버시스템에서 실행될수 있는 각별히 신경써야 하는 파일입니다.), 이를 탐색기에서 강제로 delete.jpg파일로 변경해서 마치 이미지 파일인것 처럼 위장해 개발자가 쳐놓은 보안장벽인 "업로드 파일 확장자필터링"를 우회하여 업로드하게 됩니다. 물론 대부분의 시스템은 JPG파일를 일반 바이너리 실행파일로 구동되지 않지만 일단 시스템의 취약점을 이용해서 충분히 시스템 전체를 포맷해 버리는 최악의 상황을 연출할 수 있고, 또 그런 보고도 많이 있습니다.

ColdFusion 8 또는 Railo 3이상부터는 IsImageFile()함수를 지원하고 있는데, 이는 서버상의 어떤 파일이 실제로 이미지 파일인지 아닌지 확인해주는 함수입니다. 가령 업로드를 구현할때 위에서처럼 delete.jpg파일이 실제 이미지 파일이 아닌 경우 false를 반환하게 됩니다. 다음의 예를 확인해 보겠습니다. 다음의 예는 어떤 디렉토리내의 파일을 조사하여 이미지 파일인지 아닌지 확인하는 것인데, jpg와 같이 확장자만 보고 이미지 파일인지 아닌지 조사하는 것이 아니라, 맨마지막의 파일의 예처럼 실제 이미지 파일이 아닌데(sample.doc) 마치 이미지 파일처럼(sample1.jpg) 확장자가 바뀌어 있는 경우 이미지파일이 아니라고 false를 반환하는 예입니다.

Demo view : http://www.nooree.com/samples/railogetfileinfo/

<cfdirectory action="LIST" name="Files" directory="#ExpandPath('./')#" filter="*.*" sort="Type ACS, Name ASC">
<cfoutput query="Files">
 #name# <br />
 <cfdump var="#IsImageFile("#name#")#">
 <br />
</cfoutput>

About me

Categories

Monthly Archives

Links

Recent Posts

Recent Comments