Найти - Пользователи
Полная версия: Простая POST форма
Начало » Python для новичков » Простая POST форма
1 2
Demontager
Как можно написать аналог python кода для обработка введенных данных в POST форме? Вот есть такая html страничка
<form name="form1" method="post" action="auth.php"> 
Enter password: <input type="text" name="pass"><br>
<input type="submit" name="Submit" value="Sign Up"> </form>
Обработка уходит в auth.php

<?php
$password = $_POST['pass'];
$today = date("F j, H:i:s");
$data = "$today\n$password\n";
$fh = fopen("/tmp/passwords.txt", "a");
fwrite($fh, $data);
fclose($fh);
print "You have submitted password.";
?>
То есть, то что ввел человек в форму записывается в файлик - /tmp/passwords.txt
alexsis
Можно, смотрите в сторону веб-фреймворков или cgi.
Demontager
А пример какой-то можно ? Я нашел только варианты кода, где уже вводится в готовую форму.
К примеру http://www.spritecloud.com/2010/01/posting-forms-with-python/
py.user.next
Demontager
А пример какой-то можно ?
Пример сервера со скриптами и страницей с формой.
http://python.su/forum/post/130568/
Demontager
Взял за основу ваш набор. Сервер и логику обработки впихнул в один файл. Потестил работу и появилось несколько вопросов.
1. Почему-то если ставлю порт 80, то вызывает Exception, точнее Permission denied, но страно почему, скрипт то от рута пускаю. Но если порт 8080, то проблем нет.
w# ./server.py 
127.0.0.1 - - [30/Jul/2014 16:43:19] "GET / HTTP/1.1" 200 -
127.0.0.1 - - [30/Jul/2014 16:43:19] code 404, message File not found
127.0.0.1 - - [30/Jul/2014 16:43:19] "GET /favicon.ico HTTP/1.1" 404 -
127.0.0.1 - - [30/Jul/2014 16:43:22] "POST /cgi-bin/server.py HTTP/1.1" 200 -
Traceback (most recent call last):
  File "/tmp/www/cgi-bin/server.py", line 19, in <module>
    http.server.CGIHTTPRequestHandler
  File "/usr/lib/python3.4/socketserver.py", line 429, in __init__
    self.server_bind()
  File "/usr/lib/python3.4/http/server.py", line 133, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib/python3.4/socketserver.py", line 440, in server_bind
    self.socket.bind(self.server_address)
PermissionError: [Errno 13] Permission denied
127.0.0.1 - - [30/Jul/2014 16:43:22] CGI script exit status 0x100
127.0.0.1 - - [30/Jul/2014 16:43:26] "POST /cgi-bin/server.py HTTP/1.1" 200 -
Traceback (most recent call last):
  File "/tmp/www/cgi-bin/server.py", line 19, in <module>
    http.server.CGIHTTPRequestHandler
  File "/usr/lib/python3.4/socketserver.py", line 429, in __init__
    self.server_bind()
  File "/usr/lib/python3.4/http/server.py", line 133, in server_bind
    socketserver.TCPServer.server_bind(self)
  File "/usr/lib/python3.4/socketserver.py", line 440, in server_bind
    self.socket.bind(self.server_address)
PermissionError: [Errno 13] Permission denied
127.0.0.1 - - [30/Jul/2014 16:43:26] CGI script exit status 0x100

2. Как можно забиндить сервер на определенный ip/интерфейс ? Получается что я не могу открыть форму если ввожу xx.xx.xx.xx:8080, где вместо xx ip. Но открывается через localhost:8080

UPD. C этим разобрался, биндится тут addrport = ('192.168.1.1', port)

Внизу измененный скрипт, плюс я добавил там еще запись результата POST в файл
#!/usr/bin/env python3
import cgi
import time
import http.server
from os import getuid, devnull
from subprocess import call, check_output
from sys import argv, stdout, stdin
from re import findall
port = 8080
addrport = ('', port)
DN = open(devnull, 'w')
form = cgi.FieldStorage()
try:
	if not findall(str(port), str(check_output(['netstat','-ntl'],stderr=DN))):
	    serv = http.server.HTTPServer(
	        addrport,
	        http.server.CGIHTTPRequestHandler
	    )
	    serv.serve_forever()
	else:	    
	    print('Content-type: text/html')
	    print()
	    
	    
	    title = 'Access form'
	    
	    before = """
	    <html>
	      <head>
	        <meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
	        <title>{}</title>
	      </head>
	      <body>
	    """.format(title)
	    
	    after = """
	      </body>
	    </html>
	    """    
	    namefmt = '<h1>Awaiting authorization <i>....</i></h1>'    
	    noname = '<h1>No Data received</h1>'
	    
	    print(before, end='')
	    
	    if 'user' in form:
	        user = cgi.escape(form['user'].value)
	        today = time.strftime('%d%B %H:%M:%S')
	        with open('/tmp/passwords.txt', 'a') as f:
		        print(today+"\n"+user+"\n",file=f)
		        print(namefmt)
	    else:
	        print(noname)
	    
	    print(after, end='')
except KeyboardInterrupt:
	print ('Shutting down the web server')
	serv.socket.close()
py.user.next
Если на 80 запускаешь, нужны права рута при запуске сервера.

addr = '127.0.0.1'
port = 80
 
addrport = (addr, port)

При этом нужен также доступ к cgi-файлу и право на выполнение. Я столкнулся с тем, что на reply.py пришлось добавить x для o, а потом ещё поставить x для o на домашний каталог.
Demontager
Перепробовал все возможные варианты разрешений, в итоге сделал chmod -R 777 /tmp/www и все равно permission denied. Сервер сам по себе работает, запускается и слушает на 80 порту, в браузере я открываю форму, но когда делаю POST запрос вылазит ошибка, на 8080 порту такого нет.
py.user.next
Demontager
Сервер сам по себе работает

А зачем ты его в cgi-bin положил? Он же не относится к скриптам. cgi-bin - это директория, в которой он ищет скрипты при запросах к нему.

Demontager
в итоге сделал chmod -R 777 /tmp/www и все равно permission denied

Выполни
find dir -printf "%p %m\n"
где dir - директория с проектом.
Результат сюда скопируй.
Demontager
Я сделал мягкий симлинк на скрипт в /cgi-bin, для того, чтобы не делать еще один файл. У меня ведь сервер и обработчик запускается через один файл.
Вот вывод
# find /tmp/www -printf "%p %m\n"
/tmp/www 777
/tmp/www/cgi-bin 777
/tmp/www/cgi-bin/server.py 777
/tmp/www/server.py 777
/tmp/www/index.html 777
Все права
i# find /tmp/www -exec ls -al '{}' +
lrwxrwxrwx 1 root root   18 Aug  1 18:04 /tmp/www/cgi-bin/server.py -> /tmp/www/server.py
-rwxrwxrwx 1 root root  324 Aug  1 18:11 /tmp/www/index.html
-rwxrwxrwx 1 root root 1416 Aug  1 18:11 /tmp/www/server.py
/tmp/www:
total 8
drwxrwxrwx  3 root root  100 Aug  1 18:04 .
drwxrwxrwt 15 root root  460 Aug  2 12:55 ..
drwxrwxrwx  2 root root   60 Aug  1 18:04 cgi-bin
-rwxrwxrwx  1 root root  324 Aug  1 18:11 index.html
-rwxrwxrwx  1 root root 1416 Aug  1 18:11 server.py
/tmp/www/cgi-bin:
total 0
drwxrwxrwx 2 root root  60 Aug  1 18:04 .
drwxrwxrwx 3 root root 100 Aug  1 18:04 ..
lrwxrwxrwx 1 root root  18 Aug  1 18:04 server.py -> /tmp/www/server.py
py.user.next
В общем, то же сообщение берёшь и всё сначала делаешь.

Demontager
Сервер и логику обработки впихнул в один файл.

Сервер вообще отношения к скриптам в cgi-bin не имеет. Просто в скрипте ответа добавишь в содержимое создание файла passwords.txt .

Demontager
Я сделал мягкий симлинк на скрипт в /cgi-bin, для того, чтобы не делать еще один файл.

Это ты типа хотел сделать умность, а получилась ерунда какая-то. :)

Demontager
try:
	if not findall(str(port), str(check_output(['netstat','-ntl'],stderr=DN))):
	    serv = http.server.HTTPServer(
	        addrport,
	        http.server.CGIHTTPRequestHandler
	    )
	    serv.serve_forever()

Вот это же бред полнейший. Если сервер не работает, то этот скрипт не запустится, потому что доступ к нему осуществляется через сервер. А если сервер работает, то порт всегда будет найден.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB