" : file.toString()) + " not found"); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ protected void doHead(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ URI resource = null;
+ try {
+ resource = getFilename(request.getRequestURI());
+ } catch (URISyntaxException e) {
+ /* ignore - just leave resource == null */
+ }
+
+ URL url = null;
+ if (resource != null) {
+ if (!resource.isAbsolute())
+ url = getServletContext().getResource(resource.getPath());
+ else
+ url = resource.toURL();
+ }
+
+ if (url == null) {
+ fileNotFound(resource, request, response);
+ return;
+ }
+ URLConnection conn = secureAction.openURL(url);
+ // always set default charset
+ // Not in Servlet 2.1 // response.setCharacterEncoding(CHARSET);
+ doDeliverHead(resource.toString(), conn, request, response); // TODO: change API to use URI?
+ }
+
+ protected void deliverHead(String filename, URLConnection conn, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ this.doDeliverHead(filename, conn, request, response);
+ }
+
+ protected void doDeliverHead(String filename, URLConnection conn, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ int contentlength = getContentLength(conn);
+ if (contentlength >= 0) {
+ response.setContentLength(contentlength);
+
+ String mimeType = computeMimeType(filename, conn);
+ response.setContentType(mimeType);
+ long modified = getLastModified(conn);
+ addDateHeader(response, HttpConstants.LAST_MODIFIED, modified);
+ } else {
+ super.doHead(request, response);
+ }
+
+ }
+
+ /**
+ * Override to lie about last modified
+ * @param conn
+ * @return time in ms
+ */
+ protected long getLastModified(URLConnection conn) {
+ return conn.getLastModified();
+ }
+
+ /**
+ * Override to lie about content length
+ * @param conn
+ * @return length in bytes
+ */
+ protected int getContentLength(URLConnection conn) {
+ return conn.getContentLength();
+ }
+
+ protected URI getFilename(String filename) throws URISyntaxException {
+ //If the requested URI is equal to the Registeration's alias, send the file
+ //corresponding to the alias. Otherwise, we have request for a file in an
+ //registered directory (the file was not directly registered itself).
+ if (filename.equals(alias)) {
+ filename = path.getPath();
+ } else {
+ // The file we re looking for is the registered resource (alias) + the rest of the
+ // filename that is not part of the registered resource. For example, if we export
+ // /a to /tmp and we have a request for /a/b/foo.txt, then /tmp is our directory
+ // (file.toString()) and /b/foo.txt is the rest.
+ // The result is that we open the file /tmp/b/foo.txt.
+
+ int aliaslen = alias.length();
+ int pathlen = path.getPath().length();
+
+ if (pathlen == 1) /* path == "/" */
+ {
+ if (aliaslen > 1) /* alias != "/" */
+ {
+ filename = filename.substring(aliaslen);
+ }
+ } else /* path != "/" */
+ {
+ StringBuffer buf = new StringBuffer(aliaslen + pathlen);
+ buf.append(path.getPath());
+
+ if (aliaslen == 1) /* alias == "/" */
+ {
+ buf.append(filename);
+ } else /* alias != "/" */
+ {
+ buf.append(filename.substring(aliaslen));
+ }
+
+ filename = buf.toString();
+ }
+ }
+ return new URI(path.getScheme(), path.getUserInfo(), path.getHost(), path.getPort(), filename, path.getQuery(), path.getFragment());
+ // return (filename);
+ }
+
+ /**
+ * This method returns the correct MIME type of a given URI by first checking
+ * the HttpContext::getMimeType and, if null, checking the httpservice's MIMETypes table.
+ * return mimetype with charset=utf-8 for all text/... types
+ */
+ protected String computeMimeType(String name, URLConnection conn) {
+ String mimeType = computeMimeType2(name, conn);
+ if (mimeType.startsWith("text/")) //$NON-NLS-1$
+ return mimeType + "; charset=utf-8"; //$NON-NLS-1$
+ return mimeType;
+ }
+
+ protected String computeMimeType2(String name, URLConnection conn) {
+ // use type set in connection if it is available
+ String mimeType = conn.getContentType();
+ if (mimeType != null) {
+ return (mimeType);
+ }
+ // use type from context
+ mimeType = getServletContext().getMimeType(name);
+ if (mimeType != null) {
+ return (mimeType);
+ }
+ // try the "extras"
+ return MimeLookup.getMimeType(name);
+ }
+
+ public HttpService getHttpService() {
+ return Activator.getInstance().getHttp();
+ }
+
+ public static final DateFormat PATTERN_RFC1123 = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss zzz", Locale.US); //$NON-NLS-1$
+
+ /**
+ * Support setting date header - in servlet > 2.1 it is possible to call this method directly on the HttpResponse.
+ * @param response
+ * @param name
+ * @param timestamp
+ */
+ public void addDateHeader(HttpServletResponse response, String name, long timestamp) {
+ DateFormat df = PATTERN_RFC1123;
+ // must always be GMT
+ df.setTimeZone(TimeZone.getTimeZone("GMT")); //$NON-NLS-1$
+ response.setHeader(name, df.format(new Date(timestamp)));
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/ChopAndDelay.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/ChopAndDelay.java
new file mode 100644
index 000000000..9359eacb0
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/ChopAndDelay.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URLConnection;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.eclipse.equinox.p2.testserver.LinearChange;
+
+/**
+ * The ChopAndDelay deliver the content chopped up in smaller packets and adds delay
+ * between packets.
+ *
+ */
+public class ChopAndDelay extends BasicResourceDelivery {
+
+ int chopFactor;
+ private LinearChange delayFunction;
+ private long msDelay;
+
+ /**
+ * Create a file molester that turns content into gibberish.
+ *
+ * @param theAlias the path this servlet is registered under
+ * @param thePath the path to use as root for the alias
+ * @param chopFactor - a value between 1 and 12 where 1 is one byte, and 12 is 4k bytes at a time.
+ * @param delayFunction - function returning a series of delay values
+ */
+ public ChopAndDelay(String theAlias, URI thePath, int chopFactor, LinearChange delayFunction) {
+ super(theAlias, thePath);
+ if (chopFactor < 1 || chopFactor > 12)
+ throw new IllegalArgumentException("chopFactor must be between 1 and 12 (inclusive) - was:" + Integer.valueOf(chopFactor)); //$NON-NLS-1$
+ this.chopFactor = chopFactor;
+ if (msDelay < 0)
+ throw new IllegalArgumentException("msDelay must be >= 0 - was:" + Integer.valueOf(chopFactor)); //$NON-NLS-1$
+ this.delayFunction = delayFunction;
+ msDelay = 0L;
+ this.delayFunction = delayFunction;
+ if (this.delayFunction.hasNext())
+ msDelay = delayFunction.next();
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ protected void deliver(URLConnection conn, InputStream in, String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ // chop up all files
+ doChop(conn, in, filename, request, response);
+ }
+
+ protected void doChop(URLConnection conn, InputStream in, String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ LinearChange delayer = delayFunction.fork();
+ int contentlength = conn.getContentLength();
+ if (contentlength >= 0) {
+ response.setContentLength(contentlength);
+
+ String mimeType = computeMimeType(filename, conn);
+ response.setContentType(mimeType);
+
+ // We want to use a writer if we are sending text
+ if (mimeType.startsWith("text/")) //$NON-NLS-1$
+ {
+ PrintWriter writer = response.getWriter();
+
+ writer.flush(); /* write the headers and unbuffer the output */
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+ int chunksize = 1 << chopFactor;
+ char buffer[] = new char[4096];
+ int read;
+ while ((read = reader.read(buffer, 0, buffer.length)) != -1) {
+ int nChunks = read / chunksize + (read % chunksize > 0 ? 1 : 0);
+ for (int i = 0; i < nChunks; i++) {
+ writer.write(buffer, i * chunksize, Math.min(chunksize, read - i * chunksize));
+ writer.flush();
+ if (msDelay > 0)
+ try {
+ Thread.sleep(msDelay);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ if (delayer.hasNext())
+ msDelay = delayer.next();
+ }
+ }
+ } else {
+ ServletOutputStream out = response.getOutputStream();
+
+ out.flush(); /* write the headers and unbuffer the output */
+
+ int chunksize = 1 << chopFactor;
+ byte buffer[] = new byte[4096];
+ int read;
+ while ((read = in.read(buffer, 0, buffer.length)) != -1) {
+ int nChunks = read / chunksize + (read % chunksize > 0 ? 1 : 0);
+ for (int i = 0; i < nChunks; i++) {
+ out.write(buffer, i * chunksize, Math.min(chunksize, read - i * chunksize));
+ out.flush();
+ if (msDelay > 0)
+ try {
+ Thread.sleep(msDelay);
+ } catch (InterruptedException e) {
+ // ignore
+ }
+ if (delayer.hasNext())
+ msDelay = delayer.next();
+ }
+ }
+ }
+ }
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/ContentLengthLier.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/ContentLengthLier.java
new file mode 100644
index 000000000..98a037736
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/ContentLengthLier.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.net.URI;
+import java.net.URLConnection;
+
+public class ContentLengthLier extends BasicResourceDelivery {
+
+ double keepFactor;
+
+ /**
+ * The ContentLengthLier sets the content length to a percentage of the original length.
+ * Values between 0 and 200 can be used (to lie about files being both smaller < 100, or larger > 100).
+ *
+ * @param theAlias
+ * @param thePath
+ * @param keepPercent - how much to lie between 0 and 200 (inclusive)
+ */
+ public ContentLengthLier(String theAlias, URI thePath, int keepPercent) {
+ super(theAlias, thePath);
+ if (keepPercent < 0 || keepPercent > 200)
+ throw new IllegalArgumentException("keepPercent must be between 0 and 200 - was:" + Integer.valueOf(keepPercent)); //$NON-NLS-1$
+ keepFactor = keepPercent / 100.0;
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ protected int getContentLength(URLConnection conn) {
+ int contentLength = conn.getContentLength();
+ return (contentLength >= 0) ? (int) (contentLength * keepFactor) : contentLength;
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/FileMolester.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/FileMolester.java
new file mode 100644
index 000000000..3a5485230
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/FileMolester.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URLConnection;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * The FileMolester will keep a certain amount of the file from the beginning, and return
+ * garbage/gibberish for the rest of the file's content. The garbage is produced by shifting every
+ * byte 1 bit to the left.
+ *
+ * The idea for keeping some percentage is to support keeping xml headers / doctype etc.
+ */
+public class FileMolester extends BasicResourceDelivery {
+
+ int keepLength;
+
+ /**
+ * Create a file molester that turns content into gibberish.
+ *
+ * @param theAlias the path this servlet is registered under
+ * @param thePath the path to use as root for the alias
+ * @param keepLength - how many bytes in the beginning that will be unmolested
+ */
+ public FileMolester(String theAlias, URI thePath, int keepLength) {
+ super(theAlias, thePath);
+ if (keepLength < 0)
+ throw new IllegalArgumentException("keepLength must be >= 0 - was:" + Integer.valueOf(keepLength)); //$NON-NLS-1$
+ this.keepLength = keepLength;
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ protected void deliver(URLConnection conn, InputStream in, String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ // molest all files
+ doMolest(conn, in, filename, request, response);
+ }
+
+ protected void doMolest(URLConnection conn, InputStream in, String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ int contentlength = conn.getContentLength();
+ if (contentlength >= 0) {
+ response.setContentLength(contentlength);
+
+ String mimeType = computeMimeType(filename, conn);
+ response.setContentType(mimeType);
+
+ // We want to use a writer if we are sending text
+ if (mimeType.startsWith("text/")) //$NON-NLS-1$
+ {
+ PrintWriter writer = response.getWriter();
+
+ writer.flush(); /* write the headers and unbuffer the output */
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+ char buffer[] = new char[4096];
+ int read;
+ int written = 0;
+ while ((read = reader.read(buffer, 0, buffer.length)) != -1) {
+ if (written + read > keepLength)
+ molest(buffer, written, read);
+ writer.write(buffer, 0, read);
+ written += read;
+ }
+ } else {
+ ServletOutputStream out = response.getOutputStream();
+
+ out.flush(); /* write the headers and unbuffer the output */
+
+ byte buffer[] = new byte[4096];
+ int read;
+ int written = 0;
+ while ((read = in.read(buffer, 0, buffer.length)) != -1) {
+ if (written + read > keepLength)
+ molest(buffer, written, read);
+ out.write(buffer, 0, read);
+ written += read;
+ }
+ }
+ }
+ }
+
+ /** Molest a char buffer */
+ private void molest(char[] buffer, int written, int read) {
+ int start = keepLength - written;
+ if (start > read)
+ return;
+ for (int i = start < 0 ? 0 : start; i < read; i++)
+ buffer[i] = (char) (buffer[i] << 1);
+ }
+
+ /** Molest a byte buffer */
+ private void molest(byte[] buffer, int written, int read) {
+ int start = keepLength - written;
+ if (start > read)
+ return;
+ for (int i = start < 0 ? 0 : start; i < read; i++)
+ buffer[i] = (byte) (buffer[i] << 1);
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/HelloWorld.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/HelloWorld.java
new file mode 100644
index 000000000..7bc682803
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/HelloWorld.java
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Simple "smoke test" servlet - for manual testing that the http server is running and is
+ * capable of running servlets.
+ */
+public class HelloWorld extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ response.setContentType("text/html"); //$NON-NLS-1$
+ PrintWriter writer = response.getWriter();
+ writer.println(""); //$NON-NLS-1$
+ writer.println(""); //$NON-NLS-1$
+ writer.println("Hello, Equinox Embedded HTTP World"); //$NON-NLS-1$
+ writer.println("
"); //$NON-NLS-1$
+ writer.println(""); //$NON-NLS-1$
+ writer.println(""); //$NON-NLS-1$
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/LastModifiedLier.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/LastModifiedLier.java
new file mode 100644
index 000000000..4b7da6cbe
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/LastModifiedLier.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.net.URI;
+import java.net.URLConnection;
+
+/**
+ * Manipulates the last modified time of serviced files.
+ * The manipulator will set all modified times to 0 if TYPE_ZERO is used, to 1 if TYPE_OLD is used,
+ * to the current time if TYPE_NOW is used, and a value 24 hours into the future if TYPE_FUTURE is used.
+ * (Future values are not allowed in HTTP - the server should guard against them and force the value
+ * to be no bigger than the response date).
+ *
+ */
+public class LastModifiedLier extends BasicResourceDelivery {
+
+ public static final int TYPE_ZERO = 1;
+ public static final int TYPE_OLD = 2;
+ public static final int TYPE_NOW = 3;
+ public static final int TYPE_FUTURE = 4;
+
+ private int type;
+
+ /**
+ * The ContentLengthLier sets the content length to a percentage of the original length.
+ * Values between 0 and 200 can be used (to lie about files being both smaller < 100, or larger > 100).
+ *
+ * @param theAlias
+ * @param thePath
+ * @param timeType - a TYPE_XXX constant defining what time to return
+ */
+ public LastModifiedLier(String theAlias, URI thePath, int timeType) {
+ super(theAlias, thePath);
+ if (timeType < TYPE_ZERO || timeType > TYPE_FUTURE)
+ throw new IllegalArgumentException("unknown timeType, was:" + Integer.valueOf(timeType)); //$NON-NLS-1$
+ type = timeType;
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ protected long getLastModified(URLConnection conn) {
+ // ignore real value and lie based on constant
+ return getLastModified();
+ }
+
+ private long getLastModified() {
+ switch (type) {
+ case TYPE_ZERO :
+ return 0L;
+ case TYPE_OLD :
+ return 1L;
+ case TYPE_NOW :
+ return System.currentTimeMillis();
+ case TYPE_FUTURE :
+ return System.currentTimeMillis() + 24 * 60 * 60 * 1000;
+ }
+ // should not happen
+ return 0L;
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/StatusCodeResponse.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/StatusCodeResponse.java
new file mode 100644
index 000000000..d162dcd75
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/StatusCodeResponse.java
@@ -0,0 +1,80 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * Produces a response with a status code specified in the request URI.
+ * Requires to be registered for "/status" path. The request is made on the format
+ * "/status/code/" where code is the HTTP integer status code. The path after /code/ can be
+ * anything - it is always ignored.
+ * The response to GET produces HTML text "Requested status: code".
+ * The response to HEAD just produces the status header response.
+ *
+ */
+public class StatusCodeResponse extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
+ response.setContentType("text/html"); //$NON-NLS-1$
+ PrintWriter writer = response.getWriter();
+ doStatus(request, response, writer);
+ }
+
+ protected void doStatus(HttpServletRequest request, HttpServletResponse response, PrintWriter writer) {
+ String requestPath = request.getRequestURI();
+ String[] result = requestPath.split("/"); //$NON-NLS-1$
+ if (result.length < 3 && !"status".equalsIgnoreCase(result[1])) //$NON-NLS-1$
+ {
+ getServletContext().log("Error Servlet requires being configured to get /status/statuscode paths. Example /status/500, got" + requestPath); //$NON-NLS-1$
+ return;
+ }
+ // get the error code
+ int errorCode = 0;
+ try {
+ errorCode = Integer.parseInt(result[2]);
+ } catch (NumberFormatException e) {
+ response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ getServletContext().log("Number format exception in /status/statuscode path.", e); //$NON-NLS-1$
+ return;
+ }
+
+ // set the errorCode as the response and write a message
+ response.setStatus(errorCode);
+ if (writer != null)
+ htmlPage(writer, "Requested Status: " + Integer.valueOf(errorCode), false); //$NON-NLS-1$
+ }
+
+ public void doHead(HttpServletRequest request, HttpServletResponse response) {
+ // produce same reponse as for GET, but no content (writer == null)
+ doStatus(request, response, null);
+ }
+
+ private void htmlPage(PrintWriter writer, String body, boolean consoleOutput) {
+ if (consoleOutput)
+ System.err.println(body);
+
+ writer.println(""); //$NON-NLS-1$
+ writer.println(""); //$NON-NLS-1$
+ writer.println(body);
+ writer.println("
"); //$NON-NLS-1$
+ writer.println(""); //$NON-NLS-1$
+ writer.println(""); //$NON-NLS-1$
+ writer.flush();
+ }
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/TimeOut.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/TimeOut.java
new file mode 100644
index 000000000..ea56102bb
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/TimeOut.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+/**
+ * This servlet is a "black hole" - it just sleeps for an hour on any request.
+ *
+ */
+public class TimeOut extends HttpServlet {
+
+ private static final long serialVersionUID = 1L;
+ private static long MINUTES_MS = 1000 * 60; // minutes in ms
+
+ protected void doGet(HttpServletRequest request, HttpServletResponse response) {
+ doDelay();
+ }
+
+ private void doDelay() {
+ // Do nothing...
+ try {
+ Thread.sleep(60 * MINUTES_MS); // sleep 1 hour
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ protected void doHead(HttpServletRequest request, HttpServletResponse response) {
+ doDelay();
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/Truncator.java b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/Truncator.java
new file mode 100644
index 000000000..17c4bf636
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/src/org/eclipse/equinox/p2/testserver/servlets/Truncator.java
@@ -0,0 +1,105 @@
+/*******************************************************************************
+ * Copyright (c) 2009, Cloudsmith Inc and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Cloudsmith Inc. - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.equinox.p2.testserver.servlets;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintWriter;
+import java.net.URI;
+import java.net.URLConnection;
+import javax.servlet.ServletException;
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+public class Truncator extends BasicResourceDelivery {
+
+ double keepFactor;
+
+ public Truncator(String theAlias, URI thePath, int keepPercent) {
+ super(theAlias, thePath);
+ if (keepPercent < 0 || keepPercent > 100)
+ throw new IllegalArgumentException("keepPercent must be between 0 and 100 - was:" + Integer.valueOf(keepPercent)); //$NON-NLS-1$
+ keepFactor = keepPercent / 100.0;
+ }
+
+ private static final long serialVersionUID = 1L;
+
+ protected void deliver(URLConnection conn, InputStream in, String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ // truncate all files
+ doTruncate(conn, in, filename, request, response);
+ }
+
+ protected void doTruncate(URLConnection conn, InputStream in, String filename, HttpServletRequest request, HttpServletResponse response) throws IOException {
+ int contentlength = conn.getContentLength();
+ if (contentlength >= 0) {
+ response.setContentLength(contentlength);
+
+ String mimeType = computeMimeType(filename, conn);
+ response.setContentType(mimeType);
+
+ // We want to use a writer if we are sending text
+ if (mimeType.startsWith("text/")) //$NON-NLS-1$
+ {
+ PrintWriter writer = response.getWriter();
+
+ writer.flush(); /* write the headers and unbuffer the output */
+
+ BufferedReader reader = new BufferedReader(new InputStreamReader(in));
+
+ char buffer[] = new char[4096];
+ int read;
+ int written = 0;
+ while ((read = reader.read(buffer, 0, buffer.length)) != -1) {
+ read = cap(contentlength, written, read);
+ writer.write(buffer, 0, read);
+ written += read;
+ }
+ } else {
+ ServletOutputStream out = response.getOutputStream();
+
+ out.flush(); /* write the headers and unbuffer the output */
+
+ byte buffer[] = new byte[4096];
+ int read;
+ int written = 0;
+ while ((read = in.read(buffer, 0, buffer.length)) != -1) {
+ read = cap(contentlength, written, read);
+ out.write(buffer, 0, read);
+ written += read;
+ }
+ }
+ }
+ }
+
+ /**
+ * Returns read if entire amount should be read. Returns a lower number if
+ * written + read > keepPercent of total
+ * @param total
+ * @param written
+ * @param read
+ * @return read, or a lower number if cap is reached
+ */
+ private int cap(int total, int written, int read) {
+ int cap = (int) (keepFactor * total);
+ return (read + written) > cap ? cap - written : read;
+ }
+
+ protected void deliverHead(String filename, URLConnection conn, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
+ // deliver normal head response
+ super.doDeliverHead(filename, conn, request, response);
+
+ }
+
+}
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/artifacts.xml b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/artifacts.xml
new file mode 100644
index 000000000..19e55d746
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/artifacts.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/features/aaFeature_1.0.0.jar b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/features/aaFeature_1.0.0.jar
new file mode 100644
index 000000000..f800a9ad2
Binary files /dev/null and b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/features/aaFeature_1.0.0.jar differ
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/plugins/aaPlugin_1.0.0.jar b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/plugins/aaPlugin_1.0.0.jar
new file mode 100644
index 000000000..65ff62b79
Binary files /dev/null and b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/plugins/aaPlugin_1.0.0.jar differ
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/readme.txt b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/readme.txt
new file mode 100644
index 000000000..6fcc19b18
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/ar/simple/readme.txt
@@ -0,0 +1,2 @@
+This is a very simple artifact repository containing a single group IU (a feature), and
+a single bundle IU. This repository is used by ArtifactRepositoryManagerTest
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html b/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html
new file mode 100644
index 000000000..ce54eb75c
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.html
@@ -0,0 +1,41 @@
+
+
+Welcome to the p2 test server
+You can access all files under the "webfiles" folder in this bundle via either a "public" or "private"
+pseudoroot. Try the public link here
+To access using a login, password, you simply use the pseudoroot "/private", and you will be asked to
+log in. The credentials are: user: Aladdin, password: open sesame. Try it
+here
+The following real content is registered:
+
+- /proxy/private/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, but requires authentication.
+- /proxy/never/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, but always fail authentication.
+- /proxy/flipFlop/ - goes to http://http://download.eclipse.org/eclipse/updates/3.4, but fails authentication every second attempt.
+- /proxy/truncated - goes to updates/3.4, but truncates all files
+- /proxy/molested - goes to updates/3.4, but generates gibberish for all files
+- /proxy/decelerate - goes to updates/3.4, but delivers files in very small delayed packets - delay increases.
+-
+
+The content listed below is also available and can be accessed under:
+
- /public
+- /private
+- /never
+- /flipFlop
+- /truncated
+- /molested
+
+Content
+
+- .../ar/simple - a simple artifact repo with a feature and a plugin, uses artifact.xml
+- .../mdr/composite - a composite meta data repository - consisting of two mdrs
+- .../mdr/composite/one - a regular meta data repostory, uses content.xml
+- .../updatesite - a classic update site with site.xml, features and plugins subdirectory
+
+The following two URL's are also available
+
+- /timeout/ - a black hole - sleeps an our and produces no response.
+- /status/nnn/xxxxx - returns the status-code "nnn", and text/html
+content, The xxxxx part is ignored. e.g. http://localhost:8080/status/500/ignored/part
+
+
+
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.xml b/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.xml
new file mode 100644
index 000000000..9e25031b4
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/index.xml
@@ -0,0 +1,10 @@
+
+
+Welcome to the p2 test server
+You can access all files under the "webfiles" folder in this bundle via either a "public" or "private"
+pseudoroot. Try the public link here
+To access using a login, password, you simply use the pseudoroot "/private", and you will be asked to
+log in. The credentials are: user: Aladdin, password: open sesame. Try it
+here
+
+
\ No newline at end of file
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/compositeContent.xml b/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/compositeContent.xml
new file mode 100644
index 000000000..af4be35bc
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/compositeContent.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/one/content.xml b/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/one/content.xml
new file mode 100644
index 000000000..41f172f48
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/one/content.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (org.eclipse.update.install.features=true)
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ [Enter License Description here.]
+
+
+
+ [Enter Copyright Description here.]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (org.eclipse.update.install.features=true)
+
+
+
+
+
+
+ [Enter License Description here.]
+
+
+
+ [Enter Copyright Description here.]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/two/content.xml b/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/two/content.xml
new file mode 100644
index 000000000..fd315dbb3
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/mdr/composite/two/content.xml
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (org.eclipse.update.install.features=true)
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+ [Enter License Description here.]
+
+
+
+ [Enter Copyright Description here.]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ (org.eclipse.update.install.features=true)
+
+
+
+
+
+
+ [Enter License Description here.]
+
+
+
+ [Enter Copyright Description here.]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/features/test.feature_1.0.0.jar b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/features/test.feature_1.0.0.jar
new file mode 100644
index 000000000..80bbc69fd
Binary files /dev/null and b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/features/test.feature_1.0.0.jar differ
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/plugins/test.bundle_1.0.0.jar b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/plugins/test.bundle_1.0.0.jar
new file mode 100644
index 000000000..00dd829d8
Binary files /dev/null and b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/plugins/test.bundle_1.0.0.jar differ
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/plugins/test.fragment_1.0.0.jar b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/plugins/test.fragment_1.0.0.jar
new file mode 100644
index 000000000..d033e2eda
Binary files /dev/null and b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/plugins/test.fragment_1.0.0.jar differ
diff --git a/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/site.xml b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/site.xml
new file mode 100644
index 000000000..4e619773e
--- /dev/null
+++ b/bundles/org.eclipse.equinox.p2.testserver/webfiles/updatesite/site.xml
@@ -0,0 +1,4 @@
+
+
+
+
--
cgit v1.2.3