Can anyone tell me what's the solution for this?
When I run it and load it from the browser... It's only loading and never displaying the "Hello Word!" text.
But the text will appear in the browser after I shutdown the server by triggering the KeyboardInterrupt.
PS: SSL is enabled in python 2.6 interpreter on Linux. Also, it's not working in Windows 7.
Here's the code:
#!/usr/bin/python
from BaseHTTPServer import BaseHTTPRequestHandler,HTTPServer
import ssl
import sys
PORT_NUMBER = int(sys.argv[1])
#This class will handles any incoming request from the browser
class myHandler(BaseHTTPRequestHandler):
#Handler for the GET requests
def do_GET(self):
print(self.requestline)
#print(self.rfile.read(content_length))
self.send_response(200)
self.send_header('Content-type','text/html')
self.end_headers()
# Send the html message
self.wfile.write("Hello World !".encode())
return
try:
#Create a web server and define the handler to manage the
#incoming request
server = HTTPServer(('', PORT_NUMBER), myHandler)
server.socket = ssl.wrap_socket(server.socket, certfile='cert.pem',keyfile='key.pem', server_side=True)
print 'Started httpserver on port ' , PORT_NUMBER
#Wait forever for incoming htto requests
server.serve_forever()
except KeyboardInterrupt:
print '^C received, shutting down the web server'
server.socket.close()
in order to run this in Python 2.x, command: python this_code.py [port]
Example:
python this_code.py 8080
Then navigate to the browser with the address: https://localhost:8080/
If I remove this line, it'll work but it's just running under HTTP protocol and not in HTTPS (which I'm intended to run in):
server.socket = ssl.wrap_socket(server.socket, certfile='cert.pem',keyfile='key.pem', server_side=True)
Related
Hey so I have been trying to make a script that just reads the amount of followers someone has and then send the amount of followers back to the server that requested it. I have absolutely no idea how http works or how to properly format a variable to go across it. Whenever I make a request I get a bad response error. I know what is causing this, it’s the variable and how python formats it, but how would I send this over http? Any help? (Also this server won't have very much traffic at all)
import selenium
from selenium import webdriver
import time
import http
import http.server
import socketserver
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
driver = webdriver.Chrome()
class requestHandler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('content-type', 'text/html')
self.end_headers
print(self.path[1:])
driver.get('https://www.tiktok.com/#%s?lang=en' % self.path[1:])
FOLLOWERS = driver.find_element_by_xpath('//*[#id="main"]/div[2]/div[2]/div/header/h2[1]/div[2]/strong').text
driver.close
print(str(FOLLOWERS))
self.wfile.write((str(FOLLOWERS).encode()))
def main():
PORT = 8000
server = HTTPServer(('', PORT), requestHandler)
print('Server running on port %s' % PORT)
server.serve_forever()
if __name__ == '__main__':
main()```
You forgot to create a function call when ending the header.
self.end_headers()
is what you want (the round brackets are missing). otherwise, chrome won't recognize this as a valid HTTP response.
Interestingly, this code works when using firefox.
I have a scenario where I need to first respond with HTTP 200 to a server request (due to a time limit) and then continue processing with the actual work.
I also can not use threads, processes, tasks, queues or any other method that would allow me to do this by starting a parallel "process".
My approach is to use the build in "Simple HTTP" server and I am looking for a way to force the server to respond with HTTP 200 and then be able to continue processing.
The current code will receive a POST request and print its content after a 3 seconds. I put a placeholder where I would like to send the response.
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
class MyWebServer(BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
self.send_response_only(200)
self.end_headers()
# force server to send request ???
time.sleep(3)
print(post_data)
def run(server_class=HTTPServer, handler_class=MyWebServer, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print('Starting httpd...')
httpd.serve_forever()
if __name__ == "__main__":
run()
I figured out a workaround solution. You can force the server to send a 200 OK and continue processing after with these two commands:
self.finish()
self.connection.close()
This solution is from this SO question: SimpleHTTPRequestHandler close connection before returning from do_POST method
However, this will apparently close the internal IO buffer that the server uses and it won't be able to server any additional requests after that.
To avoid running into an exception it works to terminate the program (which works for me). However this is just a workaround and I would still be looking for a solution that allows the server to keep processing new requests.
from http.server import BaseHTTPRequestHandler, HTTPServer
import time
class MyHandler(BaseHTTPRequestHandler):
def do_POST(self):
content_length = int(self.headers['Content-Length'])
post_data = self.rfile.read(content_length)
self.send_response_only(200)
self.end_headers()
self.finish()
self.connection.close()
time.sleep(3)
print(post_data)
quit()
def run(server_class=HTTPServer, handler_class=MyHandler, port=8000):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
print('Starting httpd...')
httpd.serve_forever()
if __name__ == "__main__":
run()
I am attempting to start a simple HTTP web server in python and then ping it with the selenium driver. I can get the web server to start but it "hangs" after the server starts even though I have started it in a new thread.
from socket import *
from selenium import webdriver
import SimpleHTTPServer
import SocketServer
import thread
def create_server():
port = 8000
handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = SocketServer.TCPServer(("", port), handler)
print("serving at port:" + str(port))
httpd.serve_forever()
thread.start_new_thread(create_server())
print("Server has started. Continuing..")
browser = webdriver.Firefox()
browser.get("http://localhost:8000")
assert "<title>" in browser.page_source
thread.exit()
The server starts but the script execution stops after the server has started. The code after I start the thread is never executed.
How do I get the server to start and then have the code continue execution?
Start your thread with function create_server (without calling it ()):
thread.start_new_thread(create_server, tuple())
If you call create_server(), it will stop at httpd.serve_forever().
For Python 3 you can use this:
import threading
threading.Thread(target=create_server).start()
I'm working on a python file that sends the response to the localhost website opened by the browser. This web can successfully open by the same device which hosts it, but when failed to be opened by the other device under the same LAN. Why does that happen?
I use http.server in Python3 to host the local server. I'm using these codes:
from http.server import BaseHTTPRequestHandler, HTTPServer
hostName = "localhost"
hostPort = 9000
class MyServer(BaseHTTPRequestHandler):
def do_GET(self):
path = self.path
print(path)
referer = self.headers.get('Referer')
print("The referer is", referer)
self.send_response(200)
self.send_header("Content-type", "text/html")
self.end_headers()
# str is the html code I used
self.wfile.write(bytes(str, "utf-8"))
myServer = HTTPServer((hostName, hostPort), MyServer)
print("Server Starts - %s:%s" % (hostName, hostPort))
try:
myServer.serve_forever()
except KeyboardInterrupt:
pass
myServer.server_close()
print("Server Stops - %s:%s" % (hostName, hostPort))
I am able to open the web by using localhost and 127.0.0.1, but just not the ip address.
Can anyone help me, please? Thank you
Use your machine's IP address instead of localhost(Loopback) as the host. If your machine's IP is 192.168.x.x then the server will run at: 192.168.x.x:9000.
I just encountered a weird issue about bottle on windows.
When I tested the my bottle codes, I found that it could run multiple same programs on WINDOWS using same address and port. But when you try to start multiple same program on the Linux or Mac using same address and port, it will report the below error:
socket.error: [Errno 48] Address already in use
my bottle codes are:
from bottle import route, run, template
#route('/hello/:name')
def index(name='World'):
return template('<b>Hello {{name}} </b>', name=name)
run(host='localhost', port=9999)
Then I traced the code, from bottle to wsgiref, and finnaly found that the problem might be in the Python27\Lib\BaseHTTPServer.py.
I mean when I use the the below simple codes:
import BaseHTTPServer
def run(server_class=BaseHTTPServer.HTTPServer,
handler_class=BaseHTTPServer.BaseHTTPRequestHandler):
server_address = ('localhost', 9999)
print "start server on localhost 9999"
httpd = server_class(server_address, handler_class)
httpd.serve_forever()
run()
The same issue would happen on windows.
But if I directly used the socketserver, like the below codes:
import SocketServer
class MyTCPHandler(SocketServer.BaseRequestHandler):
def handle(self):
# self.request is the TCP socket connected to the client
self.data = self.request.recv(1024).strip()
print "{} wrote:".format(self.client_address[0])
print self.data
# just send back the same data, but upper-cased
self.request.sendall(self.data.upper())
if __name__ == "__main__":
HOST, PORT = "localhost", 9999
print "Start a server on localhost:9999"
# Create the server, binding to localhost on port 9999
server = SocketServer.TCPServer((HOST, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
server.serve_forever()
The same issue will not happen, I mean even on window the above socketserver codes will report the error, when you try to start another programe.
socket.error: [Errno 48] Address already in use
All my tests used the Python 2.7, Windows 7 and Centos 5.
So my questions are why the HTTPServer will have this issue on windows?
And how can I let my bottle programe will report the same error on windows, just like on windows?
Sorry to bother all.
I've found the resolution, just so simple.
Simply change the BaseHTTPServer.HTTPServer's attribute allow_reuse_address to 0.
The codes should be:
from bottle import route, run, template
import BaseHTTPServer
#route('/hello/:name')
def index(name='World'):
return template('<b>Hello {{name}} </b>', name=name)
setattr(BaseHTTPServer.HTTPServer,'allow_reuse_address',0)
run(host='localhost', port=9999)