Rails on me :)
2011년 12월 20일 화요일
  오랜만에 포스팅
테스트 입니다.
 
2010년 11월 13일 토요일
  Javascript의 this 매개변수의 다양성
자바스크립트에는 함수를 호출하는데 메서드 호출패턴, 함수호출 패턴, 생성자 호출패턴, apply 호출패턴이라는 네가지 패턴이 있다. 각각의 패턴에 따라 this 라는 매개변수를 다르게 초기화 한다.

1. 메서드 호출 패턴

함수를 객체의 속성에 저장하는 경우 이 함수를 메서드라 부르며, 이때 this는 메서드를 포함하는 객체에 바인딩된다.

var oj = {
    value : 99,
    get_value : function () {
        alert(this.value);
    }
};

oj.get_value();  // 99

2. 함수 호출 패턴

함수가 객체의 속성이 아닌 단지 함수(function)로서 호출될때, this는 전역객체에 바인딩된다.

var doSomething = function () {
    alert(this); // window
};

3. 생성자 호출 패턴

함수를 new라는 전치 연산자와 함께 호출하면, 호출한 함수의 prototype 속성값에 연결된 (숨겨진) 링크를 갖는 객체가 생성되고, this 는 이 새로운 객체에 바인딩된다.

var Obj = function (str) {
    this.status = str;
};

Obj.prototype.get_status = function () {
    return this.status;
};

var myObj = new Obj("going");
myObj.get_status() // "going"


4. apply(또는 call) 호출 패턴

apply 매서드는 this의 값을 선택할 수 있도록 해준다. apply 메서드에는 매개변수 두개가 있는데, 첫째는 this 에 묶이게 될 값이며, 두번째는 매개변수들의 배열이다.

var statusOj = {
    status : 'Z-OK'
};

* 3번에서 정의한 Obj 객체를 이용하자
Obj.prototype.get_status.apply(statusOj);  // "Z-OK"

라벨: ,

 
2010년 7월 15일 목요일
  파일 이어받기 구현
[현재 작성 중인 포스트]

===============================================================================================================
다운로드 요청
request
특별한 파라미터 없음

response
07-15 20:24:29.619: INFO/response *name* and *value*(8182): Date = Thu, 15 Jul 2010 11:27:16 GMT
07-15 20:24:29.619: INFO/response *name* and *value*(8182): Server = Apache/2.2.12 (Ubuntu)
07-15 20:24:29.629: INFO/response *name* and *value*(8182): Last-Modified = Mon, 05 Jul 2010 01:58:21 GMT
07-15 20:24:29.629: INFO/response *name* and *value*(8182): ETag = "a0ac5-1400000-48a9a4570a8c9"
07-15 20:24:29.629: INFO/response *name* and *value*(8182): Accept-Ranges = bytes
07-15 20:24:29.629: INFO/response *name* and *value*(8182): Content-Length = 20971520
07-15 20:24:29.629: INFO/response *name* and *value*(8182): Keep-Alive = timeout=15, max=100
07-15 20:24:29.629: INFO/response *name* and *value*(8182): Connection = Keep-Alive
07-15 20:24:29.639: INFO/response *name* and *value*(8182): Content-Type = application/zip

07-16 09:52:37.606: INFO/**status code**(13384): HTTP/1.1 200 OK

! etag 가 반환된다.
다운로드 이어받기를 구현하려면,
(1) 이 etag 를 기억하고,
(2) 현재까지 다운받을 양을 기억해둬야 다음 이어받기 요청시 서버가 이를 자동으로 처리해준다(Apache 의 경우, 그 외 다른 서버는 모르겠다).

===============================================================================================================
파일 이어서 다운받기 요청시,

request
07-15 20:28:02.999: INFO/request *name* and *value*(8467): Range = bytes=6295290-
07-16 09:54:17.046: INFO/request *name* and *value*(13608): If-Range = "a0ac5-1400000-48a9a4570a8c9"

response 시,
07-15 20:28:02.999: INFO/response *name* and *value*(8467): Date = Thu, 15 Jul 2010 11:30:49 GMT
07-15 20:28:02.999: INFO/response *name* and *value*(8467): Server = Apache/2.2.12 (Ubuntu)
07-15 20:28:02.999: INFO/response *name* and *value*(8467): Last-Modified = Mon, 05 Jul 2010 01:58:21 GMT
07-15 20:28:02.999: INFO/response *name* and *value*(8467): ETag = "a0ac5-1400000-48a9a4570a8c9"
07-15 20:28:02.999: INFO/response *name* and *value*(8467): Accept-Ranges = bytes
07-15 20:28:02.999: INFO/response *name* and *value*(8467): Content-Length = 14676230
07-15 20:28:03.009: INFO/response *name* and *value*(8467): Content-Range = bytes 6295290-20971519/20971520
07-15 20:28:03.009: INFO/response *name* and *value*(8467): Keep-Alive = timeout=15, max=100
07-15 20:28:03.009: INFO/response *name* and *value*(8467): Connection = Keep-Alive
07-15 20:28:03.009: INFO/response *name* and *value*(8467): Content-Type = application/zip

07-16 09:45:55.276: INFO/**status code**(13117): HTTP/1.1 206 Partial Content

! etag 가 동일하다

================================================================================================================
파일 이어서 다운받기 요청시 (하지만 서버의 다운받을 파일이 변경되었을 때!!),

request
07-16 09:54:17.046: INFO/request *name* and *value*(13608): Range = bytes=12388474-
07-16 09:54:17.046: INFO/request *name* and *value*(13608): If-Range = "a0b25-2137785-48b76a85b3857"

response
07-16 09:54:17.276: INFO/response *name* and *value*(13608): Date = Fri, 16 Jul 2010 00:57:07 GMT
07-16 09:54:17.276: INFO/response *name* and *value*(13608): Server = Apache/2.2.12 (Ubuntu)
07-16 09:54:17.286: INFO/response *name* and *value*(13608): Last-Modified = Fri, 16 Jul 2010 00:56:19 GMT
07-16 09:54:17.286: INFO/response *name* and *value*(13608): ETag = "a0b25-321f627-48b76afd27997"
07-16 09:54:17.286: INFO/response *name* and *value*(13608): Accept-Ranges = bytes
07-16 09:54:17.286: INFO/response *name* and *value*(13608): Content-Length = 40168877
07-16 09:54:17.286: INFO/response *name* and *value*(13608): Keep-Alive = timeout=15, max=100
07-16 09:54:17.286: INFO/response *name* and *value*(13608): Connection = Keep-Alive
07-16 09:54:17.286: INFO/response *name* and *value*(13608): Content-Type = application/zip

07-16 09:54:17.296: INFO/**status code**(13608): HTTP/1.1 200 OK

! etag 가 다르다 :)
응답코드도 206 이 아닌 200 이다.
서버 파일이 변경되었기에, 요청 header 의 Range 헤더는 무시되고, 처음부터 다운로드 받는다.

라벨: , ,

 
2010년 7월 12일 월요일
  Android : Network Exception 유형 간단 정리

요청이 무사히 전달되면,
-
HTTP_OK(200)

존재하지 않는 주소로 요청을 보낼 때,
-
java.net.UnknownHostException 발생

존재하는 주소지만, 요청한 경로(혹은 파일)를 찾을 수 없을 때,
-
HTTP_NOT_FOUND(404)

존재하는 주소지만, 응답을 보내주는 웹서버가 없거나 비활성화인 경우,
-
IOException 발생 (java.net.ConnectionException)

인증실패시,

HTTP_UNAUTHORIZED(401) 



인터넷 연결이 안된 상태에서 connection 시도할 경우,
-
(1) IOException
(2) SocketException

위 두 exception 이 순차적으로 발생한다.




다운로드중 인터넷이 끊겼을 때, 
-
* exception 발생 시키려면 반드시, 
HttpURLConnection 객체에 setReadTimeout() 으로 시간을 적용시켜야 한다.

*만약, HttpClient 를 사용한다면 client.getParams().setParameter("http.socket.timeout", 5000);
위와 같이 적용해준다.


인터넷 끊김 후 위에 적용한 시간이 흐른 뒤,

(1) SocketTimeoutException

이 발생한다.

라벨:

 
2010년 6월 20일 일요일
  AJAX in Rails with Authenticity Token

출처 : http://archive.alwaysmovefast.com/ajax-in-rails-with-authenticity-token.html

ajax 요청을 post 로 보낼 경우, InvalidAuthenticityToken 에러가 발생한다. 이를 해지해줄 방법은 다음과 같다. 

AJAX in Rails with Authenticity Token


When you use active_record_store instead of the cookie-based default, you need to uncomment the line in controllers/application.rb that says protect_from_forgery :secret => 'blah'. This makes sure all your HTML and JavaScript requests are coming from your web application. It essentially protects you from something called "Cross-site request forgery" by embedding a token into your web forms.

As a side note, it's really not giving you much security at all, but that might be better left for another blog post.

I was banging my head against the wall yesterday trying to figure out why a custom Ajax.Updater wasn't working and I kept getting an ActionController::InvalidAuthenticityToken exception. I decided to dig into the request_forgery_protection.rb file in actionpack-*/lib/action_controller and found that for custom requests, you need to include the authenticity_token yourself by taking advantage of the form_authenticity_token helper. When building the updater's request url I just added "&authenticity_token=" to the end and everything was fine.

Another way would be to not use the forgery protection at all for that action by including this in your controller: protect_from_forgery :except => [:updater]

You can also completely remove forgery protection from a controller by doing skip_before_filter :verify_authenticity_token

Back to the vulnerability of your web forms: I imagine this does protect your web application from someone hosting a form on their site that posts to your site. However, if someone really wants to spam some stuff they'll scrape your page with cookies enabled on their scraping software, scrape your form's fields (which include the authenticity_token hidden field) and POST to their heart's desire.

라벨: ,

 
2010년 5월 31일 월요일
  vinyl - 정철씨, 성진대리 마지막 날
정철씨가 계약기간이 끝나 오늘 떠나게 됬다. 점심시간 맥주마시며, 조촐한 짧은 송별회를 가졌다.

다들 화알짝~

둘이 사귄다.

성진대리님 새로운 직장 적응 잘하고, 아이폰 개발 건승하세요 !

완휘선임, 나, 그리고 정철씨.








그리고 퇴근하는길, 두포과장님의 간지컷.

라벨: ,

 
2010년 5월 16일 일요일
  vinyl 우리 팀원들
나, 성진, 용욱. 




카메라 버튼 누르라고 

라벨: ,

 
2010년 4월 13일 화요일
  Ruby on Rails : MS SQLSERVER 연동하기
Rails 와 SQL Server 를 연동하는건 꽤 힘든 작업이었다. ruby 에 심어주어야하는 odbc 드라이버에는 버전 문제가 있었고, winxp 와 ubuntu 환경에서 DSN(Data Source Name) 을 생성하는 방법을 익히는데도 시간이 걸렸고, 이를 database.yml 에 작성하는데도 혼선이 있었다. 

다행히 구글링을 통해 여러 블로거들이 제시하는 방법을 적용하며 해결할 수 있었다. 이 글에서는 내가 경험하고 맞딱드린 문제들과 해결방법을 기록하고자 한다. 전체 과정을 상세히 기록하기엔 너무 양이 많기에, 블로그 링크를 걸어두어 그곳의 내용을 자세히 살펴보아야 할것이다.

본 포스팅을 실행한 환경은 다음과 같다.

os : Ubuntu Karmic Koala,
      Windows XP Service Pack 3
ruby : 1.8.7 version
rails : 2.3.5 version

우선, windows xp 환경부터 보자. 윈도우 환경은 꽤 간단한 편이다.

Windows XP 에서 설치하기 

1. ruby용 odbc 드라이버 받기

http://www.ch-werner.de/rubyodbc/ 에서 1.8용 i386-msvcrt-ruby-odbc.zip 파일을 다운받자. 링크된 페이지에는 다음과 같은 내용이 있다.

For Win32 operating systems DLLs of 0.997 are available in i386-msvcrt-ruby-odbc.zip. It contains the files odbc.so and odbc_utf8.so which need to be copied into the .../ruby/1.8/i386-msvcrt directory of MSVC based Ruby 1.8 installations.
ruby 1.8 환경에서는 0.997 버전을 다운받아 해당 디렉토리에 압축을 풀라는 내용이다.

이는 최신버전을 사용하지 말라는 얘긴데, ubuntu 에서 설정시에도 낮은 버전의 odbc 파일을 받아야 한다. 이는 ubuntu 설정 과정에서 설명하겠다.

2. activerecord-sqlserver-adapter 설치하기
우선 gem 을 업데이트 한후 파일을 설치하자.

gem update --system
gem install activerecord-sqlserver-adapter

3. DSN 생성하고, odbc 에 연결하기

윈도우에서는 odbcad32.exe 라는 tool 을 이용하여 DSN 을 생성해야 하는데,

http://www.truthsolutions.com/sql/odbc/creating_a_new_odbc_dsn.htm 페이지에 나온 방법대로 한단계씩 수행하면 된다.

참고로 위 링크 페이지는 windows server2000 에서 예제를 실행하는데, xp 에서는 제어판 > 관리도구 > 데이터 원본(ODBC) 로 프로그램을 실행하면 된다.
4. database.yml 에 명시하기 

development:
  adapter: sqlserver
  mode: odbc
  database: databasename
  username: yourid
  password: yourpassword
  dsn: dsnname
dsn 입력란에는 방금 생성한 DSN 의 이름을 적으면 된다.

위의 단계를 통해 성공적으로 sqlserver 와 연결된 rails 어플을 뛰울 수 있다.

이제, Ubuntu 환경에서 연동하는 법을 알아보자.

Ubuntu 에서 설치하기 

1. 필수 패키지 설치하기

$> sudo apt-get install unixodbc tdsodbc libodbc-ruby1.8

2. activerecord-sqlserver-adapte 설치하기

$> sudo gem install activerecord-sqlserver-adapter

3. freeTDS 드라이버를 unixODBC 에 인식시키기

$> sudo odbcinst -i -d -f /usr/share/tdsodbc/odbcinst.ini

만약, Ubuntu 가 아닌 다른 리눅스 배포판을 사용한다면, http://piao-tech.blogspot.com/2008/02/using-activerecord-with-microsoft-sql.html 에 나온 방법을 이용하면 된다.

4. DSN 생성후, unixODBC 에 추가하기

$> vim mydsn.ini

[mySQL Server]
Driver = FreeTDS
Description = My MSSQL Database
Trace = No
Server = ipadress_or_hostname
Port = 1433
Database = databasename


$> odbcinst -i -s -f mydsn.ini -h

sudo 가 빠진 점에 유의하자. 이렇게 해야 System 전반에 사용되는 것을 방지할 수 있다.

unixODBC 에 추가되었는지 테스트 해보자.

$> isql -v "mySQL Server" uid upassword
+---------------------------------------+
| Connected!                            |
|                                       |
| sql-statement                         |
| help [tablename]                      |
| quit                                  |
|                                       |
+---------------------------------------+
SQL>

위 화면이 뜬다면 성공이다. 간단한 sql 문을 적어 결과를 얻어올 수도 있다. 

5. database.yml 에 명시하기 


development:
  adapter: sqlserver
  mode: odbc
  database: databasename
  username: yourid
  password: yourpassword
  dsn: mySQL Server

6. rails 어플리케이션 구동하기

모든 설정이 완료되었음에도,

INTERN (0) [RubyODBC]Cannot allocate SQLHENV 

라는 에러메세지가 보인다면, 이는 1단계에서 설치한 libodbc-ruby1.8 의 버전문제인데, 이경우 구버전인 0.9995 를 사용해야 한다. http://gehling.dk/2010/02/the-woes-of-libodbc-ruby1-8-and-debian-ubuntu/ 에 이에대한 설명이 나와있다.

우선 기존 libodbc-ruby1.8 을 지우자
$> sudo apt-get remove libodbc-ruby1.8

http://packages.ubuntu.com/hu/hardy/i386/libodbc-ruby1.8/download 에서 구버전을 다운받는다.

$> wget http://mirrors.kernel.org/ubuntu/pool/universe/libo/libodbc-ruby/libodbc-ruby1.8_0.9995-1_i386.deb

$> sudo dpkg -i libodbc-ruby1.8_0.9995-1_i386.deb

이제 서버를 재시작하면 연결에 성공한 화면을 볼수 있다.

참고 블로그 :
http://piao-tech.blogspot.com/2008/02/using-activerecord-with-microsoft-sql.html
http://gehling.dk/2010/02/the-woes-of-libodbc-ruby1-8-and-debian-ubuntu/

라벨: , ,

 
2010년 3월 31일 수요일
  Ruby on Rails : Phusion Passenger 설치하기
Phusion Passenger 설치과정을 간단하게 기록하려한다. 본 예제는 Ubuntu 환경이며, Apache2 가 깔려있다는 전제에서 시작된다.

os : Ubuntu 9.10 Karmic Koala
ruby : 1.8 version

> sudo gem install passenger

만약,
Error installing passenger
Failed to build gem native extension

위 메세지가 보인다면,

> sudo apt-get install ruby1.8-dev

를 설치해주면 된다.

이제 다시 passenger 를 설치해보자.

> sudo gem install passenger

Apache2 관련 passenger 모듈 설치하기

> sudo passenger-install-apache2-module

설치과정은 아래 단계를 거치며 진행된다. enter 를 치며, 다음 단계로 진행하면 된다.

step 1.
Welcome to the Phusion Passenger Apache 2 module installer, v2.2.11.

This installer will guide you through the entire installation process. It
shouldn't take more than 3 minutes in total.

Here's what you can expect from the installation process:

1. The Apache 2 module will be installed for you.
2. You'll learn how to configure Apache.
3. You'll learn how to deploy a Ruby on Rails application.

Don't worry if anything goes wrong. This installer will advise you on how to
solve any problems.

Press Enter to continue, or Ctrl-C to abort.

step2.
Checking for required software...

* GNU C++ compiler... not found

* Ruby development headers... found

* OpenSSL support for Ruby... found

* RubyGems... found

* Rake... found at /usr/bin/rake

* rack... found

* Apache 2... found at /usr/sbin/apache2

* Apache 2 development headers... not found

* Apache Portable Runtime (APR) development headers... not found

* Apache Portable Runtime Utility (APU) development headers... not found

Some required software is not installed.

But don't worry, this installer will tell you how to install them.

Press Enter to continue, or Ctrl-C to abort.

자기 환경에 설치되어 있지 않은 프로그램에 대한 정보를 친절하게 보여준다.  Enter 를 치면 다음단계에서 설치방법에 대해 친절하게 설명해준다.

step 3.
Installation instructions for required software

* To install GNU C++ compiler:

Please run apt-get install build-essential as root.

* To install Apache 2 development headers:

Please run apt-get install apache2-prefork-dev as root.

* To install Apache Portable Runtime (APR) development headers:

Please run apt-get install libapr1-dev as root.

* To install Apache Portable Runtime Utility (APU) development headers:

Please run apt-get install libaprutil1-dev as root.


If the aforementioned instructions didn't solve your problem, then please take

a look at the Users Guide:
/usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/doc/Users guide Apache.html

위의 메세지대로 하나씩 설치를 한후, 다시 sudo passenger-install-apache2-module 명령을 실행하자.

step 4.
The Apache 2 module was successfully installed.

Please edit your Apache configuration file, and add these lines:

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11
PassengerRuby /usr/bin/ruby1.8

After you restart Apache, you are ready to deploy any number of Ruby on Rails
applications on Apache, without any further Ruby on Rails-specific

configuration!

Press ENTER to continue.

성공이다. 바탕색이 칠해진 부분은 나중에 apache 설정에 넣어야할 부분임으로 복사해두자.

step 5.
Deploying a Ruby on Rails application: an example

Suppose you have a Rails application in /somewhere. Add a virtual host to your Apache configuration file and set its DocumentRoot to /somewhere/public:

<virtualhost *:80="">

  ServerName www.yourhost.com

  DocumentRoot /somewhere/public # <-- be sure to point to 'public'!

  <directory public="" somewhere="">

    AllowOverride all # <-- relax Apache security settings

    Options -MultiViews # <-- MultiViews must be turned off

  </directory>

</virtualhost>

And that's it! You may also want to check the Users Guide for security and

optimization tips, troubleshooting and other useful information:

/usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/doc/Users guide Apache.html

마지막 단계에서는 apache 의 virtual host 설정에 관한 예제도 보여준다.


자기 환경에서 Apache Configure 파일을 찾는 방법은 다음과 같다.
> apache2ctl -V | grep SERVER_CONFIG_FILE
 output> -D SERVER_CONFIG_FILE="/etc/apache2/apache2.conf"



표시된 경로에 있는 파일을 열고(이때, 반드시 sudo 를 입력하여 root 계정으로 편집해야한다),

Phusion Passenger 설치과정에서 복사한 문구를 파일 끝에 넣는다.

LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11/ext/apache2/mod_passenger.so
PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.11
PassengerRuby /usr/bin/ruby1.8

이제 virtualhost 설정을 해주자.
> sudo vim /etc/apache2/sites-available/default


파일에 virtualhost 설정해준다

<virtualhost *:80="">

  ServerName www.yourhost.com

  DocumentRoot /somewhere/public  # <-- be sure to point to 'public'!

  <directory /somewhere/public >

    AllowOverride all   # <-- relax Apache security settings

    Options -MultiViews # <-- MultiViews must be turned off

  </directory>

</virtualhost>

DocumentRoot 선언에 rails 어플리케이션의 public 폴더를 명시하는 점에 주목하자.
참고로, # 주석은 실제 입력시 빼야 문법오류가 안뜬다

설정이 완료되었으면,  apache 를 재시작하자.
> sudo /etc/init.d/apache2 restart

이제 http://localhost/ 로 접속했을 때, rails 어플리케이션이 생성된 폴더가 root 로 잡히는걸 확인할 수 있다.

라벨: ,

 
2010년 3월 26일 금요일
  Ruby on Rails : Action Controller 예외처리(404, 500) 다루기
사용자가 브라우저에 존재하지 않는 경로를 요청하거나, 혹은 잘못된 ID값을 get 방식으로 전달할 때 Rails 는 exception 을 일으킨다. Rails API의 ActionController::Rescue 모듈에 관한 설명에는 다음과 같이 나와있다.

Actions that fail to perform as expected throw exceptions. These exceptions can either be rescued for the public view (with a nice user-friendly explanation) or for the developers view (with tons of debugging information). The developers view is already implemented by the Action Controller, but the public view should be tailored to your specific application.

The default behavior for public exceptions is to render a static html file with the name of the error code thrown. If no such file exists, an empty response is sent with the correct status code.

You can override what constitutes a local request by overriding the local_request? method in your own controller. Custom rescue behavior is achieved by overriding the rescue_action_in_public and rescue_action_locally methods.

위의 설명대로, rescue_action_in_public 와 rescue_action_locally 함수를 오버라이딩 함으로써 잘못수행된 요청에 대한 처리를 할수 있다.
rescue_action 메서드 명뒤에 붙은 public 과 local 은 어떤 차이가 있을까? 잘못된 수행에 의해 exception 이 발생할때, Rails 는 local_request? 함수를 통해 먼저 이 exception이 localhost 에서 발생했는지를 체크한다. 만약, true 일 경우, rescue_action_locally 를 호출하며 rescue_action_public 은 호출하지 않는다.

위의 exception 발생환경에 따른 분기는 유용할지도 모르나, 내 경우 모든 경우가 localhost 에서 발생했기에, rescue_action_in_public 을 언제 활용할 수 있는지는 모르겠다. 아래의 예제는 두 환경을 동일하게 처리하도록 코딩된 예제이다.
ApplicationController 에 다음 메서드를 오버라이딩 한다.


def rescue_action_in_public(exception)
  case exception
    when ActiveRecord::RecordNotFound, ActionController::RoutingError, ActionController::UnknownController, ActionController::UnknownAction
      #render_404
      render :file => "#{RAILS_ROOT}/public/404.html", :layout => false, :status => 404
    else
      #render_500
      render :file => "#{RAILS_ROOT}/public/500.html", :layout => false, :status => 500
    end
end

def rescue_action_locally(exception)
  rescue_action_in_public(exception)
end

라벨: , , , ,

 
with ruby core and CGIs

내 사진
이름:
위치: Seoul, South Korea

모니터 앞에서 싸구려 커피를 마시며

아카이브
3월 2010 / 4월 2010 / 5월 2010 / 6월 2010 / 7월 2010 / 11월 2010 / 12월 2011 /


Powered by Blogger

에 가입
글 [Atom]