package com.limegroup.gnutella.uploader; import java.io.IOException; import java.io.OutputStream; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.limegroup.gnutella.RouterService; import com.limegroup.gnutella.URN; import com.limegroup.gnutella.http.ConstantHTTPHeaderValue; import com.limegroup.gnutella.http.HTTPHeaderName; import com.limegroup.gnutella.http.HTTPUtils; import com.limegroup.gnutella.util.CommonUtils; /** * An implementaiton of the UploadState that sends an error message * for the limit of uploads allowed has been reached. This is an * HTTP 503 error. */ public class LimitReachedUploadState extends UploadState { private static final Log LOG = LogFactory.getLog(LimitReachedUploadState.class); /** Time to wait for a retry-after because we're validating the file */ public static final String RETRY_AFTER_VALIDATING = 20 + ""; /** * The time to wait for a normal retry after. */ public static final int RETRY_AFTER_TIME = 60 * 15; /** * Number of seconds the remote host should wait before retrying in * case we don't have any alt-locs left to send. (20 minutes) */ private static final String NO_ALT_LOCS_RETRY_AFTER = "" + (60 * 20); /** * Number of seconds the remote host should wait before retrying in * case we still have alt-locs left to send. (15 minute) */ private static final String NORMAL_RETRY_AFTER = "" + RETRY_AFTER_TIME; /** * The error message to send in the message body. */ private static final byte[] ERROR_MESSAGE = "Server busy. Too many active uploads.".getBytes(); /** Error msg to use when validating. */ private static final byte[] VALIDATING_MSG = "Validating file. One moment please.".getBytes(); /** True if this is a LimitReached state because we're validating the file */ private final boolean validating; /** * Creates a new <tt>LimitReachedUploadState</tt> with the specified * <tt>FileDesc</tt>. * * @param fd the <tt>FileDesc</tt> for the upload */ public LimitReachedUploadState(HTTPUploader uploader) { this(uploader, false); } public LimitReachedUploadState(HTTPUploader uploader, boolean validating) { super(uploader); this.validating = validating; LOG.debug("creating limit reached state"); } public void writeMessageHeaders(OutputStream ostream) throws IOException { LOG.debug("writing headers"); String str; str = "HTTP/1.1 503 Service Unavailable\r\n"; ostream.write(str.getBytes()); str = "Server: " + CommonUtils.getHttpServer() + "\r\n"; ostream.write(str.getBytes()); str = "Content-Type: text/plain\r\n"; ostream.write(str.getBytes()); writeProxies(ostream); writeAlts(ostream); byte[] errorMsg = ERROR_MESSAGE; if(FILE_DESC != null) { URN sha1 = FILE_DESC.getSHA1Urn(); if(validating) { errorMsg = VALIDATING_MSG; HTTPUtils.writeHeader(HTTPHeaderName.RETRY_AFTER, RETRY_AFTER_VALIDATING, ostream); } else if(sha1 != null) { // write the Retry-After header, using different values // depending on if we had any alts to send or not. HTTPUtils.writeHeader(HTTPHeaderName.RETRY_AFTER, ! RouterService.getAltlocManager().hasAltlocs(sha1) ? NO_ALT_LOCS_RETRY_AFTER : NORMAL_RETRY_AFTER, ostream); ostream.write(str.getBytes()); writeRanges(ostream); } else { HTTPUtils.writeHeader(HTTPHeaderName.RETRY_AFTER, NO_ALT_LOCS_RETRY_AFTER, ostream); } } ostream.write(str.getBytes()); str = "Content-Length: " + errorMsg.length + "\r\n"; HTTPUtils.writeHeader(HTTPHeaderName.CONNECTION, ConstantHTTPHeaderValue.CLOSE_VALUE, ostream); str = "\r\n"; ostream.write(str.getBytes()); } public void writeMessageBody(OutputStream ostream) throws IOException { LOG.debug("writing body"); ostream.write(ERROR_MESSAGE); } public boolean getCloseConnection() { return true; } }