User talk:Gracenotes/Java code

Latest comment: 12 years ago by DavidL in topic Problems

Problems edit

I've tried this bot on Wikibooks, and I've got two problems:

  1. Impossible to login, whereas it works with the same user and password in my Python scripts.
  2. When I comment the two return; supposed to block the editions when not logged, I've got this:
C:\Program Files (x86)\Java\bot>java WikiEditTest
Not logged in
Not logged in.
Exception in thread "main" java.lang.IllegalStateException: No match found
        at java.util.regex.Matcher.group(Unknown Source)
        at WikiEdit.editPage(WikiEdit.java:99)
        at WikiEditTest.main(WikiEditTest.java:17)

JackPotte (talk) 21:44, 12 February 2012 (UTC)Reply

1
The following code seems to contains the bug:
        while ((headerName = connection.getHeaderFieldKey(++i)) != null)
        {
            headerName = connection.getHeaderFieldKey(i);
            if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie"))
            {
                receivedCookie.append("; " + connection.getHeaderField(i).split(";")[0]);
            }
        }
        receivedCookie.delete(0, 2);
  • The getHeaderFieldKey is called twice and first called with i == 1 (because ++ before).
  • Also the last line delete the first two characters even if the string is empty (-> exception will be thrown).
Try this instead:
        while ((headerName = connection.getHeaderFieldKey(i)) != null)
        {
            if (headerName != null && headerName.equalsIgnoreCase("Set-Cookie"))
            {
                if (receivedCookie.length()>0) receivedCookie.append("; ");
                receivedCookie.append(connection.getHeaderField(i).split(";")[0]);
            }
            i++;
        }
        // receivedCookie.delete method call removed
2
Also try to explicitly specify the request method POST in userLogin method:
        connection.setDoOutput(true);
        connection.setUseCaches(false);
        connection.setRequestMethod("POST"); // <-- HERE
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
3
Calling the connect() method is useless (I don't use it in my Java code, which seems to work properly) :
        connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
        // connection.connect(); // <-- useless
        OutputStreamWriter output = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
4
Before getting response header the request should be sent, by getting the HTTP response:
        Arrays.fill(password, ' ');
    // ---------- INSERT THE FOLLOWING CODE: -----------------

        // Send request and get code
        int code = connection.getResponseCode();
        if (code != HttpURLConnection.HTTP_OK)
                throw new IOException("HTTP error "+code+": "+connection.getResponseMessage());

    // -------------------------------------------------------
        String headerName;
        StringBuffer receivedCookie = new StringBuffer();
5
The lgtoken is missing (See mw:API:Login). It should be a random string, or the one returned by the server when none is provided in the NeedToken response (to copy in a 2nd login request).
        String token = "login_"+System.currentTimeMillis();  // <-- HERE
        output.write("action=login" +
            "&lgname=" + URLEncoder.encode(username, "UTF-8") +
            "&lgpassword=" + URLEncoder.encode(new String(password).trim(), "UTF-8") +
            "&lgtoken=" + URLEncoder.encode(token, "UTF-8")  // <-- HERE
            );
-
Otherwise, see also https://web.archive.org/web/20131208024735/http://wiki-java.googlecode.com/svn/trunk/src/org/wikipedia/Wiki.java
-- ◄ David L • discuter ► 09:15, 13 February 2012 (UTC)Reply