I'm doing pages in html and python (I'm novice in python), I would like to have IP client address, but I don't know if it is possible. I saw it is possible with PHP language.
So, I execute my code in command line (with Linux) like that:
./code.py client_server app_name app_version
infos.py
def main( client_server, app_name, app_version):
template = open('infoHTML.py').read()
c = string.Template(template).substitute(
app_name = app_name,
app_version = app_version,
os = user,
user = login)
f = tempfile.NamedTemporaryFile(prefix='/tmp/info.html', mode='w', delete=False)
f.write(contenu)
f.close()
webbrowser.open(f.name)
if __name__ == "__main__":
client_server = sys.argv[1]
app_name = sys.argv[2]
app_version = sys.argv[3]
user = sys.platform
sys.argv.append(user)
login = getpass.getuser()
sys.argv.append(login)
main(client_server, app_name, app_version)
I have an html code into python code here: infoHTML.py
<html>
App: ${app_name}<br/><br/>
Version: ${app_version}<br/><br/>
User: ${user}<br/><br/>
<form name="sendData" method="get" action="http://localhost:8000/cgi/display.py">
Project: <input type="text" name="pro"><br/><br/>
Number: <input type="text" name="num"/><br/><br/>
<input type="submit" value="OK"/>
</form>
</body>
</html>
It's possible. You need to do it either by rendering the address on the response body or by requesting it with ajax after the response has already been rendered.
It would be hard to give you a code solution without seeing what web server you are using, but here are a couple of pointers for the first approach. To obtain the address, on the server side (python handler):
import socket
ip = socket.gethostbyname(socket.gethostname())
or if you are using something like Google App Engine:
ip = self.request.remote_addr
you should then write the IP to the response. For example, if you are using a templating engine to render your HTML, your HTML can look like something similar to this:
<html>
<script>
var ip = {{ip}}
</script>
and on the python code that renders the template you should do something like that:
htmlContent = template.render(ip=ip)
self.response.write(htmlContent)
Related
So I tried to develop a web proxy using Flask. in the progress I found out that somehow I need to handle Likns so all redirects take place in the web proxy, this is what I write:
import requests
from flask import Flask , request
from requests import get
import re
app = Flask(__name__)
mainURL = ""
myHost = "http://127.0.0.1:5000/"
#app.route("/", methods =["GET", "POST"])
def Home():
#a small form for users to write thier URL inside it
mainpage = '<!DOCTYPE html><html><body><form action="/" method="post"><label for="url">URL:</label><br><input type="text" id="url" name="url" value="https://www.google.com/"><br><input type="submit" value="Open"></form></body></html>'
#check if submit button trigered
if request.method == "POST":
mainURL = request.form.get("url")
response = requests.get(mainURL)
#this is for handling links and pictures. I know its not optimal, thats why im here!
a = response.text.replace("='/",f"='{mainURL}")
a = a.replace('="/',f'="{mainURL}')
a = a.replace("url(/",f"url({mainURL}")
a = a.replace('href="http',f'href="{myHost}http')
a = a.replace("href='http",f"href='{myHost}http")
a = a.replace(r'href="(?!http)',f'href="{myHost}{mainURL}')
a = a.replace(r"href='(?!http)",f"href='{myHost}{mainURL}")
return a
return mainpage
#decroator for the times when a path opened
#app.route('/<path:path>')
def proxy(path):
#this RegEx find the website FQDN from path
if re.match(r"https?://w{3}\.\w*\.\w*/",path):
temp = re.match(r"https?://w{3}\.\w*\.\w*/",path)
mainURL = temp[0]
response = requests.get(path)
#again links and pictures handler. dont judge me, I wrote a function for it but IDK why it didn't works for pictures!
a = response.text.replace("='/",f"='{mainURL}")
a = a.replace('="/',f'="{mainURL}')
a = a.replace("url(/",f"url({mainURL}")
a = a.replace('href="http',f'href="{myHost}http')
a = a.replace("href='http",f"href='{myHost}http")
a = a.replace(r'href="(?!http)',f'href="{myHost}{mainURL}')
a = a.replace(r"href='(?!http)",f"href='{myHost}{mainURL}")
return a
return "URL is Incorrect!"
if __name__ == "__main__":
app.run(host='127.0.0.1',port='5000',debug=True)
This is Output:
opening Google using proxy
so its open a webpage but its so slow because of all those replace and with all of these its still can't load CSS!
so what I want is a optimized way to redirect all links to proxy and handling CSS!
I am currently trying to do simple web stuff with the http.server module in Python.
When I try to POST a form to my script, it does not receive the POST data, $_POST ist empty and file_get_contents('php://input') as well.
This is my post_test.html:
#!/usr/bin/php
<!DOCTYPE html>
<html>
<body>
<form method="post" action="post_test.html">
Name: <input type="text" name="fname">
<input type="submit">
</form>
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// collect value of input field
echo "RAW POST: " . file_get_contents('php://input') . "<br>";
$name = $_POST['fname'];
if (empty($name)) {
echo "Name is empty";
} else {
echo $name;
}
}
?>
</body>
</html>
And this is my server script:
import urllib.parse
from http.server import CGIHTTPRequestHandler, HTTPServer
hostName = "localhost"
serverPort = 8080
handler = CGIHTTPRequestHandler
handler.cgi_directories.append('/php-cgi')
class MyServer(handler):
def do_GET(self):
# get path without first '/' and without anything besides path and filename
file = self.path[1:].split("?")[0].split("#")[0]
# if the file is in the script list, execute from php-cgi, else load from webapp
php_handle = ["post_test.html"]
if file in php_handle:
self.path = "/php-cgi" + self.path
else:
self.path = "/webapp" + self.path
CGIHTTPRequestHandler.do_GET(self)
def do_POST(self):
# get path without first '/' and without anything besides path and filename
file = self.path[1:].split("?")[0].split("#")[0]
# if the file is in the script list, execute from php-cgi
php_handle = ["post_test.html"]
if file in php_handle:
length = int(self.headers['Content-Length'])
post_data = urllib.parse.parse_qs(self.rfile.read(length).decode('utf-8'))
for key, data in post_data.items():
self.log_message(key + ": " + str.join(", ", data))
self.path = "/php-cgi" + self.path
CGIHTTPRequestHandler.do_POST(self)
def do_HEAD(self):
CGIHTTPRequestHandler.do_HEAD(self)
if __name__ == "__main__":
webServer = HTTPServer((hostName, serverPort), MyServer)
try:
webServer.serve_forever()
except KeyboardInterrupt:
pass
webServer.server_close()
print("Server stopped.")
Okay, I was finally able to solve the problem: #!/usr/bin/php is wrong, it should be #!/usr/bin/php-cgi.
Reason: php does NOT use the POST data, and there is no way giving it to php.
php-cgi is made for the webserver purpose and can handle it.
Hwo to solve the next problem: To run php-cgi successfully you have to create a php.ini in the current directory tho, with two settings.
First one to allow executing it directly, second one to set the directory where the scripts are. If you don't set it, you will be greeted with a 404 not found.
php.ini:
cgi.force_redirect = 0
doc_root = /home/username/server-directory
Where the server-directory folder is the folder containing the php.ini, and the php-cgi folder. Also the name of the folder is not related to the php-cgi binary, it's just bad naming that I did.
If you try to recreate this, it should work perfectly now.
I have a problem submitting a HIT to Amazon Mechanical Turk sandbox.
I'm using the following code to submit a HIT:
external_content = """"
<ExternalQuestion xmlns="http://mechanicalturk.amazonaws.com/AWSMechanicalTurkDataSchemas/2006-07-14/ExternalQuestion.xsd">
<ExternalURL>https://MY_HOST_GOES_HERE/</ExternalURL>
<FrameHeight>400</FrameHeight>
</ExternalQuestion>
"""
import boto3
import os
region_name = 'us-east-1'
aws_access_key_id = 'MYKEY'
aws_secret_access_key = 'MYSECRETKEY'
endpoint_url = 'https://mturk-requester-sandbox.us-east-1.amazonaws.com'
# Uncomment this line to use in production
# endpoint_url = 'https://mturk-requester.us-east-1.amazonaws.com'
client = boto3.client('mturk',
endpoint_url=endpoint_url,
region_name=region_name,
aws_access_key_id=aws_access_key_id,
aws_secret_access_key=aws_secret_access_key,
)
# This will return $10,000.00 in the MTurk Developer Sandbox
print(client.get_account_balance()['AvailableBalance'])
response = client.create_hit(Question=external_content,
LifetimeInSeconds=60 * 60 * 24,
Title="Answer a simple question",
Description="Help research a topic",
Keywords="question, answer, research",
AssignmentDurationInSeconds=120,
Reward='0.05')
# The response included several helpful fields
hit_group_id = response['HIT']['HITGroupId']
hit_id = response['HIT']['HITId']
# Let's construct a URL to access the HIT
sb_path = "https://workersandbox.mturk.com/mturk/preview?groupId={}"
hit_url = sb_path.format(hit_group_id)
print(hit_url)
The error message I get is:
botocore.exceptions.ClientError: An error occurred (ParameterValidationError) when calling the CreateHIT operation: There was an error parsing the XML question or answer data in your request. Please make sure the data is well-formed and validates against the appropriate schema. Details: Content is not allowed in prolog. (1493572622889 s)
What might be the reason here? The xml fully agrees with xml schema located on amazon servers.
The html returned by the external host is:
<!DOCTYPE html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'/>
<script src='https://s3.amazonaws.com/mturk-public/externalHIT_v1.js' type='text/javascript'></script>
</head>
<body>
<!-- HTML to handle creating the HIT form -->
<form name='mturk_form' method='post' id='mturk_form' action='https://workersandbox.mturk.com/mturk/externalSubmit'>
<input type='hidden' value='' name='assignmentId' id='assignmentId'/>
<!-- This is where you define your question(s) -->
<h1>Please name the company that created the iPhone</h1>
<p><textarea name='answer' rows=3 cols=80></textarea></p>
<!-- HTML to handle submitting the HIT -->
<p><input type='submit' id='submitButton' value='Submit' /></p></form>
<script language='Javascript'>turkSetAssignmentID();</script>
</body>
</html>
Thank you
This message "Details: Content is not allowed in prolog." is the clue. It turns out that what this is saying is that you can't have content outside of where it is expected. This is what usually happens when a junk character (think smart-quotes or non-printable ASCII value) appears in there. These can be a real pain in the butt to diagnose.
In your case, it's a little easier to debug but still just as frustrating. Check out this line:
external_content = """"
It turns out that Python only needs three quotes (""") in order to acknowledge a multi-line string definition. Thus your fourth " was actually rendering as part of the XML. Change that line to this:
external_content = """
And you're golden. I just tested it and it works. Sorry for all the frustration, but hopefully this unblocks you. Happy Sunday!
As part of a project, I am trying to have python receive a form sent by HTML. Upon getting the variables, I need python to print either "True" or "False" in the console. Here is my current HTML code for the form.
...
<form name = "input" action = "CheckLogin.py" method = "get">
<!-- This is the form. Here the user submits their username and password.
The words before the colon are the words that appear on the user's screen -->
Username: <input type = "text" name = "htmlUser">
<br>
Password: <input type = "password" name = "htmlPassword">
<input type = "submit" value = "Submit">
<br>
</form>
...
Once I have had them submit their username and password, I want to use this data to check if they can log into an email server (I have used Google's in this case, Microsoft Server 2003 doesn't play nicely.) Here is my Python 3 script to do so:
def login(username, password):
import poplib
try:
server = poplib.POP3_SSL('pop.gmail.com', 995)#Weird bug here. When I use the exeter server, I am informed that the SSL number is incorrect. How do I fix?
server.user(username)
server.pass_(password)
print ("True")
except:
print("False")
login (username, password)
My question is, how can I have python get the username and password variables from the HTML webform?
Just get those values in CheckLogin.py and pass them to login():
import cgi
# ...
i = cgi.FieldStorage()
username = i["htmlUser"]
password = i["htmlPassword"]
login(username, password)
I tried this:
#!/usr/bin/python
from wsgiref.simple_server import make_server
from cgi import parse_qs, escape
import logging
import os
import sys
html = """
<html>
<body>
<form method="post" action="parsing_post.wsgi">
<p>
Age: <input type="text" name="age">
</p>
<p>
Hobbies:
<input name="hobbies" type="checkbox" value="software"> Software
<input name="hobbies" type="checkbox" value="tunning"> Auto Tunning
</p>
<p>
<input type="submit" value="Submit">
</p>
</form>
<p>
Age: %s<br>
Hobbies: %s
</p>
</body>
</html>
"""
def application(environ, start_response):
# the environment variable CONTENT_LENGTH may be empty or missing
try:
request_body_size = int(environ.get('CONTENT_LENGTH', 0))
except (ValueError):
request_body_size = 0
# When the method is POST the query string will be sent
# in the HTTP request body which is passed by the WSGI server
# in the file like wsgi.input environment variable.
logger = logging.getLogger(__name__)
request_body = environ['wsgi.input'].read(request_body_size)
d = parse_qs(request_body)
age = d.get('age', [''])[0] # Returns the first age value.
hobbies = d.get('hobbies', []) # Returns a list of hobbies.
# Always escape user input to avoid script injection
age = escape(age)
hobbies = [escape(hobby) for hobby in hobbies]
response_body = html % (age or 'Empty',
', '.join(hobbies or ['No Hobbies']))
status = '200 OK'
response_headers = [('Content-Type', 'text/html'),
('Content-Length', str(len(response_body)))]
start_response(status, response_headers)
return [response_body]
But i don't know where it logs. I'm trying to display/log the value on webpage or in a file /var/log/apache2/myapp.log
What's the best way to do this?
Any answer will be highly appreciated.
Note that the above code won't actually produce any log whatsoever since your not calling any of the logger.log() variants - but I guess that's not the point.
If you're running your code with apache/mod_wsgi, the simplest solution is to configure your logger(s) to log to sys.stderr using a StreamHandler (cf http://docs.python.org/howto/logging.html#configuring-logging), and define the error log path, name and level in your apache conf (beware, the default apache behaviour is to only log "error level" message).