blob: a543cf9c1f2cbf8d53ee3cafb56c969827897413 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2008 IBM Corporation 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:
* Hisashi MIYASHITA - initial API and implementation
* Kentarou FUKUDA - initial API and implementation
*******************************************************************************/
package org.eclipse.actf.model.flash.bridge.proxy;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.HashMap;
import org.eclipse.actf.util.httpproxy.core.IHTTPHeader;
import org.eclipse.actf.util.httpproxy.core.IHTTPRequestMessage;
import org.eclipse.actf.util.httpproxy.core.IHTTPResponseMessage;
import org.eclipse.actf.util.httpproxy.proxy.IHTTPLocalServer;
import org.eclipse.actf.util.httpproxy.proxy.IHTTPProxyConnection;
import org.eclipse.actf.util.httpproxy.proxy.IHTTPProxyTranscoder;
import org.eclipse.actf.util.httpproxy.proxy.ISecretManager;
import org.eclipse.actf.util.httpproxy.util.HTTPUtil;
import org.eclipse.actf.util.httpproxy.util.Logger;
import org.eclipse.actf.util.httpproxy.util.ParseURI;
import org.eclipse.actf.util.httpproxy.util.TimeoutException;
public class HTTPLocalServerSWF implements IHTTPLocalServer {
private static final boolean LOCAL_FILE_ACCESS = false;
private static final int HTTP_WELL_KNOWN_PORT = 80;
private static final byte[] MIME_TYPE_APPLICATION_XML_A = "application/xml".getBytes();
private static final Logger LOGGER = Logger.getLogger(HTTPLocalServerSWF.class);
static public class MIMEType {
public final String suffix;
public final String type;
public final String subtype;
MIMEType(String suffix, String type, String subtype) {
this.suffix = suffix;
this.type = type;
this.subtype = subtype;
}
}
private static HashMap mimeTypeMap = new HashMap();
public static void addMIMEType(String suffix, String type, String subtype) {
mimeTypeMap.put(suffix, new MIMEType(suffix, type, subtype));
}
public static MIMEType getMIMEType(String suffix) {
return (MIMEType) mimeTypeMap.get(suffix);
}
private static byte[] bridgeInitSwf;
public static void setBridgeInitSwf(InputStream is) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
int b;
try {
while (true) {
b = is.read();
if (b < 0) break;
os.write(b);
}
} catch (IOException e) {
return;
}
bridgeInitSwf = os.toByteArray();
}
private IHTTPResponseMessage processBridgeInitSwf(IHTTPRequestMessage request) {
IHTTPResponseMessage response = HTTPUtil.createHTTPResponseInMemoryMessage(request.getSerial(),
IHTTPHeader.HTTP_VERSION_1_0_A,
"200".getBytes(),
"OK".getBytes(),
bridgeInitSwf);
response.setHeader(IHTTPHeader.CONTENT_TYPE_A,
SWFUtil.MIME_TYPE_APPLICATION_X_SHOCKWAVE_FLASH_A);
return response;
}
private IHTTPResponseMessage processLoadVarsForSwf(IHTTPRequestMessage request, ISecretManager secretManager) {
IHTTPResponseMessage response = HTTPUtil.createHTTPResponseInMemoryMessage(request.getSerial(),
IHTTPHeader.HTTP_VERSION_1_0_A,
"200".getBytes(),
"OK".getBytes(),
secretManager.requestSecret());
response.setHeader(IHTTPHeader.CONTENT_TYPE_A,
SWFUtil.MIME_TYPE_APPLICATION_X_WWW_FORM_URLENCODED_A);
return response;
}
private IHTTPResponseMessage processSwfCrossDomainPolicyFile(IHTTPRequestMessage request) {
//int port = SwfORBFactory.getInstance().getListenPort();
LOGGER.info("Request crossdomain.xml policy file.");
int port = getSwfORBPort();
/*
String contents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<cross-domain-policy><allow-access-from domain=\"*\" to-ports=\""
+ port + "\"/></cross-domain-policy>\n";
*/
String contents = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<cross-domain-policy><allow-access-from domain=\"*\"/></cross-domain-policy>\n";
IHTTPResponseMessage response = HTTPUtil.createHTTPResponseInMemoryMessage(request.getSerial(),
IHTTPHeader.HTTP_VERSION_1_0_A,
"200".getBytes(),
"OK".getBytes(),
contents.getBytes());
response.setHeader(IHTTPHeader.CONTENT_TYPE_A, MIME_TYPE_APPLICATION_XML_A);
return response;
}
private IHTTPResponseMessage processLocalFile(int id,
IHTTPRequestMessage request,
String absPath,
IHTTPProxyTranscoder transcoder) {
try {
absPath = URLDecoder.decode(absPath, "UTF-8");
} catch (UnsupportedEncodingException e) {
}
LOGGER.info("Local Server Mode. Send:" + absPath);
File f = new File(absPath);
if (!f.canRead()) {
return null;
}
int len = (int) f.length();
byte[] contents = new byte[len];
FileInputStream is = null;
try {
is = new FileInputStream(f);
is.read(contents, 0, len);
} catch (Exception e) {
return null;
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
}
}
IHTTPResponseMessage response = HTTPUtil.createHTTPResponseInMemoryMessage(request.getSerial(),
IHTTPHeader.HTTP_VERSION_1_0_A,
"200".getBytes(),
"OK".getBytes(), contents);
int dotPos = absPath.lastIndexOf(".");
if (dotPos > 0) {
int sPos = absPath.lastIndexOf("/");
if (dotPos > sPos) {
String suffix = absPath.substring(dotPos + 1);
MIMEType mt = getMIMEType(suffix);
if (mt != null) {
StringBuffer sb = new StringBuffer();
sb.append(mt.type).append('/').append(mt.subtype);
response.setHeader(IHTTPHeader.CONTENT_TYPE_A, sb.toString().getBytes());
}
}
}
if (transcoder != null) {
response = transcoder.transcode(id, request, response);
}
return response;
}
/* (non-Javadoc)
* @see org.eclipse.actf.util.httpproxy.proxy.IHTTPLocalServer#processRequest(int, org.eclipse.actf.util.httpproxy.proxy.HTTPProxyConnection, org.eclipse.actf.util.httpproxy.core.HTTPRequestMessage, org.eclipse.actf.util.httpproxy.proxy.IHTTPProxyTranscoder)
*/
public boolean processRequest(int id,
IHTTPProxyConnection fClient,
IHTTPRequestMessage request,
IHTTPProxyTranscoder transcoder)
throws InterruptedException, IOException {
if (!IHTTPHeader.METHOD_GET.equals(request.getMethodAsString()))
return false;
String uriStr = request.getRequestURIString();
String authority = ParseURI.getAuthority(uriStr);
String absPath = ParseURI.getAbsolutePath(uriStr);
String hostStr;
String host;
int port;
if (authority != null) {
hostStr = authority;
} else {
IHTTPHeader hostHeader = request.getHeader(IHTTPHeader.HOST_A);
if (hostHeader == null)
return false;
hostStr = new String(hostHeader.getValue());
}
host = ParseURI.parseHost(hostStr);
port = ParseURI.parsePort(hostStr, HTTP_WELL_KNOWN_PORT);
IHTTPResponseMessage response = null;
if (absPath.endsWith(SWFUtil.BRIDGE_INIT_SWF_FILENAME)) {
response = processBridgeInitSwf(request);
} else if (absPath.endsWith(SWFUtil.LOADVARS_PROPERTY_FILENAME)) {
response = processLoadVarsForSwf(request, fClient.getSecretManager());
} else {
if (!("localhost".equals(host)))
return false;
if ((port == HTTP_WELL_KNOWN_PORT) && ("/crossdomain.xml".equals(absPath))) {
response = processSwfCrossDomainPolicyFile(request);
} else if (LOCAL_FILE_ACCESS) {
if (port != fClient.getListenPort())
return false;
response = processLocalFile(id, request, absPath, transcoder);
}
}
if (response == null) {
HTTPUtil.sendFailedToClient(fClient, request);
return true;
}
try {
fClient.sendResponse(0, response);
} catch (TimeoutException e) {
LOGGER.fatal("Timeout in local server mode", e);
}
return true;
}
// TODO!!!!
private int swfORBPort = -1;
public int getSwfORBPort() {
if (swfORBPort < 0)
throw new IllegalStateException("swfORBPort is not set");
return swfORBPort;
}
public void setSwfORBPort(int swfORBPort) {
this.swfORBPort = swfORBPort;
}
public HTTPLocalServerSWF() {
addMIMEType("html", "text", "html");
addMIMEType("htm", "text", "html");
addMIMEType("js", "application", "x-javascript");
addMIMEType("swf", "application", "x-shockwave-flash");
addMIMEType("gif", "image", "gif");
addMIMEType("jpeg", "image", "jpeg");
addMIMEType("jpg", "image", "jpeg");
addMIMEType("png", "image", "png");
}
}