|
||
Both RHTTPSession
and
RHTTPTransaction
can have a set of properties associated
with them. Properties take the form of name-value pairs, where the name is an
RStringF
and the value is a
THTTPHdrVal
, allowing integers, strings, URIs, and dates
to be stored.
Session properties are called Connection Information in the API, as they
mainly relate to the type of connection that is made between a client and an
HTTP server. They are accessed using the
RHTTPSession::ConnectionInfo()
method, which returns an
RHTTPConnectionInfo
handle.
Note that in general, session properties must be defined before the first transaction is created; filters do not check the connection information if the values have changed after this point. However, some exceptions are allowed with HTTP version and proxy configuration.
By default, HTTP sessions use HTTP/1.1. To use HTTP/1.0, the connection
information property HTTP::EHTTPVersion
must be set to
HTTP::EHttp10
.
From HTTPEXAMPLECLIENT
:
switch(cmd)
{
case EVersion10:
SetHttpVersion(HTTP::EHttp10);
break;
case EVersion11:
SetHttpVersion(HTTP::EHttp11);
break;
...
void CHttpClient::SetHttpVersion(HTTP::TStrings aHttpVersion)
{
RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
RStringPool p=iSess.StringPool();
connInfo.SetPropertyL(p.StringF(HTTP::EHTTPVersion,RHTTPSession::GetTable()),THTTPHdrVal(p.StringF(aHttpVersion)));
}
The version chosen will apply to all new transactions following the property change, but will not affect any transactions currently in progress.
As HTTP/1.1 mandates the use of a persistent connection for requests made in series to a single origin server, the default behaviour of HTTP Client is to set up persistent connections for each transaction. This can be overridden by specifying a Connection header in the client request.
By default, a new RHTTPSession
is set to make direct
connections to an origin server. To switch it to use a proxy, the following two
properties must be set: HTTP::EProxyUsage
and
HTTP::EProxyAddress
.
HTTP::EProxyUsage
can take the values
HTTP::EDoNotUseProxy
(the default) or
HTTP::EUseProxy
.
HTTP::EProxyAddress
must be set using an
RStringF
value that contains the proxy address as an IP
Address and port number separated by a colon, for example, "10.158.7.4:9003".
void CHttpClient::SetProxyL(RStringF aProxyAddr)
{
RHTTPConnectionInfo connInfo = iSess.ConnectionInfo();
THTTPHdrVal proxyUsage(iSess.StringPool().StringF(HTTP::EUseProxy,RHTTPSession::GetTable()));
connInfo.SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyUsage,RHTTPSession::GetTable()), proxyUsage);
THTTPHdrVal proxyAddr(aProxyAddr);
connInfo.SetPropertyL(iSess.StringPool().StringF(HTTP::EProxyAddress,RHTTPSession::GetTable()), aProxyAddr);
Printf(_L("Proxy set to:%S\n\n"), &iProxyName);
}
Changes made to the proxy settings will affect only new transactions opened on the session, and not any currently in progress.
A proxy setting can be set for an individual transaction by setting the proxy properties on the transaction. Proxy properties set on the transaction override any proxy properties set on the session.
By default, the HTTP Transport Framework uses the default receive
buffer size of 6 KB for an HTTP session. The default receive buffer size value
can be overridden by the client before the first HTTP transaction is submitted
for a particular HTTP session. The default receive buffer size for a particular
session can be set using the HTTP::ERecvBufferSize
property. The
following example code illustrates how to set the default receive buffer size
for an HTTP session:
RHTTPSession mySess;
THTTPHdrVal myHdrVal (10240);
RHTTPConnectionInfo httpConnInfo = mySess.ConnectionInfo();
httpConnInfo.SetPropertyL (mySess.StringPool().StringF(HTTP::ERecvBufferSize, RHTTPSession::GetTable()), myHdrVal);
In this example, the default receive buffer size value is overridden and the receive buffer size is set to 10240 bytes (10 KB).
Some tuning can be made to optimize HTTP comms performance. The session
properties HTTP::EMaxNumTransportHandlers
and
HTTP::EMaxNumTransPerTranspHndlr
determine how the
internal queueing works.
HTTP::EMaxNumTransportHandlers
determines the maximum
number of sockets that may be open at a time. Its default value is 4.
HTTP::EMaxNumTransPerTranspHndlr
determines how many
transactions may be allocated to a given transport handler (that is, socket)
before being backed up in a pending queue. Its default value is 5.
HTTP session ID is an optional non-negative integer which is attached
to the session and any sockets it creates. The session ID is set on sockets by
using RSocket::SetOpt()
.
With this session ID, clients can specify an integer ID for an HTTP session, which is assigned to subsequent sockets. An ID that is set applies to subsequent socket connections.
HTTP session ID can be accessed using a Flow hook implementing the
SetFlowOption()
method, which is called whenever
RSocket::SetOpt()
is called. The Flow hook helps determine
if a socket came from a specific session.
The session ID is set when the socket is created and is not changed. To
find the session ID of a socket, the flow object must look for Set Option
commands that request setting session ID. The ID that is set can be saved in
the Flow hook object, and used later when needed. This can be done using an
iSessionId
variable to hold the value, as shown in the following
example:
#include <HTTPSocketConstants.h> // option consts defined here....
class CMip4Protocol : public CIp6Hook
{
public:
...
virtual TInt SetFlowOption(TUint aLevel, TUint aName, const TDesC8 &aOption, CFlowContext &aFlow);
private:
...
TInt iSessionId; // session ID is stored here. Should be initialized to KErrNotFound
};
The HTTP session ID, HTTP::ESessionId
, when set, is
accessed using the session’s connection info object. For example:
RHTTPSession session;
...
RHTTPConnectionInfo ConnectionInfo = session.ConnectionInfo();
To access the value, RString
must first be extracted from
the string pool. For example:
RStringF sessionId = session.StringPool().StringF(HTTP::ESessionId, RHTTPSession::GetTable());
sessionId.Close();
The SetPropertyL
method is used to set the ID. For
example:
const TInt KMySessionID = 74; // a random arbitrary ID
const THTTPHdrVal Id(KMySessionID);
ConnectionInfo.SetPropertyL(sessionId, Id);
All subsequent sockets will have the session ID specified by
KMySessionID
. Multiple sessions can share the same session ID,
which helps multiple concurrent sessions to be treated similarly by the Flow
hook.
The Property
method is used to get the current value of the
session ID. For example:
THTTPHdrVal value;
TBool exists = ConnectionInfo.Property(sessionId, value);
if ( exists )
{
TInt theSessionId = value.Int();
...
}
If the session ID has been set, this returns ETrue
and sets
the value to the session ID that was requested by the last call to
SetPropertyL()
. If an ID has not been set, or the ID has
been removed, this will return EFalse
.
The session ID can be removed using RemoveProperty
. For
example:
ConnectionInfo.RemoveProperty(sessionId);
Sockets created after this call to RemoveProperty
will not
have any ID set. Any call to Property()
will return
EFalse
. This does not affect existing sockets.
Transaction properties are accessed using the
RHTTPTransaction::PropertySet()
method, which returns an
RHTTPTransactionPropertySet
handle. They are used to store
information related to a transaction that is required to persist during the
transaction lifetime. Such information is not transmitted; the mechanism only
provides an association, mainly used by filter developers.
The two pre-defined properties that can be set by the client are
HTTP::EUsername
and HTTP::EPassword
.
Their use is described in Validation filter.
An example of properties in use is taken from the Redirection filter, where a count is maintained of the number of redirections made in response to 300-series HTTP status codes:
// see if this transaction has been redirected before
THTTPHdrVal redirectCountProperty;
if (aTransaction.PropertySet().Property(p.StringF(HTTP::ERedirectCount,RHTTPSession::GetTable()),
redirectCountProperty))
{
__ASSERT_DEBUG(redirectCountProperty.Type() == THTTPHdrVal::KTIntVal, HTTPPanic::Panic(HTTPPanic::EHeaderInvalidType));
redirectCount = redirectCountProperty.Int();
__ASSERT_DEBUG(redirectCount > 0, HTTPPanic::Panic(HTTPPanic::EHeaderInvalidType));
}
// Only redirect a certain number of times, and update the redirect count property of the transaction
if (++redirectCount < KRedirectLimit)
aTransaction.PropertySet().SetPropertyL(p.StringF(HTTP::ERedirectCount,RHTTPSession::GetTable()), redirectCount);