1

I'm trying to send logging data from a document scanning applet to a django powered web server.

I'm testing using django's own webserver. I've constructed a simple POST request with java, but the django server is throwing a 500 error. I can't get any information regarding the error. I can't seem to use pydevd to break on code in my django view (my url's are set correctly - I can step through the code if I go to the url with a browser). I don't have any debugging setup on my applet, but I do have lots of info going to the console. I know that django sends lots of html info along with a 500 error, but my java applet is throwing an exception (in response to the 500 error), before it can read the message.

Here's the code in my applet -

private boolean log(String scanURL) {

    try {
        String data = "log=" + buffer.toString();
        URL url = new URL(scanURL);
        URLConnection conn = url.openConnection();
        conn.setDoOutput(true);
        OutputStreamWriter writer = new OutputStreamWriter(conn.getOutputStream());
        writer.write(data);
        writer.flush();

        // Handle the response
        int responseCode = ((HttpURLConnection) conn).getResponseCode();
        addItem("Http response code " + new Integer(responseCode).toString());
        addItem("creating BufferedReader");
        BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream()));
        String line;
        addItem("reading response");
        while ((line = reader.readLine()) != null) {
            addItem(line);
        }
        addItem("Closing Writer");
        writer.close();
        addItem("Closing Reader");
        reader.close();

        if (responseCode == 200) {
            return true;
            }
        else {
            return false;
        }

    } catch (Exception e) {
        addItem("Error - writing to log failed. " + e);
        return false;
    }

}

And my django view is currently -

from django.http import HttpResponse
from django.contrib.auth.decorators import login_required
from cache.shortcuts import permission_required

@login_required
@permission_required('documents.add_documentindex', raise_exception=True)
def save_log(request):
    import pydevd;pydevd.settrace()
    log_text = request.POST['log']
    with open("scanning.log", "a") as f:
        f.write(log_text)
    return HttpResponse('ok')

I suspect I need to do some work on the http headers, but without a bit more info from django my knowledge of http is a big handicap.

Any suggestions for getting this to work, or even getting a bit more information on django's server 500 error would be greatly appreciated!

UPDATE The stacktrace from the java exception is as follows

java.io.IOException: Server returned HTTP response code: 500 for URL: http://10.0.0.68:8000/scanning_log
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source)
    at java.lang.reflect.Constructor.newInstance(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection$6.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.net.www.protocol.http.HttpURLConnection.getChainedException(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at co.altcom.cache.scanner.CacheScan.log(CacheScan.java:408)
    at co.altcom.cache.scanner.CacheScan.createLog(CacheScan.java:385)
    at co.altcom.cache.scanner.CacheScan.destroy(CacheScan.java:70)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: Server returned HTTP response code: 500 for URL: http://10.0.0.68:8000/scanning_log
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
    at java.net.HttpURLConnection.getResponseCode(Unknown Source)
    at co.altcom.cache.scanner.CacheScan.log(CacheScan.java:405)
    ... 4 more
Aidan Ewen
  • 11,754
  • 8
  • 57
  • 80
  • `"Error - writing to log failed." + e` Uh-huh?.. Pretend we are not looking at your computer and consider adding `e.printStackTrace();` and copy/pasting the output. – Andrew Thompson Aug 29 '12 at 10:36
  • Thanks Andrew. I've added the stack trace. It's probably the stuff from the server that I'm more interested in - it looks like that exception is always thrown in response to a 500 error. I need to know why the 500 error is being thrown. Perhaps I need an alternative to getInputStream, that will still look at the input stream without throwing an exception on the 500 response. – Aidan Ewen Aug 29 '12 at 10:59
  • conn.getInputStream() fails, but conn.getErrorStream() returns the output I want from the server. (Thanks to http://stackoverflow.com/questions/3432263/java-io-ioexception-server-returned-http-response-code-500) – Aidan Ewen Aug 29 '12 at 11:16
  • All this stuff like `creating BufferedReader` - exactly where is that appearing? Which is line 405 of `CacheScan.java`? – Andrew Thompson Aug 29 '12 at 11:21
  • It's failing on BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream())); Specifically it fails on conn.getInputStream(). I've now updated code so it doesn't fail there anymore (see comment above). However the java console crashes with a message about 'Thread death' or something (and disappears before I can get any more info - it crashes my server in the process!). I'll update when I get more info. – Aidan Ewen Aug 29 '12 at 11:40
  • My server crash gives the same stack trace as an open python bug - http://bugs.python.org/issue14574. (Still getting no info on the java side). Starting to wonder how deep the rabbit hole goes - think I need to go away and do a little reading on http and socket programming. – Aidan Ewen Aug 29 '12 at 14:42
  • 1
    Looks like the server crash was caused by running the http connection code in the applets stop or destroy methods. I think the connection was killed and that was what causing the python server to crash. running the connection outside the stop or destroy method fixed the issue. – Aidan Ewen Aug 30 '12 at 14:49

1 Answers1

2

My original question asked for suggestions to get more information from the django server. I guess the answer I needed was found at java.io.IOException: Server returned HTTP response code: 500.

Java's getInputStream method of a URLConnection object throws an exception when the server returns an error code (such as 500). The solution was to use getErrorStream instead. This allowed me to access the html error information produced by django's server.

The final working code for the logging method of my applet is -

public boolean log(String logURL) {

    String charset = "UTF-8";
    String logData = logBuffer.toString();
    OutputStream output = null;
    HttpURLConnection conn = null;
    BufferedReader reader = null;
    InputStream in = null;

    try {
        String query = String.format("log=%s", URLEncoder.encode(logData, charset));
        conn = (HttpURLConnection) new URL(logURL).openConnection();
        conn.setDoOutput(true);
        conn.setRequestProperty("Accept-Charset", charset);
        conn.setRequestProperty("Content-Type","application/x-www-form-urlencoded;charset=" + charset);
        output = conn.getOutputStream();
        output.write(query.getBytes(charset));

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return false;
    } catch (MalformedURLException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } finally {
         if (output != null) try { output.close(); } catch (IOException e) {e.printStackTrace();}
    }

    // Handle the response
    try {
        int responseCode = conn.getResponseCode();
        if (responseCode == 200) {
            in = conn.getInputStream();
        } else {
            in = conn.getErrorStream();
        }
        reader = new BufferedReader(new InputStreamReader(in));
        String line;
        logNote("reading response");
        while ((line = reader.readLine()) != null) {
            System.out.println(line);
        }
        reader.close();         
        if (responseCode == 200) {
            return true;
            }
        else {
            return false;
        }

    } catch (UnsupportedEncodingException e) {
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        e.printStackTrace();
        return false;
    } finally {
        if (reader != null) try { reader.close(); } catch (IOException e) {e.printStackTrace();}
    }   
}

Using java.net.URLConnection to fire and handle HTTP requests was very informative.

Hope this is helpful for someone else.

Community
  • 1
  • 1
Aidan Ewen
  • 11,754
  • 8
  • 57
  • 80