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;
}
}