Skip to content

Commit

Permalink
Import DataURLStreamHandler from bndtools project and restore headers
Browse files Browse the repository at this point in the history
  • Loading branch information
laeubi committed Jan 4, 2024
1 parent 11e9f23 commit 5c700f5
Showing 1 changed file with 126 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
/*******************************************************************************
* Copyright (c) 2015, 2019 bndtools project and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Neil Bartlett <[email protected]> - initial API and implementation
* BJ Hargrave <[email protected]> - ongoing enhancements
*******************************************************************************/
package bndtools;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLDecoder;
import java.util.StringTokenizer;

import org.osgi.service.url.AbstractURLStreamHandlerService;

import aQute.lib.base64.Base64;

/**
* Basic implementation of IETF RFC 2397, the "data" URL scheme
* (http://tools.ietf.org/html/rfc2397).
*/
public class DataURLStreamHandler extends AbstractURLStreamHandlerService {

public final static String PROTOCOL = "data";

@Override
public URLConnection openConnection(URL u) throws IOException {
if (!PROTOCOL.equals(u.getProtocol()))
throw new MalformedURLException("Unsupported protocol");
return new DataURLConnection(u);
}

static class ParseResult {
String mediaType = "text/plain";
String charset = "US-ASCII";
byte[] data;
}

static final class DataURLConnection extends URLConnection {

private ParseResult parsed = null;

DataURLConnection(URL url) {
super(url);
}

@Override
public void connect() throws IOException {
parsed = parse(url.getPath());
}

static ParseResult parse(String ssp) throws IOException {
int commaIndex = ssp.indexOf(',');
if (commaIndex < 0)
throw new MalformedURLException("missing comma");

String paramSegment = ssp.substring(0, commaIndex);
String dataSegment = ssp.substring(commaIndex + 1);

String mediaType = null;
boolean base64 = false;
String charset = "US-ASCII";

StringTokenizer tokenizer = new StringTokenizer(paramSegment, ";");
boolean first = true;
while (tokenizer.hasMoreTokens()) {
String token = tokenizer.nextToken();
if (first)
mediaType = token;
else if ("base64".equals(token))
base64 = true;
else if (token.startsWith("charset="))
charset = token.substring("charset=".length());
first = false;
}

byte[] bytes;
if (base64) {
bytes = Base64.decodeBase64(dataSegment);
} else {
String decoded = URLDecoder.decode(dataSegment, charset);
bytes = decoded.getBytes("UTF-8");
}

ParseResult parsed = new ParseResult();
parsed.data = bytes;
if (mediaType != null && !mediaType.isEmpty())
parsed.mediaType = mediaType;
if (charset != null && !charset.isEmpty())
parsed.charset = charset;
return parsed;
}

@Override
public InputStream getInputStream() throws IOException {
if (parsed == null)
connect();

return new ByteArrayInputStream(parsed.data);
}

@Override
public String getContentType() {
return parsed != null ? parsed.mediaType : null;
}

@Override
public String getContentEncoding() {
return parsed != null ? parsed.charset : null;
}

}

}

0 comments on commit 5c700f5

Please sign in to comment.