I've study the twisted xmlrpc tutorial: http://twistedmatrix.com/documents/current/web/howto/xmlrpc.html to setup a xmlrpc server for building my xmlrpc method, but I want to know some request information from client like ip address. Tutorials just tell my add xmlrpc_ as prefix makes my method to be a remote procedure call. Does anyone know how to rewrite it? Any help will be appreciated. Or maybe I need to force client to send its ip as parameters?
def xmlrpc_some_method(self):
if request.ip in bad_ips():
return '404'
else:
return do_something()
I haven't used xmlrpc myself but by going through the source [1], it looks like you can decorate the function with t.w.x.withRequest [2] and then you will get request as the first argument to the function.
[1] http://twistedmatrix.com/trac/browser/tags/releases/twisted-13.0.0/twisted/web/xmlrpc.py#L169
[2] http://twistedmatrix.com/trac/browser/tags/releases/twisted-13.0.0/twisted/web/xmlrpc.py#L37
Related
This question already has answers here:
FastAPI (starlette) get client real IP
(11 answers)
Closed 1 year ago.
I have an API method deploy on my local server,
#app.post("/test/api")
async def method():
if incoming.request.url or domain == "this":
do some operation
else:
skip it
.....
return something
Now, Few people are using my API method, but is there any way I could track who is calling my api method and do specific extra operations to the once I specified who is calling my api.
How can I track the incoming domain name or ip or url of the people who are using my api method?
Note: Need a basic example on how to acheive it if you familiar with it
Is it something possible?
If you were using flask it could happen simply by getting remote_addr as below:
from flask import FLASK, request
#app.route('/test/api', methods=['POST']):
def method():
visitor_ip = request.remote_addr
In fastapi it should happen like this: request.client.host
any way you can work with headers in your code and get many details of your client
If you can access incoming request headers, then check if X-Forwarded-For has IP address of client. If not it is possible that changing configuration of your setup will make it works as intended, however I have not experience with neither fastapi or uvicorn, so I am unable to write anything more precise.
If I add #gen.coroutine to the method handling a request that was generated by connexion, it stops working. It will break the connection with the client and does not return anything.
How can I use connexion+tornado asynchronously? gen.sleep for example?
If I yield gen.sleep in the request handler without #gen.coroutine, it does not wait for the specified time.
I found the answer.
It's not pleasant though..
https://waffle.io/zalando/connexion/cards/57c036758b96c67f0165fb9f
#funseiki ... giving it more though we would need to actually do quite some changes in other parts of the Connexion code to support Tornado async. For now the answer is "not possible". :/
I work on a Django based app, and I want to know if there's a way to know if my server uses http connections or https.
I know that using
import socket
if socket.gethostname().startswith('****'):
I can get the hostname, is it possible to do something like that so I can get to know if the hosting uses a ssl certificate?
PD: I'm a rookie here, so I'm asking to see if it's possible and, if it is, how should I do it.
Thanks
it's completely possible:
def some_request_function(request):
if request.is_secure():
#You are safe!
else:
#You are NOT safe!
More details:
https://docs.djangoproject.com/en/2.0/ref/request-response/#django.http.HttpRequest.is_secure
There simply is an is_secure() method on the request object, returning True if the connection is secure.
Depending on your specific server configuration you may also need to set SECURE_PROXY_SSL_HEADER in your settings.
django requests (HttpRequest) have is_secure method:
https://docs.djangoproject.com/en/dev/ref/request-response/#django.http.HttpRequest.is_secure
I am trying to add authentication to a xmlrpc server (which will be running on nodes of a P2P network) without using user:password#host as this will reveal the password to all attackers. The authentication is so to basically create a private network, preventing unauthorised users from accessing it.
My solution to this was to create a challenge response system very similar to this but I have no clue how to add this to the xmlrpc server code.
I found a similar question (Where custom authentication was needed) here.
So I tried creating a module that would be called whenever a client connected to the server. This would connect to a challenge-response server running on the client and if the client responded correctly would return True. The only problem was that I could only call the module once and then I got a reactor cannot be restarted error. So is there some way of having a class that whenever the "check()" function is called it will connect and do this?
Would the simplest thing to do be to connect using SSL? Would that protect the password? Although this solution would not be optimal as I am trying to avoid having to generate SSL certificates for all the nodes.
Don't invent your own authentication scheme. There are plenty of great schemes already, and you don't want to become responsible for doing the security research into what vulnerabilities exist in your invention.
There are two very widely supported authentication mechanisms for HTTP (over which XML-RPC runs, therefore they apply to XML-RPC). One is "Basic" and the other is "Digest". "Basic" is fine if you decide to run over SSL. Digest is more appropriate if you really can't use SSL.
Both are supported by Twisted Web via twisted.web.guard.HTTPAuthSessionWrapper, with copious documentation.
Based on your problem description, it sounds like the Secure Remote Password Protocol might be what you're looking for. It's a password-based mechanism that provides strong, mutual authentication without the complexity of SSL certificate management. It may not be quite as flexible as SSL certificates but it's easy to use and understand (the full protocol description fits on a single page). I've often found it a useful tool for situations where a trusted third party (aka Kerberos/CA authorities) isn't appropriate.
For anyone that was looking for a full example below is mine (thanks to Rakis for pointing me in the right direction). In this the user and password is stored in a file called 'passwd' (see the first useful link for more details and how to change it).
Server:
#!/usr/bin/env python
import bjsonrpc
from SRPSocket import SRPSocket
import SocketServer
from bjsonrpc.handlers import BaseHandler
import time
class handler(BaseHandler):
def time(self):
return time.time()
class SecureServer(SRPSocket.SRPHost):
def auth_socket(self, socket):
server = bjsonrpc.server.Server(socket, handler_factory=handler)
server.serve()
s = SocketServer.ForkingTCPServer(('', 1337), SecureServer)
s.serve_forever()
Client:
#! /usr/bin/env python
import bjsonrpc
from bjsonrpc.handlers import BaseHandler
from SRPSocket import SRPSocket
import time
class handler(BaseHandler):
def time(self):
return time.time()
socket, key = SRPSocket.SRPSocket('localhost', 1337, 'dht', 'testpass')
connection = bjsonrpc.connection.Connection(socket, handler_factory=handler)
test = connection.call.time()
print test
time.sleep(1)
Some useful links:
http://members.tripod.com/professor_tom/archives/srpsocket.html
http://packages.python.org/bjsonrpc/tutorial1/index.html
I'm working on a project that works with tornado's websocket functionality. I see a decent amount of documentation for working with asychronous code, but nothing on how this can be used to create unit tests that work with their WebSocket implementation.
Does tornado.testing provide the functionality to do this? If so, could someone provide a brief example of how to make it happen?
Thanks in advance.
As #Vladimir said, you can still use AsyncHTTPTestCase to create/manage the test webserver instance, but you can still test WebSockets in much the same way as you would normal HTTP requests - there's just no syntactic sugar to help you.
Tornado also has its own WebSocket client so there's no need (as far as I've seen) to use a third party client - perhaps it's a recent addition though. So try something like:
import tornado
class TestWebSockets(tornado.testing.AsyncHTTPTestCase):
def get_app(self):
# Required override for AsyncHTTPTestCase, sets up a dummy
# webserver for this test.
app = tornado.web.Application([
(r'/path/to/websocket', MyWebSocketHandler)
])
return app
#tornado.testing.gen_test
def test_websocket(self):
# self.get_http_port() gives us the port of the running test server.
ws_url = "ws://localhost:" + str(self.get_http_port()) + "/path/to/websocket"
# We need ws_url so we can feed it into our WebSocket client.
# ws_url will read (eg) "ws://localhost:56436/path/to/websocket
ws_client = yield tornado.websocket.websocket_connect(ws_url)
# Now we can run a test on the WebSocket.
ws_client.write_message("Hi, I'm sending a message to the server.")
response = yield ws_client.read_message()
self.assertEqual(response, "Hi client! This is a response from the server.")
# ...etc
Hopefully that's a good starting point anyway.
I've attempted to implement some unit tests on tornado.websocket.WebSocketHandler based handlers and got the following results:
First of all AsyncHTTPTestCase definitely has lack of web sockets support.
Still, one can use it at least to manage IOLoop and application stuff which is significant. Unfortunately, there is no WebSocket client provided with tornado, so here enter side-developed library.
Here is unit test on Web Sockets using Jef Balog's tornado websocket client.
This answer (and the question) may be of interest, I use ws4py for the client and Tornado's AsyncTestCase which simplifies the whole thing.