03-10-2011 03:09 PM - edited 03-10-2011 03:10 PM
Hi,
in an OS6 App I run into a problem which costs me some time to find the reason:
HTTP GET or POST fail on BIS_B connections using OS6 Communication API - I didn't found a way to make it run, so falling back to OS5 Network API
here's the story:
a very simple szenario: send something through HTTP to a server and the server sends back a small stream of data. ("text/plain")
so far so good ... you can take a look at the 'Communication API Demo from OS6 samples to see what should be possible using OS6 Communication API
at first I tried it running from Simulator: all works well using Blocking or NonBlockingSenderDestinations.
the tried on a Device:
WIFI: it works the same as on Simulator+MDSCS
TCP Cellular: works the same as on Simulator
BISB: FAILS - doesn't matter if using GET or POST or using Blocking or NonBlocking destinations
same URL entered from Browser: it works well, the text send back from Server was displayed well
stepped thru the code, debugged, added logging statements and finally found what happened:
TransportHeaders of respose message were different.
This is the Transportheader coming back using WIFI, TCP Cellular, Simulator+MDSCS:
|
Content-Type |
text/plain; charset=utf-8 |
|
Content-Length |
19 |
|
Connection |
close |
|
Server |
Jetty(6.1.x) |
was exactly what was expected: plain text of length 19 sent from my OSGI Jetty Server.
Now take a look at the TransportHeaders coming back using BISB on device (9800):
|
connection |
close |
|
server |
Jetty(6.1.x) |
|
content-length |
78 |
|
x-rim-etag |
"B93405A8E587FE3E45F4210D41D1A1218E7DE4C5" |
|
x-rim-bsm-session |
none |
|
x-cache-lookup |
MISS from Blackberry.Internet.Browsing.Service:3128 |
|
via |
1.1 pmds95.bisb4.blackberry:3128 (squid/2.7.STABLE7) |
|
content-type |
application/vnd.rim.html |
|
x-cache |
MISS from Blackberry.Internet.Browsing.Service |
the Server was Jetty and the Connection is closed - thats the same and correct,
but the other TransportHeaders make me think that perhaps this was how the content was transported thru BlackBerry Infratructure, but forgot to convert into what should be delivered to the Client.
I analyzed the byte[] of length 78 and found that inside this array also my 19 Bytes sent from server were found and the Byte before this text was a byte of value '19' - the length of following data. I also found 'text/plain' isnide the array.
could it be that I should set some more Headers at my server side ?
But it couldn't be that wrong because using OS5 Network API it comes correctly through BISB to the Device. the code was similar.
Here's the(simplified) OS6 code for aNonBlockingSenderDestination:
NonBlockingSenderDestination subscribeDestination = null;
ConnectionFactory cf = new ConnectionFactory();
cf.setPreferredTransportTypes(new int[]{
TransportInfo.TRANSPORT_TCP_WIFI,
TransportInfo.TRANSPORT_MDS,
TransportInfo.TRANSPORT_BIS_B,
TransportInfo.TRANSPORT_TCP_CELLULAR,
TransportInfo.TRANSPORT_WAP2
});
BisBOptions biso = new BisBOptions(seekretConnectionType);
cf.setTransportTypeOptions(TransportInfo.TRANSPORT _BIS_B, biso);
Context subscribeContext = new Context("SUBSCRIBE_NON_BLOCKING", cf );
try {
subscribeDestination = (NonBlockingSenderDestination)DestinationFactory
.getSenderDestination(
subscribeContext.getName(),
getPushInitiatorSubscribeURI());
if (subscribeDestination == null) {
MessageListener subscriptionListener = new SubscriptionResponseListener("Subscription");
subscribeDestination = DestinationFactory
.createNonBlockingSenderDestination(
subscribeContext,
getPushInitiatorSubscribeURI(),
subscriptionListener
);
ConnectionDescriptor connectionDescriptor = subscribeContext.getConnectionFactory().getConnect ion(getPushInitiatorSubscribeURL());
HttpMessage httpMessage = (HttpMessage) subscribeDestination.createByteMessage();
httpMessage.setMethod(HttpMessage.POST);
subscribeDestination.send((Message)httpMessage);
and here's the (simplified) OS5 Network API code:
DataBuffer buffer = new DataBuffer( 256, false );
InputStream is = null;
Connection conn = null;
try {
ConnectionFactory cf = new ConnectionFactory();
cf.setPreferredTransportTypes(new int[]{
TransportInfo.TRANSPORT_TCP_WIFI,
TransportInfo.TRANSPORT_MDS,
TransportInfo.TRANSPORT_BIS_B,
TransportInfo.TRANSPORT_TCP_CELLULAR,
TransportInfo.TRANSPORT_WAP2});
BisBOptions biso = new BisBOptions(seekretConnectionType);
cf.setTransportTypeOptions(TransportInfo.TRANSPORT _BIS_B, biso);
ConnectionDescriptor connectionDescriptor = cf.getConnection(getPushInitiatorSubscribeURL());
conn = (HttpConnection) connectionDescriptor.getConnection();
if( conn instanceof HttpConnection ) {
HttpConnection httpConn = (HttpConnection) conn;
((HttpConnection) conn).setRequestMethod(HttpConnection.POST);
OutputStream os = httpConn.openOutputStream();
os.write(("user="+user+";pw="+password).getBytes() );
os.flush();
int responseCode = httpConn.getResponseCode();
is = httpConn.openInputStream();
int length = is.read( buffer.getArray() );
buffer.setLength( length );
String response = new String( buffer.getArray(), buffer.getArrayStart(), buffer.getArrayLength() );
if( responseCode == 200 ) {
return true;
}
}
so it's similar using same values and the server always gets the data correct even from BISB using Communication API - only the response for this transport way gets wrong.
any ideas ?
or should I report an Issue as Bug ?
Solved! Go to Solution.
03-12-2011 09:03 AM
because of null response I created an Issue
https://www.blackberry.com/jira/browse/JAVAAPI-171
04-05-2011 05:53 PM
there's really a bug: if using BISB together with HTTP and OS 6 Communication API, then:
this works for BISB-over-WIFI
but it fails for BISB-over-carrier
bug will be fixed in >6.0
the GOOD NEWS: there's a workaround:
simply add a TransportHeader "User-Agent" with any value to your HTTP Request Message, but the value must NOT begin with the word 'BlackBerry'
then it works always - doesn't matter if transport is over WIFI or Carrier
thx RIM for helping
04-05-2011 06:27 PM
"add a TransportHeader "User-Agent" with any value to your HTTP Request Message,..."
This workaround applies when using BIS-B in all situations. When using http connections directly, do not specify a User-Agent Header containing the text "BlackBerry".
As I understand it, the issue is that the BIS-B gateway assumes it is talking to a Browser and will optimize the data passed based on the Browser it thinks it is talking to.
Naturally in our code, we do NOT want the returned data optimized, we want it as is. As long as we don't supply the BlackBerry User Agent Header, the BIS-B gateway will not try to optimize the returned data.
04-05-2011 06:32 PM
thx Peter for this info...
in my case I had NO "User-Agent" defined and it worked using BISB-WIFI, but not BISB-Carrier if using OS 6 Communication API.
using OS 5 Network API it worked both transport ways
04-05-2011 09:13 PM
Sounds like there is a default User Agent specified in the OS 6.0 communication.
05-12-2011 11:24 AM
Hello Ekke,
I don't know if I should start a new thread or should I just ask you directly since I'm facing perhaps the same probleme as yours.
anyway I'll jsut ask it here and see if you can help me ![]()
actually I'm new to blackberry developement so I guess I'm just missing a simple trick. over the last three weeks I've been devloping a blackberry aplication that retrieves RSSs over a web service and show its contents in some lists and categories... so at this point everything works fine on the simulator ( torch 9800). but when I tested it on a real device it just can't download my xml files. so my problem is in seting up the HTTPconnection over the BIS. when I'm connected via wifi everything works just fine and as expected ..but unfortunatly not with BIS.
Sorry for my poor english and I hope you can help ... I realy don't know how I can fix this.
05-12-2011 01:28 PM
perhaps you can provide some sourcecode ?
05-13-2011 04:07 AM
Thanks for your reply
So here's my code :
HttpConnection conn;
String connectionParameters = "";
if (WLANInfo.getWLANState() == WLANInfo.WLAN_STATE_CONNECTED) {
// Connected to a WiFi access point
connectionParameters = ";interface=wifi";
} else {
int coverageStatus = CoverageInfo.getCoverageStatus();
ServiceRecord record = getWAP2ServiceRecord();
if ((coverageStatus & CoverageInfo.COVERAGE_MDS) == CoverageInfo.COVERAGE_MDS) {
// Have an MDS service book and network coverage
connectionParameters = ";deviceside=false";
}
else
if(record != null && (coverageStatus & 1) == 1) {
// Have network coverage and a WAP 2.0 service book record
connectionParameters = ";deviceside=true;ConnectionUID=" + record.getUid();
}else
if ((coverageStatus & 1) == 1) {
// Have network coverage but no WAP 2.0 service book record
connectionParameters = ";deviceside=true";
}
}
try {
isupdating=true;
conn=(HttpConnection)Connector.open(XML_URL+connec tionParameters);
InputStream dataIn=conn.openInputStream();
FileConnection fc= (FileConnection)Connector.open("file:///store/home /user/documents/"+fileName+"_tmp.txt");
if(!fc.exists())fc.create();
OutputStream dataOut=fc.openOutputStream();
int copie;
while((copie=dataIn.read())!=-1)
{
dataOut.write(copie);
}
dataIn.close();
dataOut.close();
conn.close();
fc.close();
I just open a simple httpconnection with the requiered parameters and I read the input stream. on the simulator it works fine both with wifi and mobile connection. but in a real device it works only with wifi.
when I browse to the downloaded file and I open it I found this errour : Sorry , error occured : access denied.
thank you for your time.
06-12-2012 12:12 AM