Revision: 2344
http://vexi.svn.sourceforge.net/vexi/?rev=2344&view=rev
Author: mkpg2
Date: 2007-09-27 08:46:56 -0700 (Thu, 27 Sep 2007)
Log Message:
-----------
Feature. Basic font repository. Install fonts. Test case.
Changed download monitoring slightly.
Fix. Testcase leaving stream open (write xml without xml/explicit close)
Modified Paths:
--------------
trunk/core/org.vexi.core/src/org/vexi/core/Resources.java
trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp
trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java
trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java
trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java
trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t
trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java
Added Paths:
-----------
trunk/core/org.vexi.core/src_junit/testdeployment/VeraSans.vexi
Modified: trunk/core/org.vexi.core/src/org/vexi/core/Resources.java
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Resources.java 2007-09-27
15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Resources.java 2007-09-27
15:46:56 UTC (rev 2344)
@@ -1,5 +1,6 @@
package org.vexi.core;
+import java.awt.Font;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
@@ -21,10 +22,11 @@
import org.ibex.js.JS;
import org.ibex.js.JSExn;
import org.ibex.js.JSU;
+import org.ibex.js.Thread;
+import org.ibex.js.JS.Enumeration;
+import org.ibex.js.JS.Keys;
import org.ibex.js.JSU.Wrapper;
-import org.ibex.js.Thread;
import org.ibex.util.Basket;
-import org.ibex.util.Callable;
import org.ibex.util.Encode;
import org.ibex.util.InputStreamToByteArray;
import org.ibex.util.Log;
@@ -61,13 +63,6 @@
//private static final boolean precache = false;
//private static final boolean download = true;
- private static final boolean zipfile = true;
- private static final String[] datefmts = {
- "EEE, dd MMM yyyy HH:mm:ss zzz",
- "EEEE, dd-MMM-yy HH:mm:ss zzz",
- "EEE MMM d HH:mm:ss yyyy"
- };
-
public static Fountain fountainForNames(final JS[] urls) throws JSExn{
if(urls.length==0) return null;
if(urls.length==1){
@@ -127,7 +122,7 @@
newStream = new RemoteArchive(cacheableName);
}
else {
- newStream = new Fountain.HTTP(cacheableName);
+ newStream = new RemoteFile(cacheableName);
}
} else {
@@ -300,7 +295,7 @@
}
/** convert a path (or URL) to a file name */
- private static String pathToFileName(String path) {
+ static String pathToFileName(String path) {
return path.replace('/', '_').replace('\\', '_').replace(':', '_');
}
@@ -316,126 +311,152 @@
}
};
- public static class RemoteArchive extends Fountain{
-
- String url;
+ public static class RemoteArchive extends RemoteFile{
Fountain.Zip cache;
- public RemoteArchive(String url) { while (url.endsWith("/"))
url = url.substring(0, url.length() - 1); this.url = url; }
+ public RemoteArchive(String url) { super(url);}
public JS _get(JS key) throws JSExn {
- try {if(cache == null)cache(this);} catch (IOException
e) {
- throw new JSExn(e.getMessage());}
+ cache_(this);
return cache._get(key);
}
public InputStream getInputStream() throws IOException {
// First download we check and potentially update the
cache
- if(cache == null){cache(this);}
+ cache(this); // FIXME - should take principal as
argument?
return cache.getInputStream();
}
- /** pull the specified file from a URL and store it in a temporary
local .vexi file
- * @throws IOException */
+ /** pull the specified file from a URL and store it in a temporary
local .vexi file
+ * @param principal
+ * @throws IOException
+ * @throws JSExn */
public void cache(final JS principal) throws IOException {
- int BUFFER_SIZE = 1024;
- byte[] buffer = new byte[BUFFER_SIZE];
+ if(cache!=null) return;
+ super.cache(principal);
+ cache = new Fountain.Zip(super.cache);
+ }
+
+ private void cache_(final JS principal) throws JSExn {
+ try{cache(principal);}catch(IOException e){throw new
JSExn(e.getMessage());}
+ }
+
+ public Keys keys() throws JSExn {
+ cache_(this); // FIXME - should take principal as
argument
+ return cache.keys();
+ }
+
+ }
+
+ static public class RemoteFile extends Fountain{
- Log.uInfo(Main.class, "Downloading vexi file from " + url);
-
- Fountain httpStream = new Fountain.ProgressWatcher(new
Fountain.HTTP(url), new Callable(){
- public Object run(Object o) throws Exception {
- Trap t = principal.getTrap(SC_Progress);
- //Log.uInfo("Blah", o);
- // FEATURE - if not run yet, update
previous
- // scheduled JS arg.
- if(t!=null && (t=t.write())!=null)
- Thread.runInNew(t.function(),
new JS[]{(JS)o});
- return null;
- }});
- //HTTP.HTTPInputStream his =
(HTTP.HTTPInputStream)HttpStream.getHeadStream();
- // get the timestamp on the remote file
- long remoteModifiedDate = 0;
- String remoteModified = null;
- try {
- JS info = httpStream.getInfo();
- remoteModified =
JSU.toString(info.get(SC_lastModified));
- Trap t = principal.getTrap(SC_Downloading);
- if(t!=null && (t=t.write())!=null)
- Thread.runInNew(t.function(), new
JS[]{info});
- } catch (JSExn e1) {
- // Should not happen!
- Log.error(Resources.class, e1);
- }
-
- if (remoteModified!=null && !remoteModified.equals("")) {
- // Try parsing the date using each of the date formats
specified in RFC2616
- DateFormat dfmt;
- Date dt = null;
- for (int i=0; dt==null && i<datefmts.length; i++) {
- dfmt = new SimpleDateFormat(datefmts[i]);
- try { dt = dfmt.parse(remoteModified); } catch
(ParseException e) { dt = null; }
- }
- if (dt==null) remoteModifiedDate = 0; // unable to
parse remote date, so ignore it
- else remoteModifiedDate = dt.getTime();
- }
+ String url;
+ String filename;
+ Fountain.File cache;
+
- String fname = getTempDir() + pathToFileName(url);
- java.io.File localFile = new java.io.File(fname);
+ public RemoteFile(String url, String filename) {
+ while (url.endsWith("/")) url = url.substring(0, url.length() -
1);
+ this.url = url;
+ this.filename = filename;
+ }
- // if the file exists, then compare the timestamps
- if (localFile.exists()) {
- long localModified = localFile.lastModified();
- if (remoteModifiedDate > 0) {
- if (remoteModifiedDate <= localModified) {
- // if the local file is newer or the
same age, then just use it
- Log.uInfo(Resources.class, "... using
cached copy of vexi file");
- cache = new Zip(new
File(localFile.getAbsolutePath()));
- return;
- }
- }
- }
+ public RemoteFile(String url) {
+ this(url, Resources.getTempDir() +
Resources.pathToFileName(url));
+ }
- // download the file
- FileOutputStream fos = new FileOutputStream(localFile);
- int len;
- InputStream is = httpStream.getInputStream();
- while ((len=is.read(buffer, 0, buffer.length)) >= 0) {
- fos.write(buffer, 0, len);
- }
- fos.close();
- is.close();
+ public InputStream getInputStream() throws IOException {
+ // First download we check and potentially update the cache
+ if(cache == null){cache(this);}
+ return cache.getInputStream();
+ }
- // set the local file's timestamp
- if (remoteModifiedDate > 0) {
- localFile.setLastModified(remoteModifiedDate);
- }
+ /** pull the specified file from a URL and store it in a temporary
local .vexi file
+ * @param principal
+ * @throws IOException
+ * @throws JSExn */
+ public void cache(final JS principal) throws IOException {
+ Log.uInfo(Main.class, "Downloading vexi file from " + url);
+ try{
+ Fountain.ProgressWatcher httpStream = new
Fountain.ProgressWatcher(principal, new Fountain.HTTP(url));
+ Trap finishTrap = principal.getTrap(SC_finish);
+ finishTrap=finishTrap==null?null:finishTrap.write();
+
+ // get the timestamp on the remote file
+ JS info = httpStream.getInfo();
+ long remoteModifiedDate =
parseDate(JSU.toString(info.get(SC_lastModified)));
- Log.uInfo(Resources.class, "Done downloading to file " +
localFile.getAbsolutePath());
- cache = new Zip(new File(localFile.getAbsolutePath()));
- }
-
- public void addTrap(JS key, JS f) throws JSExn {
- //TODO - worthwhile optimisation or not?
- //String s = JSU.toString(key);
- //if(s.equals("Downloading") || s.equals("Progress"))
watch=true;
- super.addTrap(key, f);
- }
-
+ java.io.File localFile = new java.io.File(filename);
+
+ // if the file exists and we know the remote
+ // modification date - then compare the timestamps
+ if (localFile.exists() && remoteModifiedDate > 0) {
+ long localModified = localFile.lastModified();
+ if (remoteModifiedDate <= localModified) {
+ // if the local file is newer or the
same age, then just use it
+ Log.uInfo(Resources.class, "... using
cached copy of file " + url);
+ cache = new
File(localFile.getAbsolutePath());
+ if(finishTrap!=null)
Thread.runInNew(finishTrap.function(), new JS[]{JSU.F});
+ return;
+ }
+ }
+
+ Resources.streamToFile(localFile,
httpStream.getInputStream());
+
+ // set the local file's timestamp
+ if (remoteModifiedDate > 0) {
+ localFile.setLastModified(remoteModifiedDate);
+ }
+
+ Log.uInfo(Resources.class, "Done downloading to file "
+ localFile.getAbsolutePath());
+ cache = new File(localFile.getAbsolutePath());
+ if(finishTrap!=null)
Thread.runInNew(finishTrap.function(), new JS[]{JSU.T});
+ }catch(JSExn e){
+ throw new IOException(e);
+ }
+ }
+
+ public void addTrap(JS key, JS f) throws JSExn {
+ //FEATURE - worthwhile optimisation or not?
+ //String s = JSU.toString(key);
+ //if(s.equals("Downloading") || s.equals("Progress"))
watch=true;
+ super.addTrap(key, f);
+ }
+
+ private static final String[] datefmts = {
+ "EEE, dd MMM yyyy HH:mm:ss zzz",
+ "EEEE, dd-MMM-yy HH:mm:ss zzz",
+ "EEE MMM d HH:mm:ss yyyy"
+ };
+ static private long parseDate(String remoteModified){
+ if (remoteModified!=null && !remoteModified.equals("")) {
+ // Try parsing the date using each of the date formats
specified in RFC2616
+ DateFormat dfmt;
+ Date dt = null;
+ for (int i=0; dt==null && i<datefmts.length; i++) {
+ dfmt = new SimpleDateFormat(datefmts[i]);
+ try { dt = dfmt.parse(remoteModified); } catch
(ParseException e) { dt = null; }
+ }
+ if (dt!=null) return dt.getTime();
+ //unable to parse remote date, so it will be ignored
+ }
+ return 0;
+ }
}
+
+ final static int BUFFER_SIZE = 1024;
+ static void streamToFile(java.io.File localFile, InputStream is ) throws
IOException{
+ byte[] buffer = new byte[BUFFER_SIZE];
+ FileOutputStream fos = new FileOutputStream(localFile);
+ int len;
+ while ((len=is.read(buffer, 0, buffer.length)) >= 0) {
+ fos.write(buffer, 0, len);
+ }
+ fos.close();
+ is.close();
+ }
+
- /*
- public static class Stream extends JS.Immutable{
-
- public JS get(JS key) throws JSExn {
- String keyStr = JSU.toString(key);
- // TODO preprocess...
- if("".equals(keyStr)){
-
- return super.get(key);
- }
-
- }*/
public static JS parseUTF8(JS[] args) throws JSExn {
if(args == null) return null;
try {
@@ -450,7 +471,6 @@
return null;
}
-
public static void writeUTF8(JS[] args) throws JSExn {
try{
OutputStream out = Fountain.getOutputStream(args[0]);
@@ -484,7 +504,8 @@
String key = JSU.toString(arg);
if(key.equals("startElement") ||
key.equals("endElement") ||
- key.equals("characters"))
+ key.equals("characters") ||
+ key.equals("close"))
return METHOD;
return super.get(arg);
}
@@ -519,7 +540,10 @@
String chars =
JSU.toString(args[0]);
out.write(chars);
return null;
- }
+ }else if(key.equals("close")){
+ out.close();
+ return null;
+ }
}catch(IOException e){
throw new JSExn(e.getMessage());
}
@@ -530,9 +554,7 @@
}catch(IOException e){
throw new JSExn(e.getMessage());
}
-
}
-
static private class XMLHelper extends XML {
@@ -620,6 +642,71 @@
}
}
}
+
+
+ static final File FONTDIR = new File(getTempDir() + "/fonts");
+ static{
+ FONTDIR.mkdirs();
+ }
+ ////////
+ // FONT STUFF
-
+ static public void installFont(JS stream) throws JSExn{
+ try {
+ // FEATURE - verify (signed vexi files)
+ // FEATURE - version (install if a later version)
+ // FEATURE - don't cache remote archive somehow -
+ // though may not be possible if we want to do versioning
+
+ Log.warn(Resources.class, "Installing fonts without
verification");
+
+ Keys ks = stream.keys();
+
+ Enumeration E = ks.iterator();
+ while(E.hasNext()){
+ JS key = E.next();
+ Fountain f = (Fountain) stream.get(key);
+ // Find out font name from .ttf
+ InputStream is = f.getInputStream();
+ Font font = Font.createFont(Font.TRUETYPE_FONT, is);
+ String filename = font.getName();
+ is.close();
+ // Copy .ttf to font directory
+ is = f.getInputStream();
+ streamToFile(new File(FONTDIR,filename+".ttf"), is);
+ Log.warn(Resources.class, "Installing font " +
filename);
+ }
+ } catch (Exception e) {
+ Log.error(Resources.class, e);
+ throw new JSExn("Error installing font");
+ }
+ }
+
+ static JS installedFonts = new JS.Immutable() {
+ public JS get(JS key) throws JSExn {
+ String s = JSU.toString(key);
+ // FEATURE true type collections (.ttc)
+ File f = new File(FONTDIR, s + ".ttf");
+ if(f.exists()){
+ return new Fountain.File(f.getPath());
+ }
+ return null;
+ }
+ public Keys keys() throws JSExn {
+ return new Keys(installedFonts){
+ protected JS contains(JS key) throws JSExn {
+ return
JSU.B(installedFonts.get(key)!=null);
+ }
+ public Enumeration iterator() throws JSExn {
+ return new Enumeration(null) {
+ String[] files = FONTDIR.list();
+ private int n = 0;
+ public boolean _hasNext() { return n <
files.length; }
+ public JS _next() { return
JSU.S(files[n++]); }
+ };
+ }
+ protected JS size() throws JSExn {return
JSU.N((FONTDIR.listFiles().length));}
+ };
+ }
+ };
}
Modified: trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp
===================================================================
--- trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp 2007-09-27 15:32:42 UTC
(rev 2343)
+++ trunk/core/org.vexi.core/src/org/vexi/core/Vexi.jpp 2007-09-27 15:46:56 UTC
(rev 2344)
@@ -113,7 +113,6 @@
case "stream": return getSub(name);
case "stream.homedir": return Resources.fountainForName("file:" +
System.getProperty("user.home"));
case "stream.tempdir": return Resources.fountainForName("file:" +
System.getProperty("java.io.tempdir"));
- case "stream.watch": return METHOD;
case "stream.unzip": return METHOD;
case "stream.uncab": return METHOD;
case "stream.cache": return METHOD;
@@ -131,6 +130,8 @@
case "thread.sleep": return METHOD;
case "ui": return getSub(name);
case "ui.font": return getSub(name);
+ case "ui.font.install": return METHOD;
+ case "ui.font.installed": return Resources.installedFonts;
case "ui.font.wait": return METHOD;
case "ui.font.width": return METHOD;
case "ui.font.height": return METHOD;
@@ -236,7 +237,8 @@
case "stream.parse.utf8": return
Resources.parseUTF8(args);
case "thread.sleep": JSU.sleep(JSU.toInt(args[0]));
return null;
case "ui.browser":
Platform.newBrowserWindow(JSU.toString(args[0])); return null;
- case "ui.insets":
+ case "ui.font.install": Resources.installFont(args[0]);
return null;
+ case "ui.insets":
if(args[0] == null) throw new JSExn("can't discern
insets for a null frame");
Box b = null;
try{ b = (Box)args[0]; }
@@ -256,15 +258,6 @@
//#switch(JSU.toString(method))
case "regexp": return new JSRegexp(args[0], args[1]);
case "stream.parse.xml": Resources.parseXML(args);
return null;
- case "stream.watch":
- final JS func = args[1];
- return new Fountain.ProgressWatcher((Fountain)args[0],
- new Callable() {
- public Object
run(Object o) throws Exception {
- JS[] args
= (JS[])o;
- return
func.call(null, args);
- }
- });
case "stream.write.utf8": Resources.writeUTF8(args);
return null;
//#end
case 3:
Modified: trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/org/vexi/core/TestResources.java
2007-09-27 15:46:56 UTC (rev 2344)
@@ -1,7 +1,9 @@
package org.vexi.core;
+import java.awt.Font;
import java.io.BufferedReader;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
@@ -11,6 +13,7 @@
import junit.framework.TestSuite;
import org.ibex.js.Fountain;
+import org.ibex.js.JS;
import org.ibex.js.JSU;
import test.Util;
@@ -22,7 +25,7 @@
public static void main(String[] args) throws Exception {
//new Local().testLocalInJarB();
Remote r = new Remote();
- r.setUp(); r.testDownload(); r.tearDown();
+ r.setUp(); r.testInstallFont(); r.tearDown();
}
static public Test suite() {
@@ -80,8 +83,11 @@
}
static public class Remote extends TestCase{
+ static final int PORT=7070;
+ static final int RATE=Integer.MAX_VALUE; // no throttling
+
static NanoHTTPD server = null;
- static final String URL = "http://localhost:" + NanoHTTPD.PORT
+ "/";
+ static final String URL = "http://localhost:" + PORT + "/";
static public boolean deleteDirectory(File path) {
if( path.exists() ) {
@@ -99,7 +105,7 @@
}
protected void setUp() throws Exception {
- NanoHTTPD.start();
+ NanoHTTPD.start(PORT,RATE);
// Set user.home and VEXIDIR_NAME to control
// where the temp dir is put
System.setProperty("user.home", ".");
@@ -126,6 +132,19 @@
System.out.println("HI");
}
+ public void testInstallFont() throws Exception{
+ // TODO delete cache
+ File installed = new File(Resources.FONTDIR,"Bitstream
Vera Sans.ttf");
+ if(installed.exists() && !installed.delete()) fail();
+ Fountain f = Resources.cacheableForName(URL +
"VeraSans.vexi");
+ JS fontJS =
Resources.installedFonts.get(JSU.S("Bitstream Vera Sans"));
+ assertNull(fontJS);
+ Resources.installFont(f);
+ assertTrue(installed.exists());
+ fontJS = Resources.installedFonts.get(JSU.S("Bitstream
Vera Sans"));
+ assertNotNull(fontJS);
+ }
+
}
Modified:
trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/test/core/download/TestDownload.java
2007-09-27 15:46:56 UTC (rev 2344)
@@ -39,7 +39,7 @@
return new CoreTestCase(resourceDirs, fileName){
protected void setUp() throws Exception {
createDotVexi(new
File(NanoHTTPD.class.getResource(".").getPath()));
- NanoHTTPD.start();
+ NanoHTTPD.start(7070,Integer.MAX_VALUE);
}
protected void tearDown() throws Exception {
Modified: trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/test/core/stream/TestStream.java
2007-09-27 15:46:56 UTC (rev 2344)
@@ -74,6 +74,7 @@
File save_ = new
File(tmpDir,"save.txt");
TestCase.assertTrue(!save_.exists() ||
save_.delete());
Fountain.File save = new
Fountain.File(save_.getPath(),true);
+ //save.remove();
Thread.beforeNonJS();
try{
JS function = Util.getStatic(v,
main, "runtest");
Modified: trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t
===================================================================
--- trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/test/core/stream/badargs.t
2007-09-27 15:46:56 UTC (rev 2344)
@@ -1,11 +1,12 @@
<vexi xmlns:ui="vexi://ui" xmlns="">
+ static.ret = null;
static.hasException = function(f /*...*/){
var exn = false;
try{
switch(arguments.length-1){
- case 1: f(arguments[1]); break;
- case 2: f(arguments[1], arguments[2]); break;
+ case 1: ret=f(arguments[1]); break;
+ case 2: ret=f(arguments[1], arguments[2]); break;
}
}catch(e){ vexi.log.info(e);exn = true;}
return exn;
@@ -24,9 +25,10 @@
assertBadArgs(vexi.stream.parse.xml,null, {});
assertBadArgs(vexi.stream.parse.xml,stream);
assertBadArgs(vexi.stream.parse.xml,stream, null);
+ assertBadArgs(vexi.stream.write.xml,{});
assertGoodArgs(vexi.stream.parse.xml,stream, {});
- assertBadArgs(vexi.stream.write.xml,{});
assertGoodArgs(vexi.stream.write.xml,stream);
+ ret.close(); // as we opened a stream we need to make sure its
closed
};
<ui:box/>
Modified: trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java
===================================================================
--- trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java
2007-09-27 15:32:42 UTC (rev 2343)
+++ trunk/core/org.vexi.core/src_junit/testdeployment/NanoHTTPD.java
2007-09-27 15:46:56 UTC (rev 2344)
@@ -1,15 +1,34 @@
package testdeployment;
-import java.io.*;
-import java.util.*;
-import java.net.*;
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.net.BindException;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.SocketException;
+import java.net.URLEncoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Locale;
+import java.util.Properties;
+import java.util.StringTokenizer;
+import java.util.TimeZone;
import org.ibex.util.Log;
-import test.core.download.TestDownload;
-
/**
- * MODIFIED - slightly, to suit test purposes (mikeg).
+ * MODIFIED - slightly
+ * 1) to suit test purposes (mikeg).
+ * 2) added basic bandwidth throttling.
*
*
* A simple, tiny, nicely embeddable HTTP 1.0 server in Java
@@ -50,14 +69,20 @@
*/
public class NanoHTTPD
{
- //static int logLevel = Log.INFO;
+ public final int PORT;
+ private final int MAX_BYTES_PER_SECOND;
- static public int PORT = 7070;
+ private static boolean log = true;
private static NanoHTTPD singleton;
+
+
static public void start() throws Exception{
- if(singleton==null) singleton = new NanoHTTPD(PORT);
+ start(7070,Integer.MAX_VALUE);
}
+ static public void start(int port, int rate) throws Exception{
+ if(singleton==null) singleton = new NanoHTTPD(port,rate);
+ }
static public void stop() throws IOException{
if(singleton!=null){
@@ -109,7 +134,7 @@
if(myFileDir==null) myFileDir = new File(".");
- return serveFile( uri, header, myFileDir, true );
+ return serveFile( uri, method, header, myFileDir, true );
}
/**
@@ -207,8 +232,10 @@
* Throws an IOException if the socket is already in use
* @throws InterruptedException
*/
- public NanoHTTPD( int port ) throws IOException, InterruptedException
- {
+ public NanoHTTPD(int port, int rate) throws IOException,
InterruptedException
+ {
+ PORT = port;
+ MAX_BYTES_PER_SECOND = rate;
myFileDir = new
File(NanoHTTPD.class.getResource(".").getPath());;
myTcpPort = port;
@@ -237,7 +264,7 @@
{
ioe.printStackTrace();
}
- System.out.println("NanoHTTPD, finished
serving");
+ Log.warn(NanoHTTPD.class, "finished
serving");
}
});
myThread.setDaemon( true );
@@ -262,7 +289,7 @@
}
// Change port if requested
- int port = 80;
+ int port = 7070;
if ( args.length > 0 && lopt != 0 )
port = Integer.parseInt( args[0] );
@@ -273,7 +300,7 @@
NanoHTTPD nh = null;
try
{
- nh = new NanoHTTPD( port );
+ nh = new NanoHTTPD( port, 600);
}
catch( Exception ioe )
{
@@ -553,7 +580,7 @@
* Serves file from homeDir and its' subdirectories (only).
* Uses only URI, ignores all headers and HTTP parameters.
*/
- public Response serveFile( String uri, Properties header, File homeDir,
+ public Response serveFile( String uri, String method, Properties
header, File homeDir,
boolean
allowDirectoryListing )
{
// Make sure we won't die of an exception later
@@ -677,13 +704,18 @@
catch ( NumberFormatException nfe ) {}
}
}
-
- FileInputStream fis = new FileInputStream( f );
- fis.skip( startFrom );
- Response r = new Response( HTTP_OK, mime, fis );
+ InputStream is = null;
+ if("HEAD".equals(method)){
+ is = new ByteArrayInputStream(new byte[]{});
+ }else{
+ is = new FileInputStream( f );
+ is.skip( startFrom );
+ }
+ Response r = new Response( HTTP_OK, mime, is );
r.addHeader( "Content-length", "" + (f.length() -
startFrom));
r.addHeader( "Content-range", "" + startFrom + "-" +
(f.length()-1) + "/" +
f.length());
+ r.addHeader( "last-modified",
""+formatDate(f.lastModified()));
return r;
}
catch( IOException ioe )
@@ -692,6 +724,11 @@
}
}
+ private static final SimpleDateFormat sdf = new SimpleDateFormat("EEE,
dd MMM yyyy HH:mm:ss zzz");
+ private static String formatDate(long t){
+ return sdf.format(new Date(t));
+ }
+
/**
* Hashtable mapping (String)FILENAME_EXTENSION -> (String)MIME_TYPE
*/
Added: trunk/core/org.vexi.core/src_junit/testdeployment/VeraSans.vexi
===================================================================
(Binary files differ)
Property changes on:
trunk/core/org.vexi.core/src_junit/testdeployment/VeraSans.vexi
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
_______________________________________________
Vexi-svn mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/vexi-svn