playn.robovm.RoboNet Maven / Gradle / Ivy
/**
* Copyright 2014 The PlayN Authors
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the
* License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing permissions and
* limitations under the License.
*/
package playn.robovm;
import java.io.UnsupportedEncodingException;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.robovm.apple.foundation.NSData;
import org.robovm.apple.foundation.NSError;
import org.robovm.apple.foundation.NSHTTPURLResponse;
import org.robovm.apple.foundation.NSMutableData;
import org.robovm.apple.foundation.NSMutableURLRequest;
import org.robovm.apple.foundation.NSURL;
import org.robovm.apple.foundation.NSURLConnection;
import org.robovm.apple.foundation.NSURLConnectionDataDelegateAdapter;
import org.robovm.apple.foundation.NSURLRequest;
import org.robovm.apple.foundation.NSURLResponse;
import playn.core.Exec;
import playn.core.Net;
import react.RFuture;
import react.RPromise;
public class RoboNet extends Net {
private final Exec exec;
public RoboNet(Exec exec) {
this.exec = exec;
}
@Override public WebSocket createWebSocket(String url, WebSocket.Listener listener) {
return new RoboWebSocket(exec, url, listener);
}
@Override protected RFuture execute(Builder req) {
RPromise result = exec.deferredPromise();
NSMutableURLRequest mreq = new NSMutableURLRequest();
mreq.setURL(new NSURL(req.url));
for (Header header : req.headers) {
mreq.setHTTPHeaderField(header.name, header.value);
}
mreq.setHTTPMethod(req.method());
if (req.isPost()) {
mreq.setHTTPHeaderField("Content-type", req.contentType());
if (req.payloadString != null) {
try {
mreq.setHTTPBody(new NSData(req.payloadString.getBytes("UTF-8")));
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException(uee);
}
} else {
mreq.setHTTPBody(new NSData(req.payloadBytes));
}
}
sendRequest(mreq, result);
return result;
}
protected void sendRequest(NSURLRequest req, final RPromise result) {
new NSURLConnection(req, new NSURLConnectionDataDelegateAdapter() {
private NSMutableData data;
private int rspCode = -1;
private Map headers;
@Override public void didReceiveResponse(NSURLConnection conn, NSURLResponse rsp) {
// if we are redirected, we may accumulate data as we bounce through requests, so we reset
// our data accumulator each time we receive the response headers
data = new NSMutableData();
// note our most recent response code
if (rsp instanceof NSHTTPURLResponse) {
NSHTTPURLResponse hrsp = (NSHTTPURLResponse)rsp;
rspCode = (int)hrsp.getStatusCode();
headers = hrsp.getAllHeaderFields();
}
}
@Override public void didReceiveData(NSURLConnection conn, NSData data) {
this.data.append(data);
}
@Override public void didFail(NSURLConnection conn, NSError error) {
String errmsg = error.getLocalizedDescription();
result.fail(rspCode > 0 ? new HttpException(rspCode, errmsg) : new Exception(errmsg));
}
@Override public void didFinishLoading(NSURLConnection conn) {
result.succeed(new Response(rspCode) {
@Override protected Map> extractHeaders() {
Map> headerMap = new HashMap>();
if (headers != null) {
for (Map.Entry entry : headers.entrySet()) {
// iOS concatenates all repeated headers into a single header separated by commas,
// which is known to be a fucking stupid thing to do, but hey, they're doing it!
headerMap.put(entry.getKey(), Collections.singletonList(entry.getValue()));
}
}
return headerMap;
}
@Override public String payloadString() {
try {
return new String(data.getBytes(), "UTF-8");
} catch (UnsupportedEncodingException uee) {
throw new RuntimeException(uee);
}
}
@Override public byte[] payload() {
return data.getBytes();
}
});
}
}, true);
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy