瀏覽代碼

nazwy plikow...

Ranides Atterwim 9 年之前
父節點
當前提交
683b3bc8ca

+ 232 - 213
assira/src/main/java/net/ranides/assira/io/uri/impl/CHttpHandler.java

@@ -1,213 +1,232 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.io.uri.impl;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URI;
-import java.nio.charset.Charset;
-import java.time.Instant;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Date;
-import java.util.Set;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-import net.ranides.assira.io.IOHandle;
-import net.ranides.assira.io.IOStreams;
-import net.ranides.assira.io.uri.URITime;
-import net.ranides.assira.io.uri.URIFlags;
-import net.ranides.assira.io.uri.URIHandle;
-import net.ranides.assira.io.uri.URIHandler;
-import net.ranides.assira.io.uri.URIResolver;
-import net.ranides.assira.text.Charsets;
-import net.ranides.assira.text.StringTraits;
-import net.ranides.assira.trace.LoggerUtils;
-import org.slf4j.Logger;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class CHttpHandler implements URIHandler {
-    
-    private static final Logger LOGGER = LoggerUtils.getLogger();
-    
-    private static final Pattern RE_CHARSET = Pattern.compile(";[ ]*charset=([^; ]+)");
-
-    private final URIResolver resolver;
-    
-    public CHttpHandler() {
-        this.resolver = URIResolver.DEFAULT;
-    }
-
-    public CHttpHandler(URIResolver resolver) {
-        this.resolver = resolver;
-    }
-    
-    @Override
-    public URIHandle resolve(URI uri) throws IOException {
-        return new CHttpHandle(uri);
-    }
-
-    @Override
-    public Collection<String> schemes() {
-        return Arrays.asList("http","https");
-    }
-    
-    private class CHttpHandle extends CHandle {
-        
-        private final URI uri;
-        private final IOHandle<HttpURLConnection> head;
-        private final IOHandle<HttpURLConnection> get;
-        private final IOHandle<HttpURLConnection> post;
-
-        public CHttpHandle(URI uri) throws MalformedURLException {
-            this.uri = uri;
-            head = new IOHandle<>(() -> connect("HEAD"));
-            get = new IOHandle<>(() -> connect("GET"));
-            post = new IOHandle<>(() -> connect("POST"));
-        }
-
-        @Override
-        public URIResolver resolver() {
-            return resolver;
-        }
-        
-        @Override
-        public URI uri() throws IOException {
-            return uri;
-        }
-        
-        @Override
-        public Charset charset() throws IOException {
-            return getContentCharset(head().getContentType());
-        }
-
-        @Override
-        public Set<URIFlags> flags() throws IOException {
-            Set<URIFlags> re = URIFlags.collect(URIFlags.FILE);
-            try {
-                HttpURLConnection c = head();
-                if(isSuccess(c)) {
-                    re.add(URIFlags.EXISTS);
-                    re.add(URIFlags.READABLE);
-                }
-
-                if(StringTraits.starts(c.getContentType(), "text/")) {
-                    re.add(URIFlags.TEXT);
-                } else {
-                    re.add(URIFlags.BINARY);
-                }
-                if(c.getContentLengthLong() >= 0) {
-                    re.add(URIFlags.SIZE);
-                }
-                if(StringTraits.contains(c.getHeaderField("Accept-Ranges"), "bytes")) {
-                    re.add(URIFlags.SEEK);
-                }
-            } catch(IOException cause) {
-                LOGGER.warn("URI.flags: HTTP error", cause);
-            }
-            return re;
-        }
-
-        @Override
-        public Instant time(URITime ut) throws IOException {
-            if(ut == URITime.MODIFIED) {
-                HttpURLConnection c = head();
-                if(null == c.getHeaderField("Last-Modified")) {
-                    return Instant.ofEpochMilli(c.getDate());
-                }
-                return new Date(c.getHeaderFieldDate("Last-Modified", 0)).toInstant();
-            }
-            return super.time(ut);
-        }
-
-        @Override
-        public long size() throws IOException {
-            HttpURLConnection c = head();
-            if(2 != (c.getResponseCode() / 100)) {
-                throw new IOException(c.getResponseMessage());
-            }
-            return c.getContentLengthLong();
-        }
-
-        @Override
-        public InputStream istream() throws IOException {
-            return get.get().getInputStream();
-        }
-
-        @Override
-        public InputStream istream(long begin, long end) throws IOException {
-            HttpURLConnection c = get.get();
-            c.setRequestProperty("Range", "bytes=" + begin + "-" + (end));
-            if (c.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) {
-                return IOStreams.limit(c.getInputStream(), begin, end);
-            } else {
-                return c.getInputStream();
-            }
-        }
-
-        @Override
-        public OutputStream ostream() throws IOException {
-            HttpURLConnection c = post.get();
-            c.connect();
-            return c.getOutputStream();
-        }
-
-        @Override
-        public void create() throws IOException {
-            execute("PUT");
-        }
-
-        @Override
-        public void delete() throws IOException {
-            execute("DELETE");
-        }
-        
-        private HttpURLConnection head() throws IOException {
-            return get.opened() ? get.get() : head.get();
-        }
-        
-        private void execute(String method) throws IOException {
-            HttpURLConnection c = connect(method);
-            boolean success = isSuccess(c);
-            c.disconnect();
-            if(!success) {
-                throw new IOException(c.getResponseCode() + ": " + c.getResponseMessage());
-            }
-        }
-        
-        private HttpURLConnection connect(String method) throws IOException {
-            HttpURLConnection c = (HttpURLConnection)uri.toURL().openConnection();
-            c.setRequestMethod(method);
-            return c;
-        }
-        
-    }
-    
-    private static boolean isSuccess(HttpURLConnection c) throws IOException {
-        return 2 == (c.getResponseCode() / 100);
-    }
-    
-    private static Charset getContentCharset(String type) throws IOException {
-        if(null == type) {
-            throw new IOException("Unknown MIME type");
-        }
-        if(!type.startsWith("text/")) {
-            throw new IOException("Unsupported MIME type: " + type);
-        }
-        Matcher hit = RE_CHARSET.matcher(type);
-        if(!hit.find()) {
-            return Charsets.UTF8;
-        }
-        return Charset.forName(hit.group(1));
-    }
-}
+/*
+ * @author Ranides Atterwim <ranides@gmail.com>
+ * @copyright Ranides Atterwim
+ * @license WTFPL
+ * @url http://ranides.net/projects/assira
+ */
+package net.ranides.assira.io.uri.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.nio.charset.Charset;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Date;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.bind.DatatypeConverter;
+import net.ranides.assira.collection.maps.GenericMap;
+import net.ranides.assira.collection.query.CQuery;
+import net.ranides.assira.credentials.UserProperty;
+import net.ranides.assira.io.IOHandle;
+import net.ranides.assira.io.IOStreams;
+import net.ranides.assira.io.uri.URITime;
+import net.ranides.assira.io.uri.URIFlags;
+import net.ranides.assira.io.uri.URIHandle;
+import net.ranides.assira.io.uri.URIHandler;
+import net.ranides.assira.io.uri.URIResolver;
+import net.ranides.assira.text.Charsets;
+import net.ranides.assira.text.StringTraits;
+import net.ranides.assira.trace.LoggerUtils;
+import org.slf4j.Logger;
+
+/**
+ *
+ * @author Ranides Atterwim <ranides@gmail.com>
+ */
+public class CHTHandler implements URIHandler {
+    
+    private static final Logger LOGGER = LoggerUtils.getLogger();
+    
+    private static final Pattern RE_CHARSET = Pattern.compile(";[ ]*charset=([^; ]+)");
+
+    private final URIResolver resolver;
+    
+    public CHTHandler() {
+        this.resolver = URIResolver.DEFAULT;
+    }
+
+    public CHTHandler(URIResolver resolver) {
+        this.resolver = resolver;
+    }
+    
+    @Override
+    public URIHandle resolve(URI uri) throws IOException {
+        return new CHttpHandle(uri);
+    }
+
+    @Override
+    public Collection<String> schemes() {
+        return Arrays.asList("http","https");
+    }
+    
+    private class CHttpHandle extends CHandle {
+        
+        private final URI uri;
+        private final IOHandle<HttpURLConnection> head;
+        private final IOHandle<HttpURLConnection> get;
+        private final IOHandle<HttpURLConnection> post;
+
+        public CHttpHandle(URI uri) throws MalformedURLException {
+            this.uri = uri;
+            head = new IOHandle<>(() -> connect("HEAD"));
+            get = new IOHandle<>(() -> connect("GET"));
+            post = new IOHandle<>(() -> connect("POST"));
+        }
+
+        @Override
+        public URIResolver resolver() {
+            return resolver;
+        }
+        
+        @Override
+        public URI uri() throws IOException {
+            return uri;
+        }
+        
+        @Override
+        public Charset charset() throws IOException {
+            return getContentCharset(head().getContentType());
+        }
+
+        @Override
+        public Set<URIFlags> flags() throws IOException {
+            Set<URIFlags> re = URIFlags.collect(URIFlags.FILE);
+            try {
+                HttpURLConnection c = head();
+                if(isSuccess(c)) {
+                    re.add(URIFlags.EXISTS);
+                    re.add(URIFlags.READABLE);
+                }
+
+                if(StringTraits.starts(c.getContentType(), "text/")) {
+                    re.add(URIFlags.TEXT);
+                } else {
+                    re.add(URIFlags.BINARY);
+                }
+                if(c.getContentLengthLong() >= 0) {
+                    re.add(URIFlags.SIZE);
+                }
+                if(StringTraits.contains(c.getHeaderField("Accept-Ranges"), "bytes")) {
+                    re.add(URIFlags.SEEK);
+                }
+            } catch(IOException cause) {
+                LOGGER.warn("URI.flags: HTTP error", cause);
+            }
+            return re;
+        }
+
+        @Override
+        public Instant time(URITime ut) throws IOException {
+            if(ut == URITime.MODIFIED) {
+                HttpURLConnection c = head();
+                if(null == c.getHeaderField("Last-Modified")) {
+                    return Instant.ofEpochMilli(c.getDate());
+                }
+                return new Date(c.getHeaderFieldDate("Last-Modified", 0)).toInstant();
+            }
+            return super.time(ut);
+        }
+
+        @Override
+        public long size() throws IOException {
+            HttpURLConnection c = head();
+            if(2 != (c.getResponseCode() / 100)) {
+                throw new IOException(c.getResponseMessage());
+            }
+            return c.getContentLengthLong();
+        }
+
+        @Override
+        public InputStream istream() throws IOException {
+            return get.get().getInputStream();
+        }
+
+        @Override
+        public InputStream istream(long begin, long end) throws IOException {
+            HttpURLConnection c = get.get();
+            if(end == Long.MAX_VALUE) {
+                c.setRequestProperty("Range", "bytes=" + begin + "-");
+            } else {
+                c.setRequestProperty("Range", "bytes=" + begin + "-" + end);
+            }
+            if (c.getResponseCode() != HttpURLConnection.HTTP_PARTIAL) {
+                return IOStreams.limit(c.getInputStream(), begin, end);
+            } else {
+                return c.getInputStream();
+            }
+        }
+
+        @Override
+        public OutputStream ostream() throws IOException {
+            HttpURLConnection c = post.get();
+            c.connect();
+            return c.getOutputStream();
+        }
+
+        @Override
+        public void create() throws IOException {
+            execute("PUT");
+        }
+
+        @Override
+        public void delete() throws IOException {
+            execute("DELETE");
+        }
+        
+        private HttpURLConnection head() throws IOException {
+            return get.opened() ? get.get() : head.get();
+        }
+        
+        private void execute(String method) throws IOException {
+            HttpURLConnection c = connect(method);
+            boolean success = isSuccess(c);
+            c.disconnect();
+            if(!success) {
+                throw new IOException(c.getResponseCode() + ": " + c.getResponseMessage());
+            }
+        }
+        
+        private HttpURLConnection connect(String method) throws IOException {
+            HttpURLConnection c = (HttpURLConnection)uri.toURL().openConnection();
+            c.setRequestMethod(method);
+            
+            CQuery<GenericMap<String>> ui = resolver.users().match(uri);
+            if(!ui.isEmpty()) {
+                setAuthorizationHeader(c, ui.first());
+            }
+            return c;
+        }
+
+    }
+    
+    private static boolean isSuccess(HttpURLConnection c) throws IOException {
+        return 2 == (c.getResponseCode() / 100);
+    }
+    
+    private static Charset getContentCharset(String type) throws IOException {
+        if(null == type) {
+            throw new IOException("Unknown MIME type");
+        }
+        if(!type.startsWith("text/")) {
+            throw new IOException("Unsupported MIME type: " + type);
+        }
+        Matcher hit = RE_CHARSET.matcher(type);
+        if(!hit.find()) {
+            return Charsets.UTF8;
+        }
+        return Charset.forName(hit.group(1));
+    }
+    
+    private static void setAuthorizationHeader(HttpURLConnection connection, GenericMap<String> user) {
+        String passphrase = user.get(UserProperty.LOGIN) + ":" + user.get(UserProperty.PASSWORD);
+        String header = "Basic " + DatatypeConverter.printBase64Binary(passphrase.getBytes());
+        connection.setRequestProperty("Authorization", header);
+    }
+}

+ 2 - 2
assira/src/test/java/net/ranides/assira/io/uri/impl/CHTTPHandlerTest.java

@@ -28,7 +28,7 @@ import org.junit.Test;
  *
  * @author Ranides Atterwim <ranides@gmail.com>
  */
-public class CHTTPHandlerTest {
+public class CHTHandlerTest {
 
     @Test
     public void testDynamicList() throws IOException, URISyntaxException {
@@ -115,7 +115,7 @@ public class CHTTPHandlerTest {
     }
 
     private static URIHandle resolve(URI uri) throws IOException {
-        return new CHTTPHandler().resolve(uri);
+        return new CHTHandler().resolve(uri);
     }
     
     @Test

+ 0 - 175
assira/src/test/java/net/ranides/assira/io/uri/impl/CHttpHandlerTest.java

@@ -1,175 +0,0 @@
-/*
- * @author Ranides Atterwim <ranides@gmail.com>
- * @copyright Ranides Atterwim
- * @license WTFPL
- * @url http://ranides.net/projects/assira
- */
-package net.ranides.assira.io.uri.impl;
-
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.time.Duration;
-import java.time.Instant;
-import java.util.Arrays;
-import net.ranides.assira.io.uri.URIFlags;
-import static net.ranides.assira.io.uri.URIFlags.*;
-import net.ranides.assira.io.uri.URIHandle;
-import net.ranides.assira.io.uri.URIResolver;
-import net.ranides.assira.io.uri.URITime;
-import static net.ranides.assira.junit.NewAssert.*;
-import net.ranides.assira.text.Charsets;
-import net.ranides.assira.text.IOStrings;
-import org.junit.Test;
-
-/**
- *
- * @author Ranides Atterwim <ranides@gmail.com>
- */
-public class CHttpHandlerTest {
-
-    @Test
-    public void testDynamicList() throws IOException, URISyntaxException {
-        
-        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/");
-        URIHandle handle1 = resolve(uri);
-        
-        assertEquals(uri, handle1.uri());
-        assertEquals(Charsets.UTF8, handle1.charset());
-        assertEquals(true, handle1.exists());
-        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, TEXT), handle1.flags());
-        assertEquals("HTML PUBLIC \"-//W3C//DTD HTML 3", IOStrings.read(handle1.istream(10,40), handle1.charset()));
-        
-        URIHandle handle2 = resolve(uri);
-        assertEquals(1231, IOStrings.read(handle2.reader()).length());
-        assertEquals(Instant.now(), handle2.time(URITime.MODIFIED), Duration.ofMinutes(60));
-        assertEquals(1231, handle2.size());
-        
-        URIHandle handle3 = resolve(uri);
-        assertEquals(-1, handle3.size());
-
-    }
-    
-    @Test
-    public void testStaticText() throws IOException, URISyntaxException {
-        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.pom");
-        URIHandle handle1 = resolve(uri);
-
-        assertEquals(uri, handle1.uri());
-        assertEquals(Charsets.UTF8, handle1.charset());
-        assertEquals(true, handle1.exists());
-        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, TEXT, SIZE, SEEK), handle1.flags());
-        assertEquals("mlns=\"", IOStrings.read(handle1.istream(10,15), handle1.charset()));
-        assertThrows(IOException.class, ()->{
-            IOStrings.read(handle1.reader());
-        });
-        
-        URIHandle handle2 = resolve(uri);
-        assertEquals(6964, IOStrings.read(handle2.reader()).length());
-        assertEquals(Instant.parse("2013-03-08T01:58:31Z"), handle2.time(URITime.MODIFIED));
-        assertThrows(IOException.class, ()->{
-            handle2.time(URITime.ACCESSED);
-        });
-        assertEquals(6964, handle2.size());
-    }
-    
-    @Test
-    public void testNotFound() throws IOException, URISyntaxException {
-        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.po");
-        URIHandle handle = resolve(uri);
-        
-        assertEquals(uri, handle.uri());
-        assertEquals(Charsets.UTF8, handle.charset());
-        assertEquals(false, handle.exists());
-        assertEquals(URIFlags.constant(FILE, TEXT, SIZE), handle.flags());
-        assertEquals(Instant.now(), handle.time(URITime.MODIFIED), Duration.ofMinutes(60));
-        
-        assertThrows(IOException.class, ()->{
-            handle.size();
-        });
-        
-        assertThrows(FileNotFoundException.class, ()->{
-            IOStrings.read(handle.istream(10,15), handle.charset());
-        });
-        
-        assertThrows(FileNotFoundException.class, ()->{
-            IOStrings.read(handle.reader());
-        });
-    }
-    
-    @Test
-    public void testDynamicPage() throws IOException, URISyntaxException {
-        URI uri = new URI("http://info.ranides.net/");
-        URIHandle handle1 = resolve(uri);
-        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, TEXT), handle1.flags());
-        assertEquals("/DTD XHTML 1.0 Trans", IOStrings.read(handle1.istream(30, 50), Charsets.UTF8));
-        assertEquals(-1, handle1.size());
-        
-        URIHandle handle2 = resolve(uri);
-        assertTrue(IOStrings.read(handle2.reader()).contains("This program is free software;"));
-        assertEquals(-1, handle2.size());
-        
-        assertTrue(IOStrings.read(resolve(uri).reader(Charsets.UTF8)).contains("This program is free software;"));
-    }
-
-    private static URIHandle resolve(URI uri) throws IOException {
-        return new CHTTPHandler().resolve(uri);
-    }
-    
-    @Test
-    public void testBinary() throws IOException, URISyntaxException {   
-        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1");
-        URIHandle handle1 = resolve(uri);
-        
-        assertEquals(uri, handle1.uri());
-        assertThrows(IOException.class, ()->{
-            handle1.charset();
-        });
-        assertThrows(IOException.class, ()->{
-            handle1.reader();
-        });
-        assertEquals(true, handle1.exists());
-        assertEquals(URIFlags.constant(READABLE, EXISTS, FILE, BINARY, SIZE, SEEK), handle1.flags());
-        assertEquals(Instant.parse("2013-03-08T01:58:30Z"), handle1.time(URITime.MODIFIED));
-        assertEquals(40, handle1.size());
-        
-        URIHandle handle2 = resolve(uri);
-        assertEquals("61b37c0973bc00bd33606a2f5050e64baec3a7df", IOStrings.read(handle2.istream(), Charsets.US_ASCII));
-        
-        URIHandle handle3 = resolve(uri);
-        assertEquals("61b37c0973bc00bd33606a2f5050e64baec3a7df", IOStrings.read(handle3.reader(Charsets.US_ASCII)));
-    }
-    
-    @Test
-    public void testError() throws IOException, URISyntaxException { 
-        URIHandle handle1 = resolve(new URI("http://m.maven.ranides.net/"));
-        assertEquals(URIFlags.constant(FILE), handle1.flags());
-        
-        URIHandle handle2 = resolve(new URI("http://no.domain/"));
-        assertEquals(URIFlags.constant(FILE), handle2.flags());
-    }
-    
-    @Test
-    public void testCopy() throws IOException, URISyntaxException {
-        URI uri = new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1");
-        URIHandle input = resolve(uri);
-        File file = File.createTempFile("CHttpHandler", ".test");
-        file.deleteOnExit();
-        URIHandle target = new URIResolver(Arrays.asList(new CFileHandler())).resolve(file);
-        
-        input.copy(target);
-        assertEquals("61b37c0973bc00bd33606a2f5050e64baec3a7df",IOStrings.read(file, Charsets.UTF8));
-    }
-    
-    @Test
-    public void testMove() throws IOException, URISyntaxException {
-        URIHandle src = resolve(new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1"));
-        URIHandle dst = resolve(new URI("http://maven.ranides.net/net/ranides/assira/0.58/assira-0.58.jar.sha1m"));
-        assertThrows(IOException.class, ()->{
-            src.move(dst);
-        });
-    }
-    
-}