태그 보관물: Apache

Apache tika를 사용하여 컨텐츠 구문 분석 RESTFul 서버 설치

Java 로 개발된 contents 를 parsing 하는 라이브러리 및 app 으로 command  line 및 GUI 모드로 동작하는 app 와 RESTFul API 로 동작하는 server 가 있습니다.

# 설치

커맨드용 app 는 다음 주소에서 받으면 됩니다.

$ wget http://apache.mirror.cdnetworks.com/tika/tika-app-1.19.jar

standalone 으로 구동하고 RESTFul 로 요청할 수 있는 서버도 있는데 자동화하려면 이게 더 편리하며 아래 주소에서 받으면 됩니다.

$ wget http://apache.mirror.cdnetworks.com/tika/tika-server-1.19.jar

서버로 구동할 경우 처리 결과를 DB 에 남기려면 SQLite JDBC 가 필요하며 아래 라이브러리를 다운받아서 동일한 폴더에 위치시키면 됩니다.

$ wget http://central.maven.org/maven2/org/xerial/sqlite-jdbc/3.23.1/sqlite-jdbc-3.23.1.jar

# 실행

실행은 java -jar 옵션으로 아래처럼 실행하면 됩니다.

App

$ java -jar tika-app-1.19.jar

Server

$ java -jar tika-server-1.19.jar

SQLite JDBC 적용하려면 -cp 옵션을 추가합니다.

$ java -cp . -jar tika-server-1.19.jar

기본 포트는 9998 이며 다른 포트(Ex: 1234)로 구동할 경우 아래와 같이 -p 옵션을 추가합니다.

$ java -cp . -jar tika-server-1.19.jar  -h 0.0.0.0 -p 1234

# 서버 정보

서버로 구동했으면 REST API 로 여러 가지 요청을 할 수 있습니다.

version 확인

$ curl localhost:9998/version

Apache Tika 1.19

detector 확인

$ curl localhost:9998/detectors

# 지원하는 mime type 확인

$ curl localhost:9998/mime-types

# 컨텐츠 parsing

meta 분석

$ curl -T a.pdf localhost:9998/meta

특정 필드가 필요할 경우 url 에 필드명 명시하며 아래는 저자 필드만 추출합니다.

$ curl -T a.pdf localhost:9998/meta/Author
PDF 렌더링 속도를 빠르게 하려면 JDK 8 을 사용하고 JVM 구동시 아래 옵션 추가합니다.
-Dsun.java2d.cmm=sun.java2d.cmm.kcms.KcmsServiceProvider

# 원하는 형식으로 출력

기존 출력은 text/csv 이며 Accept 헤더에 원하는 포맷을 설정해서 호출하면 됩니다.

XML

$ curl -T a.pdf -H "Accept: application/rdf+xml" localhost:9998/meta

아래는 json 형식으로 결과물을 전달 받습니다.

$ curl -T a.pdf -H "Accept: application/json" localhost:9998/meta

JSON 일 경우 개행을 안 해서 보기가 힘드니 jq 로 포맷팅 하면  결과물이 보기 편해집니다.

$ curl -T a.pdf -H "Accept: application/json" localhost:9998/meta | jq .

Example

$ curl -H "Accept: application/json" localhost:9999/meta -T sample.pdf

 $ curl -H "Accept: text/plain" localhost:9999/tika -T sample.pdf

 $ curl -H "Accept: application/json" localhost:9999/rmeta -T sample.pdf

다른 도메인 내 iframe의 세션이 유지가 안될때 ( Same Site )

문 제

A.com 내에 내가만든 B.com/B.jsp 을 iframe 으로 걸었다.

내가 만든 B.com/B.jsp 내의 세션값을 뽑아도 계속 null인 상황이다.

줄곧 크롬으로 테스트 했던터라 IE로 하니까 또 잘된다.

확인한 부분을 정리하면 이렇다.

1. 크롬 개발자 도구로 Response Headers 를 확인 보았다.

2. Set-Cookie 값안에 JSESSIONID 값이 만들어 지는데, 이값이 호출때마다 변경 된다.

자세히 보면 오른쪽에 노란색 느낌표가 떠있고, 마우스를 가져가면, SameSite 관련 부연설명이 나온다.

웹 search를 해보면 SameSite관련 이슈로 A.com -> B.com POST 방식으로

리다이렉트 했을때 기존에 읽어지던 쿠키값을 읽을수 없는케이스가 제일 많은듯 했다.

3. iframe을 걸어놓은 B.com/B.jsp 에서는 session.getAttribute를 통해서 값이 꺼내지지만,

   java servlet 레벨에서 아래와 같이 뽑아도 null 값만 나오게 된다.

request.getSession().getAttribute("String");

원인 – Chrome 80 쿠키 SameSite 정책이 변경 되었다.

– 도메인이 서로 다른 사이트 간 이동을 하는 경우 쿠키 전달 불가

– 기본 SameSite를 Lax로 변경

( 2020년 2월4일 크롬 80버전 부터 변경 !! )

SamteSite 쿠키에 대해

SameSite 쿠키의 정책으로 None, Lax, Strict 세 가지 종류를 선택할 수 있고

동작하는 방식이 다르다고 할수 있다.

None: 

– SameSite 가 탄생하기 전 쿠키와 동작하는 방식

– None으로 설정된 쿠키의 경우 크로스 사이트 요청의 경우에도 항상 전송

– SameSite를 None으로 설정할 경우 쿠키에 암호화된 HTTPS 연결이 필요함을 나타내는

   Secure 속성을 같이 설정해주어야 한다.
– HTTPS 일때만 사용 가능.

Lax: 

Strict에 비해 상대적으로 느슨한 정책입니다. Lax로 설정된 경우, 대체로 서드 파티 쿠키는 전송되지 않지만, 몇 가지 예외적인 요청에는 전송 된다.

Strict: 

– 가장 보수적인 정책.

– Strict로 설정된 쿠키는 크로스 사이트 요청에는 항상 전송않음.

– 즉, 서드 파티 쿠키는 전송되지 않고, 퍼스트 파티 쿠키만 전송 된다

해 결

결론은 크롬의 쿠키 보안정책이 바뀌어서,

기본이 SameSite의 레벨이 NONE에서 LAX 올라갔으니, 다시 NONE으로 내려주면 된다는 것이다.

중요한점은 HTTPS 일때 사용가능하다.

SameSite 설정시에 None 옵션과 Secure를 함께 주도록되어있는데,

이때 Https일때만 사용이 가능하다고 한다.

즉 B.com 의 도메인은 https 호출이 가능해야 한다.

A.com 의 설정을 건드릴 필요없이 iframe이 걸리는 B.com 쪽에 서버 설정을 수정해야 했다.

나는 앞단에 Apache 서버가 있고, WAS 가 따로 있는 상황이었다.

이럴경우는 apache 웹서버에서 설정을 해줄수 있다.

Apache_HOME / conf / httpd.conf

<IfModule headers_module>
        Header edit Set-Cookie ^(.*)$ $1;SameSite=None;Secure;
</IfModule>

값을 넣어주고 apache 재기동을 했다.

다음부터는 호출시 B.com/b.jsp에서도 세션값에서 정상적으로 값이 꺼내지고

Set-Cookie 값안에 JSESSIONID 값 자체가 유지되는 것을 확인 할수 있었다.

구글 공지

https://blog.chromium.org/2019/10/developers-get-ready-for-new.html

참고자료

https://web.dev/samesite-cookies-explained/

https://chromestatus.com/feature/5088147346030592

http://www.gnujava.com/board/article_view.jsp?board_no=37&article_no=8583

https://velog.io/@jsj3282/%EA%B5%AC%EA%B8%80-Chrome-SameSite-%EC%9D%B4%EC%8A%88

Apache에서 gzip을 이용한 압축전송하기

웹서비스 최적화 방법중에 하나로 gzip 압축전송이 있습니다.
gzip은 파일 압축에 쓰이는 응용 소프트웨어로 GNU zip의 준말이며 무료 소프트웨어이다(출처: 위키백과)
이를 사용하기 위해서는 사용하는 브라우저가 지원을 해야합니다.
(브라우저에서 request headers > “Accept-Encoding”에 gzip이 포함되어 있어야 합니다.)

마찬가지로 서버에서도 gzip으로 전송해야 합니다.
(response headers > “Content-Encodding:gzip”)

배경

일반적인 Http Request & Response와 gzip사용시 차이점을 간단히 설명하면 다음과 같습니다.

1.브라우저에서 index.html을 서버에 요청합니다.

2.서버는 해당 파일을 찾습니다.

3.파일을 요청한 브라우저로 전송합니다(100KB).

4.브라우저는 해당 파일을 표시합니다.

 

 

1.브라우저에서 index.html을 서버로 요청시 gzip을 지원한다는 내용을 서버로 전달합니다.

2.서버는 해당 파일을 찾습니다.

3.gzip으로 파일을 압축해서 보냅니다(30KB).

4.브라우저에서 압축된 파일을 풀고 표시합니다.

테스트 환경

  • 서버 OS: Windows7
  • 웹서버: Apache 2.4
  • 브라우저: IE9, 크롬, Firefox, Safari
환경설정

1.Apache httpd.conf 파일 열기
2.LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.

LoadModule deflate_module modules/mod_deflate.so
LoadModule headers_module modules/mod_headers.so
LoadModule filter_module modules/mod_filter.so
3.적당한 위치에 아래 내용을 추가합니다.
<IfModule mod_deflate.c>

        AddOutputFilterByType DEFLATE text/plain
        AddOutputFilterByType DEFLATE text/html
        AddOutputFilterByType DEFLATE text/xml
        AddOutputFilterByType DEFLATE text/css
        AddOutputFilterByType DEFLATE application/xml
        AddOutputFilterByType DEFLATE application/xhtml+xml
        AddOutputFilterByType DEFLATE application/rss+xml
        AddOutputFilterByType DEFLATE application/javascript
        AddOutputFilterByType DEFLATE application/x-javascript

        DeflateCompressionLevel 9

        BrowserMatch ^Mozilla/4 gzip-only-text/html  # Netscape 4.xx에는 HTML만 압축해서 보냄
        BrowserMatch ^Mozilla/4\.0[678] no-gzip  # Netscape 4.06~4.08에는 압축해서 보내지 않음
        BrowserMatch \bMSIE !no-gzip !gzip-only-text/html  # 자신을 Mozilla로 알리는 MSIE에는 그대로 압축해서 보냄
        
        ##예외 설정
        SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png|bmp|zip|gz|rar|7z)$ no-gzip dont-vary
        
        ####로그설정.
        ##DeflateFilterNote Input instream
        ##DeflateFilterNote Output outstream
        ##DeflateFilterNote Ratio ratio
        ##
        ##LogFormat '"%r" %{outstream}n/%{instream}n (%{ratio}n%%)' deflate
        ##CustomLog logs/deflate_log deflate

4.아파치를 restart 시킨 후 아래 사이트에서 gzip전송이 정상동작하는지 테스트 합니다.

http://www.whatsmyip.org/http-compression-test/

 

위 결과 페이지에서는 특정페이지가 84.5% 절감되고 있습니다.

Response Headers 내용은 아래와 같습니다.

 

 

 

 

 

※ 3번 “로그설정” 주석해제 후 apache logs폴더에 생성된 deflate_log파일을 보면 압축률을 확인할 수 있습니다.

.

"GET /nexacro14lib/framework/SystemBase.js HTTP/1.1" 23987/176486 (13%)
"GET /nexacro14lib/framework/Platform_HTML5.js HTTP/1.1" 18786/138984 (13%)
"GET /nexacro14lib/framework/ErrorDefine.js HTTP/1.1" 4886/18684 (26%)
"GET /nexacro14lib/framework/CssObjs.js HTTP/1.1" 25266/271916 (9%)
"GET /nexacro14lib/framework/BasicObjs.js HTTP/1.1" 9152/50003 (18%)
"GET /nexacro14lib/framework/Platform.js HTTP/1.1" 58726/370077 (15%)
"GET /nexacro14lib/framework/SystemBase_HTML5.js HTTP/1.1" 50261/334443 (15%)
"GET /nexacro14lib/component/CompBase/CompBase.js HTTP/1.1" 28574/167299 (17%)
"GET /nexacro14lib/component/CompBase/CompEventBase.js HTTP/1.1" 17397/255753 (6%)

미리 gzip으로 압축후 사용할 순 없을까?
gzip 사용시 단점은 요청시 gzip으로 압축하는 과정으로 인해
서버의 CPU사용량이 gzip을 사용하지 않을 때 보다 증가한다는 것이다.
그렇다면 거의 변할 일이 없는 file은 미리 압축해서 사용하는것도 괜찮지 않을까?
1.gzip으로 압축하기
Online YUI Compressor에 접속 후 아래그림 처럼 소스를 gz파일로 변환한다.
① 원하는 소스를 붙여넣기 한다.
② 결과는 “Redirect to gzipped output”을 선택한다.
③ “Compress”버튼을 누르면 잠시 후 파일을 저장할 수 있는 팝업창이 표시된다.
④ “gz”확장자로 원하는 위치와 파일명으로 저장합니다.

 

 

2.해당 파일을 영역안에 포함시킵니다.
<script type="text/javascript" src="./pkg/EcoBasic.js.gz"></script>
3.위와 같이 하고 해당페이지에 접속하면 아래처럼 log가 발생하고 정상적으로 load되지 않습니다(크롬).
Content-Encoding:gzip
Content-Type:application/x-gzip

Resource interpreted as Script but transferred with MIME type application/x-gzip: "http:// ~ /pkg/EcoBasic.js.gz". 
4.Apache httpd.conf 파일의 LoadModule 영역에서 아래내용에 주석처리 되었으면 해제합니다.
​LoadModule dir_module modules/mod_dir.so
  아래 2줄을 주석처리 되어있으면 해제합니다.
AddEncoding x-compress .Z
AddEncoding x-gzip .gz .tgz
  아래 2줄을 주석처리 합니다.
#AddType application/x-compress .Z
#AddType application/x-gzip .gz .tgz
  아래 내용도 추가해야 한다고 나와있었는데 실제로 해보니 적용하지 않아도 처리되었습니다(참고하세요).
  :gz 확장자에 대해서 강제로 content-encoding을 설정하는 내용입니다.
# root .
<Directory /~/EcoPkg>
    Options Indexes MultiViews FollowSymLinks
    #AllowOverride None
    #Order deny,allow
    #Deny from all
    #Allow from 127.0.0.0/255.0.0.0::1/128 

    AddEncoding gzip gz
    <FilesMatch "\.gz$">
      ForceType text/plain
      Header set Content-Encoding: gzip
    FilesMatch>
    
##   <FilesMatch "\.css\.gz$">
##        ForceType text/css
##        Header set Content-Encoding: gzip
##    FilesMatch>
Directory>
5.설정 후 아파치 restart후에 Response Headers를 확인하면 다음과 같습니다.

 

 

 

 

 

마치며…

※ RUNTIME(2014,9,3,1 버전 기준)에서는 지원하지 않습니다.
이미지와 PDF파일은 gzip으로 압축하지 않는다(이미 압축되어 있음).
gzip을 지원하는 브라우저 목록(출처: webmasters.stackexchange.com, 참고: schroepl.net)
  • Netscape 6+ (Netscape 4-5 does, but with some bugs).
  • Internet Explorer 5.5+ (July 2000) and IE 4 if set to HTTP/1.1.
  • Opera 5+ (June 2000)
  • Firefox 0.9.5+ (October 2001)
  • Chrome since forever
  • Safari since forever (as far as I can tell)
이 글에서는 Apache httpd.conf 파일을 이용한 예제가 작성되었지만 .htaccess 파일을 이용할 수 도 있다.