2015年12月16日 星期三

[Java] download file from HTTP (HTTP status)

最近發現一個從http下載檔案的程式出現了問題,
(其實常常發生XD, 因為http下載檔案的URL可能常常被變更, 所以只要下載有問題時, 都會第一時間照慣例去檢查URL有沒有異動)

但是這次URL變更, 只是從http改成https, 只是多了s讓我找了好苦阿(這時候就覺得瀏覽器聰明多了, 會自己去導向https)
不過呢, 程式有寫try catch, 理應會回傳錯誤訊息, 但是程式卻沒catch到而讓它pass,
經過debug檢查後, 才發現它download下來的是一個"空"的檔案, 所以程式認為有download成功才讓它pass吧!?

我是在程式裡面加了get HTTP status來debug, 發現這case的HTTP status是301(不是常見的403, 404)
這類status似乎是不會被catch!?

boolean downloadUrlFile(String urlpath, String filepath){
 try {
   String proxyURL="proxy.google.com.tw";
   String proxyPort="3128";
   SocketAddress sa = new InetSocketAddress( proxyURL , Integer.parseInt( proxyPort ) );
   Proxy proxy = new Proxy(Proxy.Type.HTTP, sa);
   URL url = new URL(urlpath);
   //URLConnection conn = url.openConnection(proxy);
   HttpURLConnection conn = (HttpURLConnection)url.openConnection(proxy);
   conn.setConnectTimeout(60000); //60sec, default: 15sec
   conn.setReadTimeout(90000); //90sec, default: 60sec
   conn.connect();
   
   /* Check Http Status*/
   int status = conn.getResponseCode();
   System.out.println(status);
   switch (status) {
   case java.net.HttpURLConnection.HTTP_GATEWAY_TIMEOUT://504
       System.out.println("連線網址逾時!");
       break;
   case java.net.HttpURLConnection.HTTP_FORBIDDEN://403
       System.out.println("連線網址禁止!");
       break;
   case java.net.HttpURLConnection.HTTP_INTERNAL_ERROR://500
       System.out.println("連線網址錯誤或不存在!");
       break;
   case java.net.HttpURLConnection.HTTP_NOT_FOUND://404
       System.out.println("連線網址不存在!");
       break;
   case java.net.HttpURLConnection.HTTP_OK:
       System.out.println("OK!");
       break;
   }
   
   java.io.BufferedInputStream in = new java.io.BufferedInputStream(conn.getInputStream());      
   java.io.FileOutputStream fos = new java.io.FileOutputStream(filepath);
   java.io.BufferedOutputStream bout = new BufferedOutputStream(fos,1024);
   byte[] data = new byte[1024];
   int x=0;
   while((x=in.read(data,0,1024))>=0)
   {
     bout.write(data,0,x);
   }
   bout.close();
   in.close();
 }catch (Exception e) {
   e.printStackTrace();
   return false;
 }
 return true;
}

2015年9月13日 星期日

[Oracle] 取得user的office level

功能:取得user的office level
情境:每家公司應該都會有office階層, 從總公司, 分公司, 分公司的分公司, ...一層層下去,
現在想要知道某位同事所屬的office(包含其上層到源頭總公司)階層
CREATE OR REPLACE FUNCTION SCHEMA_NAME.GET_USER_OFC_LEVEL(p_user_id VARCHAR2)
RETURN VARCHAR2
IS
/*
CREATED BY CHRIS ON 2015.09.14
*/
vUSERPath VARCHAR2(200);
vOFFICEID OFFICE.OFFICE_ID%TYPE;
vOFFICE OFFICE.OFFICE%TYPE;
vUPOFFICEID OFFICE.UP_OFFICE_ID%TYPE;
BEGIN
    SELECT B.OFFICE_ID,B.OFFICE,B.UP_OFFICE_ID INTO vOFFICEID,vOFFICE,vUPOFFICEID FROM USERS A, OFFICE B WHERE A.OFFICE_ID=B.OFFICE_ID AND A.USER_ID=p_user_id;
    
    vUSERPath := vOFFICE;
    
    WHILE vUPOFFICEID <> 0
    LOOP
        SELECT OFFICE_ID,AGENT,OFFICE,UP_OFFICE_ID INTO vOFFICEID,vAGENT,vOFFICE,vUPOFFICEID FROM OFFICE WHERE OFFICE_ID=vUPOFFICEID;
        // UP_OFFICE_ID就是OFFICE_ID的上一層
        
         vUSERPath := vOFFICE || ' ==> ' || vUSERPath;
    END LOOP;
    
    RETURN vUSERPath;
END;
取得user的office level
SELECT GET_USER_OFC_LEVEL('CHRISLIN') FROM DUAL;
結果可能類似下面
HQ ==> ERO ==> HAM

2015年9月7日 星期一

[NodeJS] nodejs加密工具NPK

NPK投影片
NPK Github

npk, 簡單說就是一個幫NodeJS加密的工具.
支援一般加密方式, 也有支援透過compile編譯成binary的方式.

下面是在Windows 7 64bit平台操作, node版本要v0.10才行(後面會說原因)
node.js v0.10.0 官網下載
node.js各版本 官網下載

1. npk安裝
npm install npk -g
NPM安裝的東西預設是放在
C:\Users\chrislin\AppData\Roaming\npm\node_modules
如果只有要用Remove Mock-up (default)跟Mom doesn't recognize兩種加密方式, 做到這就可以了.
若要用Dad doesn't recognize加密, 就往下繼續做.

2.1. node-gyp 安裝(參考)
npm install -g node-gyp
2.2. Microsoft Visual Studio C++ 安裝(我自己是裝VS 2015 Professional)

2.3. Microsoft Windows SDK for Windows 7 and .NET Framework 4 安裝 (下載)

我有遇到Microsoft Windows SDK裝不進去的問題, 參考官網解法
● 解除安裝Microsoft Visual C++ 2010 x64 Redistributable
● Microsoft Windows SDK安裝
● 重新安裝Microsoft Visual C++ 2010 x64 Redistributable (下載)

npk怎麼用?
1. 先從NPK安裝好的目錄copy範例出來改, 我是copy下面目錄
C:\Users\chrislin\AppData\Roaming\npm\node_modules\npk\tests
2. 目錄說明
tests\purejs\lib 放NodeJS source code的地方
tests\package.json 目錄設定檔(設定source code以及output code位置等...)
tests\purejs\out\app.js 加密後產生output code的地方
tests\purejs\out\app.js\app.js 加密後的檔案

3. 執行
npk tests\purejs\
npk tests\purejs\ --mom-doesnt-recognize
npk tests\purejs\ --dad-doesnt-recognize

3.1.執行時出現下面錯誤(不過binding.gyp跟output.cpp還是有產生), 要設定環境變數

3.2.新增Python環境變數


PYTHONPATH=D:\Program Files (x86)\Python\27 PYTHON=%PYTHONPATH%\python.exe
4. 小編運氣不好, 執行爸爸不認識還是有問題(還是上面的錯誤), 所以還是去看一下npk背後怎麼作業

4.0. npk原始檔及相關lib位置
C:\Users\chrislin\AppData\Roaming\npm\node_modules\npk\lib
4.1. 把NodeJS檔案編譯成output.cpp, 並產生binding.gyp

4.2. 利用node-gyp把output.cpp編成binary
node-gyp configure
node-gyp build

4.2.1. 先到專案目錄下
C:\Users\chrislin\Desktop\tests\purejs\out\app.js
4.2.2. 執行configure沒問題
node-gyp configure
4.2.3. 再執行build
node-gyp build
4.2.4. 會發現出現下面錯誤訊息

去大神查了一下, 發現v8.h這個library在node v0.10跟v0.12是不一樣的(參考網頁)
像是v8::String在這兩個版本就不一樣(如下)

但是npk的compiler產生cpp的寫法是用v0.10
C:\Users\chrislin\AppData\Roaming\npm\node_modules\npk\lib\compiler.js
所以我就把v0.12移除, 重新裝了v0.10

5. 結果執行爸爸不認識還是同樣的錯誤ORZ
compiler.js似乎只執行到self.generateMakefile產生出binding.gyp
child_process.spawn執行node-gyp好像有問題@@?

6. 只好先用下面方式產生binary檔案了= =
● 產生configure需要的兩個檔案: binding.gyp跟output.cpp
npk tests\purejs\ --dad-doesnt-recognize
● 手動compile, 產生npk.node
cd tests\purejs\out\app.js\
node-gyp configure
node-gyp build

產生的binary檔案位置
C:\Users\chrislin\Desktop\tests\purejs\out\app.js\build\Release\npk.node
之後就可以用require('npk.node')的方式使用此檔案

2015年8月19日 星期三

[Oracle] 自動滾流水號

1. create一個流水號sequence(USERS_KEY)
DROP SEQUENCE SCHEMA_NAME.USERS_KEY;

CREATE SEQUENCE SCHEMA_NAME.USERS_KEY START WITH 100 MAXVALUE 999999999999999999999999999 MINVALUE 0 NOCYCLE NOCACHE NOORDER;

2. 上述case代表, 此sequence已經用了0~99, 下次取流水號就會是100
SELECT KPI_USERS_KEY.NEXTVAL FROM DUAL

應用:
假設有一個USERS的table, 有個key的欄位, key欄位的值就可以用此方式產生
每insert一筆資料都去取下一個流水號, 可以避免產生重複的key

2015年8月13日 星期四

[IIS] 關閉SSL低強度加密演算法

參考來源
雖然走https的網頁, 資料傳輸有加密較為安全, 但是有些加密方式已被證實有瑕疵, 也就是即使加密傳輸, 有心人士一樣可以攔截後, 反解密取得封包原始內容.

如何關閉一些低強度的加密演算法
1.
regedit.exe
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Ciphers\
2.
IIS的修補方式為關閉低於128位元之加密演算法,包括以下5個子機碼:DES 56/56、NULL、RC2 40/128、RC4 40/128、RC4 56/128,在這些機碼內新增DWORD,名稱為Enabled,值為0。

[Oracle] [DBA] 追蹤table被lock的原因

1. 找出lock的session
SELECT * FROM V$LOCK WHERE BLOCK > 0 OR REQUEST > 0 ORDER BY ID1,ID2,BLOCK DESC;
2. 把上面的sid帶入 (ex: 1755)
SELECT * FROM V$SESSION WHERE SID IN ( 1755 )
3. 找出被lock的table (ex: users)
SELECT * FROM DBA_DML_LOCKS WHERE NAME='USERS'
4. 查看是什麼SQL語法造成上面table被lock
SELECT * FROM V$SQL WHERE HASH_VALUE=2803307291

[Oracle] [DBA] kill job

參考來源

1. 確認該job目前是否有正在run
SELECT * FROM DBA_JOBS_RUNNING where job=44807673

2. 先把該job disabled(take offline)
begin
 dbms_job.broken(44807673,true);
end;
3. 立即砍掉該job
ALTER SYSTEM KILL SESSION '2060,44807673' immediate;  --參數'SID, JOB'

[Oracle] string分割成multi-rows

參考來源

輸入來源如下
Name | Project | Error
108    test      Err1, Err2, Err3
109    test2     Err1
輸出結果如下
Name | Project | Error
108    Test      Err1
108    Test      Err2
108    Test      Err3
109    Test2     Err1

SQL
with temp as  (
       select 108 Name, 'test' Project, 'Err1, Err2, Err3' Error  from dual
       union all
       select 109, 'test2', 'Err1' from dual
     )

SELECT distinct Name, Project, trim(regexp_substr(str, '[^,]+', 1, level)) str
FROM (SELECT Name, Project, Error str FROM temp) t
CONNECT BY instr(str, ',', 1, level - 1) > 0
order by Name

2015年8月12日 星期三

[ASP.NET] 前端js/後端cs互相傳值

參考來源 前端js傳值給後端cs

test.aspx(前端)
//新增一個hidden變數, 前後端pass value可透過此變數(常用手法)
<input type="hidden" id="abc" runat='server' />

//新增一個js, 把要傳給後端的參數寫到hidden變數
<script type="text/javascript">
function setvalue() {
  var a = document.getElementById("abc");
  a.value = "這是js要給後端的參數";
} 
</script>

test.aspx.cs(後端)
Label1.Text = "承接js傳過來的參數是 "+ Request.Params["abc"];


後端CS傳值給前端JS

test.aspx.cs(後端)
protected void Page_Load(object sender, EventArgs e) {
  form1.InnerHtml = "";
  for (int i = 0; i < 10; i++) {
    form1.InnerHtml += "<button onclick='send(" + i + ")'>click</button>";
  }
}

test.aspx(前端)
<script type="text/javascript">
  function send(id) {
    alert(id);
  }
</script>

[ASP] ASP/JS互相傳值

參考來源

test.asp
<script language="javascript">
  var emp_id = "<%= catchID %">"; //asp傳值給js ,其實只有這一行 
  document.form1.method = "post";
  document.form1.action = "person.asp?emp_no=" + encodeURIComponent(emp_id);
  //js把參數傳回給asp,說穿了也只是帶參數傳回而已,就上面那一行而已
  //encodeURIComponent是安全考量加的(避免類似XSS攻擊)
  //如果要回傳多參數, 再用&連接
  document.form1.submit();
</script>

防範XSS (Cross Site Scripting) 攻擊

之前寫的網頁有拿去做弱點掃描, 被掃出來發現有嚴重的XSS
請教神人同事後, 他建議我針對有傳參數的部分要進行encode(什麼是encode?)
其實我覺得XSS很類似SQL injection

先來看看可能被XSS攻擊的網頁長什麼樣子

test.html
<html>
  <form action="test.asp" method="get">
    <input name="tid" type="text" />
    <input type="submit" />
  </form>
</html>
test.asp
<html>
  <input type="text" name="get_tid" id="get_tid" value="<%= request("tid") %>" />
</html>

接著在test.html的textbox輸入下面字串
120" onMouseOver=alert('XSS_attack') size="1
Submit後, 把滑鼠游標移到test.asp的textbox上, 會出現alert視窗, 這就是比較常見的XSS攻擊

[JS] 判斷字串是否為integer


下面例子會跳出alert視窗, 顯示回傳值為false(1235.6不是整數)
<script language="javascript">
Object.prototype.isInteger = function () {
  return (this.toString().search(/^-?[0-9]+$/) == 0 ) //回傳值為true/false
}

var myNum=1235.6;
alert (myNum.isInteger());
</script>

[ASP] 接GET/POST值

ASP接HTML(GET)

test.html
<html>
  <form action="test.asp" method="get">
    <input name="tid" type="text" />
    <input type="submit" />
  </form>
</html>

test.asp
<%
response.write encodeURIComponent(request("tid"))
%>

ASP接HTML(POST)
把上面例子http method的get改成post即可
  <form action="test.asp" method="post">