Welcome!

Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Java Development

Reply
New Contributor
Posts: 9
Registered: ‎10-17-2009
My Device: Not Specified

Https with BlackBerry

Hi,

I've been struggling with POSTing a large file to my server via HTTPS. I've read the sticky "Connecting your BlackBerry" as well as numerous other similar threads and documents (including http://docs.blackberry.com/en/developers/deliverables/7693/Use_an_HTTPS_connection_508959_11.jsp).

 

The code I have works well with HTTP, but once I switch it to HTTPS it fails on files larger than about 8k. On the server side, I receive the first 8k of the transmission; on the client side I get an the exception "Connection Closed" once I getResponse() or os.flush().  It works in J2ME.

 

I suspect BlackBerry is internally buffering the data then counting the bytes (to determine the length for HTTP 1.0, even though I specify the header) before it's streamed out because no data hits my server until getResponse() or os.flush() is called. Perhaps this is creating some memory errors or something. This concerns me as OutOfMemory exceptions are bound to occur eventually if the output is being buffered.

 

My code is below (minus the details). It's pretty standard. Can anyone suggest alternatives? I've tried different URL parameters as discussed in http://www.blackberry.com/knowledgecenterpublic/livelink.exe/fetch/2000/348583/800451/800563/What_Is...

 

httpsConn = (HttpsConnection) Connector.open(uri, Connector.READ_WRITE);
httpsConn.setRequestMethod(HttpsConnection.POST);
httpsConn.setRequestProperty("User-Agent", "Profile/MIDP-2.0 Configuration/CLDC-1.0");
httpsConn.setRequestProperty("Connection", "Keep-Alive");

httpsConn.setRequestProperty(HttpProtocolConstants.HEADER_CONTENT_LENGTH,String.valueOf(length));
OutputStream os = httpsConn.openOutputStream();

byte[] b = new byte[1024*4];
for (int n; (n = is.read(b)) != -1Smiley Wink

      os.write(b, 0, n);

 

httpsConn.getResponseCode() ;

 

 

THANKS!

 

Developer
Posts: 587
Registered: ‎01-19-2010
My Device: BOLD 9700 OS5.0.0.x on Rogers Canada
My Carrier: Rogers

Re: Https with BlackBerry

First off Kudos for an excellent structure in presenting your question. That said, have you tried openOutputDataStream, rather than openOutputStream? You did say you were streaming files.

 

Hope that helps,

~Dom

----------------------------------------------------------------------------
chown -R us ./base
~J!NX
New Contributor
Posts: 9
Registered: ‎10-17-2009
My Device: Not Specified

Re: Https with BlackBerry

Thanks for the suggestion. Now I get an exception at getResponseCode(): net.rim.device.cldc.io.ssl.TLSIOException(net.rim.device.api.crypto.tls.TLSAlertException)

 

There's no description, but the "alert" level is 2 which I assume is "critical".

 

I tried several permutations of the code using getDataOutputStream(), but nothing worked.

New Developer
Posts: 13
Registered: ‎11-12-2008
My Device: Not Specified

Re: Https with BlackBerry

[ Edited ]

Please try:

 

int offset = 0;
int size = b.length;

int lastread = -1;
int remaining = b.length;                      

 while (lastread != 0 && remaining != 0)          

 {
       lastread = _in.read(b, offset, remaining);
       if (lastread < 0)
               lastread = 0;
       remaining = remaining - lastread;
       offset = offset + lastread;
 }

 


while (offset < size)
{
    int ldataSize = Math.min(256, size - offset);
   os.write(b, offset, ldataSize);
   offset += ldataSize;                   
}

New Contributor
Posts: 9
Registered: ‎10-17-2009
My Device: Not Specified

Re: Https with BlackBerry

Thanks for the suggestion, MaxBB. What is that code trying to accomplish?

 

I looked into my issue further and have found several supporting threads on the issue, none of which seem to have a resolution.

 

http://supportforums.blackberry.com/t5/Java-Development/Http-Connection-Vs-Https-connection-on-CDMA-...

 

http://rim.lithium.com/t5/Java-Development/HttpsConnection-Outputstream-hanging-indefinitely-on-Spri...

New Developer
Posts: 13
Registered: ‎11-12-2008
My Device: Not Specified

Re: Https with BlackBerry

I found some OS versions of BB have buffer limitation of inputStream and output stream, you cannot read or write data to stream once by calling read(byte[] b) or write(byte[] b), you have to read dara or write data to stream by loop.

 

Hope that will give you some help.

New Contributor
Posts: 9
Registered: ‎10-17-2009
My Device: Not Specified

Re: Https with BlackBerry

[ Edited ]

Thanks for your reply. As you can see by my code example, I am already looping. Is that what you mean?

 

I'm starting to find that it works on my v4.2 BlackBerry, but it never works on the v4.5 emulator.

New Developer
Posts: 13
Registered: ‎11-12-2008
My Device: Not Specified

Re: Https with BlackBerry

[ Edited ]

Your loop is different from my loop.

 

I also used the similar loop like your before, it did not work for device 4.5 and above. After i changed the code to read and write, the problem was solved.

 

I guess your problem is os.write(b, 0, n), n is too big.

 

 

New Contributor
Posts: 9
Registered: ‎10-17-2009
My Device: Not Specified

Re: Https with BlackBerry

"n" is no larger than "b", however you didn't specify the size of "b" in your example. I have tried various sizes of "n", but I'll try your code exactly and hope for the best. Thanks.

New Contributor
Posts: 9
Registered: ‎10-17-2009
My Device: Not Specified

Re: Https with BlackBerry

Hi. I just tried your function. As is, it doesn't write anything out because it never reaches the os.write(). See my inline comments for the test case.

 

Assuming "b" is a byte[] b = new byte[1024];

(If b is supposed to be the byte array for the entire file, that means this solution would have to hold the entire file in memory which could be 1 MB, 100MB, maybe even 1G so that's clearly not a viable solution)

 

int offset = 0;
int size = b.length;

int lastread = -1;
int remaining = b.length;                      

 while (lastread != 0 && remaining != 0)          

 {

       // if "remaining" = b.length and there's more than

       // b.length data available, lastread = b.length = remaining


       lastread = _in.read(b, offset, remaining);
       if (lastread < 0)
               lastread = 0;

 

       // per the comment above, "remaining" = "lastread" thus this evaluates to 0.
       remaining = remaining - lastread;

       // offset = lastread = b.length

       offset = offset + lastread;
 } //remaining = 0, so this never loops

 

// offset = b.length = size, so this loop never goes.
while (offset < size)
{
    int ldataSize = Math.min(256, size - offset);
   os.write(b, offset, ldataSize);
   offset += ldataSize;                   
}

 

Thanks for your suggestion, but if your objective is to stream bytes out in smaller chunks you can just do.

 

byte[] b = new byte[1024];
for (int n; (n = is.read(b)) != -1Smiley Wink

      os.write(b, 0, n);