0

Here is my python server code...

#Copyright Jon Berg , turtlemeat.com

import string,cgi,time
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
#import pri

class MyHandler(BaseHTTPRequestHandler):

    # our servers current set ip address that clients should look for.
    server_address = "0.0.0.0"

    def do_GET(self):
        try:
            if self.path.endswith(".html"):
                f = open(curdir + sep + self.path)
                self.send_response(200)
                self.send_header('Content-type',    'text/html')
                self.end_headers()

                str = ""
                seq = ("<HTML>", MyHandler.server_address, "</HTML>")
                str = str.join( seq )
                print str
                self.wfile.write( str )
                return
            return

        except IOError:
            self.send_error(404,'File Not Found: %s' % self.path)


    def do_POST(self):
        global rootnode

        try:
            ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
            if ctype == 'application/x-www-form-urlencoded':
                query=cgi.parse_multipart(self.rfile, pdict)
            self.send_response(301)

            self.end_headers()
            MyHandler.server_address = "".join( query.get('up_address') )
            print "new server address", MyHandler.server_address
            self.wfile.write("<HTML>POST OK.<BR><BR>")

        except :
            pass

def main():
    try:
        server = HTTPServer(('', 80), MyHandler)
        print 'started httpserver...'
        server.serve_forever()
    except KeyboardInterrupt:
        print '^C received, shutting down server'
        server.socket.close()

if __name__ == '__main__':
    main()

And here is my Java code to post a value to "up_address"...

static public void post( String address, String post_key, String post_value ){

        try {
            // Construct data
            String data = URLEncoder.encode(post_key, "UTF-8") + "=" + URLEncoder.encode(post_value, "UTF-8");

            // Send data
            URL url = new URL(address);
            HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
            httpCon.setDoOutput(true);
            httpCon.setRequestMethod("POST"); 
            httpCon.setRequestProperty("content-type", "application/x-www-form-urlencoded"); 
            httpCon.setRequestProperty("charset", "utf-8");
            httpCon.setRequestProperty("Content-Length", "" + Integer.toString(address.getBytes().length));
            httpCon.setUseCaches (false);

            OutputStreamWriter wr = new OutputStreamWriter(httpCon.getOutputStream());
            wr.write(data);
            wr.flush();

            // Get the response
            BufferedReader rd = new BufferedReader(new InputStreamReader(httpCon.getInputStream()));
            String line;
            while ((line = rd.readLine()) != null) {
                // Process line...
            }
            wr.close();
            rd.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }

    }

It all seems simple enough but I am unable to successfully post to the server. I get one of two errors.

The server either never gets the request (the python print out doesn't happen), or, it gets the request(prints) but doesn't change the value (when it does it prints the change of .

The original python server tutorial came with a html page with a form for directly updating the value. This form page works perfectly. However I need to be able to POST from Java.

I've used the following apache code also and it doesn't work either...

HttpClient client = new DefaultHttpClient();
        HttpPost post = new HttpPost(address);
        try {
          List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
          nameValuePairs.add(new BasicNameValuePair( post_key, post_value));
          post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

          HttpResponse response = client.execute(post);
          BufferedReader rd = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
          String line = "";
          while ((line = rd.readLine()) != null) {
            System.out.println(line);
          }

        } catch (IOException e) {
          e.printStackTrace();
        }

I have no idea what is wrong. My literal POST key/value is "up_address=10.0.1.2" if that helps.

This is all of the code. Do you see anything wrong with it?

5
  • The server_address variable the value of a specific other machine's address. Commented Oct 18, 2012 at 3:37
  • use urlparse.parse_qs() instead of cgi.parse_multipart for x-www-form-urlencoded data. Commented Oct 18, 2012 at 4:02
  • I will try this and let you know how it goes (ty for your response). Commented Oct 18, 2012 at 14:47
  • no, replacing ...cgi.*... with ...urlparse.parse_qs(self.rfile, pdict)... doesn't help. The server sends the 301 response but it doesn't seem to find the query.get() that the Java app is sending. Commented Oct 18, 2012 at 16:00
  • read the docs for parse_qs. It expects a string such as: 'key1=value1&key2=value2' Commented Oct 18, 2012 at 16:41

1 Answer 1

0

I was unable to discern the issues. I believe it was the python server code though.

I decided to re-implement the server as a GET with arguments instead of a Get and a POST. I import urlparse to grab the keys appended to the url (source). Then I just look for w/e keys I expect.

Here is my new server code... (the expected arguments are 'up_address':'10.0.1.2').

import string,cgi,time, urlparse
from os import curdir, sep
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
#import pri

class MyHandler(BaseHTTPRequestHandler):

    # our servers current set ip address that clients should look for.
    server_address = "0.0.0.0"

    def do_GET(self):
    qs = {}
    path = self.path
    if '?' in path:
        path, tmp = path.split('?', 1)
        qs = urlparse.parse_qs(tmp)
        MyHandler.server_address = qs['up_address']
        print 'new server address: ', MyHandler.server_address


def main():
    try:
        server = HTTPServer(('', 8080), MyHandler)
        print 'started httpserver...'
        server.serve_forever()
    except KeyboardInterrupt:
        print '^C received, shutting down server'
        server.socket.close()

if __name__ == '__main__':
    main()

This seems to work just fine for my project's needs.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.