Get the response code from an HTTP connection

Hi there,

I'm using the URL class to do some request, but i do not know how to get the status code. There is any callback or something that can help mi with this??

Thanks in advance!

If you use URL::createInputStream and get the response headers, that should contain the code.

The response code is not there on macOS an android, in android is completly empty

hmm.. well android uses the same code as linux.. Looks like it'd work to me - have you tried debugging into it to see how far it gets?

This is what I found on MacOS:

In the didReceiveResponse function in the juce_Mac_network.mm I print the NSURLResponse* response object and I get the following:

(lldb) po response
<NSHTTPURLResponse: 0x600000226880> { URL: http://example.com/test?param1=value1&param2=value2&param3=value3&param4=value4&param5=value5 } { status code: 403, headers {
    "Content-Length" = 34;
    "Content-Type" = "text/html; charset=iso-8859-1";
    Date = "Fri, 28 Feb 2014 09:53:25 GMT";
    "Proxy-Connection" = "Keep-alive";
    Server = nginx;
} }

the status code is not in the headers section (it belongs to the "Status line" see: RFC http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6), I guess that's why it is not stored in the header c++ object.

I would like to propose a solution for this issue. When whe use the createInputStream I would like to see there also the status code, something like this:

int statusCode;

InputStream* inputStream = url.createInputStream (false,
                                                  staticProgressCallback,
                                                  this,
                                                  String(),
                                                  timeOut,
                                                  &statusCode, // a reference to the status code
                                                  &responseHeaders );

Then in the didReceiveResponse it just need to call [((NSHTTPURLResponse*) response) statusCode] to store de value. What do you think?

Yes.. that seems like the right approach.

I’m fixing the issue, for now I have Android and MacOS, I’m expecting to finish iOS on Monday and then I’ll send you The code. I also found a bug on the Android Javanese code for some new Android devices, let’s see how it goes :slight_smile:

Awesome, much appreciated!


I uploaded the changes on dropbox. here there are: https://dl.dropboxusercontent.com/u/1242513/juce_core.zip


On the android activity .java I changed some code to be able to get the headers and the response code:


    // ==============================================================================
    public static class HTTPStream
    {
        public HTTPStream(HttpURLConnection connection_, int[] statusCode_, StringBuffer responseHeaders_) throws IOException
        {
            connection = connection_;
            try {
                inputStream = new BufferedInputStream(connection.getInputStream());
            } catch (IOException e) {
                if (connection.getResponseCode() < HttpStatus.SC_BAD_REQUEST)
                    throw e;
            }
            finally
            {
                statusCode_[0] = connection.getResponseCode();
            }
            
            // On android 4.x it is possible to get an exception when the server return an status code >= 400
            if (statusCode_[0] >= HttpStatus.SC_BAD_REQUEST)
                inputStream = connection.getErrorStream();
            else
                inputStream = connection.getInputStream();
            
            Map<String, List<String>> map = connection_.getHeaderFields();
            for (Map.Entry<String, List<String>> entry : map.entrySet())
            {
                if ( entry.getKey() == null) continue;
                StringBuilder value = new StringBuilder();
                for (String subVal : entry.getValue())
                    value.append(subVal + ",") ;
                
                if (value.length() > 0)
                    value.deleteCharAt (value.length() - 1); // remove the last ','
                
                responseHeaders_.append (entry.getKey() + ": " + value.toString() + "\n");
            }
        }
        public final void release()
        {
            try
            {
                inputStream.close();
            } catch (IOException e)
            {
            }
            connection.disconnect();
        }
        public final int read(byte[] buffer, int numBytes)
        {
            int num = 0;
            try
            {
                num = inputStream.read(buffer, 0, numBytes);
            } catch (IOException e)
            {
            }
            if (num > 0)
                position += num;
            return num;
        }
        public final long getPosition()
        {
            return position;
        }
        public final long getTotalLength()
        {
            return -1;
        }
        public final boolean isExhausted()
        {
            return false;
        }
        public final boolean setPosition(long newPos)
        {
            return false;
        }
        private HttpURLConnection connection;
        private InputStream inputStream;
        private long position;
    }
    public static final HTTPStream createHTTPStream(String address,
            boolean isPost, byte[] postData, String headers, int timeOutMs, int[] statusCode,
            StringBuffer responseHeaders)
    {
        try
        {
            HttpURLConnection connection = (HttpURLConnection) (new URL(address)
                    .openConnection());
            if (connection != null)
            {
                try
                {
                    if (isPost)
                    {
                        connection.setRequestMethod("POST");
                        connection.setConnectTimeout(timeOutMs);
                        connection.setDoOutput(true);
                        connection.setChunkedStreamingMode(0);
                        OutputStream out = connection.getOutputStream();
                        out.write(postData);
                        out.flush();
                    }
                    return new HTTPStream(connection, statusCode, responseHeaders);
                } catch (Throwable e)
                {
                    connection.disconnect();
                }
            }
        } catch (Throwable e)
        {
        }
        return null;
    }
    public final void launchURL(String url)
    {
        startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
    }
    public static final String getLocaleValue(boolean isRegion)
    {
        java.util.Locale locale = java.util.Locale.getDefault();
        return isRegion ? locale.getDisplayCountry(java.util.Locale.US)
                : locale.getDisplayLanguage(java.util.Locale.US);
    }
    // ==============================================================================

I hope this will helps. It works on Android, MacOS and iOS, I did not fix it for the rest of the platforms.

Did you accepted that solution?

Sorry, didn't have chance to look at the android stuff yet, but I did implement it for the other platforms, didn't I?

nice!! :) I also see that it is also implemented for android: https://github.com/julianstorer/JUCE/commit/4889822eaf7d7d45f9f0c02fe5c298efff764bd5