Python HTTP POST request - python

I'm currently trying to send a HTTP POST via requests library in Python to a remote server to validate a serial number. I've already accomplished this with the following script:
validate-request.py
#!/usr/bin/env python
import requests
print "Content-type: text/html\r\n"
print "\r\n"
r = requests.post("https://xx.xx.xx.xx/cgi-bin/verify.py", data={'serial':'XXXXXXX')}, verify=True)
This already works great. When the serial number is validated, I would really like it to respond by offering a download and/or possibly text accompanied with it. I'm currently only able to validate the serial (the actual script is much longer as it fetches it from MySQL, so this is a simpler version.)
validate.py
#!/usr/bin/python
import cgi
form = cgi.FieldStorage()
serial = form.getvalue('serial')
print "Content-type:text/html\r\n\r\n"
print "<b>SERIAL OK</b></br>"
if serial == "XXXXXXX":
print "Content-type:text/html\r\n\r\n"
print "SERIAL <b>OK</b></br>"
else:
print "Content-type:text/html\r\n\r\n"
print "SERIAL <b>NOT OK</b></br>"
What I would also like to include is returning some extra information (text, mainly) and possibly offering a file to download.
This means, on the validate-request.py, I would have to play with the r.text it returns. Is there perhaps a way to scan the return text to find what I'm looking for? Also, how would I go about offering the file from validate.py and how would I go about accepting it from validate-request.py?

Related

How to get CSGO gamestate integration data with vb.net

I have been writing python code for quite some time to get CSGO gamestate_integration, but I currently need to write something in vb.net to do the same thing and it's not working.
tl;dr version: vb.net won't accept the post request from CSGO, but a simple python script can echo the post request to vb.net and it works. The vb.net application IS being run as administrator.
I have a simple class file (obviously my URIs are private):
Imports System.IO
Imports System.ServiceModel
Imports System.ServiceModel.Web
Imports JSONReceiver
<ServiceContract()>
Public Interface iJSONReceiver
<OperationContract>
<WebGet()>
Function get_stats(ByVal data As String) As String
<OperationContract()>
<WebInvoke(RequestFormat:=WebMessageFormat.Json)>
Function post_stats(ByVal request As Stream) As String
End Interface
Public Class JSONReceiver
Implements iJSONReceiver
Public Function post_stats(ByVal request As Stream) As String Implements iJSONReceiver.post_stats
Dim reader As New StreamReader(request)
Console.WriteLine("In post_stats")
Console.WriteLine(reader.ReadToEnd())
Console.WriteLine()
Return "OK"
End Function
Public Function get_stats(ByVal data As String) As String Implements iJSONReceiver.get_stats
Console.WriteLine("In get_stats")
Console.WriteLine(data)
Console.WriteLine()
Return "OK"
End Function
End Class
And simple code to test it:
Public host As WebServiceHost
Public post_ep As ServiceEndpoint
Public Sub main()
host = New WebServiceHost(GetType(JSONReceiver), New Uri("http://192.168.1.102:8080"))
post_ep = host.AddServiceEndpoint(GetType(iJSONReceiver), New WebHttpBinding(), "")
host.Open()
Console.WriteLine("Press enter to quit...")
Console.ReadLine()
host.Close()
End Sub
I can use a web browser to point to the get_stats() endpoint, and it works just fine, but I am trying to use CSGOs gamestate_integration functionality to post the data to my service, and it just doesn't seem to like it.
So what I did was ripped my old python code to simply echo the request to the vb.net web service, it it works... the python code receives the data and simply posts it to the vb.net service, and the vb.net service happily accepts it.
So I change the URI for the vb JSONReceiver to port 8081, and run this script on the original uri (192.168.1.102:8080)
import web
import urllib2
class Stats(object):
def POST(self):
json_data = web.data()
try:
echo(json_data)
except Exception, e:
print(e.__str__())
return "OK"
def echo(data):
request = urllib2.Request("http://192.168.1.102:8081/post_stats")
request.add_data(data)
f = urllib2.urlopen(request)
print f.read()
urls = (
'/post_stats', 'Stats',
)
if __name__ == "__main__":
app = web.application(urls, globals())
app.run()
In short, the URI CSGO is using to post to my service is http://192.168.1.102:8080, which hits my python service, which then echoes the request verbatim to http://192.168.1.102:8081 (again, these are private URIs).
I don't know why, but it works... but having to run a wrapper to get this data is not only weird, it's really not an acceptable solution to the problem... obviously vb.net is handling post requests just fine when it's coming from my python script; obviously CSGO is posting requests correctly, or my python script wouldn't be able to receive it, so I'm having a problem finding the disconnect...
Is Python adding something to the request that CSGO might not be?
Do I need to fall back to socket programming?

How to check if server is apache in python?

I need some idea to test the server from a link. I do not know where to start
Would be:
site = 'example.com'
if(site === Apache)
print '[ok] Apache - Version:'
else
print '[No] Is not apache'
I prefer using requests since it's simple and well documented. And it doesn't return an error like urllib
import requests
request = requests.get("http://stackoverflow.com/")
if "Apache" in request.headers['server']:
print "Apache Server found"
else:
print "This is no Apache Server"
Also see : http://www.python-requests.org/en/latest/ for more information
In python 3:
import urllib.request
response = urllib.request.urlopen('http://www.google.com')
print(response.headers['Server'])
would be the simplest way to get the server header in some cases.
Some sites (like stackoverflow), however, will return 403 error code.

How to get the IP address of a client issuing a GET request to a server-side Python script

I have a web app that performs a GET request and submits data to a server that runs a python script and writes this data to a file.
import cgi
import cgitb
import os
cgitb.enable()
if cgi.FieldStorage() is not None:
form = cgi.FieldStorage()
data = form.getvalue("data")
filename = "datalog.txt"
with open(filename, "a") as myfile:
myfile.write(data)
The above code catches the GET request data and then writes it to a file.
My question is, is there a way that I am able to find out the IP address from which the request was sent? Since the data catch was done by cgi I suspect that this must almost be done by cgi.
Any help is greatly appreciated.

Python file sending correct way? (urllib2, PyCurl).

Hello!
My problem is the python sending to a controller which works with a prepared html sending script. Here the problem is that upload does not succeed (doesn't even start uploading) although the script runs through. The file is a binary container file. The problem should be in the code, because other way the upload could be completed
Here the output:
09:54:40:11 ...STEP: Upload Firmware
09:54:49:63 ...Upload was successful!
09:54:49:64 ...POST resource
09:54:50:60 ...Response: {"uploadFirmwareAck":0}
So the upload "was done" it says within 9 sec but it should take about 5 minutes. With debugger I monitored that it did not start just jump over it and give the "Upload was successful" message. I have no clue why. Any ideas?
The code:
import pycurl
from cStringIO import StringIO
import urllib2
import simplejson as json
url = 'http://eData/pvi?rName=FirmwareUpload'
req = urllib2.Request(url)
req.add_header('Content-Type','application/json')
c = pycurl.Curl()
c.setopt(c.POST, 1)
c.setopt(c.URL, url)
c.setopt(c.CONNECTTIMEOUT,0)
c.setopt(c.TIMEOUT, 0)
c.setopt(pycurl.FOLLOWLOCATION, 1)
c.setopt(pycurl.MAXREDIRS, 5)
c.setopt(pycurl.NOSIGNAL, 1)
c.setopt(c.HTTPPOST, [("file1", (c.FORM_FILE, "c:\\Users\\dem2bp\\Desktop\\HMI_Firmware update materials\\output_38.efc"))])
c.perform()
print "Upload was successful!"
print "Tx JSON:"
print "POST resource"
res = urllib2.urlopen(req)
print "Response:"
str_0 = res.read()
print str_0
c.close()
From the documentation:
PycURL is targeted at an advanced developer - if you need dozens of
concurrent, fast and reliable connections or any of the sophisticated
features listed above then PycURL is for you.
I would give http://www.python-requests.org/en/latest/ a try. For me, it's always the first choice when doing some http stuff. Usually it just does what it' supposed to do in a few lines of code.
Thank you, but as I see this request library does not run with an old version of Python like 2.6. I think it would be too risky to upgrade. Do you have other idea?
When I import requests library at some point of library which requires later versions throw me synthax errors.

Checking if website responds in python using a browser user agent

I am trying to come up with a script to check if a domain name resolves to its IP address via dns; using a python script I wrote.
I want to be able to do this in a few sequential loops, however after trying to run a loop once, the second time i run the script, the names that previously returned a successful dns resolution response, now do not.
Below is my script:
#! C:\Python27
import socket,time
localtime = time.asctime( time.localtime(time.time()) )
def hostres(hostname):
print "Attempting to resolve " + hostname
try:
socket.gethostbyname(hostname)
print "Resolved Successfully!"
except socket.error:
print "Could Not Resolve"
print "*************************************************"
print "Website loop starting.."
print "Local current time :", localtime
print "*************************************************"
print ""
text_file = open("sites.txt", "r")
lines = text_file.readlines()
for line in lines:
hostres(line)
text_file.close()
The contents of the text file are:
www.google.com
en.wikipedia.org
www.youtube.com
us.gamespot.com
I am thinking it is to do with these domains servers recognizing the script as a "bot" rather than a legitimate end-user, would it be correct to assume this?
If so, how can I still check if the dns name resolves by looking up the name of the website (or IP, does not matter) and be able to run this without getting a false reading of "request failed" despite the fact that the service is fully accessible from a browser?
Several problems in this question.
You are not checking if "a website responds" you are testing DNS resolution. All your DNS requests go to a single name server, your LDNS resolver. If all of them resolve, it still says nothing about the status of the website. Also, since you aren't actually talking to these website, they have no way of knowing you're a bot. They can only detect this (based on the HTTP user-agent header) if you make a HTTP request.
Regarding your code problem, you need to trim the newline character before you can do a socket.gethostbyname() on it. Replace socket.gethostbyname(hostname) with socket.gethostbyname(hostname.rstrip()) and you'll be fine.

Categories