韩剧1988免费观看全集_久久影视三级福利片_亚洲视频在线观看免费_在线观看欧美日韩_国产亚洲激情在线_亚洲精品美女久久久_欧美国产日韩一区二区在线观看_91在线观看免费高清完整版在线观看_日韩av免费看_国产又爽又黄的激情精品视频_琪琪亚洲精品午夜在线_欧美性猛xxx_不卡毛片在线看_国产亚洲日本欧美韩国_91国内在线视频_精品国产福利视频

當(dāng)前位置:蘿卜系統(tǒng)下載站 > 技術(shù)開發(fā)教程 > 詳細(xì)頁面

“穿越”防火墻的XML技術(shù)

“穿越”防火墻的XML技術(shù)

更新時間:2022-06-05 文章作者:未知 信息來源:網(wǎng)絡(luò) 閱讀次數(shù):

程序員可能會經(jīng)常碰到這樣的事情:建立一個servlet應(yīng)用程序,它與公司的數(shù)據(jù)庫相連接,為客戶提供一種特定的服務(wù),這個應(yīng)用程序受到一個強大的驗證機制保護,全世界有成千上萬的客戶都在使用它。現(xiàn)在就出現(xiàn)了一個問題:當(dāng)應(yīng)用程序處在公司的防火墻之外時,你將如何從應(yīng)用程序提供用戶對數(shù)據(jù)庫的訪問?你知道,網(wǎng)絡(luò)管理員是不會專門為你的應(yīng)用程序與數(shù)據(jù)庫相連接而打開一個特殊端口的。

HTTP隧道技術(shù)和XML
如何越過防火墻與客戶/服務(wù)器應(yīng)用程序相連接這個問題已經(jīng)困擾程序員很久了。在多數(shù)情況下,一個公司的防火墻總是盡可能少地打開端口。一般情況下,你能夠使用的唯一端口就是80,這也就是Web所使用的端口。

解決這個問題的方法就是使用HTTP隧道技術(shù)(HTTP tunneling)。這個方法首先將請求包裝在一個HTTP POST請求中,然后這個請求再由一個在防火墻內(nèi)的Web 服務(wù)器上的CGI 應(yīng)用程序(例如一個servlet)來處理。

Servlet恢復(fù)原始的請求,執(zhí)行它,然后將結(jié)果插入到HTTP響應(yīng)流中。防火墻將這種相互作用解釋為對一個 Web頁面的常規(guī)請求,并允許對它繼續(xù)進行處理。這就象特洛伊木馬一樣:看起來是一個普通的請求,但其中隱藏著預(yù)料不到的負(fù)載。

下一個問題是如何對請求進行格式化?當(dāng)然,使用XML是將這些負(fù)載送入一個HTTP請求中去的最佳選擇。這個觀念很有獨創(chuàng)性,HTTP之上的XML是一個熱門的新興領(lǐng)域,一些新的規(guī)則正在編寫中,將來可以成為分布式應(yīng)用程序的標(biāo)準(zhǔn)通訊協(xié)議。其中,簡單對象訪問協(xié)議(SOAP)是最得到公認(rèn)的。

遺憾的是,現(xiàn)在還沒有一個穩(wěn)定執(zhí)行的SOAP供我們使用,目前所能找到的最好的一個來自Apache集團,但是它只支持簡單的返回類型。因此,它對于我們的項目是沒有用的。但是這也不錯,這意味著我們可以提出自己的HTTP上的XML的協(xié)議,并且借此來學(xué)習(xí)其中包含的概念。
概念
現(xiàn)在我們來建立一個簡單的框架結(jié)構(gòu)(framework),它將HTTP上的XML作為基本的通訊策略,從而讓我們能夠創(chuàng)建一套服務(wù),而且使得這些服務(wù)從分布在Internet上四面八方的桌面應(yīng)用程序都可以進行訪問。

首先,我們需要建立普通請求和響應(yīng)的語法。請求看起來是這樣的:

<?xml version='1.0' encoding='utf-8' ?>
<http-request>
<requestType>
[type of request]
</requestType>
<request>
[Application specific request.This will be an XML Elment ]
</request>
</http-request>

響應(yīng)看起來是這樣的:

<?xml version='1.0' encoding='utf-8' ?>
<response>
<responseMessage>
[the response Message]
</responseCode>
<responseCode>
[an application specific return code.]
</responseCode>
<response>
[Application specific request.This will be an XML Element]
</response>
</http-response>

為了理解這個框架結(jié)構(gòu)背后的概念,我們要編寫一個應(yīng)用服務(wù)例程:一個簡單的數(shù)據(jù)庫服務(wù),它對任何SQL語句進行處理,并且將結(jié)果作為一個向量來返回。請求的細(xì)節(jié),也就是請求元素所包含的XML標(biāo)記非常簡單,如下:

<sql-statement>
[The SQL statement to be executed]
</ sql-statement >
響應(yīng)結(jié)果是這樣的:
<result-set>
</result-count>
[the number of rows in the result set]
</result-count>
<row>
<col name='name'>
[the value]
</col>
?
</row>
?
<result-set>

HTTPService是一個servlet,它響應(yīng)一個POST請求,恢復(fù)XML負(fù)載,并使用它來創(chuàng)建一個ServiceRequest例示。然后,根據(jù)請求的類型,將請求交給HttpServiceHandler 抽象類的一個特定子類。Handler類執(zhí)行請求,在ServiceResponse的一個例示中存儲結(jié)果,然后將這個結(jié)果發(fā)送回客戶端應(yīng)用程序。

通過按照慣例為服務(wù)處理器類命名,我們可以利用Java的映象功能來創(chuàng)建處理器類的一個例示,這個處理器類僅僅是建立在ServiceRequest 對象的服務(wù)類型屬性的基礎(chǔ)上。這就取消了HttpService和所有服務(wù)處理器類之間的依賴性,從而意味著當(dāng)我們增加一個新服務(wù)時,不再需要改變 HttpService類。

在我們這個例子中,服務(wù)的類型是DBService,因此我們將創(chuàng)建HttpServiceHandler的一個子類,叫做DBServiceHandler。在HttpService中,我們使用以下代碼:

String className = PACKAGE_NAME + "." + request.getRequestType() + "Handler";
HttpServiceHandler handler = Class.fromName(className).newInstance();
handler.handleRequest(request);

一個HttpServiceHandler子類需要執(zhí)行一個方法processRequest(),它需要取一個ServiceRequest對象,然后返回一個ServiceResponse對象。這個方法是在handleRequest 方法的過程中由子類調(diào)用的:

Public void handleRequest(ServiceRequest request)
{
Serviceresponse response = processRequest(request);
SendResponse(response);
}

這是使用Template(模板)方法模式的一個典型例子,在這個過程中,抽象超類調(diào)用在一個子類中執(zhí)行的方法。

ServiceRequest類將服務(wù)特定數(shù)據(jù)存儲為一個XML 文檔。這個類由訪問者來設(shè)置和獲取請求類型,它還有方法來處理請求的細(xì)節(jié)。getRequest()方法返回包含在請求標(biāo)記中的XML節(jié)點,setRequest()方法則用一個新生成的請求來覆蓋原來的請求。這個類還使用兩個factory方法,創(chuàng)建新的元素和文本節(jié)點,允許開發(fā)人員生成新的請求。ServiceResponse類以一種非常簡單的方法來處理請求的細(xì)節(jié)。

雖然這兩個類允許我們對所有類型的請求和響應(yīng)進行處理,但是開發(fā)人員也必須要了解每個請求的特殊語法。開發(fā)人員不能對請求的格式是否正確進行任何確認(rèn)。

為了簡化這個過程,我們將創(chuàng)建ServiceRequest和 ServiceResponse的子類,它們分別叫做DBServiceRequest和DBServiceResponse,它們都有處理服務(wù)特定細(xì)節(jié)的方法。例如,DBServiceRequest有設(shè)置和獲取SQL 語句的方法,同時 DBServiceResponse有設(shè)置和獲取結(jié)果記數(shù)值和結(jié)果設(shè)置矢量的方法。

服務(wù)是用HttpServiceClient類來訪問的。在客戶端應(yīng)用程序中,有以下的代碼:

HttpServiceClient client = new HttpServiceClient(serviceURL);
DBServiceRequest request = new DBServiceRequest();
request.setSqlStatement(statement);
DBServiceResponse response = new DBServiceResponse(client.executeRequest(request));

其中服務(wù)的URL是這樣的:

http://myHost/servlet/httpservice.HttpService.

細(xì)節(jié)
上面我們已經(jīng)看到了框架結(jié)構(gòu)中的所有元素,現(xiàn)在來看看那些有趣的細(xì)節(jié)。首先讓我們來注意一下協(xié)議層。我們應(yīng)該如何創(chuàng)建包裝XML負(fù)載的HTTP POST 請求?我們應(yīng)該如何處理HTTP響應(yīng)?

HTTP 請求是標(biāo)準(zhǔn)化的、基于ASCII的、與一個Web 服務(wù)器的socket通訊。這里有一個例子:

POST /servlet/
httpService.Httpservice HTTP/1.0
Host: localhostt:80
Content-Type: text/xml
Content-Length: 248
<?xml version='1.0' encoding='utf-8' ?>
<http-request>
<requestType>DBService</requestType>
<request>
<sql-statement>
SELECT * FROM MyTable
</sql-statement >
</request>
</http-request>

來自Web服務(wù)器的響應(yīng)如下所示:

HTTP/1.0 200 OK
Date: Fri, 24 Nov 2000 16:09:57 GMT
Status: 200
Servlet-Engine: Tomcat Web Server/3.1 (JSP 1.1;
Servlet 2.2; Java 1.3.0; Windows 2000 5.0 x86;
java.vendor=Sun Microsystems Inc.)
Content-Type: text/xml
Content-Length: 726
Content-Language: en
<?xml version='1.0' encoding='utf-8' ?>
<http-response>
<responseMessage>OK</responseCode>
<responseCode>200</responseCode>
<response>
<result-set>
</result-count>2 </result-count>
<row>
<col name='col1'>value11</col>
<col name='col2'>value12</col>
</row>
<row>
<col name='col1'>value21</col>
<col name='col2'>value22/</col>
</row>
<result-set>
</response>
</http-response>


下面的代碼顯示了HttpServiceClient類的執(zhí)行,它將處理HTTP 請求的所有細(xì)節(jié)。你能看到,一旦你了解了那些請求的準(zhǔn)確格式,這就是一個非常簡單的過程:

public class HttpServiceClient
{
private static final String HTTP_VERSION = "1.0";
private static final String HTTP_POST_REQUEST ="POST";
private static final String HEADER_HOST = "Host";
private static final String HEADER_CONTENT_TYPE = "Content-Type";
private static final String XML_MIME_TYPE = "text/xml";
private static final String
HEADER_CONTENT_LENGTH = "Content-Length";
private static final int DEFAULT_PORT = 80;

private String serviceUrl;
private int returnCode;
private String returnMessage;
private Reader responsePayload;

public HttpServiceClient(String serviceUrl)
{
this.serviceUrl = serviceUrl;
}

public ServiceResponse executeRequest(ServiceRequest request)
throws HttpServiceException
{

try
{
String data = request.serializeRequestToString("utf-8");
postRequest(data);

//check for failures
if(returnCode != 200)
throw new HttpServiceException(returnMessage);

InputSource source =
new InputSource(responsePayload);
DOMParser parser = new DOMParser();
parser.parse(source);
ServiceResponse serviceResponse =
new ServiceResponse(parser.getDocument());

String theResponse =
serviceResponse.serializeResponseToString("utf-8");
System.err.println(theResponse);

return serviceResponse;

}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException(ex.getMessage());
}
}


private void postRequest(String payload)
throws HttpServiceException
{
PrintWriter out = null;
BufferedReader in = null;


URL url = null;
try
{
url = new URL(serviceUrl);

// No port? use default port 80
int port = url.getPort () < 0 ? DEFAULT_PORT : url.getPort();

Socket soket = new Socket (url.getHost (), port);
out = new PrintWriter (soket.getOutputStream ());

in = new BufferedReader (new InputStreamReader(soket.getInputStream ()));
}
catch (Exception ex)
{
throw new HttpServiceException ("error opening socket: " + ex.getMessage ());
}

out.print (HTTP_POST_REQUEST + " " + url.getFile() + "HTTP/" + HTTP_VERSION + "\r\n");
out.print (HEADER_HOST + ": " + url.getHost () + ':' + url.getPort () + "\r\n");
out.print (HEADER_CONTENT_TYPE + ": " + XML_MIME_TYPE + "\r\n");
out.print (HEADER_CONTENT_LENGTH + ": " + payload.length () + "\r\n");
out.print ("\r\n");
out.print (payload);
out.print ("\r\n\r\n");
out.flush ();

try
{
String statusLine = in.readLine();
System.err.println(statusLine);
parseStatusLine(statusLine);
}
catch (Exception ex)
{
throw new HttpServiceException ("error parsing HTTP status line: " + ex.getMessage ());
}

// I will ignore all the headers and keep reading
// until I get an empty line
try
{
String headerLine = null;
while ((headerLine = in.readLine ()) != null)
{
if (headerLine.length () == 0)
break;
}
}
catch (Exception ex)
{
throw new HttpServiceException ("error reading HTTP headers: " + ex.getMessage ());
}

//what remains of the input Stream is my payload
responsePayload = in;

}

private void parseStatusLine(String statusLine)
throws Exception
{
StringTokenizer st =
new StringTokenizer (statusLine);

// this is the HTTP Version
st.nextToken ();

returnCode = Integer.parseInt (st.nextToken ());

StringBuffer retMessage = new StringBuffer ();

while (st.hasMoreTokens ())
{
retMessage.append (st.nextToken ());
if (st.hasMoreTokens ())
{
retMessage.append (" ");
}
}

returnMessage = retMessage.toString ();

}

}


Web服務(wù)器接受了HTTP請求后,它就創(chuàng)建一個HttpService servlet的新例示,接著調(diào)用doPost()方法,在HttpServletRequest和HttpServletResponse對象中傳遞。然后這個servlet 就恢復(fù)XML負(fù)載,并且創(chuàng)建ServiceRequest類的一個例示,最后將其轉(zhuǎn)交給正確的處理器:

Document dom;
DOMParser parser = new DOMParser();
InputSource input = new InputSource(request.getInputStream());
parser.parse(input);
dom = parser.getDocument();
ServiceRequest serviceRequest = new ServiceRequest(dom);
String className = PACKAGE_NAME + "." + request.getRequestType() + "Handler";
HttpServiceHandler handler = Class.fromName(className).newInstance();
handler.handleRequest(request);


下面的代碼顯示了DBServiceHandler類的執(zhí)行情況,這個類創(chuàng)建數(shù)據(jù)庫連接、執(zhí)行查詢并且生成DBServiceResponse對象。同樣,要注意這個過程非常簡單,因為許多復(fù)雜的問題都隱藏在ServiceResponse和ServiceRequest類及子類的后面了:

public class DBServiceHandler extends
HttpServiceHandler

{
public ServiceResponse processRequest(ServiceRequest req)
throws HttpServiceException
{
DBServiceRequest request = new DBServiceRequest(req);

String sql = request.getSqlStatement();
DBServiceResponse response = new DBServiceResponse();
Connection connection;

try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
String connectionString = "jdbc:oracle:thin:@fender.openport.com:1521:iplp";
connection = DriverManager.getConnection(connectionString ,"op1","op1");

}
catch(ClassNotFoundException ex)
{
ex.printStackTrace(System.err);
response.setResponseCode(400);
response.setResponseMessage("Oracle driver not found");
return response;
}
catch(SQLException ex2)
{
ex2.printStackTrace(System.err);
response.setResponseCode(400);
response.setResponseMessage("Could Not Connect To Database!");
return response;
}

String theSql = sql.trim().toUpperCase();
ResultSet resultSet;

try
{
Statement statement =
connection.createStatement();

if(theSql.startsWith("SELECT"))
{
resultSet = statement.executeQuery(theSql);

Vector theResults = parseResultSet(resultSet);
response.setResultsCount(theResults.size() - 1);
response.setResultSet(theResults);
}
else
{
statement.executeUpdate(theSql);
response.setResultsCount(-1);
response.setResultSet(new Vector());
}

}catch(SQLException ex)
{
response.setResponseCode(400);
response.setResponseMessage(ex.getMessage());
return response;
}

response.setResponseCode(200);
response.setResponseMessage("OK");

String res = response.serializeResponseToString("utf-8");
System.out.println(res);

return response;
}
?
}


在下面的代碼中,你能看到ServiceRequest 和DBServiceRequest的執(zhí)行。請注意隨著DBService-Request還提供了一個額外的構(gòu)造器,它將ServiceRequest作為一個自變量。這就允許我們把原始請求的XML 文檔作為當(dāng)前文檔來使用,從而向現(xiàn)有的數(shù)據(jù)提供一個額外的應(yīng)用程序特有的界面:

public class ServiceRequest

{
public final static String REQUEST_TYPE_TAG_NAME = "requestType";
public final static String REQUEST_TAG_NAME = "request";
public final static String ROOT_TAG_NAME = "http-request";

protected Document dom;

public ServiceRequest(Document request)
{
dom = request;
}

public ServiceRequest()
{
dom = new DocumentImpl();
initializeRequest();
}

//initializes an empty request
private void initializeRequest()
{
Element root = dom.createElement(ROOT_TAG_NAME);
dom.appendChild(root);

Element eRequestType =
dom.createElement(REQUEST_TYPE_TAG_NAME);
eRequestType.appendChild(dom.createTextNode(""));

root.appendChild(eRequestType);

Element eRequest =
dom.createElement(REQUEST_TAG_NAME);
root.appendChild(eRequest);
}

public String getRequestType()
throws HttpServiceException
{
try
{
return getTextAttribute(REQUEST_TYPE_TAG_NAME);
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException("Invalid Request Format.");
}

}

public void setRequestType(String requestType)
throws HttpServiceException
{
try
{
setTextAttribute(REQUEST_TYPE_TAG_NAME,requestType);
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException("Invalid Request Format.");
}

}

public Node getRequest()
throws HttpServiceException
{
try
{
Node request =
((NodeList)dom.getElementsByTagName(REQUEST_TAG_NAME)).item(0);

return request.getFirstChild().cloneNode(true);

}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException("Invalid Request Format.");
}
}

public Element createElementNode(String elementName)
{
return dom.createElement(elementName);
}

public Text createTextNode(String value)
{
return dom.createTextNode(value);
}

public void setRequest(Node request)
throws HttpServiceException
{

try
{
Node requestElement =
((NodeList)dom.getElementsByTagName(REQUEST_TAG_NAME)).item(0);
Node oldRequest =
requestElement.getFirstChild();

if(oldRequest != null)
requestElement.removeChild(oldRequest);

requestElement.appendChild(request);
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException("Invalid Request Format.");
}
}

public byte[] serializeRequestToByteArray(String encoding)
throws HttpServiceException
{
try
{
return serializeDOM(encoding).toByteArray();
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException("Error during serialization");
}
}

public String serializeRequestToString(String encoding)
throws HttpServiceException
{
try
{
return serializeDOM(encoding).toString();
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException(
"Error during serialization");
}
}

private ByteArrayOutputStream serializeDOM(String encoding)
throws HttpServiceException
{
try
{
ByteArrayOutputStream bytes =
new ByteArrayOutputStream (4096);
PrintWriter out = new PrintWriter (new OutputStreamWriter (bytes,encoding),true) ;
OutputFormat of =
new OutputFormat(dom,encoding,true);
XMLSerializer serializer = new XMLSerializer(out,of);
serializer.serialize(dom);
out.close();

return bytes;
}
catch(Exception ex)
{
ex.printStackTrace(System.err);
throw new HttpServiceException("Error during serialization");
}
}

protected String getTextAttribute(String name)
{
Node textAttributeNode = ((NodeList)dom.getElementsByTagName(name)).item(0);
Node textAttribute = textAttributeNode.getFirstChild();
if(textAttribute.getNodeType() == Node.TEXT_NODE)
return textAttribute.getNodeValue();
else
return null;
}

protected void setTextAttribute(String name, String value)
{
if (value == null)
value ="";
Node textAttributeNode =((NodeList)dom.getElementsByTagName(name)).item(0);
Node textAttribute =
textAttributeNode.getFirstChild();
textAttribute.setNodeValue(value);

}
}

public class DBServiceRequest extends ServiceRequest
{

public final static String SERVICE_NAME = "DBService";

public final static String SQL_STATEMENT_TAG_NAME = "sql-statement";

public DBServiceRequest()
{
super();
initializeParameters();
}

public DBServiceRequest(Document request)
{
super(request);
}

public DBServiceRequest(ServiceRequest request)
{
dom = request.dom;
}

public void setSqlStatement(String sql)
{
setTextAttribute(SQL_STATEMENT_TAG_NAME,sql);
}

public String getSqlStatement()
{
return getTextAttribute(SQL_STATEMENT_TAG_NAME);
}
private void initializeParameters()
{
Element eDBRequest = null;
//not very nice but this should never fail

try
{
setRequestType(SERVICE_NAME);
eDBRequest = createElementNode(SQL_STATEMENT_TAG_NAME);
}
catch(Exception ex)
{}

eDBRequest.appendChild(dom.createTextNode(""));

try
{
setRequest(eDBRequest);
}
catch(Exception ex)
{
}
}


擴展框架結(jié)構(gòu)
我們可以對這個框架進行擴展,從而處理任何類型的服務(wù)。要想創(chuàng)建一個新的服務(wù),首先必須要定義XML請求和響應(yīng)的語法。然后,創(chuàng)建ServiceRequest和ServiceResponse的一個子類,它們將幫助處理服務(wù)特有的數(shù)據(jù)。最后,創(chuàng)建Http-ServiceHandler的一個新子類,它將處理請求并生成適當(dāng)?shù)捻憫?yīng)。整個過程就是這樣。

雖然這個框架包含了一些功能,但是如果不增加一些更多功能的話,它在實際應(yīng)用情況下還不是很實用。我有意識地省略了這些功能,以使框架結(jié)構(gòu)保持簡單,并將注意力集中到了最重要的細(xì)節(jié)上。為了完整起見,現(xiàn)在我們來簡要分析這個框架結(jié)構(gòu)的一些局限性以及應(yīng)該如何去克服這些局限性。

首先,這個框架結(jié)構(gòu)不能限制對服務(wù)的訪問。這就意味著知道如何訪問這個服務(wù)的每個人都能夠進行訪問。在你允許對服務(wù)的訪問之前,請求某種證明可以解決這個問題。你可以用這同一個框架來創(chuàng)建一個證明服務(wù),這樣就能確認(rèn)用戶并生成一個唯一的ID,當(dāng)用戶訪問任何其它服務(wù)時,都會被要求這個ID。系統(tǒng)會將這個ID存儲在某些類型的訪問列表中,并且要求在一個有限時間內(nèi),每個請求都必須通過一個有效ID才能訪問服務(wù)。

另外,每次用戶訪問服務(wù)時,服務(wù)都要創(chuàng)建一個與數(shù)據(jù)庫的連接。將服務(wù)與一個連接pooling框架組合起來可以解決這個問題,這樣就將給請求分配一個現(xiàn)有連接,而不是每次都創(chuàng)建新連接。

最后一個局限是缺乏session的管理。由于我們是通過一個socket 直接訪問servlet,因此不能使用特別有用的HttpSession對象。由于在Web 服務(wù)器與瀏覽器相互作用的過程中,在客戶計算機上沒有生成session cookie ,因此不能管理自動session。為了克服這個局限,我們可以執(zhí)行我們自己的session管理。一個session可以是一個與唯一ID相關(guān)聯(lián)的對象,它可以存儲其它對象。例如,你可以有一個上下文hash信號表格,在其中存儲session對象,使用唯一的ID 作為關(guān)鍵字。這個session對象還可以包含一個hash信號表格,它存儲了你想在session中堅持使用的每個對象。

這個框架利用HTTP隧道技術(shù),允許一個桌面應(yīng)用程序訪問防火墻后面的服務(wù),對其進行擴展后還提供對其它類型服務(wù)的簡易訪問。

溫馨提示:喜歡本站的話,請收藏一下本站!

本類教程下載

系統(tǒng)下載排行

網(wǎng)站地圖xml | 網(wǎng)站地圖html
亚洲第一网中文字幕| 精品国产二区在线| 97dyy97影院理论片在线| 欧美中文字幕不卡| 天堂在线视频播放| 踪合国产第二页| 成人影院在线| 好吊色视频在线观看| 一级毛片在线播放| 日韩在线三区| 亚洲免费成人av在线| 男女视频在线观看| 国产又爽又黄网站亚洲视频123| 精品国产一区二区三区香蕉沈先生| 日韩av在线免费| 欧美xxxx性xxxxx高清视频| 亚洲综合激情网| 色噜噜狠狠色综合网| 中文字幕免费视频| 免费在线播放电影| 国产一区欧美一区| 日本麻豆一区二区三区视频| 一代武则天秘史| 欧美日韩精品久久| 欧美一区三区四区| 亚洲欧美日本一区| 日韩电影在线一区二区三区| 中文字幕一区二区三区人妻不卡| 影音先锋男人看片资源站| 色久优优欧美色久优优| 欧美高清hd| 一区二区三区在线观看动漫| 久久激情久久| 黄页大全在线免费观看| 美女被草91| 五月婷婷在线播放| 隔壁人妻偷人bd中字| 国产精品一区二区三区乱码| 欧美日韩日本网| 国产成人久久精品77777综合| 欧美日韩1区2区| 亚洲第一久久影院| 日本japanese极品少妇| 欧美日韩免费一区二区三区视频| 日韩成人亚洲| 91最新在线免费观看| 成人在线观看你懂的| 国产欧美精品区一区二区三区| 亚洲精品永久免费精品| 久久精品magnetxturnbtih| 懂色av一区二区在线播放| 久久久国产精品成人免费| 黄色国产网站在线播放| 国产一区二区视频在线观看| 国产三级视频在线播放| 五月天婷婷综合社区| 国产精品一区二区三区精品| 四虎成人影院网址| 亚洲精品国偷拍自产在线观看蜜桃| 欧美成人免费电影| 国产一区二区三区精品在线| 成都免费高清电影| 日韩一区网站| 色噜噜狠狠色综合网图区| 免费看一区二区三区| 成人av先锋影音| 国产 欧美 在线| 三级视频网站在线观看| 欧日韩在线观看| 男人天堂网站| 精品国产乱码久久久久久图片| 欧美日韩色网| 日韩成人在线免费观看| 久久激五月天综合精品| 男女av免费观看| 免费观看亚洲天堂| 老妇女50岁三级| 亚洲理论在线观看| 亚洲欧美精品伊人久久| 99re6这里有精品热视频| 久久人人爽人人爽人人片亚洲| 国产精品素人一区二区| 中文字幕色av一区二区三区| 天堂在线一区二区三区| 久久亚洲精品爱爱| 日韩欧美在线视频一区二区| 天堂在线一区二区三区| 亚洲色图在线看| 91久久偷偷做嫩草影院| 黑森林福利视频导航| 15—17女人毛片| 日本va欧美va国产激情| 欧美捆绑视频| 色先锋最新资源| 91在线观看入口| 福利小视频在线| 久久久久久久成人| 日本三级电影网站| √最新版天堂资源网在线| 主播福利视频一区| 青春有你2免费观看完整版在线播放高清| 国产美女久久| 亲子伦视频一区二区三区| 国产免费一区二区三区香蕉精| 91高清在线观看视频| 国产一区二区香蕉| 一区二区精品免费| 在线中文字幕观看| 日韩av午夜| 欧美久久久久久久久中文字幕| 日本在线成人一区二区| 黄色免费在线观看网站| 国产二区国产一区在线观看| 污污免费在线观看| 黄动漫在线免费观看| www亚洲人| 玖玖爱视频在线| 欧美一区二区三区激情| 久久中文字幕人妻| 亚洲午夜精品在线观看| av电影在线观看| 欧美特级特黄aaaaaa在线看| 免费在线看大片无需流量| 又色又爽又黄视频| 久久av红桃一区二区小说| 国产女精品视频网站免费| 欧美疯狂爱爱xxxxbbbb| 草民午夜欧美限制a级福利片| 成人免费视频网站在线看| 一区二区视频国产| 中文字幕在线成人| 亚洲天堂av女优| 日韩在线视频观看| 精品无码国产污污污免费网站| 网上成人av| 老太脱裤让老头玩ⅹxxxx| 欧美性极品少妇精品网站| 国产精品中文有码| 日韩一区二区三区高清| 一区二区三区在线免费播放| 国产黄色麻豆视频| 亚洲警察之高压线| 久久这里只有精品视频网| 亚洲精品一区二区精华| 在线国产一区二区| av电影在线不卡| 99久久免费国| 久久精品欧美| 欧美剧在线免费观看网站| 亚洲第一中文字幕在线观看| 日韩精品――色哟哟| xxxxwww一片| 一区二区三区四区视频精品免费| 亚洲无码精品国产| 性欧美暴力猛交另类hd| 污视频在线观看网站| xxxxx中文字幕| 日韩精品中文在线观看| 97人妻精品一区二区三区| 日本免费网站在线观看| 亚洲中无吗在线| freehdxxxx护士| 一区二区日韩电影| 国产美女视频免费看| 电影中文字幕一区二区| 伊人精彩视频| 日韩有码免费视频| 97在线精品| 国产口爆吞精一区二区| 99精品免费在线观看| 国产精品视频yy9099| 男人插女人下面免费视频| 国产精品久久久久久久久免费高清| 日韩欧美一级大片| 中文字幕校园春色| 亚洲 欧美 日韩系列| 欧美成人免费大片| 欧美日韩激情一区二区| 97人妻天天摸天天爽天天| av观看久久| 成人综合久久| 欧美午夜精品免费| 日本三级在线观看网站| 情趣网站视频在线观看| 日韩亚洲视频在线| 波多野结衣在线观看一区二区三区| 久久久久一区二区三区| 亚洲精品一区二区三区新线路| 精品国产午夜| 亚洲一区二区三区中文字幕在线观看| 欧美电影《轻佻寡妇》| 七七成人影院| 欧美成熟毛茸茸| 亚洲综合爱爱久久网| 92福利视频午夜1000合集在线观看| 久久久久久亚洲精品中文字幕| 国产精品涩涩涩视频网站| 国产精品国产自产拍高清av王其| 欧美日本一道| 污污免费在线观看| 成人看的羞羞网站| 国产野外作爱视频播放| 日本一区二区高清不卡| 中国美女黄色一级片| 五十路亲子中出在线观看| 国模视频一区二区三区| 一级黄色特级片| 在线成人免费视频| 国产精品国产三级国产在线观看| 欧美探花视频资源| 九九热99久久久国产盗摄| 美脚丝袜脚交一区二区| 91九色精品国产一区二区| 日日噜噜夜夜狠狠久久丁香五月| 丝袜 亚洲 另类 欧美 重口| 精品国产电影一区二区| 艳色歌舞团一区二区三区| wwwwww在线观看| 国产精品日韩欧美一区二区| 日日噜噜噜噜人人爽亚洲精品| 欧美色图一区二区| 欧美激情视频在线播放| 久久色视频免费观看| 三上悠亚av一区二区三区| 国产剧情在线观看一区二区| 日韩的一区二区| 国产精品激情偷乱一区二区∴| 亚洲网站一区| 欧美国产亚洲另类动漫| 成人丝袜高跟foot| 亚洲欧美综合在线精品| 窝窝九色成人影院| 97aⅴ精品视频一二三区| 成人妇女淫片aaaa视频| 精品久久久久久一区二区里番| 黑人极品videos精品欧美裸| 久久综合五月天| 国产精品一区二区三区99| 99久久精品国产成人一区二区| 黄色激情视频在线观看| 久久久人成影片一区二区三区观看| 俄罗斯黄色一级片| aaaaa毛片| 欧美日韩精品高清| 免费精品视频一区| 亚洲人成电影网站色…| 欧美日韩一区二区三区四区不卡| 久久午夜福利电影| 日本vs亚洲vs韩国一区三区| 蜜臀av在线播放一区二区三区| 中文字幕日韩在线视频| 亚欧洲精品在线视频免费观看| 色狠狠av一区二区三区香蕉蜜桃| 自拍视频在线播放| 老头吃奶性行交视频| 国产精品人人妻人人爽人人牛| 精品国产乱码| 久久综合久久久久| а√天堂中文资源在线bt| 亚洲已满18点击进入久久| 4438全国亚洲精品观看视频| 中文乱码人妻一区二区三区视频| 盗摄女厕thunder| 日本午夜免费一区二区| 91免费版网站在线观看| 男女性杂交内射妇女bbwxz| 又色又爽又黄视频| av在线资源观看| 亚洲精品欧美综合四区| 国产精品一区二区久久久久| 亚洲淫片在线视频| 国产精成人品localhost| 一区二区三区高清在线| 99re6热只有精品免费观看| 正在播放国产一区| 日本免费高清一区| av大片在线播放| zjzjzjzjzj亚洲女人| 欧美黄色成人网| 欧美视频四区| 国产a∨精品一区二区三区仙踪林| 久久精品91| 欧美性色综合| 狠狠搞狠狠干| 国产精品久久久久婷婷| 免费观看国产精品视频| 欧美视频一区| 超碰成人在线免费观看| 中文字幕一二区| 一区二区免费在线| www.中文字幕av| 国产人妻精品一区二区三| 黄网动漫久久久| 韩国一级黄色录像| 在线手机中文字幕| 久草在在线视频| 国产一区精品| 国产永久av在线| 色婷婷av一区二区三区之一色屋| 青青草视频在线观看| 久久出品必属精品| 色一情一伦一子一伦一区| 日产精品一线二线三线芒果| 首页欧美精品中文字幕| 日批免费观看视频| 男人的天堂最新网址| 亚洲国产婷婷| 国产成人av一区二区三区| 国产精品96久久久久久| 国产精品视频你懂的| 欧美亚洲国产精品久久| 日韩妆和欧美的一区二区| 国产伦理在线观看| www免费视频观看在线| gay欧美网站| 日韩欧美二区| 久久久999国产精品| 特种兵之深入敌后| 粉嫩av一区二区夜夜嗨| 女同性一区二区三区人了人一| 91视频欧美| 国产精品自拍视频一区| xxxxx日韩| 免费在线观看a视频| 超碰精品一区二区三区乱码| 欧美久久一区二区三区| av男人的天堂在线| 国产视频九色蝌蚪|