Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Support for POST and binary data through flex. Silverlight not workin…

…g yet
  • Loading branch information...
commit 4208f536458d71d9cdcd053394b8e019ea5df1f1 1 parent e26a877
Erlend Oftedal authored
View
129 flex/malariaproxy.mxml
@@ -3,64 +3,87 @@
xmlns="*" creationComplete="useHttpService()">
<mx:Script>
<![CDATA[
- import mx.controls.Alert;
- import mx.rpc.http.HTTPService;
- import mx.rpc.events.ResultEvent;
- import mx.rpc.events.FaultEvent;
- import flash.external.*;
- private var socket:Socket;
+ import mx.controls.Alert;
+ import mx.rpc.http.HTTPService;
+ import mx.rpc.events.ResultEvent;
+ import mx.rpc.events.FaultEvent;
+ import flash.events.Event;
+ import flash.events.EventDispatcher;
+ import flash.net.URLLoader;
+ import flash.net.URLLoaderDataFormat;
+ import flash.net.URLRequest;
+ import flash.utils.ByteArray;
+ import flash.external.*;
+ private var socket:Socket;
- public function useHttpService():void {
- socket = new Socket();
- ExternalInterface.call("log", "Connecting back to malaria server...");
- socket.addEventListener(Event.CONNECT, this.connectHandler);
- socket.addEventListener(ProgressEvent.SOCKET_DATA, this.onData);
- socket.connect("localhost", 8081);
- }
- private function onData(event:ProgressEvent):void
- {
- ExternalInterface.call("log", "Got data from proxy");
- var data:String = socket.readUTFBytes(socket.bytesAvailable);
- var url:String = getValue(/.* (.*) .*/, data);
- handle(url);
- }
+ public function useHttpService():void {
+ socket = new Socket();
+ ExternalInterface.call("log", "Connecting back to malaria server...");
+ socket.addEventListener(Event.CONNECT, this.connectHandler);
+ socket.addEventListener(ProgressEvent.SOCKET_DATA, this.onData);
+ socket.connect("localhost", 8081);
+ }
+ private function onData(event:ProgressEvent):void
+ {
+ ExternalInterface.call("log", "Got data from proxy");
+ var data:String = socket.readUTFBytes(socket.bytesAvailable);
+ handle(data);
+ }
- public function connectHandler(event:Event):void
- {
- ExternalInterface.call("log", "Connected and ready");
- socket.writeUTFBytes("Hello");
- socket.flush();
- }
+ public function connectHandler(event:Event):void
+ {
+ ExternalInterface.call("log", "Connected and ready");
+ socket.writeUTFBytes("Hello");
+ socket.flush();
+ }
- public function handle(url:String):void {
- ExternalInterface.call("log", "Trying: [" + url + "]");
- var service:HTTPService = new HTTPService();
- service.url = url;
- service.resultFormat = "text";
- service.addEventListener("result", this.httpResult);
- service.addEventListener("fault", this.httpFault);
- service.send();
- }
+ public function handle(data:String):void {
+ var regresult:Object = /([^ ]+) ([^ ]+) ([^ ]+)( (.*))?/.exec(data);
+ var verb:String = regresult[1];
+ var url:String = regresult[2];
+ var accept:String = regresult[3];
+ var reqData:String = regresult[5];
+ ExternalInterface.call("log", "Trying: [" + verb + " " + url + " " + accept + " " + (verb == "POST" ? " " + reqData : "") + "]");
+ var urlRequest:URLRequest = new URLRequest(url);
+ urlRequest.method = (verb == "POST") ? URLRequestMethod.POST : URLRequestMethod.GET;
+ if (reqData != null && reqData != "") {
+ urlRequest.data = new URLVariables(reqData);
+ }
+ urlRequest.requestHeaders.push(new URLRequestHeader("Accept", accept));
+ var loader:URLLoader = new URLLoader();
+ loader.dataFormat = URLLoaderDataFormat.BINARY;
+ loader.addEventListener(Event.COMPLETE, onComplete);
+ loader.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
+ loader.load(urlRequest);
+ ExternalInterface.call("log", "Sent");
+ }
+ public function toNameValuePairs(reqData:String):Object {
+ var parts:Object = reqData.split("&");
+ var result:Object = {};
+ for(var i:String in parts) {
+ var pparts:Object = i.split("=", 2);
+ result[pparts[0]] = (pparts.length == 2 ? pparts[1] : "");
+ }
+ return result;
+ }
+
+ public function onComplete(event:Event):void {
+ socket.writeUTFBytes(event.target.bytesTotal + ":");
+ socket.writeBytes(event.target.data);
+ socket.flush();
+ ExternalInterface.call("log", "Sending back data - length " + event.target.bytesTotal + " (" + event.target.data.length + ")");
+ }
- public function httpResult(event:ResultEvent):void {
- var result:String = event.result.toString();
- socket.writeUTFBytes(result.length + ":" + result);
- socket.flush();
- ExternalInterface.call("log", "Sending back data - length " + result.length);
- }
+
+ public function onIOError(event:IOErrorEvent):void {
+ ExternalInterface.call("log", "Fault");
+ var faultstring:String = event.text;
+ ExternalInterface.call("log", "FAULT:" + faultstring);
+ socket.writeUTFBytes("HTTP/1.1 502 Not accessible - " + event.text);
+ socket.flush();
+ ExternalInterface.call("log", "Sending back 502");
+ }
- public function httpFault(event:FaultEvent):void {
- var faultstring:String = event.fault.faultString;
- ExternalInterface.call("log", "FAULT:" + faultstring);
- socket.writeUTFBytes("HTTP/1.1 502 Not accessible");
- socket.flush();
- ExternalInterface.call("log", "Sending back 502");
- }
-
- public function getValue(pattern:RegExp, result:String):String {
- var regresult:Object = pattern.exec(result);
- return regresult[1];
- }
]]>
</mx:Script>
View
3  proxy-backend/malaria/FlexPolicyServer.java
@@ -9,10 +9,11 @@ public FlexPolicyServer(String hostname, int port) {
super(hostname, port, 843, "Flex policy server");
}
-
+ @Override
protected void printPolicy(PrintStream clientOut) {
printFlexPolicy(clientOut, hostname, port);
}
+
public static void printFlexPolicy(PrintStream clientOut, String hostname, int port) {
clientOut.print("<?xml version=\"1.0\"?>\n");
clientOut.print("<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">");
View
91 proxy-backend/malaria/MalariaServer.java
@@ -1,10 +1,13 @@
package malaria;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
+import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -24,12 +27,8 @@ public static void main(String[] args) {
private MalariaServer(String hostname, int port) {
System.out.println(">> Starting MalariaServer");
try {
- SilverlightPolicyServer slServer = new SilverlightPolicyServer(hostname, port);
- FlexPolicyServer flexServer = new FlexPolicyServer(hostname, port);
- Thread slThread = new Thread(slServer);
- Thread flexThread = new Thread(flexServer);
- slThread.start();
- flexThread.start();
+ new Thread(new SilverlightPolicyServer(hostname, port)).start();
+ new Thread(new FlexPolicyServer(hostname, port)).start();
ServerSocket clientSocket = new ServerSocket(port);
ServerSocket proxySocket = new ServerSocket(8080);
@@ -43,10 +42,10 @@ private MalariaServer(String hostname, int port) {
public void serveSocket(Socket client, ServerSocket proxySocket, String hostname, int port) {
try {
- InputStreamReader clientIn = new InputStreamReader(client.getInputStream(), "UTF8");
PrintStream clientOut = new PrintStream(client.getOutputStream());
+ InputStream clientIn = client.getInputStream();
System.out.println("Client connected");
- String message = readMessage(clientIn);
+ String message = readMessage(new InputStreamReader(clientIn, "UTF8"));
System.out.println("<- " + message);
if (message.indexOf(PolicyServer.policyRequest) > -1) { //Flex will do this if it cannot connect to port 843
FlexPolicyServer.printFlexPolicy(clientOut, hostname, port);
@@ -59,59 +58,55 @@ public void serveSocket(Socket client, ServerSocket proxySocket, String hostname
while (true) {
Socket proxyClient = proxySocket.accept();
InputStreamReader proxyIn = new InputStreamReader(proxyClient.getInputStream());
- PrintStream proxyOut = new PrintStream(proxyClient.getOutputStream());
-
-
+ OutputStream proxyOut = proxyClient.getOutputStream();
String proxyMessage = readMessage(proxyIn);
- Pattern hostAndAccept = Pattern.compile("(GET|POST) ([^ ]+)(.|[\\s])+Accept: ([\\S]+)(.|[\\s])+");
- Matcher m = hostAndAccept.matcher(proxyMessage);
- if (m.matches()) {
- if (isBinaryData(m)) {
- proxyOut.print("HTTP/1.1 500 OK\n");
- proxyOut.flush();
- proxyClient.close();
- System.out.println("Binary data currently not supported");
- continue;
- }
- clientOut.print(m.group(1) + " " + m.group(2) + " " + m.group(4) + "\n");
+ String[] parts = parseRequest(proxyMessage);
+ String clientRequest = buildClientRequest(parts);
+ if (clientRequest != null) {
+ clientOut.print(clientRequest + "\n");
clientOut.flush();
- System.out.println("-> " + m.group(1) + " " + m.group(2) + " " + m.group(4));
+ System.out.println("-> " + clientRequest);
boolean done = false;
- StringBuffer sbuffer = new StringBuffer();
int dl = -1;
int read = 0;
System.out.println("Ready to read...");
+ ArrayList<byte[]> fullBuffer = new ArrayList<byte[]>();
while (!done) {
- char[] buffer = new char[4096];
+ byte[] buffer = new byte[4096];
int length = clientIn.read(buffer, 0, buffer.length);
- sbuffer.append(buffer, 0, length);
- if (sbuffer.toString().equals("HTTP/1.1 502 Not accessible")) {
- proxyOut.print(sbuffer.toString());
+ if (new String(buffer, "UTF8").equals("HTTP/1.1 502 Not accessible")) {
+ proxyOut.write(buffer, 0, length);
proxyOut.flush();
proxyClient.close();
System.out.println("Not accessible");
continue;
}
if (dl == -1) {
- String fl = sbuffer.toString().split(":", 2)[0];
+ String fl = new String(buffer, "UTF8").toString().split(":", 2)[0];
dl = Integer.parseInt(fl);
System.out.println("DL: " + dl);
read -= fl.length() + 1;
+ byte[] bytes = new byte[buffer.length - fl.length() - 1];
+ for(int i = fl.length() + 1; i < buffer.length; i++) {
+ bytes[i - fl.length() - 1] = buffer[i];
+ }
+ fullBuffer.add(bytes);
+ } else {
+ fullBuffer.add(buffer);
}
read += length;
System.out.println("<- Read " + length + ":" + read + "/" + dl);
if (read >= dl)
done = true;
}
- String res = sbuffer.toString();
- res = res.split(":", 2)[1];
- proxyOut.print("HTTP/1.1 200 OK\n");
- proxyOut.print("\n");
- proxyOut.print(res);
+ proxyOut.write("HTTP/1.1 200 OK\r\n\r\n".getBytes("UTF8"));
+ for (int i = 0; i < fullBuffer.size(); i++) {
+ proxyOut.write(fullBuffer.get(i));
+ }
proxyOut.flush();
} else {
System.out.println("No match");
- proxyOut.print("HTTP/1.1 500 OK\n");
+ proxyOut.write("HTTP/1.1 500 OK\n".getBytes("UTF8"));
proxyOut.flush();
}
proxyClient.close();
@@ -122,9 +117,29 @@ public void serveSocket(Socket client, ServerSocket proxySocket, String hostname
}
}
-
- private boolean isBinaryData(Matcher m) {
- return m.group(2).matches(".*\\.(png|jpg|jpeg|gif|ico)");
+ private String[] parseRequest(String proxyMessage) {
+ ArrayList<String> parts = new ArrayList<String>();
+ Pattern hostAndAccept = Pattern.compile("(GET|POST) ([^ ]+)(.|[\\s])+Accept: ([\\S]+)(.|[\\s])+");
+ Matcher m = hostAndAccept.matcher(proxyMessage);
+ if (!m.matches()) {
+ return null;
+ }
+ parts.add(m.group(1));
+ parts.add(m.group(2));
+ parts.add(m.group(4));
+ String[] headersAndData = proxyMessage.split("\r\n\r\n", 2);
+ if (headersAndData.length > 1) {
+ parts.add(headersAndData[1]);
+ }
+ return parts.toArray(new String[parts.size()]);
+ }
+ private String buildClientRequest(String[] parts) {
+ if (parts == null) return null;
+ String message = parts[0];
+ for(int i = 1; i < parts.length; i++) {
+ message += " " + parts[i];
+ }
+ return message;
}
private String readMessage(InputStreamReader clientReader) throws IOException {
View
5 proxy-backend/malaria/SilverlightPolicyServer.java
@@ -8,10 +8,7 @@ public SilverlightPolicyServer(String hostname, int port) {
super(hostname, port, 943, "Silverlight policy server");
}
- protected int getListenerPort() {
- return 943;
- }
-
+ @Override
protected void printPolicy(PrintStream clientOut) {
clientOut.print("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
clientOut.print("<access-policy>");
View
77 silverlight/SilverlightMalaRIA/MainPage.xaml.cs
@@ -1,4 +1,6 @@
using System;
+using System.Collections.Generic;
+using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Text;
@@ -42,7 +44,7 @@ public void OnConnected(object o, SocketAsyncEventArgs args)
if (_socket.Connected)
{
Log("Connected and ready");
- Send("Silverlight hello", true);
+ Send("Silverlight hello", null, true);
}
else
{
@@ -60,14 +62,27 @@ public void HandleIncomingTraffic()
public void OnReceive(object o, SocketAsyncEventArgs e)
{
string message = Encoding.UTF8.GetString(e.Buffer, 0, e.BytesTransferred);
- Regex msgRex = new Regex("([^ ]+) ([^ ]+) ([^ ]+)");
+ Regex msgRex = new Regex("([^ ]+) ([^ ]+) ([^ ]+)( (.*))?");
Match match = msgRex.Match(message);
if (match.Success)
{
- Log("Trying: [" + match.Groups[2].Value + "]");
- WebClient client = new WebClient();
- client.DownloadStringCompleted += DataDownloaded;
- client.DownloadStringAsync(new Uri(match.Groups[2].Value));
+ try
+ {
+ Log("Trying: [" + match.Groups[2].Value + "]");
+ var request = WebRequest.Create(new Uri(match.Groups[2].Value)) as HttpWebRequest;
+ request.Method = match.Groups[1].Value;
+ request.Accept = match.Groups[3].Value;
+ var context = new Context {Request = request};
+ if (request.Method == "POST")
+ {
+ context.Data = match.Groups[5].Value;
+ }
+ request.BeginGetRequestStream(GetRequestStreamCallback, context);
+ }
+ catch(Exception ex)
+ {
+ Log("Fack 2");
+ }
}
else
{
@@ -75,11 +90,44 @@ public void OnReceive(object o, SocketAsyncEventArgs e)
HandleIncomingTraffic();
}
}
+ public class Context
+ {
+ public HttpWebRequest Request;
+ public string Data;
+ }
+
+ private void GetRequestStreamCallback(IAsyncResult asynchronousResult)
+ {
+ var context = (Context)asynchronousResult.AsyncState;
+ var request = context.Request;
+ Stream postStream = request.EndGetRequestStream(asynchronousResult);
+
+ if (context.Data != null)
+ {
+ byte[] byteArray = Encoding.UTF8.GetBytes(context.Data);
+
+ postStream.Write(byteArray, 0, byteArray.Length);
+ }
+ postStream.Close();
+ request.BeginGetResponse(GetResponseCallback, request);
+ }
- private void DataDownloaded(object sender, DownloadStringCompletedEventArgs e)
+ private void GetResponseCallback(IAsyncResult asynchronousResult)
{
- string data = e.Result;
- Send(data.Length + ":" + data, false);
+ var request = (HttpWebRequest)asynchronousResult.AsyncState;
+ var response = (HttpWebResponse)request.EndGetResponse(asynchronousResult);
+ Stream streamResponse = response.GetResponseStream();
+ var fullBuffer = new List<byte>();
+ var buffer = new byte[4096];
+ int length;
+ do
+ {
+ length = streamResponse.Read(buffer, 0, buffer.Length);
+ for (int i = 0; i < length; i++) fullBuffer.Add(buffer[i]);
+ } while (fullBuffer.Count < streamResponse.Length);
+
+ byte[] data = fullBuffer.ToArray();
+ Send(data.Length + ":", data, false);
}
public void OnSend(object o, SocketAsyncEventArgs e)
@@ -87,10 +135,17 @@ public void OnSend(object o, SocketAsyncEventArgs e)
Log("Data sent back: " + e.Buffer.Length);
}
- public void Send(string message, bool skipLog)
+ public void Send(string message, byte[] data, bool skipLog)
{
- Byte[] bytes = Encoding.UTF8.GetBytes(message);
+ Byte[] msgBytes = Encoding.UTF8.GetBytes(message);
var args = new SocketAsyncEventArgs();
+ var fullBuffer = new List<byte>();
+ fullBuffer.AddRange(msgBytes);
+ if (data != null)
+ {
+ fullBuffer.AddRange(data);
+ }
+ byte[] bytes = fullBuffer.ToArray();
args.SetBuffer(bytes, 0, bytes.Length);
if (!skipLog)
{
Please sign in to comment.
Something went wrong with that request. Please try again.