값지고 귀한 정보당~

 

 

 

출처 :

http://blog.n-nuri.com/category/?page=31

출처 : http://hubgo.com/


이제 IT 업종에 종사하는 사람들 중에서 스위치를 모른다고 하는 사람은 거의 없을 것입니다. 스위치의 포트에 UTP케이블을 연결하여 LED에 불이 들어오고, 인터넷이 잘 연결되면 “아! 스위치가 잘 동작하는 구나”라고 생각하면 그만일 정도로 간편하여졌기 때문일 것입니다.

단순한 더미 이더넷 스위치나 Un-management 기반의 100Base-TX 스위칭 허브를 사용하는 독자라면 스위치가 아주 단순한 기능을 수행하는 장비라고 생각할 수 있습니다. 하지만, 좀더 IT계에서 네트워크 관리를 해본 사람이라면 자신이 사용하는 고급기능의 스위치에 대하여 완벽히 알고 있다고 장담할 사람이 얼마나 될까요? Management 기반의 L2 스위치만을 말하는 것은 아닙니다. 근래 들어 필수 불가결하게 업계에서 사용되는 L3/L4 스위치에 대하여 그 다양한 기능과 사양(specification)을 온전히 이해하고 설정하여 사용하는 사람은 흔치 않을 것입니다.

여기에서는 Layer 7 (L7) 스위치의 개념과 동작원리 및 활용 방법들을 소개합니다.
L7스위치는 그 기능 및 목적 시장이 대단히 다양합니다만, 기본적으로 콘텐츠를 인지하여 스위칭하는 장비로서 미션크리티컬한 응용 프로그램의(예를 들면, Pointcast, ERP Application, FTP, NFS, VoIP관련, 화상회의)관리 및 제어에 필요한 솔루션입니다. L7 스위치제품의 올바른 선택과 사용을 위해 보다 정확한 의미를 소개하도록 하겠습니다.



L7 스위치란 앞에서 언급하였듯이 콘텐츠를 인지하여 원하는 포트로 전달하는 스위치라고 말하곤 합니다. 하지만 “콘텐츠”와 “인지” 하는 말은 매우 광범위하고 애매모호한 기술용어이며 이 두 단어가 L7 스위치의 모든 기능을 내포한다고 보기는 어렵습니다. 혹자는 L4 스위치와 구별하여 OSI 7 참조모델을 참고하면서 L5-L7 layer의 packet의 데이타 영역을 분석하여 스위칭하는 장비라고 설명하기도 합니다. 이러한 설명은 매우 효율적이고, 적당한 설명이라고 생각합니다. 필자의 경험으로 L7 스위치를 한 문장으로 표현하는 것은 어렵습니다. 하지만 현재 상용되는 L7 스위치가 가져야 하는 기본 기능은 아래와 같습니다.
- TCP/UDP 헤더및 데이터(Payload)의 일부를 분석하고 분류합니다.
- HTTP URL 기반의 패킷 스위칭기능을 수행합니다.
- 세션별, 유저별, 혹은 응용별 QoS 정책을 지정할 수 있습니다.
- 응용프로그램 레벨의 로직구성이 가능합니다.

L7 스위치는 L3/L4 스위치의 기능을 대부분 포용하며, 최상의 레벨의 스위칭 기능을 제공하는 것은 사실이지만, L7 스위치에 대하여 몇 가지 오해의 소지는 존재합니다. 아래 몇 가지 유형을 적습니다.

- L7 스위치는 Layer 7 계층을 위한 스위치입니다.
- L7 스위치란 URL-based 스위치입니다.
- L7 스위치는 모든 TCP/UDP port(0-65535) 에 대한 인지가 가능합니다.

L7 스위치는 L7계층만을 다루는 것은 아닙니다. 스위치로서 동작하기 위하여 기본적인 L2, L3 스위치 기능을 포함하고, 부분적으로 L4 스위치기능를 지원합니다. 엄밀히 말하면 현재 상용의 L7 스위치는 Layer 5의 세션 계층 스위칭 역활에 충실하였다고 말할 수 있고, 모든 application들의 세션을 분류할 수 있는 것은 아닙니다.

한편으로, 현재 L7 스위치 장비는 웹 트래픽에 대한 패킷 구별 및 제어가 많은 부분을 차지하는 것이 사실이지만, L7 스위치 장비가 URL만을 다루는 것 만은 아닙니다. 많은 응용 프로그램들은 멀티미디어 및 미션크리티컬한 데이타 전송을 위해 데이타를 가공하므로, 이러한 데이타에 대한 처리가 L7 스위치에 필요합니다.

또한, L7 스위치가 모든 TCP/UDP에 기반한 응용프로그램을 분류하고 제어할 수 있는 것은 아닙니다. 일반적으로 널리 알려진 well-known port인 (FTP, NFS, H.323, RTP)등에서 세션 처리가 가능하지만, 순간적으로 사용하는 임시 port들을 분석하는 것은 매우 제한적입니다. 또한, L7 스위치에서 QoS기능을 지원하지만, 전문 QoS 장비들 (예를 들어, 시타라 네트웍스의 QoSWorks, 패킷티어사의 PacketShaper, 넷리얼리티사의 WiseWan)에서 제공하는 트래픽 쉐이핑(shaping), rate control등과 동일시 해서는 안됩니다. 물론, 차후에 L7 스위치는 QoS기능을 기본으로 제공하게 될 것입니다.



L7 스위치의 동작은 개념적으로 매우 단순할 수도 있습니다. 하지만, 그 내부의 패킷에 대한 분류 및 제어는 매우 난해하며 정교한 기술이라고 할 수 있습니다. 따라서, 세계적으로도 L7 스위치는 이미 성숙된 기술이 아니라, 지속적으로 개선되어지고 있는 기술이라고 할 수 있습니다.
일반적으로 클라이언트 단에서는 특정 응용(application)에 대한 요청정보(request data)를 보내고 받음으로써 응용계층에서의 데이터 전송이 가능하게 됩니다. 이러한 특정 응용의 요청으로는 HTTP 정보, FTP, telnet, email 정보등이 될 수 있습니다.

L7 스위칭기능은 이러한 특정 응용데이터에 따라 패킷의 경로와 서버의 할당을 결정하는 기능이라고 할 수 있습니다. 즉, TCP SYN 패킷을 검사하여 바로 서버로 할당하기 보다는 요청정보(request data)를 검사하여 서버로 할당하도록 해야 합니다. 이러한 콘텐츠 기반의 스위칭을 수행하기 위해서는 클라이언트와 서버단 사이에 TCP 세션을 형성을 잠시 보류할 필요가 있습니다.
L7 스위칭을 담당하는 장비는 클라이언트와의 TCP 세션을 잠시 보류시킨 상태에서 특정 요청정보가 전송되어 왔을 때, 이를 기반으로 서버쪽과 TCP 세션을 중계하는 역할을 담당하여야 합니다. 이러한 기능을 delayed binding 기능, tcp splicing 기능 혹은 tcp termination 기능이라고 부를 수 있습니다. Delayed binding 동작을 TCP 패킷의 흐름으로 표현하면 아래의 그림과 같습니다.

 
 

'web' 카테고리의 다른 글

L4 이야기  (0) 2007.09.29
L4 사용여부.  (0) 2007.09.29
L4스위치와 L7스위치의 차이점  (0) 2007.09.29
자바 - include 관련  (1) 2007.09.28
외부 컨텐츠를 가져오는 법  (0) 2007.09.28
Posted by '김용환'
,

 

회사에 L7스위치가 생기면서 L7check라는 jsp파일을 이용하여 L7체크를 한다.

실제 tomcat 인스턴스에 대한 모니터링이라 할 수 있겠지..

밑에 보니까. L7가 다양하게 패턴등을 분석해 패킷을 처리할 수 있도록 되어 있단다..  

 

이런거 시스템 관리자가 개발자에게 알려주면 좋을텐데.. 좀 더 화려운 헬쓰 체크를 보내줄 수 있을껴 아녕~ ㅋㅋ

 

 

발췌:

http://blog.n-nuri.com/category/?page=31

 

출처 : http://hubgo.com/

1. 구조적 차이점 - Intellingence
L4스위치 : TCP/UDP 포트 정보를 분석해 해당 패킷이 현재 사용하는 서비스 종류(HTTP, FTP, 텔넷, SMTP, POP3, SSL등)별로 PACKET을 처리

L7스위치 : 트래픽의 내용(e-mail제목/내용의 문자열, HTTP컨텐츠URL, FTP파일 제목, SSL ID, Cookie 정보, 특정 바이러스(e.g. CodeRed, Nimda)패턴등을 분석해 Packet을 처리

공통점 : 스위치로 들어온 Packet을 적절한 목적지(주로 네트워크 장비나 클라이언트, 때로는 불필요한 Packet을 Drop시키기도 함)로 전송해줌. 기본적인 기능과 역할은 동일하나 Packet을 분석해 성격과 중요도를 분류하는 Intelligence가 달라서 "적절한 목적지"를 찾아내 해당 Packet을 처리해 주는 능력에 차이가 발생함.

2. 기능적 차이점
* 보다 높은 수준의 Intelligence를 갖춘 스위치일수록 더 정교한 패킷의 부하분산(Load Ballancing)및 Qos기능 구현이 가능함.
* L7스위치는 다음과 같은 기능을 통해 네트워크 시스템의 보안성 강화가 가능함.
1) Dos/SYN Attack에 대한 방어
2) CodeRed/Nimda등 바이러스 감염 패킷의 필터링
3) 네트워크 자원의 독점 방지를 통한 네트워크 시스템의 보안성 강화가 가능함.

'web' 카테고리의 다른 글

L4 사용여부.  (0) 2007.09.29
L7 스위치 개념 및 동작원리  (0) 2007.09.29
자바 - include 관련  (1) 2007.09.28
외부 컨텐츠를 가져오는 법  (0) 2007.09.28
jsp에서 한글이 깨지는 현상  (0) 2007.09.28
Posted by '김용환'
,

자바 - include 관련

web 2007. 9. 28. 20:39

어제 c:import를 쓰면서 문득 생각난 것이 있었는데. jsp:include였다.

차이가 무엇일까 문서를 찾게 되었다.

 

c:import는 상대적인 URL, 외부 웹을 include하지만, jsp:include는 내부가 한계인듯 하다. (틀리면 알려주시요...)

 

밑에 발췌한 jsp:include는 relativeURL 나 표현식만을 page 어트리뷰트에 저장할 수 있다.

 

발췌

http://java.sun.com/products/jsp/syntax/1.2/syntaxref1214.html

 

 

<jsp:include>

Includes a static file or the result from another web component.

JSP Syntax

<jsp:include page="{relativeURL | <%= expression %>}" 	
   flush="true| false" />

or

<jsp:include page="{relativeURL | <%= expression %>}" 	
   flush="true| false" >	
   <jsp:param name="parameterName"	
      value="{parameterValue | <%= expression %>}" />+	
</jsp:include>

XML Syntax

<jsp:include page="{relativeURL | %= expression %}"	
   [ flush="true | false" ] /> 

or

<jsp:include page="{relativeURL | %= expression %}"	
[ flush="true | false" ] > 	
   [ <jsp:param name="parameterName" 	
      value="{parameterValue | %= expression %}" /> ] +	
</jsp:include> }

Examples

<jsp:include page="scripts/login.jsp" />
<jsp:include page="copyright.html" />
<jsp:include page="/index.html" />
<jsp:include page="scripts/login.jsp">	
   <jsp:param name="username" value="jsmith" />	
</jsp:include>

Description

The <jsp:include> element allows you to include either a static or dynamic resource in a JSP page. The results of including static and dynamic resources are quite different. If the resource is static, its content is included in the calling JSP page. If the resource is dynamic, it acts on a request and sends back a result that is included in the JSP page. When the include action is finished, the JSP container continues processing the remainder of the JSP page.

You cannot always determine from a pathname if a resource is static or dynamic. For example, http://server:8080/index.html might map to a servlet through a server alias. The <jsp:include> element handles both types of resources, so it is convenient to use when you don't know whether the resource is static or dynamic.

If the included resource is dynamic, you can use a <jsp:param> clause to pass the name and value of a parameter to the resource. As an example, you could pass the string username and a user's name to a login form that is coded in a JSP page.

Attributes

  • page="{ relativeURL | <%= expression %> }"

    The relative URL that locates the resource to be included, or an expression that evaluates to a String equivalent to the relative URL.

    The relative URL looks like a pathname--it cannot contain a protocol name, port number, or domain name. The URL can be absolute or relative to the current JSP page. If it is absolute (beginning with a /), the pathname is resolved by your web or application server.

  • flush="true | false"

    If the page output is buffered and the flush attribute is given a true value, the buffer is flushed prior to the inclusion, otherwise the buffer is not flushed. The default value for the flush attribute is false.

  • <jsp:param name="parameterName"
      value="{parameterValue | <%= expression %>}" />+ 

The <jsp:param> clause allows you to pass one or more name/value pairs as parameters to an included resource. The included resource should be dynamic, that is, a JSP page, servlet, or other resource that can process the parameter.

You can use more than one <jsp:param> clause if you want to send more than one parameter to the included resource. The name attribute specifies the parameter name and takes a case-sensitive literal string. The value attribute specifies the parameter value and takes either a case-sensitive literal string or an expression that is evaluated at request time.

 

 

발췌

http://aboutjsp.com/lec/include.jsp

 

 
* JSP Action - <jsp:include page="URI" flush="true" />

[syntax]
1). body 구문이 없는 경우
<jsp:include page="URI" flush="true" />

2). body 구문이 있는 경우
<jsp:include page="URI" flush="true">
<jsp:param name="파라메터이름" value="파라메터값" /> /* xxx.jsp?파라메터이름=파라메터값 */
</jsp:include>  

위와 같이 두가지 사용 용법이 있으며, 두번째 방법을 사용하면 해당 jsp파일에 파라메터값도 넘겨 줄수가 있습니다.
JSP Action 구문의 include 는 include되는 파일과 include 시키는 파일(doc1.jsp와 doc3.jsp)를 각각 컴파일 한후 두 파일의 실행 결과를 한곳에 합쳐서 출력을 하게 됩니다. 즉, 완전히 "별도로" 동작하게 됩니다.
여기에서 flush="true" 문장은 true나 false 가 들어 갈수 있는 부분으로써 include를 실행하기 전에 out.flush()를 실행할지 여부를 결정하는 것입니다. 물론 true일때 out.flush()를 실행하겠지요. JSP 스펙 1.1 까지는 반드시 true로 설정이 되어 있어야만 했으니, 1.2 부터는 true/false중 원하는것을 선택하면 됩니다.


* include 지시어 - <%@ include file="URI" %>

include 지시어 와 Action 구문과의 가장 큰 차이점은 include 지시어는 컴파일 되기전에 파일이 내용이 합쳐진다는 것입니다. 즉, doc3.jsp 는 doc2.jsp의 내용을 자신의 문서내에 포함하여 하나의 파일로 인식한다는 것입니다. doc2.jsp 에 보면 page Directive 가 생략이 되어 있는데, 그것이 바로 이러한 이유 때문입니다.

doc2.jsp에도 page Directive를 설정해 주었다면 에러가 발생할 것입니다. 하나의 페이지에 두번 선언을 하는 꼴이 되어 버릴테니까 말이죠.

 

그런데, Action 구문을 사용 하였을 때에는 두개의 파일 각각 다른 파일처리 되어 두개의 servlet 파일 생성하게 됩니다. 따라서 어느 한 파일이 수정되면 곧바로 적용되어 화면에 출력이 되게 됩니다.

하지만 include 지시어 문을 사용하게 되면 하나의 servlet 파일이 생성되게 됩니다. 이로 인해 엄청난 차이점이 발생하게 되는데, JSP의 특성상 JSP파일이 조금이라도 수정이 되어 있으면 servlet 으로 재 변경되어 다시 컴파일이 이루어 지게 됩니다. 그런데, doc2.jsp 파일을 내용을 수정하고, doc3.jsp 파일을 부르게 되면 수정되기 전의 doc2.jsp 파일의 내용이 출력됩니다.

 

이러한 특징은 tomcat 5 버젼대부터 달라지게 되었는데, include되는 파일을 수정하더라도 서블릿 컨테이너가 알아서 모두 재 컴파일 해준다는 것입니다. 필자가 확인한 바로는 OC4J 최신 버젼에서도 tomcat 5와 같이 자동으로 처리되었습니다.

 

 

 톰캣 5부터는 이러한 문제가 사라진다고 하는군... include에 대한 dependency를 제거된다고 한다.. 오호라~ 굿!

'web' 카테고리의 다른 글

L7 스위치 개념 및 동작원리  (0) 2007.09.29
L4스위치와 L7스위치의 차이점  (0) 2007.09.29
외부 컨텐츠를 가져오는 법  (0) 2007.09.28
jsp에서 한글이 깨지는 현상  (0) 2007.09.28
SSL (c, java)  (0) 2007.09.28
Posted by '김용환'
,

jsp에서 한글이 깨지는 것때문에 공부하게 되는 팁~~^^

이미 이런 jsp 베스트 프랙티스라 해서 사용하고 있는데...  굳이 코딩하거나 고민하지 않아도 된다는거....(살짝은 재미없다.)

그러나 나에게는 편하다라는 것~^^

 

 

발췌

JSP best practices: Import content to your Web site

http://www.ibm.com/developerworks/java/library/j-jsp06173.html

 

이 문서를 보면 다음과 같다.

 

 

Importing external content

One of the real advantages of using c:import is its ability to pull in content from external Web sites or Web applications. Back when you were learning about jsp:includes, you may have noticed that we used file attributes to designate static content to include. The file attribute does just what its name implies: it allows you to pull in a local file's content. The corresponding attribute for c:import is url, and it too does what its name suggests: it allows you to pull in any URL. Rather than just populating your site pages with content from local files, c:import lets you pull in content from any URL, which is essentially a really slick way to wrap content from other sites in your own look and feel.

Let's consider a simple example. Say I want to place some pictures of a gorgeous Madagascar Rosewood guitar on my Web site. While I could build my own page, complete with image files and relative links, it seems much easier to simply import the content from another site, then wrap it up in my site's look and feel. Listing 3 shows how easy it would be to use c:import's url attribute to pull in image files from my favorite guitar site:


Listing 3. Importing external content
<%@ page language="java" contentType="text/html" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<html>
<head>
     <title>newInstance.com</title>
     <meta http-equiv="Content-Type" 
       content="text/html; charset=iso-8859-1" />
     <link href="/styles/default.css" rel="stylesheet" type="text/css" />
</head>

<body>

<c:import url="header.jsp">
     <c:param name="pageTitle" 
       value="newInstance.com :: True North Guitars"/>
     <c:param name="pageSlogan" value="...building it from scratch" />
</c:import>
<%@ include file="/navigation.jsp" %>
<c:import url="bookshelf.jsp" />

<c:import 
  url="http://www.truenorthguitars.com/Clients/Richman/index.htm" />

<%@ include file="/footer.jsp" %>
</body>
</html>

The code looks good enough -- but if you try this out on your own, you'll quickly see a problem. None of the images show up and all of the relative links fail. Of course, if you think about it, the cause is perfectly clear. Because the external resource (in this case an image file) is interpreted, you get the result of that interpretation inserted directly into your output stream. External image links like /images/guitar-01-24.jpg will show up as missing. The only way to resolve this problem would be to copy the image to your site, which is an entirely different (and more time consuming) technique as compared to a simple import.

So importing external content really only makes sense if the content is purely text-based. For example, consider a site geared toward system administrators, with its own header, footer, and look and feel. One page of the site details how to set up an initial README file for users to see how the site should be used. You could refer to an existing FTP site's instructions as follows:

<c:import url="ftp://ftp.oreilly.com/pub/README.ftp" />

Notice that it's just as simple to import FTP server content as it is to pull in HTTP material. You can use the same command for HTTPS, as well as any other protocol that both your site and the target site understand and speak.

 

 

설명을 달면, c:import는 외부 웹싸이트 정보 또는 웹 어플리케이션의 컨텐츠를 가져올 수 있다고 한다.

 

<c:import url="bookshelf.jsp" />

<c:import
  url="http://www.truenorthguitars.com/Clients/Richman/index.htm" />

<c:import url="ftp://ftp.oreilly.com/pub/README.ftp" />

 

 

이렇게 다양하게 사용가능하다고 한다.

 

'web' 카테고리의 다른 글

L4스위치와 L7스위치의 차이점  (0) 2007.09.29
자바 - include 관련  (1) 2007.09.28
jsp에서 한글이 깨지는 현상  (0) 2007.09.28
SSL (c, java)  (0) 2007.09.28
아파치 래퍼럴 (apache referal)  (0) 2007.09.27
Posted by '김용환'
,

 

HTTPClient를 이용할때,  한글이 깨지는 현상이 있어서..

다음과 같이 처리했다.

 

Before

<%

 

 try {
    HttpClient client = new HttpClient();
   client.setTimeout(3000);
   GetMethod m = new GetMethod(content);
   int status = client.executeMethod(m);
   
   if (status == HttpStatus.SC_OK) {
      
    body = m.getResponseBodyAsString();
    m.releaseConnection();
    out.println("<base href="+dir+">");
    out.println(body);
   }
  }
  catch (Exception e) {
   System.out.println(e);
  }

%>

 

 

 

After

<%

String content = "";  

  if (url.indexOf("/community") != -1 ) {
   content = host + url;
  }
  else {
   content = host + "/static" + url;
  }

%>

 

<c:import url="${content}" charEncoding="MS949"/>

 

 

 

 

 

 

'web' 카테고리의 다른 글

자바 - include 관련  (1) 2007.09.28
외부 컨텐츠를 가져오는 법  (0) 2007.09.28
SSL (c, java)  (0) 2007.09.28
아파치 래퍼럴 (apache referal)  (0) 2007.09.27
외부싸이트에서 호출되는 것 확인하기  (0) 2007.09.22
Posted by '김용환'
,

SSL (c, java)

web 2007. 9. 28. 03:50

SSL 통신과 관련되어 좋은 정보가 있어서 소개한다.

c언어를 이용하여 SSL 통신을 java로 컨버팅한것이다. HTTPClient를 이용하면 굉장히 쉽게 사용할 수 있다.

 

c언어 공부용으로 발췌함~^^

 

출처

http://kldp.org/node/28194

 

 

서버(serv.c)

/* serv.cpp  -  Minimal ssleay server for Unix 
   30.9.1996, Sampo Kellomaki <sampo@iki.fi> */ 


/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b 
   Simplified to be even more minimal 
   12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */ 

#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <memory.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 

#include <openssl/rsa.h>       /* SSLeay stuff */ 
#include <openssl/crypto.h> 
#include <openssl/x509.h> 
#include <openssl/pem.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 


/* define HOME to be dir for key and cert files... */ 
#define HOME "./" 

/* Make these what you want for cert & key files */ 
#define CERTF  HOME "server-req.pem" 
#define KEYF  HOME  "server-key.pem" 


#define CHK_NULL(x) if ((x)==NULL) exit (1) 
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); } 
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); } 

void main () 
{ 
    int err; 
    int listen_sd; 
    int sd; 
    struct sockaddr_in sa_serv; 
    struct sockaddr_in sa_cli; 
    size_t client_len; 

    SSL_CTX* ctx; 
    SSL*     ssl; 
    X509*    client_cert; 

    char*    str; 
    char     buf [4096]; 

    SSL_METHOD *meth; 

    /* SSL preliminaries. We keep the certificate and key with the context. */ 
    SSL_load_error_strings(); 
    SSLeay_add_ssl_algorithms(); 
    meth = TLSv1_server_method(); 

    // create a new SSL_CTX object as framework for TLS/SSL enabled functions 
    ctx = SSL_CTX_new (meth); 
    if (!ctx) { 
        ERR_print_errors_fp(stderr); 
        exit(2); 
    } 

    if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0) { 
        ERR_print_errors_fp(stderr); 
        exit(3); 
    } 
    if (SSL_CTX_use_PrivateKey_file(ctx, KEYF, SSL_FILETYPE_PEM) <= 0) { 
        ERR_print_errors_fp(stderr); 
        exit(4); 
    } 
    if (!SSL_CTX_check_private_key(ctx)) { 
        fprintf(stderr,"Private key does not match the certificate public key\n"); 
        exit(5); 
    } 




    /* Prepare TCP socket for receiving connections */ 

    // Create Internet Socket and Fill sockaddr_in 
    listen_sd = socket (AF_INET, SOCK_STREAM, 0);    
    CHK_ERR(listen_sd, "socket"); 

    memset (&sa_serv, '\0', sizeof(sa_serv)); 
    sa_serv.sin_family      = AF_INET; 
    sa_serv.sin_addr.s_addr = INADDR_ANY; 
    sa_serv.sin_port        = htons (1111);          /* Server Port number */ 

    // Bind 
    err = bind(listen_sd, (struct sockaddr*) &sa_serv, sizeof (sa_serv));                    
    CHK_ERR(err, "bind"); 

    // Listening 
    err = listen (listen_sd, 5);  
    CHK_ERR(err, "listen"); 

    // Accept 
    client_len = sizeof(sa_cli); 
    sd = accept (listen_sd, (struct sockaddr*) &sa_cli, &client_len); 
    CHK_ERR(sd, "accept"); 

    // Close Listening socket 
    close (listen_sd); 

    // Connected-client info. 
    printf ("Connection from %lx, port %d\n", 
    sa_cli.sin_addr.s_addr, sa_cli.sin_port); 



    // TCP connection is ready. Do server side SSL. 
    // create a new SSL structure for a connection 
    ssl = SSL_new (ctx);                     
    CHK_NULL(ssl); 

    // connect the SSL object with a file descriptor 
    SSL_set_fd (ssl, sd); 
    err = SSL_accept (ssl);    
    CHK_SSL(err); 

    // Get the cipher - opt  
    printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); 

    // Get client's certificate (note: beware of dynamic allocation) - opt 
    client_cert = SSL_get_peer_certificate (ssl); 
    if (client_cert != NULL)  
    { 
        printf ("Client certificate:\n"); 

        str = X509_NAME_oneline (X509_get_subject_name (client_cert), 0, 0); 
        CHK_NULL(str); 
        printf ("\t subject: %s\n", str); 
        free (str); 

        str = X509_NAME_oneline (X509_get_issuer_name  (client_cert), 0, 0); 
        CHK_NULL(str); 
        printf ("\t issuer: %s\n", str); 
        free (str); 

        /* We could do all sorts of certificate verification stuff here before 
           deallocating the certificate. */ 

        X509_free (client_cert); 
    }  
    else 
    { 
        printf ("Client does not have certificate.\n"); 
    } 

    // DATA EXCHANGE - Receive message and send reply. 
    err = SSL_read (ssl, buf, sizeof(buf) - 1);        
    CHK_SSL(err); 

    buf[err] = '\0'; 
    printf ("Got %d chars:'%s'\n", err, buf); 

    err = SSL_write (ssl, "I hear you.", strlen("I hear you.")); 
    CHK_SSL(err); 

    /* Clean up. */ 
    close (sd); 
    SSL_free (ssl); 
    SSL_CTX_free (ctx); 
} 

클라이언트(cli.c)

/* cli.cpp  -  Minimal ssleay client for Unix 
   30.9.1996, Sampo Kellomaki <sampo@iki.fi> */ 

/* mangled to work with SSLeay-0.9.0b and OpenSSL 0.9.2b 
   Simplified to be even more minimal 
   12/98 - 4/99 Wade Scholine <wades@mail.cybg.com> */ 

#include <stdio.h> 
#include <memory.h> 
#include <errno.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 

#include <unistd.h> 

#include <openssl/crypto.h> 
#include <openssl/x509.h> 
#include <openssl/pem.h> 
#include <openssl/ssl.h> 
#include <openssl/err.h> 


#define CHK_NULL(x) if ((x)==NULL) exit (1) 
#define CHK_ERR(err,s) if ((err)==-1) { perror(s); exit(1); } 
#define CHK_SSL(err) if ((err)==-1) { ERR_print_errors_fp(stderr); exit(2); } 

void print_x509(SSL *ssl) 
{ 
    char *ascii_cert; 
    X509 *cert = SSL_get_peer_certificate(ssl); 
    BIO *b; 
    BUF_MEM *bptr; 

    b = BIO_new(BIO_s_mem()); 

    if(X509_print(b, cert) > 0) 
    { 
        BIO_get_mem_ptr(b, &bptr); 
        ascii_cert = (char *)malloc(1 + bptr->length); 
        memcpy(ascii_cert, bptr->data, bptr->length); 
    } 
    else 
    { 
        ascii_cert = (char *)malloc(1024); 
        sprintf(ascii_cert, "This certificate has never been seen before and can't be shown\n"); 
    } 
    BIO_free(b); 

    /* X.509 인증서 출력 */ 
    printf("X.509:\n%s\n", ascii_cert); 
} 

void main (int argc, char **argv) 
{ 
    int err; 
    int sd; 
    struct sockaddr_in sa; 

    SSL_CTX* ctx; 
    SSL*     ssl; 
    X509*    server_cert; 

    char*    str; 
    char     buf [4096]; 
    char hello[80]; 

    SSL_METHOD *meth; 

    printf ("Message to send: "); 
    fgets (hello, 80, stdin); 

    SSLeay_add_ssl_algorithms(); 
    //meth = SSLv2_client_method(); 
    meth = TLSv1_client_method(); 
    SSL_load_error_strings(); 
    ctx = SSL_CTX_new (meth); 
    CHK_NULL(ctx); 
    CHK_SSL(err); 


    /////////////////////////////////////////////////////////////////////////////////////// 
    // Create a socket and connect to server using normal socket calls. 
    sd = socket (AF_INET, SOCK_STREAM, 0);   
    CHK_ERR(sd, "socket"); 

    memset (&sa, '\0', sizeof(sa)); 
    sa.sin_family      = AF_INET; 
    sa.sin_addr.s_addr = inet_addr ("203.247.40.139");   /* Server IP */ 
    sa.sin_port        = htons     (atoi(argv[1]));          /* Server Port number */ 

    // Normal-connect 
    err = connect(sd, (struct sockaddr*) &sa, sizeof(sa));      
    CHK_ERR(err, "connect"); 

    // Now we have TCP conncetion. Start SSL negotiation. 
    // create a new SSL structure for a connection 
    ssl = SSL_new (ctx);     
    CHK_NULL(ssl);     

    // connect the SSL object with a file descriptor 
    SSL_set_fd (ssl, sd); 

    // initiate the TLS/SSL handshake with an TLS/SSL server 
    err = SSL_connect (ssl);     
    CHK_SSL(err); 

    /*  
     * Following two steps are optional and not required for 
     * data exchange to be successful.  
     */ 

    printf ("SSL connection using %s\n", SSL_get_cipher (ssl)); 

    // Get server's certificate (note: beware of dynamic allocation) - opt  
    server_cert = SSL_get_peer_certificate (ssl);     
    CHK_NULL(server_cert); 
    print_x509(ssl); 

    /* 
    printf ("Server certificate:\n"); 
    str = X509_NAME_oneline (X509_get_subject_name (server_cert),0,0); 
    CHK_NULL(str); 
    printf ("\t subject: %s\n", str); 
    free (str); 

    str = X509_NAME_oneline (X509_get_issuer_name  (server_cert),0,0); 
    CHK_NULL(str); 
    printf ("\t issuer: %s\n", str); 
    free (str); 
    */ 

    /*  
     * We could do all sorts of certificate verification stuff here before 
     * deallocating the certificate.  
     */ 
    X509_free (server_cert); 

    /////////////////////////////////////////////////////////////////////////////////////// 
    // DATA EXCHANGE - Send a message and receive a reply. 
     
    //err = SSL_write (ssl, "Hello World!", strlen("Hello World!")); 
    //CHK_SSL(err);  
    err = SSL_write (ssl, hello, strlen(hello));   
    CHK_SSL(err); 

    err = SSL_read (ssl, buf, sizeof(buf) - 1);     
    CHK_SSL(err); 
    buf[err] = '\0'; 
    printf ("Got %d chars:'%s'\n", err, buf); 

    // send SSL/TLS close_notify 
    SSL_shutdown (ssl);   

    /* Clean up. */ 

    close (sd); 
    SSL_free (ssl); 
    SSL_CTX_free (ctx); 
} 

서버의 개인키와 셀프 사인된 인증서 입니다. 그리고 인증서의 패스워드는 abcd 입니다.

*server-key.pem

-----BEGIN RSA PRIVATE KEY----- 
Proc-Type: 4,ENCRYPTED 
DEK-Info: DES-EDE3-CBC,AA26BA50E01C1524 

oXXeC9GyPwvJxVyqRXROLXp5Ew5n/gS6+vpDXXSIsuE8RIk17Mtx1NpOGWxmQ/hd 
L9zAvDniOoavTyKyVI0VZx13A1RzptaSP1CqEBeQUlT5DU3IFhwdj8BRXfpaWrve 
NnCZiyvr5CNgSLg0pVvcUhI9CmQtj94bLN6KATbZ/FyQZTSkrN6kh1jBwHd04RvZ 
2YvxtuzevtxvLLHOvxCxocIYnPWJzViEyuKbz/co3ywZibFXrqu2Xpgrk3lHN21M 
ZXWPeVJ2DzAIWMhqjpOX98w0hLHvZHVWpiO09avH/wzR7YbCKZpwFZUdjcUuzETZ 
OzJO3p97mf9D64KbAOmq7h6Pme8pkT/io8Qe24XyaV0C7ca67t3J3NSBVmyPNgEP 
MsfTctk98FfKmOXD7fm1y5k4YZ7weDuDRs09KNFxn6sm94Q5ssQmaAPNCVZTpGSW 
p6/sDb1dU8/2lTFFU67tquwR679h2AouF/Ea0Sa2l0o8HfcAS8YJxp77+W2qB9Zt 
ymkSJlvX7s5qt4oBryTOyDKVFzmzksjJHaar7tRJ00fTh+AICxxQvfzUE82oH49R 
+07clHW7DCh4FMevvflSujfIChVIwvwg2Vr1b63QIp8tlZ0BiPAZH8TV6cPDROVQ 
5dWDQlcOrvfNsC1qI17kvn/N4ZzKyvdB4cEZh6xMH8UfFJ+qpNhJ1gwJFe9XI11z 
90hSa9lsFqBBw2sGmnN9QxKC1UpdvjoZV1VTBEqGWYDR4S1lx575gm77nF9XcJAr 
pW7Fs9qKLWi7trWQxI0ncKQ6DGuGbh/ctebgchKe/kIA/4E0nQjTcg== 
-----END RSA PRIVATE KEY----- 

*server-req.pem

-----BEGIN CERTIFICATE----- 
MIIDYjCCAsugAwIBAgIBADANBgkqhkiG9w0BAQQFADCBgzELMAkGA1UEBhMCQVUx 
EzARBgNVBAgTClNvbWUtU3RhdGUxDDAKBgNVBAcTA0ZvbzENMAsGA1UEChMETGFu 
ZDEMMAoGA1UECxMDRm9vMRYwFAYDVQQDEw1zbmFmdS5taXQuZWR1MRwwGgYJKoZI 
hvcNAQkBFg1mdWJvYkBtaXQuZWR1MB4XDTAwMTExMzAyMjgxMVoXDTAwMTIxMzAy 
MjgxMVowgYMxCzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMQwwCgYD 
VQQHEwNGb28xDTALBgNVBAoTBExhbmQxDDAKBgNVBAsTA0ZvbzEWMBQGA1UEAxMN 
c25hZnUubWl0LmVkdTEcMBoGCSqGSIb3DQEJARYNZnVib2JAbWl0LmVkdTCBnzAN 
BgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAtvnaO7XYscdlXoTwql5uHa5Vx1ecKZOc 
pSAqGQx4LnMGbRvnb+m2OxUZ3xFc8V1a2eKlUyTKoo0bebTeS5/BLBik47TjfUlw 
/P1hLYhIFZNb+o/g3ZeWG/9QZYs0favV+0iAoqpy/scHwHZg2Vnpjivsit543s+x 
uuWuD4fpUIsCAwEAAaOB4zCB4DAdBgNVHQ4EFgQUTkDDGu1osvRIZY/LlZdmRbAs 
rM0wgbAGA1UdIwSBqDCBpYAUTkDDGu1osvRIZY/LlZdmRbAsrM2hgYmkgYYwgYMx 
CzAJBgNVBAYTAkFVMRMwEQYDVQQIEwpTb21lLVN0YXRlMQwwCgYDVQQHEwNGb28x 
DTALBgNVBAoTBExhbmQxDDAKBgNVBAsTA0ZvbzEWMBQGA1UEAxMNc25hZnUubWl0 
LmVkdTEcMBoGCSqGSIb3DQEJARYNZnVib2JAbWl0LmVkdYIBADAMBgNVHRMEBTAD 
AQH/MA0GCSqGSIb3DQEBBAUAA4GBAEmPUSEShK6tHGdwPUvwYwp7cR0mwRNi3peB 
vu5nqwjCnCFaQaUdBfh/18kT5uEpGB48A/6BImov36Aiq9cq6dVNGQkVI0y/FJ0J 
28zSYrRHXGOS5qMoWRaqCabuYbDUsx/bvCr21ET948jMawdd8nq+3ungEQzlIZtO 
oWcmJYad 
-----END CERTIFICATE----- 

*컴파일

# gcc -o serv serv.c -lssl -lcrypto 
# gcc -o serv cli.c -lssl -lcrypto 

*실행

# ./serv 
Enter PEM pass phrase: abcd 

# ./cli 
Message to send: hello!! 

이번에는 자바 클라이언트 입니다.. 여기에서 에러가 나는데.. 봐주세요..^^;

*SunSSLSocketClient.java

import java.io.*; 
import java.net.*; 
import java.security.*; 
import javax.net.ssl.*; 

public class SunSSLSocketClient { 
    private static final String HOST = "127.0.0.1"; 
    private static final int    PORT = 1111; 
    private static String [] socketProtocolVersion = new String[] {"TLSv1"}; 

    public static void main(String [] args) throws Exception { 
        char [] passPhrase = "abcd1234".toCharArray(); 

        KeyStore keystore = KeyStore.getInstance("JKS"); 
        keystore.load(new FileInputStream(".keystore"), passPhrase); 

        TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); 
        tmf.init(keystore); 

        SSLContext context = SSLContext.getInstance("TLS"); 
        TrustManager [] trustManagers = tmf.getTrustManagers(); 

        context.init(null, trustManagers, null); 

        SSLSocketFactory sf = context.getSocketFactory(); 
        SSLSocket socket = (SSLSocket)sf.createSocket(HOST, PORT); 
        socket.setEnabledProtocols(socketProtocolVersion); 
     
        System.out.println(socket); 

        PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true); 
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream())); 

        pw.println("Hello!!"); 
        String fromServer = br.readLine(); 
        System.out.println(fromServer); 
    } 
} 

책에보니까 보통 이렇게 하더라구요.. 이렇게 코드를 작성하고 keytool을 사용해서 키저장소를 만들었습니다..
# keytool -genkey -keystore .keystore
.....

자바 클라이언트 실행
# java SunSSLSocketClient

Posted by '김용환'
,

 

머리만 쓴다면, DDOS 공격을 검색엔진을 통해서 할 수 있다.

아직까지 리포트된 것이 없지만, 오늘 급격한 리쿼스트를 확인해보니. 검색엔진으로부터의 요청이었다.

http request header의 refer 가 검색엔진이었다.

 

네이버

다음

파란

플래이포럼

msn검색

구글

 

이런 싸이트로부터 엄청난 공격이 시작되면 아파치에서 도메인이름을 가지고 필터링할 수 있다.

 

httpd.conf 파일이다.

 SetEnvIfNoCase Referer "http://(search\.)?naver\.com" link_denied
SetEnvIfNoCase Referer "http://(search\.)?empas\.com" link_denied
SetEnvIfNoCase Referer "http://(search\.)?daum\.net" link_denied
SetEnvIfNoCase Referer "http://(search\.)?playforum\.com" link_denied
SetEnvIfNoCase Referer "http://(dns\.)?paran\.com" link_denied
SetEnvIfNoCase Referer "http://kr\.search\.yahoo\.com" link_denied
SetEnvIfNoCase Referer "http://www5\.searchfun\.co\.kr" link_denied

 

<Directory ...>

      Order Deny,Allow
      Deny from  env=link_denied

</Directory>


 

 

특정 도메인으로부터 오는 DDOS 공격 또는 원치않은 검색은 다음과 같이 막을수도 있다.

 

이외 robot.txt 라 하여 검색엔진이 들어오지 못하도록 막을 수는 있다~

Posted by '김용환'
,

 

HTTP 헤더에 보면, Referer라는 헤더가 존재한다. 이는 브라우져가 가지고 있다가 요청시 사용하게 된다.

예를 들어 어느 웹서버로부터 우리 서버가 노출되고 있는지 알고 싶을 때, 또는 쇼핑 서버로부터 연동하는 웹서버의 경우 유용하게 써먹어 볼 수 있다.

 

(HttpServeltRequest request)

String ref = request.getHeader("referer");

if ("google".indexOf(ref)) {

    // DB 저장.

}

 

 

 

javax.servlet.http
Interface HttpServletRequest

 

getHeader

public java.lang.String getHeader(java.lang.String name)
Returns the value of the specified request header as a String. If the request did not include a header of the specified name, this method returns null. The header name is case insensitive. You can use this method with any request header.
Parameters:
name - a String specifying the header name
Returns:
a String containing the value of the requested header, or null if the request does not have a header of that name

 

Posted by '김용환'
,

회사에서 login을 주기적으로 확인하여

 

 

HTTPClient 3.0으로 로그인을 테스트를 할 수 있다.

 

 
public class Login {

    private static Log log = LogFactory.getLog(Login.class);

 

    private static String LOGON_SITE = "i4h082.google.com";

 

    private static int LOGON_PORT = 80;

 

    static HttpClient client = new HttpClient();

    public static void loginID() {

        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT, "http");
        client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);

        PostMethod authpost = new PostMethod("/login.ggl");
        NameValuePair nextURL = new NameValuePair("nxtURL","http://www.google.com/login.ggl");
        NameValuePair secukey = new NameValuePair("secukey", "");
        NameValuePair turtle = new NameValuePair("sqer", "knight76");
        NameValuePair earthworm = new NameValuePair("max", "xa");

        authpost.setRequestBody(new NameValuePair[] { nextURL, secukey, sqer,max });

        String response = null;
        try {
            client.executeMethod(authpost);
            response = authpost.getResponseBodyAsString();
        } catch (IOException ioe) {
            log.error(ioe, ioe);
        } finally {
            authpost.releaseConnection();
        }

        authpost.releaseConnection();
        int statuscode = authpost.getStatusCode();

        if (statuscode == HttpStatus.SC_OK && (response.indexOf("성공") > 0)) {
            System.out.println("login is successed");
        } else {
            System.out.println("login is failed");
        }

    }

 

 

 

HTTPClient 2.0으로도 로그인을 테스트를 할 수 있다.

 

 

 

 
public class Login {

    private static Log log = LogFactory.getLog(Login.class);

 

    private static String LOGON_SITE = "i4h082.google.com";

 

    private static int LOGON_PORT = 80;

 

    static HttpClient client = new HttpClient();

    public static void loginID() {

        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT, "http");
        PostMethod authpost = new PostMethod("/login.ggl");
        NameValuePair nextURL = new NameValuePair("nxtURL","http://www.google.com/login.ggl");
        NameValuePair secukey = new NameValuePair("secukey", "");
        NameValuePair turtle = new NameValuePair("sqer", "knight76");
        NameValuePair earthworm = new NameValuePair("max", "xa");

        authpost.setRequestBody(new NameValuePair[] { nextURL, secukey, sqer,max });

        String response = null;
        try {
            client.executeMethod(authpost);
            response = authpost.getResponseBodyAsString();
        } catch (IOException ioe) {
            log.error(ioe, ioe);
        } finally {
            authpost.releaseConnection();
        }

        authpost.releaseConnection();
        int statuscode = authpost.getStatusCode();

        if (statuscode == HttpStatus.SC_OK && (response.indexOf("성공") > 0)) {
            System.out.println("login is successed");
        } else {
            System.out.println("login is failed");
        }

    }

 

 

문제는 https 다.

난 이렇게 해결했다.

 

HTTPClient 3.0 버젼

 

        HttpClient client = new HttpClient();

         client.getState().setCredentials(
            new AuthScope("ids.google.com", 443 ),
            new UsernamePasswordCredentials("", "" )
        );

         client.getHostConfiguration().setHost("i4h080.google.com", LOGON_PORT, "https");
        client.getParams().setCookiePolicy(CookiePolicy.BROWSER_COMPATIBILITY);

            PostMethod authpost = new PostMethod("/login.ggl");
        NameValuePair nextURL = new NameValuePair("nxtURL","http://www.google.com/login.ggl");
        NameValuePair secukey = new NameValuePair("secukey", "");
        NameValuePair turtle = new NameValuePair("sqer", "knight76");
        NameValuePair earthworm = new NameValuePair("max", "xa");

        authpost.setRequestBody(new NameValuePair[] { nextURL, secukey, sqer,max });

        String response = null;
        try {
            client.executeMethod(authpost);
            response = authpost.getResponseBodyAsString();
        } catch (IOException ioe) {
            log.error(ioe, ioe);
        } finally {
            authpost.releaseConnection();
        }

        authpost.releaseConnection();
        int statuscode = authpost.getStatusCode();

        if (statuscode == HttpStatus.SC_OK && (response.indexOf("성공") > 0)) {
            System.out.println("login is successed");
        } else {
            System.out.println("login is failed");
        }

    }

 

 

 

HTTPClient 2.0으로도 로그인을 테스트를 할 수 있다.

 

 

 

 
public class Login {

    private static Log log = LogFactory.getLog(Login.class);

 

    private static String LOGON_SITE = "i4h082.google.com";

 

    private static int LOGON_PORT = 80;

 

    static HttpClient client = new HttpClient();

    public static void loginID() {

        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT, "http");
        PostMethod authpost = new PostMethod("/login.ggl");
        NameValuePair nextURL = new NameValuePair("nxtURL","http://www.google.com/login.ggl");
        NameValuePair secukey = new NameValuePair("secukey", "");
        NameValuePair turtle = new NameValuePair("sqer", "knight76");
        NameValuePair earthworm = new NameValuePair("max", "xa");

        authpost.setRequestBody(new NameValuePair[] { nextURL, secukey, sqer,max });

        String response = null;
        try {
            client.executeMethod(authpost);
            response = authpost.getResponseBodyAsString();
        } catch (IOException ioe) {
            log.error(ioe, ioe);
        } finally {
            authpost.releaseConnection();
        }

        authpost.releaseConnection();
        int statuscode = authpost.getStatusCode();

        if (statuscode == HttpStatus.SC_OK && (response.indexOf("성공") > 0)) {
            System.out.println("login is successed");
        } else {
            System.out.println("login is failed");
        }

 

 

 

HTTPClient 2.0 버젼

 

 

         HttpClient client = new HttpClient();

         client.getState().setCredentials(
                "realm", "ids.google.com",
                new UsernamePasswordCredentials("", "" )
            );

       client.getHostConfiguration().setHost("i4h080.google.com", LOGON_PORT, "https");

 

       PostMethod authpost = new PostMethod("/login.ggl");
        NameValuePair nextURL = new NameValuePair("nxtURL","http://www.google.com/login.ggl");
        NameValuePair secukey = new NameValuePair("secukey", "");
        NameValuePair turtle = new NameValuePair("sqer", "knight76");
        NameValuePair earthworm = new NameValuePair("max", "xa");

        authpost.setRequestBody(new NameValuePair[] { nextURL, secukey, sqer,max });

        String response = null;
        try {
            client.executeMethod(authpost);
            response = authpost.getResponseBodyAsString();
        } catch (IOException ioe) {
            log.error(ioe, ioe);
        } finally {
            authpost.releaseConnection();
        }

        authpost.releaseConnection();
        int statuscode = authpost.getStatusCode();

        if (statuscode == HttpStatus.SC_OK && (response.indexOf("성공") > 0)) {
            System.out.println("login is successed");
        } else {
            System.out.println("login is failed");
        }

    }

 

 

 

HTTPClient 2.0으로도 로그인을 테스트를 할 수 있다.

 

 

 

 
public class Login {

    private static Log log = LogFactory.getLog(Login.class);

 

    private static String LOGON_SITE = "i4h082.google.com";

 

    private static int LOGON_PORT = 80;

 

    static HttpClient client = new HttpClient();

    public static void loginID() {

        client.getHostConfiguration().setHost(LOGON_SITE, LOGON_PORT, "http");
        PostMethod authpost = new PostMethod("/login.ggl");
        NameValuePair nextURL = new NameValuePair("nxtURL","http://www.google.com/login.ggl");
        NameValuePair secukey = new NameValuePair("secukey", "");
        NameValuePair turtle = new NameValuePair("sqer", "knight76");
        NameValuePair earthworm = new NameValuePair("max", "xa");

        authpost.setRequestBody(new NameValuePair[] { nextURL, secukey, sqer,max });

        String response = null;
        try {
            client.executeMethod(authpost);
            response = authpost.getResponseBodyAsString();
        } catch (IOException ioe) {
            log.error(ioe, ioe);
        } finally {
            authpost.releaseConnection();
        }

        authpost.releaseConnection();
        int statuscode = authpost.getStatusCode();

        if (statuscode == HttpStatus.SC_OK && (response.indexOf("성공") > 0)) {
            System.out.println("login is successed");
        } else {
            System.out.println("login is failed");
        }


 

Posted by '김용환'
,

jakarta-taglibs-src-20060829  소스를 다운받는다.

 

custom tag 라이브러를 사용했는데, memberid를 사용했다.

<hb:usercontribinfo memberId="${param.memberid}" />

 

 

실제 자바 클래스이다.

public class UserContribListTag extends TagSupport {

           public int doStartTag() throws JspException {

                     memberId = (String) ExpressionEvaluatorManager.evaluate("memberId", memberId, String.class, this, pageContext);

 

jsp 1.0 스펙을 사용중이기 때문에 JSTL을 사용하기 위해서 ExpressionEvaluatorManager를 사용했다.

 

 ExpressionManager 클래스이다.

<ExpressionEvaluatorManager.java>

 

public static Object evaluate(String attributeName,

                                  String expression,

                                  Class expectedType,

                                  Tag tag,

                                  PageContext pageContext)

           throws JspException    {

 

        // the evaluator we'll use

        ExpressionEvaluator target = getEvaluatorByName(EVALUATOR_CLASS); // 이 부분은 문제 없음

 

        // delegate the call

        return (target.evaluate(attributeName, expression, expectedType, tag, pageContext));

    }

 

 

 

ExpressionEvaluator target = getEvaluatorByName(EVALUATOR_CLASS);

이 부분은 Target 인스턴스(ExpressionEvaluator) Evaluator 라는 클래스를 생성한다. Evaluator 는 내부적으로 static ELEvaluator 객체를 리턴하고, ELEvaluator Wrapper 클래스인데..

 

(target.evaluate(attributeName, expression, expectedType, tag, pageContext));

이때 ELEvalueator evaluator 메소드를 호출하게 된다. 다음의 코드를 죽 따라가보면 알겠지만, attributeName 파라미터로 넘겨지는 pExpressionString 아큐먼트를 쫓아가다 보면, sCachedExpressionStrings Map에 추가되는 것이 보인다.

바로 여기서도 static map이 있었다. 그래서, memberid가 계속 추가될 때마다 문제가 된 부분이었다.

 

 

<ELEvaluator.java>

static Map sCachedExpressionStrings = Collections.synchronizedMap (new HashMap ());

 

public Object evaluate (String pExpressionString, Object pContext,  Class pExpectedType, Map functions,  String defaultPrefix)  throws ELException   {

    return evaluate (pExpressionString, pContext,  pExpectedType, functions, defaultPrefix,  sLogger);

}

 

Object evaluate (String pExpressionString, Object pContext, Class pExpectedType, Map functions, String defaultPrefix, Logger pLogger)  throws ELException {

    // Check for null expression strings

    if (pExpressionString == null) {

          throw new ELException (Constants.NULL_EXPRESSION_STRING);

    }

    // Get the parsed version of the expression string

    Object parsedValue = parseExpressionString (pExpressionString);

    // Evaluate differently based on the parsed type

    if (parsedValue instanceof String) {

      // Convert the String, and cache the conversion

      String strValue = (String) parsedValue;

      return convertStaticValueToExpectedType (strValue, pExpectedType, pLogger);

    }   else if (parsedValue instanceof Expression) {

      // Evaluate the expression and convert

      Object value = ((Expression) parsedValue).evaluate (pContext, mResolver, functions, defaultPrefix, pLogger);

      return convertToExpectedType (value, pExpectedType, pLogger);

    }   else if (parsedValue instanceof ExpressionString) {

      // Evaluate the expression/string list and convert

      String strValue =

           ((ExpressionString) parsedValue).evaluate (pContext, mResolver, functions, defaultPrefix, pLogger);

      return convertToExpectedType (strValue, pExpectedType, pLogger);

    } else {

      // This should never be reached

      return null;

    }

}

 

public Object parseExpressionString (String pExpressionString)  throws ELException {

// See if it's an empty String

    if (pExpressionString.length () == 0) {

      return "";

    }

    // See if it's in the cache

    Object ret = mBypassCache ? null :  sCachedExpressionStrings.get (pExpressionString);

 

    if (ret == null) {

      // Parse the expression

      Reader r = new StringReader (pExpressionString);

      ELParser parser = new ELParser (r);

        try {

    ret = parser.ExpressionString ();

        sCachedExpressionStrings.put (pExpressionString, ret);

      } catch (ParseException exc) {

           throw new ELException (formatParseException (pExpressionString, exc));

      } catch (TokenMgrError exc) {

           throw new ELException (exc.getMessage ());

      }

    }

    return ret;

}

 

 

 

 

메모리가 계속 늘 나는 현상을 발견했는데.. 정확하게 문제를 파악하지 못한것이 흠이었다.

 

현상은 다음과 같다.

 

 

 

 

 

 

 

 

Posted by '김용환'
,