sentry의 경우 에러 로그를 한 번에 받다보니 조금 이슈가 생길 수 있다. 


request body 가 1메가를 초과하는 경우 nginx 오류 발생하는 경우가 있다.


    * nginx : 기본설정(1M) 로 일반적인 경우에는 문제가 없으나 예외적으로 필요한 경우가 있어서 설정을 변경할 수 있다.

    => client_max_body_size 5M;



     * PG의 DB 변경
    => send_buffer를 128K에서 5M로 변경, max_connection을 100에서 500으로 변경한다.


Posted by 김용환 '김용환'




MacOS의 최신 파이어폭스(firefox)에 인증 정보/쿠키 정보를 lz4로 암호화되어 있다. 그러나 표준이 아니라서 파이썬으로 확인해볼 수 없으나, 툴로는 확인할 수 있다.





git clone https://github.com/andikleen/lz4json.git

cd lz4json

make

cp ~/Library/Application Support/Firefox/Profiles/*.default/sessionstore.jsonlz4 .

./lz4jsoncat sessionstore.jsonlz4



Posted by 김용환 '김용환'


맥 High Sierra OS 버전의 크롬 브라우저의 쿠키를 확인하려면 sqlite를 확인하면 된다.


table을 확인할 수 있고


schema를 사용하면 스키마 정보를 볼 수 있다.


$ cd /Users/sameul/Library/Application Support/Google/Chrome/Default

$ sqlite3 Cookies

SQLite version 3.19.3 2017-06-27 16:48:08

Enter ".help" for usage hints.


sqlite> .tables

cookies  meta


sqlite> .schema

CREATE TABLE meta(key LONGVARCHAR NOT NULL UNIQUE PRIMARY KEY, value LONGVARCHAR);

CREATE TABLE cookies (creation_utc INTEGER NOT NULL,host_key TEXT NOT NULL,name TEXT NOT NULL,value TEXT NOT NULL,path TEXT NOT NULL,expires_utc INTEGER NOT NULL,is_secure INTEGER NOT NULL,is_httponly INTEGER NOT NULL,last_access_utc INTEGER NOT NULL, has_expires INTEGER NOT NULL DEFAULT 1, is_persistent INTEGER NOT NULL DEFAULT 1,priority INTEGER NOT NULL DEFAULT 1,encrypted_value BLOB DEFAULT '',firstpartyonly INTEGER NOT NULL DEFAULT 0,UNIQUE (host_key, name, path));




sqlite3에 읽을 데이터 파일 이름을 주지 않아도 .open 커맨드를 사용해 파일을 읽을 수 있다.


$ sqlite3

SQLite version 3.19.3 2017-06-27 16:48:08

Enter ".help" for usage hints.

Connected to a transient in-memory database.

Use ".open FILENAME" to reopen on a persistent database.

sqlite> .open Cookies



cookies 테이블 정보를 인덴트를 주어 보고 싶다면 다음 커맨드를 사용한다.


sqlite> .schema --indent cookies

CREATE TABLE cookies(

  creation_utc INTEGER NOT NULL,

  host_key TEXT NOT NULL,

  name TEXT NOT NULL,

  value TEXT NOT NULL,

  path TEXT NOT NULL,

  expires_utc INTEGER NOT NULL,

  is_secure INTEGER NOT NULL,

  is_httponly INTEGER NOT NULL,

  last_access_utc INTEGER NOT NULL,

  has_expires INTEGER NOT NULL DEFAULT 1,

  is_persistent INTEGER NOT NULL DEFAULT 1,

  priority INTEGER NOT NULL DEFAULT 1,

  encrypted_value BLOB DEFAULT '',

  firstpartyonly INTEGER NOT NULL DEFAULT 0,

  UNIQUE(host_key, name, path)

);



encrypted_value를 보려면 파이썬을 활용할 수 있다.

Posted by 김용환 '김용환'

html에서는 form안에 form을 넣을 수 없다. 

(정확히 말하면 chrom 기준)



html 코드에 div를 사용하는 것이 좋다.


<div class="form-group">

<label for="objectUrl" class="col-xs-2 control-label"><span class="fa fa-fw fa-bars"></span>이미지/동영상 업로드</label>

<div class="col-xs-10">

<input type="text" class="form-control" id="objectUrl" name="objectUrl" value="${actionTagGuide.objectUrl!}" ><br/>

   <label><input type="file" name="file" id="file" accept="image/*,video/*"/></label>

   <button type="button" class="btn btn-danger btn-upload">file upload</button> 

</div>

</div>



스크립트 코드는 다음과 같다.


<script>

$(document).ready(function() {

$('.btn-upload').on('click', function (){

if (confirm('Want to upload a image or a video file?')) {

var data = new FormData();

data.append("file", $('#file').prop('files')[0]);

console.log(data);

$.ajax({

            type: "POST",

            enctype: 'multipart/form-data',

            url: "/actiontag_guide/upload/",

            data: data,

            processData: false,

            contentType: false,

            cache: false,

            timeout: 600000,

            success: function (result) {

                console.log("SUCCESS : ", result.data.url);

                $('#objectUrl').attr("disabled", true) 

                $('#objectUrl').val(result.data.url)

            },

            error: function (e) {

                console.log("ERROR : ", e);

            }

        });

}

     });




Posted by 김용환 '김용환'




google place api response는 200이고, 

status 결과에 REQUEST_DENIED 라는 내용이 보인다. 



다양한 원인이 있을 수 있다. 동작되다가 갑자기 안된다면, ip whitelist 이슈 일 수 있다. 

whitelist를 관리 중에 새롭게 변경된 ip가 빠져 있거나,

아예 처음부터 whitelist ip를 넣지 않았다가 ip를 추가하면, 기존의 요청하던 IP가 disallow되면서 에러가 날 수도 있다.






https://developers.google.com/places/web-service/faq#_6


문제 해결

계속 "status": "REQUEST_DENIED"를 받는 이유는 무엇인가요?

다음과 같은 경우 Google Places API 웹 서비스에서 "status": "REQUEST_DENIED"를 반환합니다.

  • Google Developers Console에서 Google Places API 웹 서비스를 활성화하지 않았습니다.
  • 요청에서 key 매개변수가 누락되었습니다.
  • key 매개변수가 Google Developers Console의 API 키와 일치하지 않습니다.
  • Google Developers Console에서 API 키가 올바르게 설정되지 않았습니다.
    • 브라우저 키를 사용 중인 경우 허용된 리퍼러가 올바른지 확인합니다.
    • 서버 키를 사용중인 경우 허용된 IP가 올바른지 확인합니다.
    • Android 및 iOS 키는 지원되지 않으므로 브라우저 또는 서버 키를 사용하세요.
  • 요청이 HTTPS 요청으로 전송되지 않았습니다. 모든 Google Places API 웹 서비스 요청에는 HTTPS가 필요합니다.
  • 요청 전송에 잘못된 HTTP method가 사용되었습니다.
    • 장소 추가를 제외한 모든 요청은 GET 요청으로 전송해야 합니다.
    • 모든 장소 추가 요청은 POST 요청으로 전송해야 합니다.





Why do I keep receiving "status": "REQUEST_DENIED"?

The "status": "REQUEST_DENIED" is returned by the Google Places API Web Service when:

  • You have not activated the Google Places API Web Service in the Google Developers Console.
  • The key parameter is missing from your request.
  • The key parameter does not match the your API key in the Google Developers Console.
  • Your API key has not been correctly set up in the Google Developers Console:
    • If you are using a browser key, check that your allowed referer(s) are correct.
    • If you are using a server key, check that your allowed IP(s) are correct.
    • Android and iOS keys are not supported, please use a Browser or Server key.
  • The request was not sent as an HTTPS request, HTTPS is required for all Google Places API Web Service requests.
  • The incorrect HTTP method was used to send the request:
    • All requests must be sent as a GET request except for Place Add.
    • All Place Add requests must be sent as a POST request.



Posted by 김용환 '김용환'



인터넷을 찾아보니..


RFC 2616 (HTTP 1.1) 스펙 규격에 따르면, HTTPS 페이지에서 HTTP 페이지로 링크로 넘어갈 때, 브라우져에서 HTTP 페이지에 Referer를 넘기지 않는다. 다음 같은 조항 때문이다.



https://www.w3.org/Protocols/rfc2616/rfc2616-sec15.html#sec15.1.3


Clients SHOULD NOT include a Referer header field in a (non-secure) HTTP request if the referring page was transferred with a secure protocol.



Posted by 김용환 '김용환'


2015년 10월 5일 작성


Google place의 map api를 사용할 때, address만 가지고 필터를 할 수 없다. 


예를 들어 특정 지역 (예를 들어 북한 관련 지역)을 자동 완성, 결과 검색시 보고 싶지 않다면 

일반적으로 address로 필터를 할 수 있다고 생각하지만, 검색해보면 많이 나오는 것을 확인할 수 있다.
(다른 회사의 서비스를 확인하다보니, 모회사의 P 서비스에서 북한 정보를 검색하면 대부분 보이지 않지만, 일부 데이터를 그대로 북한 정보가 보인다. 아마도 단어 단위의 필터를 쓴 것 같다. 독도도 리암쿠리암으로 검색하면 나온다 ㅠ)


이를 방지하려면 오직 위/경도로만 체크해야 한다. 

폴리곤 위/경도 데이터를 사용하면 완벽하게 특정 지역에 있는지를 확인할 수 있다. 북한 위치에 대한 위경도는 거의 완벽하게 나온다.






** 제일 중요. **

또한 Google place map api 사용시, 독도를 리암쿠리암으로 보이는 심각한 문제가 있기 때문에, 독도 위경도를 폴리곤으로 잡아 리암쿠리암으로 검색되지 않도록 개발할 필요가 있다.  또는 언어 locale에 어떻게 나타나는지 잘 볼 필요가 있다. 



--- 2017년 1월 내용 추가.


http://'독도'를 '리앙쿠르 암초'로 썼다가 혼난 기업들

http://v.media.daum.net/v/20170118175504257


내가 한 작업에 대해서 아무도 알아 주지도 않았지만, 내가 만든 서비스에서는 이런 이슈가 나타나지 않았다..  (뿌듯..)



Posted by 김용환 '김용환'

Java App--Web 환경 테스트할 때, 

jquery.ajax에서 java url에서 리턴하는 json string을 읽기 위해서는 

dataType을 json으로 한다. 

jQuery.ajax({
method: "GET",
data : params,
dataType: "json",
url : "/search/" + query,
success: function(searchResult){

... }

});


Posted by 김용환 '김용환'


nginx 모듈 대부분은 모듈 설치 없이 nginx 에서 지원하고 있다.


http://nginx.org/en/docs/



그러나 특정 모듈은 컴파일시 특별히 옵션을 주어야 같이 설치가 되는 모듈이 있다.

예를 들어 ngx_http_ssl_module은 --with_http_ssl_module을 설정 매개변수를 주어야 사용할 수 있다. 

http://nginx.org/en/docs/http/ngx_http_ssl_module.html


The ngx_http_ssl_module module provides the necessary support for HTTPS.

This module is not built by default, it should be enabled with the --with-http_ssl_module configuration parameter.

This module requires the OpenSSL library.



또는 이미 포함된 모듈은 --without 접두사가 붙는 형태로 컴파일시 옵션으로 설치가 안되게 할 수 있다.

--without-http_access_module과 같이 사용한다.


기본적으로 nginx에 포함된 모듈과 포함되지 않는 모듈을 확인하기 위해서는 

다음 페이지를 방문한다. 자세히 설명된다.
http://wiki.nginx.org/Modules

http://nginx.org/en/docs/



Posted by 김용환 '김용환'


nginx를 설치하면, ngx_http_upstream_module 을 따로 로딩할 필요 없이 사용할 수 있다.

nginx -V 로 보이는 모듈 리스트에서는 보이지 않는다. 


$ /usr/local/nginx/sbin/nginx -V
nginx version: nginx/1.6.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC)

TLS SNI support enabled

...



nginx.conf 파일을 upstream 및 proxy_pass로 설정한다. 192.168.0.1~2로 reverse proxy 연결을 지원한다(예를 들어 nginx-tomcat 간의 connection을 연결하는 형태). keepalive를 사용하면 keep alive 기능과 동일하다. (time_wait 이 거의 발생하지 않는다.)


http {


  upstream pp-server {

    server 192.168.0.1;

    server 192.168.0.2;

    server 192.168.0.3;

    keepalive 30;

  }


  server {

    listen 80;

    server_name localhost;



    location / {

      proxy_pass http://pp-server;

    }

  }

}



nginx+ (상용 버전)에서는 고급 기능을 쓸 수 있다.



*튜닝 요소

keepalive 사용시 숫자를 잘 정의해야 한다. keepalive를 사용하는 것이 socket close를 최대한 적게 할 수 있다는 장점이 있지만, 너무 작게 설정하면, 작은 수의 socket close를 계속 발생할 수 있다. 

개인적으로 ulimit으로 해서 file socket 개수가 무한대라면, 높은 값(15000)을 주어도 무방한 듯 하다. 

테스트를 통해 확인해보니 너무 작게 주면 그 개수안에서 LRU 정책을 사용하여 socket close가 여전히 발생한다. 많이 줄 수록 socket close는 거의 발생하지 않았다.




* 참조

http://nginx.org/en/docs/http/ngx_http_upstream_module.html






Posted by 김용환 '김용환'