第十五章 基于Http的应用
一、主要内容
(1)、HTTP协议简介
(2)、IWeb接口的基本功能
(3)、IWeb接口与其他接口的协同操作
(4)、Brew Web功能的代理规范
二、HTTP协议的主要特点
(1)、支持客户/服务器模式。
(2)、.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
(3)、灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
(4)、无连接:无连接的含义是限制每次连接只处理一个请求。
(5)、无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。
三、HTTP 通信的基本过程
(1)、客户端连接一个主机
(2)、服务器接收连接
(3)、客户端请求一个文件
(4)、服务器发送一个应答
四、IWeb接口的特点
(1)、IWeb 接口是进行和完成 Web 处理的环境, 也是处理 BREW Web 支持的 API。
(2)、IWeb 接口指针在应用程序启动时创建、初始化,并使用到应用程序关闭。
(3)、IWeb 的一个有用的入口点是IWEB_GetResponse(),它接受 URL 和 AEECallback,并取消异步的 Web 处理
(4)、IWeb 可以监督代理、持续连接和其它的 Web 相关行为
五、IWeb接口的功能
(1)、IWeb接口的主要目的是为BREW应用产生一个HTTP请求
(a)、对文件的请求使用HTTP中的“Get”方法
(b)、上载数据是通过HTTP的“Post”方法实现的
(2)、IWEB 能够管理自己的连接和sockets,使用IWEB_GetResponse 函数就可以启动一个 web 访问 ,IWEB_GetResponse的函数原型如下:
void IWEB_GetResponse(IWeb * pIWeb,IWebResp * * ppiwresp,AEECallback * pcb,
const char * cpszUrl,
...
)
六、IWEB接口请求一个文件的示例
七、获得服务器的响应内容
(1)、通过IWEBRESP_GetInfo()方法获得服务器的响应内容,存储在WebRespInfo数据结构中
(2)、WebRespInfo 用于简化最基本的 Web 处理编码,并保留如何进行 Web 处理的最易见和重要的信息。
typedef structure
{
int nCode;
ISource * pisMessage;
long lContentLength;
const char * cpszContentType;
const char * cpszCharset;
int32 tExpires;
int32 tModified;
} WebRespInfo;
八、获得服务器的响应内容示例
// Callback
static void WebReadCB(void* cxt)
{
…
// Get information about the response
WebRespInfo* pWebRespInfo = IWEBRESP_GetInfo(pMe->m_pIWebResp);
// the body of the response is contained in the ISOURCE within
ISource* pISource = pWebRespInfo->pisMessage;
}
九、Web请求的选项
(1)、WebOpts (Web 选项)管理 API 用于操作 IWeb 配置。
(2)、IWebOpts 代表选项堆栈或列表,这些选项可以为单值或多值。
(3)、IWebOpts 接口不强制单值或多值选项的语义。
(4)、选项堆栈的访问按添加选项的顺序进行
十、IWebOpts 接口的语义
(1)、按以下操作构成的列表:
AddOpt({OPT1, x}) ==> push {OPT1, x}
AddOpt({OPT1, y}) ==> push {OPT1, y}
AddOpt({OPT1, z}) ==> push {OPT1, z}
RemoveOpt(OPT1, 0) ==> 删除第 0 个 OPT1 (即 {OPT1, z})
AddOpt({OPT2, b},{OPT2, a})) ==> push {OPT2, a},然后 push {OPT2, b}
(2)、将产生下列应答:
GetOpt(OPT1, 0) ==> 查找第 0 个 OPT1 => {OPT1, y}
GetOpt(OPT1, 1) ==> 查找第 1 个 OPT1 => {OPT1, x}
GetOpt(OPT1, 2) ==> 查找第 2 个 OPT1 => EFAILED
GetOpt(OPT1, 3) ==> 查找第 3 个 OPT1 => EFAILED
GetOpt(OPT2, 1) ==> 查找第 1 个 OPT2 => {OPT2, a}
十一、利用 IWEB_AddOpt添加选项
十二、直接使用选项参数
IWEB_GetResponse(pMe->m_pIWeb,
(pMe->m_pIWeb,
&pMe->m_pIWebResp,
&pMe->m_Callback,
"http://www.qualcomm.com",
WEBOPT_HANDLERDATA,
pMe,
WEBOPT_STATUSHANDLER,
WebStatusNotification,
WEBOPT_METHOD,
"GET",
WEBOPT_END));
十三、主要选项的说明
(1)、WEBOPT_METHOD
(2)、WEBOPT_BODY
(3)、WEBOPT_CONNECTTIMEOUT
(4)、WEBOPT_IDLECONNTIMEOUT
(5)、WEBOPT_HEADER
(6)、WEBOPT_PROXYSPEC
(7)、WEBOPT_FLAGS
(a)、WEBREQUEST_NOKEEPALIVE
(b)、WEBREQUEST_FORCENEWCONN
(c)、WEBREQUEST_NOWAITCONN
十四、解释WebRespInfo 中的错误编码
(1)、pWebRespInfo->nCode 包含了该响应的状态信息
(a)、如果nCode为正值,则代表从服务器返回的信息;
(b)、如果nCode为负值,则代表系统错误
(2)、获得nCode的具体含义
(a)、WEB_ERROR_SUCCEEDED(nCode): 返回 TRUE 则表示通信成功
(b)、WEB_ERROR_MAP(nCode): 如果是一个HTTP错误,则返回 WEB_ERROR_PROTOCOL,参考AEEWeb.h 文件或者RFC2626,就能得到 nCode 的具体含义。
十五、检查响应的状态和HTTP头
(1)、PFNWEBHEADER是用于 web 头信息的回调原型。它将作为 IWEBOPT_HEADERHANDLER pVal 传递给IWEB_AddOpt() 或 IWEB_GetResponse() typedef void (* PFNWEBHEADER)
(
void * pNotifyData,
const char * pszName,
GetLine * pplVal
);
(2)、PFNWEBSTATUS是 web 请求状态的回调原型,将作为 IWEBOPT_STATUSHANDLER pVal 传递给IWEB_AddOpt() 或 IWEB_GetResponse()
typedef void (* PFNWEBSTATUS)
(
void * pNotifyData,
WebStatus ws,
void * pData
);
十六、响应的状态信息
WebStatus是个枚举类型的数据结构列表,传递给相应的回调函数,以通知 API 客户端有关进行中的 Web 请求状态
typedef enum WebStatus
{
WEBS_STARTING = 0,
WEBS_CANCELLED,
WEBS_GETHOSTBYNAME,
WEBS_CONNECT,
WEBS_SENDREQUEST,
WEBS_READRESPONSE,
WEBS_GOTREDIRECT,
WEBS_CACHEHIT
} WebStatus;
十七、使用 HTTP POST 方法
/ set up the callback
CALLBACK_Init(&pMe->m_Callback, WebReadCB, pMe);
// Create a Source Util object which will create an ISource object
// from a buffer, file, socket, etc.
ISHELL_CreateInstance(pMe->a.m_pIShell,
AEECLSID_SOURCEUTIL,
(void**)&pMe->m_pISourceUtil);
// Create ISOURCE object
ret = ISOURCEUTIL_SourceFromMemory(pMe->m_pISourceUtil,
pMe->m_szData, // data in buffer
pMe->m_nContentLength, // length of data
NULL,// No callback
NULL,
&pMe->m_pISource //object to be created
);
// Kick off the transaction
IWEB_GetResponse(pMe->m_pIWeb,
(pMe->m_pIWeb,
&pMe->m_pIWebResp,
&pMe->m_Callback,
pMe->m_pURL,
WEBOPT_METHOD,
"POST", // Set method to POST
WEBOPT_BODY,
pMe->m_pISource, // Set body of message to ISOURCE object
WEBOPT_CONTENTLENGTH,
pMe->m_dwContentLength,
WEBOPT_END));
十八、在 URL中使用保留字
(1)、当发送HTTP 请求的时候,URL中是不能包括如何保留字的。
(2)、如果必须要在URL中使用保留字,就需要在发送请求前对URL进行编码。
(3)、在BREW中,是通过IWEBUTIL接口实现的。
(4)、此接口用于为 Web 处理提供实用函数(大多为无状态 API)。使用函数IWEBUTIL_UrlEncode,就可以实现对URL的编码。
char * IWEBUTIL_UrlEncode
(
IWebUtil * pIWebUtil,
const char * cpcIn,
int * pnInLen,
char * pcOut,
int * pnOutLen
)
十九、在 URL中使用保留字示例
// Determine what the length of the output buffer needs to be
IWEBUTIL_UrlEncode(pMe->m_pIWebUtil,
(const char *)(buf), // buffer containing the suffix of URL with reserved chars
&nDataLen, // number of characters to be encoded
NULL, // if NULL, method calculatessize of buffer needed
&pMe->m_dwContentLength // contains the length of the buffer required
);
// Allocate space to hold the encoded string
if(pMe->m_dwContentLength)
pMe->m_szData = (char*) MALLOC(pMe->m_dwContentLength);// Encode the string.
IWEBUTIL_UrlEncode(pMe->m_pIWebUtil,
(const char *)(buf),
&nDataLen,
pMe->m_szData,
&pMe->m_dwContentLength);
二十、保持连接激活和缓存
(1)、保持激活状态的永久连接
(a)、 IWEB 接口使用了这一特性使连接一直处于激活状态,而且这是IWeb接口的默认状态。
(b)、通过使用Web选项WEBREQUEST_NOKEEPALIVE 和 WEBOPT_FLAG可以禁用这一功能
(2)、对于保持激活状态的永久连接有一些限制
(a)、保持激活状态依赖于Content-Length 的HTTP头。
(b)、只有当“Content-Length: xxx” 的HTTP头有效时,这一特性才能正常工作。
(c)、对于远端需要知道何时调整读取的时候或者需要知道内容长度的时候,连接都需要被关闭
二十一、页面内容的相关处理
(1)、在IWEBUTIL接口中的IWEBUTIL_ParseFormFields方法可以提供页面内容的相关处理
(a)、“x-www-url 编码”形式字段字符串具有以下形式:
name1=value1&name2=value2&name3=value3& ...
或:
name1=value1;name2=value2;name3=value3; ...
(b)从“x-www-url 编码”字符串 *ppszIn 中解析出下一个 nMaxFields 形式字段,并将指向每个名称和值开头的指针存储在 awff 的连续元素中,然后将 ppszIn 推进至下一个未解析形式字段的开头
(2)、 利用IHTMLViewer 接口在手机上可以显示HTML的表单
二十二、页面内容的相关处理示例
// Find the suffix
pszIter = STRCHREND(pszIter, '?');
if (*pszIter)
{
IWebUtil *piwu;
WebFormField wff[4]; // Create an array of WebFormField structs
++pszIter;
ISHELL_CreateInstance(pApp->a.m_pIShell, AEECLSID_WEBUTIL,(void **)&piwu)) ;
// This populates the WebFormField structs with a maximum of 4 fields
IWEBUTIL_ParseFormFields(piwu,&pszIter,wff,4,0);
IWEBUTIL_Release(piwu);
piwu = 0;
}
二十三、BREW WEB 代理规范的特点
(1)、BREW WEB 代理规范易于使用 ,是一组固定的以 null 结尾的字符串,类似于常见的 URL 语法。 具体形式如下:
<scheme>://<domainspec>:/<proxypath> 。
(2)、可以为一个处理指定多个代理规范,并按 IWEBOPTS_GetOpt() 顺序检验。
(3)、它们具有一套简单但有效的语法,可用于指定代理 URL 的包含和排除
(4)、BREW WEB 代理规范无需复制,并可将其当作 WebOpts 管理。
(5)、它们的范围和寿命与它们添加的 IWebOpts 对象(可以是 IWeb 或 IWebReq)相同。
二十四、BREW WEB 代理规范说明
(1)、代理规范包含资源类型、域规范和代理路径
(2)、系统将会根据所有已知的代理规范(在 GetOpt() 中)检查 IWeb 客户端请求的 URL,直至找到匹配项
(a)、检查时,URL 资源类型对应代理规范的资源类型;URL 主机字段(如果适用)对应域规范。 两者均需与 IWeb 使用的代理规范匹配
(b)、一旦资源类型和域规范匹配,IWeb 就能根据代理规范的代理路径为 URL 找到适当的协议处理程序。
(c)、代理路径其实是一个 URL,用于指定如何在适当的协议中进行代理
(3)、代理路径也可能为空
(4)、代理规范的资源类型也可能为 "*"
二十五、BREW WEB 代理规范的示例说明
(1)、ftp:///http://proxy.vzw.com
通过 http://proxy.vzw.com代理 FTP 协议和域
(2)、*:///http://proxy.vzw.com
通过 http://proxy.vzw.com代理所有协议和域
(3)、http://!.vzw.com/http://proxy.vzw.com
代理所有 HTTP 协议、域,以 vzw.com 结尾的除外
(4)、*://.sun.com,.iplanet.com!www!internal/http://brewproxy.iplanet.com 。
代理 iplanet 和 sun 中的任何事宜,www 除外但包括 www.internal。 这可以供企业用户使用,其中 brewproxy.iplanet.com 是 BREW 电话的 iPlanet/Sun 内联网网关。
二十六、本章关键点
(1)、HTTP协议回顾
(2)、IWEB的功能特点
(3)、BREW中HTTP协议的其他功能实现
(4)、BREW WEB 代理基础
二十七、问题回顾
(1)、如何使用IWeb接口?
(2)、在URL中可以使用保留字符么?例如:?
(3)、添加WEB选项的方法有那些?具体是怎么做的?
(4)、如何产生HTTP POST 方法?
(5)、怎么样使连接一直处于激活状态?
(6)、IWebUtil接口有那些功能?
(7)、如何打开网络同时功能?应该注意什么?
(8)、BREW WEB 代理规范是什么?