SOAP web service behind proxy, access using python-suds - python

I have this strange case scenario with python suds.
I have a soap service (java) running on a local ip, say http://10.0.0.1:8080/services/
I use suds http base auth within the local network and it's working fine.
from suds.client import Client
c = Client(url, username="user", password="pass")
But I want to make it accessible from outside, so I asked the system admin : "Can you set up a external IP use reverse proxy for this soap service"
"Yes, but the company firewall doesn't allow port 8080, so your rule will be:
http://10.0.0.1:8080/services/* <-> https://example.com/services/*
Then the rule is setup but I just can't make the client to work. I tried all kinds of transport:
from suds.transport.https import WindowsHttpAuthenticated
from suds.transport.http import HttpAuthenticated
#from suds.transport.https import HttpAuthenticated
from suds.client import Client
http = HttpAuthenticated(username="jlee", password="jlee")
#https = HttpAuthenticated(username="jlee", password="jlee")
ntlm = WindowsHttpAuthenticated(username="jlee", password="jlee")
url = "https://example.com/services/SiteManager?wsdl"
c = Client(url, transport = http)
it always returns:
suds.transport.TransportError: HTTP Error 403: Forbidden ( The server denied the specified Uniform Resource Locator (URL). Contact the server administrator. )
I tried to access the URL https://example.com/services/SiteManager?wsdl from chrome, it returns 403 too!
But if I sign in first using other routes (my server is running other http pages on tomcat), and then access the URL again the wsdl desc page shows up!
Can anybody tell me what's wrong with this? is it to do with the configuration of the reverse proxy server or the suds transport?
Thanks very much!
Jackie

Found the solution by talking to system admin(who's in charge of setting up the reverse proxy), he said there is an checkbox option in MS DMZ(reverse proxy server) for allow http base auth.

Related

Why python post request with nordvpn socks proxy doesn't work on distant hosted server while working on local windows?

On a python app, i send a request post through a socks proxy of nordvpn :
(los-angeles.us.socks.nordhold.net)
prox = {'https':'socks5://user:pass#host:port'}
requests.post(url, proxies=prox, data=data)
While this code works on my local windows environnement, the request been sent and received, the code gets an error when the app is hosted on a shared server.
socks.ProxyConnectionError: Error connecting to SOCKS5 proxy los-angeles.us.socks.nordhold.net:1080:
[Errno 111] Connection refused
Hoster says i need a root ssh access from a dedidated server. But how would it help ?
amsterdam.nl.socks.nordhold.net
atlanta.us.socks.nordhold.net
dallas.us.socks.nordhold.net
dublin.ie.socks.nordhold.net
ie.socks.nordhold.net
los-angeles.us.socks.nordhold.net
nl.socks.nordhold.net
se.socks.nordhold.net
stockholm.se.socks.nordhold.net
us.socks.nordhold.net
Port is 1080
your username is manually setup credentials and passwords too.
Dont try to use ur login data for it because it will never work.
Try with closing the connection.

Python socket.io server error 400 (NodeJS server works)

I'm trying to make JavaScript client to a Python websocket server through an Apache2 proxy.
The client is dead simple:
const socket = io({
transports: ['websocket']
});
I have a NodeJS websocket server and a working Apache2 reverse proxy setup.
Now I want to replace the NodeJS server with a Python server - but none of the example implementations from socket.io works. With each of the my client reports an "error 400" when setting up the websocket connection.
The Python server examples come from here:
https://github.com/miguelgrinberg/python-socketio/tree/master/examples/server
Error 400 stands for "Bad Request" - but I know that my requests are fine because my NodeJS server understands them.
When not running behind a proxy then all Python examples work fine.
What could be the problem?
I found the solution - all the Python socket.io server examples that I refered to are not configured to run behind a reverse proxy. The reason is, that the socket.io server is managing a list of allowed request origins and the automatic list creation is failing in the reverse proxy situation.
This function creates the automatic list of allowed origins (engineio/asyncio_server.py):
def _cors_allowed_origins(self, environ):
default_origins = []
if 'wsgi.url_scheme' in environ and 'HTTP_HOST' in environ:
default_origins.append('{scheme}://{host}'.format(
scheme=environ['wsgi.url_scheme'], host=environ['HTTP_HOST']))
if 'HTTP_X_FORWARDED_HOST' in environ:
scheme = environ.get(
'HTTP_X_FORWARDED_PROTO',
environ['wsgi.url_scheme']).split(',')[0].strip()
default_origins.append('{scheme}://{host}'.format(
scheme=scheme, host=environ['HTTP_X_FORWARDED_HOST'].split(
',')[0].strip()))
As you can see, it only adds URLs with {scheme} as a protocol. When behind a reverse proxy, {scheme} will always be "http". So if the initial request was HTTPS based, it will not be in the list of allowed origins.
The solution to this problem is very simple: when creating the socket.io server, you have to either tell him to allow all origins or specify your origin:
import socketio
sio = socketio.AsyncServer(cors_allowed_origins="*") # allow all
# or
sio = socketio.AsyncServer(cors_allowed_origins="https://example.com") # allow specific

How to get the ip address of a request machine using python (On Sanic)

I am trying to get the IP address of the requesting computer on my server. I can successfully get the IP-address from request header if the request came from a web browser. The code example below. However, I cannot fetch the client IP, if I send the request via curl/postman. I checked the nginx log, and I found there is a log of my public IP when I sent a curl request. How can I achieve this?
PS: I am using the Sanic Framework.
client_ip = request.headers.get('x-real-ip')
In sanic's docs for Request Data:
ip (str) - IP address of the requester.
Therefore, just use
client_ip = request.ip

Python HTTP HEAD request keepalive

Using Python httplib or httpclient, what code do I need to use in my HTTP client to:
use an HTTP HEAD request and
contact a web server by just specifying only its IP address and
contact a web server without specifying any webpage (or homepage) on the request
to extend its HTTP connection using Keepalive messages?
I used the following code example but it has two problems:
It does not extend the http connection using Keepalive,
It gives me an error message "500 Domain Not Found" if I use the IP address instead of the domain name.
import http.client
Connection = http.client.HTTPConnection("www.python.org")
Connection.request("HEAD", "")
response = Connection.getresponse()
print(response.status, response.reason)
requests allows to:
send requests with HEAD method:
import requests
resp = requests.head("http://www.python.org")
use sessions for auto Keep-alive: info
s = requests.Session()
resp = s.head("http://www.python.org")
resp2 = s.get("http://www.python.org/")
Regarding using the IP address instead of domain, that has nothing to do with your request. Most sites use some kind of virtual hosts, so they don't respond to IP address only to specific domain names. If you ask for the IP address you may get a 500 error or a message error.

Send mail with Chilkat Mailman using authenticated HTTP proxy

I am trying to send emails using the chilkat mailman api in python, through an authenticated http proxy. I have followed the instructions from the Chilkat docs to the best of my ability but am having issues with the proxy server. I have verified that this proxy works given the specified port and auth using phantomjs scripts.
import chilkat
# The mailman object is used for sending and receiving email.
mailman = chilkat.CkMailMan()
# set the http proxy
mailman.put_HttpProxyAuthMethod("LOGIN")
mailman.put_HttpProxyHostname("xxx.xxx.xxx.xxx")
mailman.put_HttpProxyPort(xxxxx)
mailman.put_HttpProxyUsername("xxxxx")
mailman.put_HttpProxyPassword("xxxxx")
# Set the SMTP server.
mailman.put_SmtpHost("smtp.live.com")
mailman.put_StartTLS(True)
mailman.put_SmtpPort(25)
# Set the SMTP login/password (if required)
mailman.put_SmtpUsername("xxxxxxx")
mailman.put_SmtpPassword("xxxxxxx")
# Create a new email object
email = chilkat.CkEmail()
email.put_Subject("This is a test")
email.put_Body("This is a test")
email.put_From("name#email.com")
email.AddTo("Chris Johnson","name#email.com")
# Call SendEmail to connect to the SMTP server via the HTTP proxy and send.
success = mailman.SendEmail(email)
if (success != True):
print(mailman.lastErrorText())
sys.exit()
If I take out the section that sets the proxy, the mail is successfully sent. Is there some other attribute I am missing?
Though Chillkat's mailman has support for HTTP proxies, it seems that it doesn't support pure HTTP proxies. Mainly, the proxy that you use must also support other protocols because SMTP doesn't broadcast over HTTP. As my proxy only supported HTTP protocol, it wouldn't work for me. I swapped to use a SOCKS proxy and now everything is working fine.

Categories

Resources