Python应用程序向服务器发送获取链接,获得200 OK响应,但服务器脚本不执行

I am trying to make a python app wich would insert data in a SQL database. To achieve this I have made the python app send parameters in a GET request, and writed a php script which is supposed to get them and make the SQL request

The Python script is (shortened):

import httplib
import time

dd = time.time().__str__()[:-3]
d = time.time().__str__()[:-3]

link = str('?id_machine=1,type_erreur=ping,description_erreur=test,date_detection=' + dd + ',date=' + d)
print link

conn = httplib.HTTPConnection('localhost')

conn.request('GET','/test/erreur.php' + link)
res = conn.getresponse()
print res.status
print res.reason

And when executed print:

drakasan@debian:~$ python Ingesup/Web/AgentS.py 
?id_machine=1,type_erreur=ping,description_erreur=test,date_detection=1381245779,date=1381245779
200
OK

And here is the php script:

<?php
    $page ='Ajoutsalle';
    require_once ('connect.php');

    $id_machine=htmlspecialchars(trim($_GET['id_machine']));
    $type_machine=htmlspecialchars(trim($_GET['type_machine']));
    $description_erreur=htmlspecialchars(trim($_GET['description_erreur']));
    $date_detection=htmlspecialchars(trim($_GET['date_detection']));
    $date=htmlspecialchars(trim($_GET['date']));

    if($nom_machine && $id_salle && $ip && $systeme)
    {
        $query = $connect->query("SELECT * FROM erreur WHERE id='".$id."'");
        $rows=$query->rowCount();
        if($rows==1)
        {
            echo" <div id='error'>Ip existe deja </div>";
        } else {
            $req = $connect->prepare('INSERT INTO     erreur(id_machine,type_erreur,description_erreur,date_detection,date) VALUES(:id_machine,:type_erreur,:description_erreur,:date_detection,:date)');
            $req->execute(array(
                'id_machine'         => $id_machine,
                'type_machine'       => $type_machine,
                'description_erreur' => $description_erreur,
                'date_detection'     => $date_detection,
                'date'               => $date,
            ));
        }

    } else echo "vous devez renseigner tous les champs";
?>
<html>
    <form method='GET' action='#'>
    </form>
</html>

The "bliss" database is as follows:

erreur (TABLE)
    -id (PRIMARY, AUTO INDENT, INT)
    -id_machine (INT, FOREIGN KEY)
    -type_erreur (VARCHAR[50])
    -description_erreur (VARCHAR[200])
    -date_detection (TIMESTAMP)
    -date (TIMESTAMP)

I'm using Xampp to have my server and database in localhost/test. So it seems the script does receive the GET request, but does not execute.

The thing is, I m still learner in python, and complete neophyte in php, so I don t know where to search in the code.

The final goal is:

agent.py --GET--> erreur.php --SQL--> bliss.erreur

Since there would be a lot of agents, sending SQL request from the Python script isn't a solution.

Can anyone validate that the Python script works, and/or give me a clue about where did I go wrong in the code?

wget with -O flag:

drakasan@debian:~$ wget -O - http://localhost/test/erreur.php?id_machine=1,type_erreur=ping,description_erreur=test,date_detection=1381241491,date=1381241491
--2013-10-08 16:19:31--  http://localhost/test/erreur.php?id_machine=1,type_erreur=ping,description_erreur=test,date_detection=1381241491,date=1381241491
Resolving localhost (localhost)... ::1, 127.0.0.1
Connecting to localhost (localhost)|::1|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 826 [text/html]
Saving to: `STDOUT'

 0% [                                                                                                             ] 0           --.-K/s              <br />
<b>Notice</b>:  Undefined index: type_machine in <b>/opt/lampp/htdocs/test/erreur.php</b> on line <b>6</b><br />
<br />
<b>Notice</b>:  Undefined index: description_erreur in <b>/opt/lampp/htdocs/test/erreur.php</b> on line <b>7</b><br />
<br />
<b>Notice</b>:  Undefined index: date_detection in <b>/opt/lampp/htdocs/test/erreur.php</b> on line <b>8</b><br />
<br />
<b>Notice</b>:  Undefined index: date in <b>/opt/lampp/htdocs/test/erreur.php</b> on line <b>9</b><br />
<br />
<b>Notice</b>:  Undefined index: id in <b>/opt/lampp/htdocs/test/erreur.php</b> on line <b>11</b><br />
<b>Notice</b>:  Undefined variable: nom_machine in <b>/opt/lampp/htdocs/test/erreur.php</b> on line <b>13</b><br />
vous devez renseigner tous les champs
<html>
    <form method='GET' action='#'>
    </form>
</html>
100%[============================================================================================================>] 826         --.-K/s   in 0s      

2013-10-08 16:19:31 (69.1 MB/s) - written to stdout [826/826]

Apart from other things, you're not following the HTTP URL syntax correctly. An example says it all:

http://my.host/some/path?foo=1&bar=2

the main point being that arguments are divided by &, not ,.


Other tips:

  • Read up basics of HTTP. It's not a complicated protocol and it helps a lot if you know where you need to look at.

    (hint: there are three parts: status line, headers and body).

  • When debugging, always examine also body of the response as well, not only the response status.

    In Python, you can do this by printing output of response.read() method. Other options are using command line tools like wget or curl with proper switches:

    $ wget -O - 'http://my.host/some/path?foo=1&bar=2'
    ...
    $ curl -v 'http://my.host/some/path?foo=1&bar=2'
    ... 
    $
    
  • Maybe even better alternative is to use a packet sniffer like Wireshark, where you can see the whole request and response. It's also great habit if you want to get protocols into your blood system.

    (hint: In Wireshark, right-click a packet and choose "Follow TCP stream")

  • Also as bruno points out, GET should not be used for storing data, you should use POST (I think it's stored as $_POST in PHP) instead.

    Just as the names suggest: GET means to get, POST means to post.

  • Last but not least, your PHP code was unlikely to produce a valid HTML. The <? ... > part is replaced by anything it prints (echoes), so your actual output would be like:

    vous devez renseigner tous les champs
    <html>
        <form method='GET' action='#'>
        </form>
    </html>
    

    which is definitely not a valid HTML.

If you have an undefined variable warning in PHP, you need to take care of that immediately. In this case, you have $nom_machine &&, which, because $nom_machine is not defined, is basically equivalent to if(FALSE &&. That means the code inside of that if will never run.

On the Python side, you should be reading the output and not just the headers. (eg. print res.read()). PHP will often display errors after the headers have been sent, which means you could have a fatal error or an empty response with a 200 header.