I have a linux server which I am running my flask app on it like this:
flask run --host=0.0.0.0
Inside the server I can access it like this:
curl http://0.0.0.0:5000/photo (and I am getting a valid response)
However, when I am trying to access it outside the server:
http://my_ip:5000/photo - the connection is refused.
The same ip, will return an image saved on public_html with apache2 configured
http://my_ip/public_html/apple-touch-icon-144x144-precomposed.png
I use this simple snippet to get the ip-address from the interface
import socket
def get_ip_address():
""" get ip-address of interface being used """
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
return s.getsockname()[0]
IP = get_ip_address()
And in main:
if __name__ == '__main__':
app.run(host=IP, port=PORT, debug=False)
And running:
./app.py
* Running on http://10.2.0.41:1443/ (Press CTRL+C to quit)
I have a suspicion you have a firewall on your Linux machine that is blocking port 5000.
Solution 1:
Open the relevant port on your firewall.
Solution 2:
I would suggest you to install nginx as a web proxy and configure it so that http://my_ip/photo would forward traffic to and from http://127.0.0.1:5000/photo:
server {
listen 80;
location /photo {
proxy_pass http://127.0.0.1:5000/photo;
}
}
Related
I want to run a web server on an ephemeral port and somehow keep the knowledge of its number. I decided to do it in such a way:
from flask import Flask
import socket
app = Flask(__name__)
def find_free_port():
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(("0.0.0.0", 0))
port = sock.getsockname()[1]
sock.close()
return port
#app.route("/")
def home():
return "Hello, World!"
if __name__ == "__main__":
app.run(host="0.0.0.0", port=find_free_port())
On my personal computer I can query both localhost and 0.0.0.0 but there is a machine where it does not work, I receive
curl: (7) Failed connect to localhost:<port_number>; Connection refused
What might be the cause? The problem disappears when I use localhost as the interface instead of binding to all of them
If you try to use the real IP address lets say 192.168.1.104 on the other machine, it will work.
This is because when you use 0.0.0.0 on the other machine, you will be requesting from the same machine yet the port is not open.
so change the request to http://ip_address:port_number
the server is running in VM with vagrant :
vagrant#ubuntu-xenial:/vagrant/email_api$ python3 emailapi.py
Bottle v0.12.17 server starting up (using WSGIRefServer())...
Listening on http://127.0.0.1:8080/
Hit Ctrl-C to quit.
but when i use IP to access to api i get :
Could not get any response
There was an error connecting to .
Why this might have happened:
-The server couldn't send a response:
Ensure that the backend is working properly
-Self-signed SSL certificates are being blocked:
Fix this by turning off 'SSL certificate verification' in Settings > General
-Proxy configured incorrectly
Ensure that proxy is configured correctly in Settings > Proxy
-Request timeout:
Change request timeout in Settings > General
*vagrant file :
config.vm.network "forwarded_port", guest: 80, host: 8080, auto_correct:
true
config.vm.network "private_network", ip: "192.168.33.10"
config.vm.network "public_network"
you should run your bottle app on 0.0.0.0 to export it to "other" machines
app.run(host="0.0.0.0", port=80, reloader=True, debug=True) # ...
For me i proxy pass the internall server with nginx works well just make a configuration on nginx like this
server{
listen 85;
listen [::]:85;
server_name rsshistory.com;
location / {
proxy_pass http://127.0.0.1:8000/;
}
}
On the vagrant file, dont turn on all of that just do this
# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine and only allow access
# via 127.0.0.1 to disable public access
# config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.$
# Create a private network, which allows host-only access to the machine
# using a specific IP.
config.vm.network "private_network", ip: "192.168.33.11"
Now you can access to the bottle server true 192.168.33.11:85
I can't preview this appliation using AWS Cloud9 (c9) python flask:
from flask import Flask
import os
app = Flask(__name__)
#app.route("/")
def hello():
return "Hello World!"
host = 'localhost' # '0.0.0.0' #"127.0.0.1" # I tried all of these ip's
if __name__ == '__main__':
app.debug = True
port = int(os.environ.get("PORT", 8080)) # I also tried port was 5000
app.run(host=host, port=port)
# This is the error I got 52.15.73.96 The connection has timed out
#The server at 52.15.73.96 is taking too long to respond.
This is similar to AWS cloud9 timeout when running flask application
Here is the answer: You have to get past the AWS firewall.
You have to
Go into EC2 (from the list of all AWS services)
Click security groups
Click your Cloud9 instance
Click Inbound
Click Edit
Click Add Rule
Add this rule:
For Type, choose Custom TCP Rule. - All Traffic also worked.
For Port Range, type 8080, 8081, or 8082. - If you did 'All Traffic' this will default to all ports.
For Source, choose Anywhere, which looks like 0.0.0.0/0
Here is a screen shot link: https://imgur.com/a/zhQbA
AWS does have this, buried, in their C9 documentation.
https://docs.aws.amazon.com/cloud9/latest/user-guide/app-preview.html#app-preview-share-security-group
In Share a Running Application over the Internet, Step 2: Set Up the Security Group for the Instance
You need to run your server in 0.0.0.0 using port 8080 (or other available C9 ports).
Change your app.run() command to something like this:
app.run(host='0.0.0.0', port=8080, debug=True)
If 8080 doesn’t work, try with 80.
flask run --host=127.0.0.1 --port=8080
I have a autobahn twisted websocket running in python which is working in a dev vm correctly but I have been unable to get working when the server is running in openshift.
Here is the shortened code which works for me in a vm.
from autobahn.twisted.websocket import WebSocketServerProtocol, WebSocketServerFactory, listenWS
from autobahn.twisted.resource import WebSocketResource
class MyServerProtocol(WebSocketServerProtocol):
def onConnect(self, request):
stuff...
def onOpen(self):
stuff...
def onMessage(self,payload):
stuff...
factory = WebSocketServerFactory(u"ws://0.0.0.0:8080")
factory.protocol = MyServerProtocol
resource = WebSocketResource(factory)
root = File(".")
root.putChild(b"ws", resource)
site = Site(root)
reactor.listenTCP(8080, site)
reactor.run()
The connection part of the client is as follows:
var wsuri;
var hostname = window.document.location.hostname;
wsuri = "ws://" + hostname + ":8080/ws";
if ("WebSocket" in window) {
sock = new WebSocket(wsuri);
} else if ("MozWebSocket" in window) {
sock = new MozWebSocket(wsuri);
} else {
log("Browser does not support WebSocket!");
window.location = "http://autobahn.ws/unsupportedbrowser";
}
The openshift configuration is as follows:
1 pod running with app.py listening on port 8080
tls not enabled
I have a non-tls route 8080 > 8080.
Firefox gives the following message in the console:
Firefox can’t establish a connection to the server at ws://openshiftprovidedurl.net:8080/ws.
when I use wscat to connect to the websocket.
wscat -c ws://openshiftprovidedurl.net/ws
I get the following error:
error: Error: unexpected server response (400)
and the application log in openshift shows the following:
2018-04-03 01:14:24+0000 [-] failing WebSocket opening handshake ('missing port in HTTP Host header 'openshiftprovidedurl.net' and server runs on non-standard port 8080 (wss = False)')
2018-04-03 01:14:24+0000 [-] dropping connection to peer tcp4:173.21.2.1:38940 with abort=False: missing port in HTTP Host header 'openshiftprovidedurl.net' and server runs on non-standard port 8080 (wss = False)
2018-04-03 01:14:24+0000 [-] WebSocket connection closed: connection was closed uncleanly (missing port in HTTP Host header 'openshiftprovidedurl.net' and server runs on non-standard port 8080 (wss = False))
Any assistance would be appreciated!
Graham Dumpleton hit the nail on the head, I modified the code from
factory = WebSocketServerFactory(u"ws://0.0.0.0:8080")
to
factory = WebSocketServerFactory(u"ws://0.0.0.0:8080", externalPort=80)
and it corrected the issue. I had to modify my index to point to the correct websocket but I am now able to connect.
Thanks!
Based on the source code of autobahn-python, you can get that message only in 2 cases.
Here is the implementation:
if not ((self.factory.isSecure and self.factory.externalPort == 443) or (not self.factory.isSecure and self.factory.externalPort == 80)):
return self.failHandshake("missing port in HTTP Host header '%s' and server runs on non-standard port %d (wss = %s)" % (str(self.http_request_host), self.factory.externalPort, self.factory.isSecure))
Because I think you are using Deployment + Service (and maybe Ingress on top of them) for your server, you can bind your server to port 80 instead of 8080 and set that port in Service and in Ingress, if you are using them.
I am running my application with Windows Azure on a Virtual Machine with ubuntu 14.04 lts. I am running my Django application through WSGI on Apache.
Previously i ran django locally with the command "python manage.py runserver", and every thing worked fine when my website connected to my sockets.py file from website.html.
I am running Django through Apache on public ip port 80
I am running the sockets.py separately in a terminal through Putty
I am reading the error through the Google Chrome console
Suddenly this error occurs: Failed to execute 'send' on 'WebSocket': Still in CONNECTING state. whenever i try to connect to the socket.
After a while my page response with: failed: Error in connection establishment: net::ERR_CONNECTION_TIMED_OUT
website.html js:
ws = new WebSocket("ws://10.77.22.74:1339/ws");
function load_all() {
target = "load_all"
ws.send(target)
}
ws.onmessage = function(evt) {
console.log(evt.data)
}
The ip is my internal ip on my virtual machine.
sockets.py:
import tornado.httpserver
import tornado.websocket
import tornado.ioloop
import tornado.web
class WSHandler(tornado.websocket.WebSocketHandler):
def check_origin(self, origin):
return True
def open(self):
print 'new connection'
def on_message(self, message):
self.write_message(message)
def on_close(self):
print 'connection closed'
application = tornado.web.Application([
(r'/ws', WSHandler),
])
if __name__ == "__main__":
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(1339)
tornado.ioloop.IOLoop.instance().start()
I have tried to change the http_server.listen(1339) to http_server.listen(1339, adress='10.77.22.74') (sockets.py)
I have tried using my public ip and opening a port through tcp (endpoints) and adjusting the scripts after that (sockets.py & website.html)
I have tried running with the localhost & 127.0.0.1 (sockets.py & website.html)
I have tried with ws & wss
I still get the error for some reason, do i need to give Apache (www-data) some permissions to connect to the sockets.py?
Which IP should i use, both on socket.py and website.htm?
Solved
Turn out Tornado is listening to all IP:s if you not specify the adress in the socket server. I opened a port on the public IP and used that IP for my javascript socket connection.