package com.limegroup.gnutella.uploader; import java.net.InetAddress; import org.limewire.http.reactor.HttpIOSession; import com.limegroup.gnutella.BandwidthTrackerImpl; import com.limegroup.gnutella.uploader.HTTPUploadSessionManager.QueueStatus; /** * Stores the state of an HTTP connection that serves multiple requests. * Maintains the queuing status and keeps a reference to an {@link HTTPUploader} * that represents the current request. */ public class HTTPUploadSession extends BandwidthTrackerImpl implements UploadSlotUser { /** * The min and max allowed times (in milliseconds) between requests by * queued hosts. */ public static final int MIN_POLL_TIME = 45000; // 45 sec public static final int MAX_POLL_TIME = 120000; // 120 sec private HTTPUploader uploader; private final InetAddress host; private final UploadSlotManager slotManager; /** The last time this session was polled if queued */ private volatile long lastPollTime; private QueueStatus queueStatus = QueueStatus.UNKNOWN; private HttpIOSession ioSession; public HTTPUploadSession(UploadSlotManager slotManager, InetAddress host, HttpIOSession ioSession) { this.slotManager = slotManager; this.host = host; this.ioSession = ioSession; } /** * Sets the <code>uploader</code> that represents the current request. */ public void setUploader(HTTPUploader uploader) { this.uploader = uploader; } /** * Returns the <code>uploader</code> that represents the current request. * * @return null, if no request has been handled or the session has been * closed */ public HTTPUploader getUploader() { return uploader; } /** * @see UploadSlotManager#positionInQueue(UploadSlotUser) */ int positionInQueue() { return slotManager.positionInQueue(this); } public String getHost() { return host.getHostAddress(); } /** * @return the same value as {@link #getHost()} */ public InetAddress getConnectedHost() { return host; } /** * Notifies the session of a queue poll. * * @return true if the poll was too soon */ public boolean poll() { long now = System.currentTimeMillis(); return lastPollTime + MIN_POLL_TIME > now; } /** * Throws an exception since <code>HTTPUploader</code>s are not * Interruptible. */ public void releaseSlot() { throw new UnsupportedOperationException(); } public void measureBandwidth() { HTTPUploader uploader = getUploader(); if (uploader != null) { // this will invoke HTTPUploadSession.measureBandwidth(int); uploader.measureBandwidth(); } } public QueueStatus getQueueStatus() { return queueStatus; } public void setQueueStatus(QueueStatus status) { this.queueStatus = status; updatePollTime(status); } /** * Returns true, if the current queue status allows uploading. */ public boolean canUpload() { return queueStatus == QueueStatus.ACCEPTED || queueStatus == QueueStatus.BYPASS; } /** * Returns true, if the current queue status is {@link QueueStatus#ACCEPTED}. */ public boolean isAccepted() { return queueStatus == QueueStatus.ACCEPTED; } /** * Returns true, if the current queue status is {@link QueueStatus#QUEUED}. */ public boolean isQueued() { return queueStatus == QueueStatus.QUEUED; } public void updatePollTime(QueueStatus status) { if (status == QueueStatus.ACCEPTED || status == QueueStatus.BYPASS) { lastPollTime = 0; } else if (status == QueueStatus.QUEUED) { lastPollTime = System.currentTimeMillis(); } } /** * Returns the underlying I/O session for the HTTP connection. */ public HttpIOSession getIOSession() { return ioSession; } @Override public String toString() { return getClass().getSimpleName() + "[host=" + getHost() + ",fileName=" + (uploader != null ? uploader.getFileName() : "no uploader yet") + ",queueStatus=" + queueStatus + "]"; } }