📄 httpsession.java
字号:
return isSecure;
}
/**
* Adds a {@link org.jivesoftware.openfire.http.SessionListener} to this session. The listener
* will be notified of changes to the session.
*
* @param listener the listener which is being added to the session.
*/
public void addSessionCloseListener(SessionListener listener) {
listeners.add(listener);
}
/**
* Removes a {@link org.jivesoftware.openfire.http.SessionListener} from this session. The
* listener will no longer be updated when an event occurs on the session.
*
* @param listener the session listener that is to be removed.
*/
public void removeSessionCloseListener(SessionListener listener) {
listeners.remove(listener);
}
/**
* Sets the time, in seconds, after which this session will be considered inactive and be be
* terminated.
*
* @param inactivityTimeout the time, in seconds, after which this session will be considered
* inactive and be terminated.
*/
public void setInactivityTimeout(int inactivityTimeout) {
this.inactivityTimeout = inactivityTimeout;
}
/**
* Returns the time, in seconds, after which this session will be considered inactive and
* terminated.
*
* @return the time, in seconds, after which this session will be considered inactive and
* terminated.
*/
public int getInactivityTimeout() {
return inactivityTimeout;
}
/**
* Returns the time in milliseconds since the epoch that this session was last active. Activity
* is a request was either made or responded to. If the session is currently active, meaning
* there are connections awaiting a response, the current time is returned.
*
* @return the time in milliseconds since the epoch that this session was last active.
*/
public synchronized long getLastActivity() {
if (connectionQueue.isEmpty()) {
return lastActivity;
}
else {
for (HttpConnection connection : connectionQueue) {
// The session is currently active, return the current time.
if (!connection.isClosed()) {
return System.currentTimeMillis();
}
}
// We have no currently open connections therefore we can assume that lastActivity is
// the last time the client did anything.
return lastActivity;
}
}
/**
* Sets the version of BOSH which the client implements. Currently, the only versions supported
* by Openfire are 1.5 and 1.6. Any versions less than or equal to 1.5 will be interpreted as
* 1.5 and any values greater than or equal to 1.6 will be interpreted as 1.6.
*
* @param version the version of BOSH which the client implements, represented as a Double,
* {major version}.{minor version}.
*/
public void setVersion(double version) {
if(version <= 1.5) {
return;
}
else if(version >= 1.6) {
version = 1.6;
}
this.version = version;
}
/**
* Returns the BOSH version which this session utilizes. The version refers to the
* version of the XEP which the connecting client implements. If the client did not specify
* a version 1.5 is returned as this is the last version of the <a
* href="http://www.xmpp.org/extensions/xep-0124.html">XEP</a> that the client was not
* required to pass along its version information when creating a session.
*
* @return the version of the BOSH XEP which the client is utilizing.
*/
public double getVersion() {
if (this.version != Double.NaN) {
return this.version;
}
else {
return 1.5;
}
}
public String getResponse(long requestID) throws HttpBindException {
for (HttpConnection connection : connectionQueue) {
if (connection.getRequestId() == requestID) {
String response = getResponse(connection);
// connection needs to be removed after response is returned to maintain idempotence
// otherwise if this method is called again, after 'waiting', the InternalError
// will be thrown because the connection is no longer in the queue.
connectionQueue.remove(connection);
fireConnectionClosed(connection);
return response;
}
}
throw new InternalError("Could not locate connection: " + requestID);
}
private String getResponse(HttpConnection connection) throws HttpBindException {
String response = null;
try {
response = connection.getResponse();
}
catch (HttpBindTimeoutException e) {
// This connection timed out we need to increment the request count
if (connection.getRequestId() != lastRequestID + 1) {
throw new HttpBindException("Unexpected RID error.",
BoshBindingError.itemNotFound);
}
lastRequestID = connection.getRequestId();
}
if (response == null) {
response = createEmptyBody();
}
return response;
}
/**
* Sets whether the initial request on the session was secure.
*
* @param isSecure true if the initial request was secure and false if it wasn't.
*/
protected void setSecure(boolean isSecure) {
this.isSecure = isSecure;
}
/**
* This methods sends any pending packets in the session. If no packets are
* pending, this method simply returns. The method is internally synchronized
* to avoid simultanious sending operations on this Session. If two
* threads try to run this method simultaniously, the first one will trigger
* the pending packets to be sent, while the second one will simply return
* (as there are no packets left to send).
*/
protected void sendPendingPackets() {
// access blocked only on send to prevent deadlocks
synchronized (packetsToSend) {
if (packetsToSend.isEmpty()) {
return;
}
if (router == null) {
router = new SessionPacketRouter(this);
}
for (Element packet : packetsToSend.remove()) {
try {
router.route(packet);
}
catch (UnsupportedEncodingException e) {
Log.error(
"Client provided unsupported encoding type in auth request",
e);
}
catch (UnknownStanzaException e) {
Log.error("Client provided unknown packet type", e);
}
}
}
}
/**
* Creates a new connection on this session. If a response is currently available for this
* session the connection is responded to immediately, otherwise it is queued awaiting a
* response.
*
* @param rid the request id related to the connection.
* @param packetsToBeSent any packets that this connection should send.
* @param isSecure true if the connection was secured using HTTPS.
* @return the created {@link org.jivesoftware.openfire.http.HttpConnection} which represents
* the connection.
*
* @throws HttpConnectionClosedException if the connection was closed before a response could be
* delivered.
* @throws HttpBindException if the connection has violated a facet of the HTTP binding
* protocol.
*/
synchronized HttpConnection createConnection(long rid, Collection<Element> packetsToBeSent,
boolean isSecure)
throws HttpConnectionClosedException, HttpBindException
{
HttpConnection connection = new HttpConnection(rid, isSecure);
if (rid <= lastRequestID) {
Delivered deliverable = retrieveDeliverable(rid);
if (deliverable == null) {
Log.warn("Deliverable unavailable for " + rid);
throw new HttpBindException("Unexpected RID error.",
BoshBindingError.itemNotFound);
}
connection.deliverBody(createDeliverable(deliverable.deliverables));
return connection;
}
else if (rid > (lastRequestID + hold + 1)) {
// TODO handle the case of greater RID which basically has it wait
Log.warn("Request " + rid + " > " + (lastRequestID + hold + 1) + ", ending session.");
throw new HttpBindException("Unexpected RID error.",
BoshBindingError.itemNotFound);
}
if (packetsToBeSent.size() > 0) {
packetsToSend.add(packetsToBeSent);
}
addConnection(connection, packetsToBeSent.size() <= 0);
return connection;
}
private Delivered retrieveDeliverable(long rid) {
for (Delivered delivered : sentElements) {
if (delivered.getRequestID() == rid) {
return delivered;
}
}
return null;
}
private void addConnection(HttpConnection connection, boolean isPoll) throws HttpBindException,
HttpConnectionClosedException {
if (connection == null) {
throw new IllegalArgumentException("Connection cannot be null.");
}
if (isPoll) {
checkPollingInterval();
}
if (isSecure && !connection.isSecure()) {
throw new HttpBindException("Session was started from secure connection, all " +
"connections on this session must be secured.", BoshBindingError.badRequest);
}
connection.setSession(this);
// We aren't supposed to hold connections open or we already have some packets waiting
// to be sent to the client.
if (hold <= 0 || (pendingElements.size() > 0 && connection.getRequestId() == lastRequestID + 1)) {
deliver(connection, pendingElements);
lastRequestID = connection.getRequestId();
pendingElements.clear();
}
else {
// With this connection we need to check if we will have too many connections open,
// closing any extras.
// Number of current connections open plus the current one tells us how many that
// we need to close.
int connectionsToClose = (getOpenConnectionCount() + 1) - hold;
int closed = 0;
for (int i = 0; i < connectionQueue.size() && closed < connectionsToClose; i++) {
HttpConnection toClose = connectionQueue.get(i);
if (!toClose.isClosed()) {
lastRequestID = toClose.getRequestId();
toClose.close();
closed++;
}
}
}
connectionQueue.add(connection);
Collections.sort(connectionQueue, connectionComparator);
fireConnectionOpened(connection);
}
private int getOpenConnectionCount() {
int count = 0;
for (HttpConnection connection : connectionQueue) {
if (!connection.isClosed()) {
count++;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -