2016년 7월 10일 일요일

http session 유지 html 접속


앞에서 android 에서 session을 유지하면서(login) 하는 소스를 만들었습니다.
http://swlock.blogspot.kr/2015/03/httpurlconnection.html
하지만 사용하다 보니 문제가 있었습니다.

saveCookie 함수인데요. Set-Cookie 값을 가져오지 않으면 m_session의 값이 false가 되어버려 다음번 연결시제대로 동작되지 않는 현상이 있습니다.
재현경로는 로그인 페이지 접속 후 곧장 다른페이지 접속시에는 문제없으나, 그 이후에 다른페이지 접속하면 문제가 발생합니다.
 public void saveCookie( HttpURLConnection conn)
 {
  
     Map<String, List<String>> imap = conn.getHeaderFields( ) ;
     if( imap.containsKey( "Set-Cookie" ) )
     {
         List<String> lString = imap.get( "Set-Cookie" ) ;
         for( int i = 0 ; i < lString.size() ; i++ ) {
             m_cookies += lString.get( i ) ;
         }
         m_session = true ;
     } else {
         m_session = false ;
     }
 }

해당 내용 수정한 전체 소스 입니다.

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.List;
import java.util.Map;

import android.util.Log;

public class GetHttp {

 final static double VERSION = 1.20160710;
 static final int ERROR_CODE_HTTP_NOT_FOUND = -404;
 static final int ERROR_CODE_HTTP_UNAUTHORIZED = -401;
 static final int ERROR_CODE_HTTP_ELSE = -1;
 static final int ERROR_CODE_HTTP_EXCEPTION = -1000;
 static final int ERROR_CODE_NOERROR = 0;
 static boolean DEBUG_ON = false;
 byte[] htmlByte = null;
 int errorCode = 0;
 boolean bUseCache = true;
 boolean m_session = false;
 String m_cookies = "";
 public String getString() {
  try {
   return new String(htmlByte, "UTF-8");
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  return null;
 }
 public byte[] getByte() {
  return htmlByte;
 }
 public int getErrorCode() {
  return errorCode;
 }
 public boolean execute(String addr) {
  return execute(addr, 5, 10);
 }
 public void saveCookie( HttpURLConnection conn)
 {

  Map<String, List<String>> imap = conn.getHeaderFields( ) ;
  if( imap.containsKey( "Set-Cookie" ) )
  {
   List<String> lString = imap.get( "Set-Cookie" ) ;
   for( int i = 0 ; i < lString.size() ; i++ ) {
    m_cookies += lString.get( i ) ;
   }
   if( DEBUG_ON ) Log.e("TAG",m_cookies);
   m_session = true ;
  }
 }
 // 참고 소스:http://markan82.tistory.com/32
 public boolean execute(String addr, int connTimeOutSec, int readTimeOutSec) {
  boolean retval = true;
  errorCode = ERROR_CODE_NOERROR;
  try {
   URL url = new URL(addr);
   if( DEBUG_ON ) Log.e("TAG",addr);
   HttpURLConnection conn = (HttpURLConnection) url.openConnection();
   if( conn != null ) {
    conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=utf-8");
    if( m_session ) {
     conn.setRequestProperty( "Cookie", m_cookies );
    }
    conn.setConnectTimeout(1000*connTimeOutSec);
    conn.setReadTimeout(1000*readTimeOutSec);
    conn.setUseCaches(bUseCache);
    conn.setDoInput(true);

    int resCode = conn.getResponseCode();
    saveCookie(conn);

    if( resCode == HttpURLConnection.HTTP_OK ) {
     htmlByte = inputStreamToByte(conn.getInputStream());
     if(htmlByte == null || htmlByte.length == 0){
      errorCode = ERROR_CODE_HTTP_ELSE;
      retval = false;
     }
    } else if( resCode == HttpURLConnection.HTTP_NOT_FOUND ) {
     errorCode = ERROR_CODE_HTTP_NOT_FOUND;
     retval = false;
    } else if( resCode == HttpURLConnection.HTTP_UNAUTHORIZED ) {
     errorCode = ERROR_CODE_HTTP_UNAUTHORIZED;
     retval = false;
    } else {
     errorCode = ERROR_CODE_HTTP_ELSE;
     retval = false;
    }
    // DISCONNECT
    conn.disconnect();
   } else {
    errorCode = ERROR_CODE_HTTP_ELSE;
    retval = false;
   }
  } catch(Exception e) {
   e.printStackTrace();
   errorCode = ERROR_CODE_HTTP_EXCEPTION;
   retval = false;
  }
  return retval;
 }
 private byte[] inputStreamToByte(InputStream in)
 {
  final int BUF_SIZE = 1024;
  ByteArrayOutputStream out = new ByteArrayOutputStream();
  byte[] buffer = new byte[BUF_SIZE];
  try {
   int length;
   while ((length = in.read(buffer)) != -1) out.write(buffer, 0, length);
  } catch (IOException e) {
   e.printStackTrace();
   return null;
  }
  return out.toByteArray();
 }
}


추가내용
위에서 쿠키 작업한 내용이 완벽하지 않습니다. 
https://en.wikipedia.org/wiki/HTTP_cookie 
https://tools.ietf.org/html/rfc2109
여기 보면 자세한 내용이 나오는데 안의 인자값에 따라 어떤 동작들을 해야합니다. 그러한 부분이 전혀 구현되어있지 않습니다.
따라서 완벽하게 하려면 httpclient libarary등의 라이브러리를 사용하시기 바랍니다.
http://swlock.blogspot.kr/2017/01/httpclient-use-in-android-httpclient.html

댓글 없음:

댓글 쓰기