Web Server & Socket Programming - python

Currently doing an assignment in which we are programming sockets in python and thus creating a web server when the webserver.py code is executed.The code should then display HTTP headers and other information when you access a file(test.html)from the web server. Now my code works (or I'd like to believe so) and I have created a test.html file and the question goes on to say that I should place the test.html file in the same directory as the web server, where exactly is that on my local machine? I placed the test.html in the same folder as webserver.py in the python's root directory and proceeded to 127.0.0.1:1336/test.html to test my code but it doesn't work, where exactly on my machine is the webserver directory in which I should place test.html? Is it that I have to use wamp/xamp and place the test.html in there?
N.B 1336 is the port I specified in the code to connect to.
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
serverPort = 1336
serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serverSocket.bind(('', serverPort)) #set up socket connection
serverSocket.listen(1) #tells the server to try a maximum of one connect request before ending connection
while True:
#Establish the connection
print 'Ready to serve...'
connectionSocket, addr = serverSocket.accept()
print 'connected to port',serverPort
try:
message = connectionSocket.recv(1024) #Makes it so that you can recieve message from client
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.open(filename[1:])
#Send one HTTP header line into socket2
#Fill in start
connectionSocket.send('HTTP/1.0 200 OK\r\n')
#Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.close()
except IOError:
#Send response message for file not found
print '404 Error : File Not Found.'
#Close client socket
connectionSocket.close()
serverSocket.close()

First of all, you shouldn't use the socket module to make a HTTP server. I recommend using the http.ser ver module, and change the working directory to where the html files are. Lets say i had test.html in C:\User\Desktop.
An example:
from http.server import HTTPServer, CGIHTTPRequestHandler
import os
os.chdir("C:/User/Desktop")
address = ("", 1336)
httpserver = HTTPServer(address,, CGIHTTPRequestHandler)
httpserver.serve_forever()
Then you can access it by 127.0.0.1:1336/test.html
If this isn't the answer you are looking for, please add the webserver.py to the question.

Related

Can I make a client socket only to establish a connection using python 3.6

I'm reading about socket module in a web learning site about python, they gave us a simple steps to use socket module like follows:
import socket
with socket.socket() as client_socket:
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
data = 'Wake up, Neo'
data = data.encode()
client_socket.send(data)
response = client_socket.recv(1024)
response = response.decode()
print(response)
when executing I got the error message:
ConnectionRefusedError: [WinError 10061] No connection could be made because the target machine actively refused it.
when I searched about this some sites was talking about server listening and I see in most of tutorials about server socket and they use it along with client one.
so Is the error message related to the fact that I'm not using a server socket and is it a must to use them both
Update:
after reading the answers I got, I went to the test.py file that the course instructors use to evaluate our codes and I see that they make the server socket in it , so the server is already made by them. that take me back to the Error I got why does it happen then.
def server(self):
'''function - creating a server and answering clients'''
self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
self.sock.bind(('localhost', 9090))
self.ready = True
try:
self.sock.listen(1)
conn, addr = self.sock.accept()
self.connected = True
conn.settimeout(15)
while True:
data = conn.recv(1024)
self.message.append(data.decode('utf8'))
if len(self.message) > 1_000_000:
conn.send(
json.dumps({
'result': 'Too many attempts to connect!'
}).encode('utf8'))
break
if not data:
break
Each connection requires a client, which initiates the connection, and a server, which listens for the incoming connection from the client. The code you have shown is for the client end of the connection. In order for this to run successfully you will need a server listening for the connection you are trying to create.
In the code you showed us you have the lines
hostname = '127.0.0.1'
port = 9090
address = (hostname, port)
client_socket.connect(address)
These are the lines that define what server you are connecting to. In this case it is a server at 127.0.0.1 (which is localhost, the same machine you are running the code on) listening on port 9090.
If you want to make your own server then you can look at the documentation for Python sockets and the particular functions you want to know about are bind, listen, and accept. You can find examples at the bottom of that same page.
Given that you appear to have found this code as part of a course, I suspect they may provide you with matching server code at some point in order to be able to use this example.

Simple Python TCP Server Not Sending the Entire Web Page

I'm a beginner compsci student and I'm trying to code a simple server in python that takes a .HTML page stored in the same directory and sends it to a client on the same network using a TCP connection.
This is my code:
from socket import *
serverPort = 8000
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
serverSocket.bind(('', serverPort)) # binds socket to port 8000
serverSocket.listen(1) # waiting for client to initiate connection
while True:
# Establish the connection
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:].decode())
outputdata = f.read()
# Send one HTTP header line into socket
http_response = 'HTTP/1.1 200 OK\n'
connectionSocket.send(http_response.encode())
# Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i].encode())
connectionSocket.send("\r\n".encode())
connectionSocket.close()
except IOError:
connectionSocket.send("\r\n".encode())
# DO LATER
serverSocket.close()
sys.exit()
And this is my simple html page:
<!DOCTYPE html>
<html>
<body>
<h1>My First Web Page</h1>
<p>You have successfully accessed the Web Server</p>
</body>
</html>
So far whenever I run my server and direct my browser to it, I only get the following served to me:
<p>You have successfully accessed the Web Server</p>
Along with the body and html tags after this. Checking the page source there's no header.
I ran Wireshark while trying to access my server and indeed it seems like I'm only sending through "You have successfully accessed the Web server" and onwards. This is despite the fact a print function shows I am definitely sending all the data in the file through the TCP connection.
Does anyone know what the issue is?
After sending the protocol answer and headers, the actual response comes after two \r\n sequences.
Use this fixed code:
from socket import *
serverPort = 8000
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
serverSocket.bind(('', serverPort)) # binds socket to port 8000
serverSocket.listen(1) # waiting for client to initiate connection
while True:
# Establish the connection
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:].decode())
outputdata = f.read()
# Send one HTTP header line into socket
http_response = 'HTTP/1.1 200 OK\n'
connectionSocket.send(http_response.encode())
connectionSocket.send("\r\n".encode())
connectionSocket.send("\r\n".encode())
# Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i].encode())
connectionSocket.close()
except IOError:
# DO LATER
serverSocket.close()
sys.exit()
I would use the http.server library
import http.server
import socketserver
PORT = 8080
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
httpd.serve_forever()
source: https://www.afternerd.com/blog/python-http-server/

Python Socket Programming Simple Web Server, Trying to access a html file from server

So, i am trying to create a simple server on python and trying to access a html file in the same directory through it, but as the output i keep on getting ready to serve...
output
EDIT:
Put an HTML file (e.g., HelloWorld.html) in the same directory that the server is in. Run the server program. Determine the IP address of the host that is running the server (e.g., 128.238.251.26). From another host, open a browser and provide the corresponding URL. For example:
http://128.238.251.26:6789/HelloWorld.html
‘HelloWorld.html’ is the name of the file you placed in the server directory. Note also the use of the port number after the colon. You need to replace this port number with whatever port you have used in the server code. In the above example, we have used the port number 6789. The browser should then display the contents of HelloWorld.html. If you omit ":6789", the browser will assume port 80 and you will get the web page from the server only if your server is listening at port 80.
Then try to get a file that is not present at the server. You should get a “404 Not Found” message.
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
serverSocket.bind(('', 12006))
serverSocket.listen(1)
while True:
print 'Ready to serve...'
#Establish the connection
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.read()
f.close()
#Send one HTTP header line into socket
connectionSocket.send('HTTP/1.0 200 OK\r\n\r\n')
#Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.close()
except IOError:
#Send response message for file not found
connectionSocket.send('404 Not Found')
#Close client socket
connectionSocket.close()
serverSocket.close()
Your output is a standart output, that used through print function. you should to make a request to your server and you'll get the correct output
If your server on your local machine, you should use localhost address; if not, you should use your server ip. Also you should to specify a port. 12006 in your case. localhost:12006 as an example
Also socket.send method requires a byte-like object. not string
If it's only a string literal, you should to add a b character before the first quotation mark
Example:
connectionSocket.send(b'HTTP/1.0 200 OK\r\n\r\n')
If it is a string object, you should to encode it:
connectionSocket.send(outputdata[i].encode())
Check out the documentation

http proxy server only working for https sites

I am trying to use this code to create an HTTP proxy cache server. When I run the code it starts running and connects to the port and everything but when I try to connect from the browser, for example, it opens a port on 55555 if I type in localhost:52523/www.google.com it works fine but when I try other sites specifically HTTP, for example, localhost:52523/www.microcenter.com or just localhost:52523/google.com it will display localhost didn’t send any data.
ERR_EMPTY_RESPONSE and shows an exception in the console though it creates the cache file on my computer.
I would like to find out how to edit the code so that I can access any website just as I would normally do on the browser without using the proxy server. It should be able to work with www.microcenter.com
import socket
import sys
import urllib
from urlparse import urlparse
Serv_Sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # socket.socket
function creates a socket.
port = Serv_Sock.getsockname()[1]
# Server socket created, bound and starting to listen
Serv_Sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # socket.socket
function creates a socket.
Serv_Sock.bind(('',port))
Serv_Sock.listen(5)
port = Serv_Sock.getsockname()[1]
# Prepare a server socket
print ("starting server on port %s...,"%(port))
def caching_object(splitMessage, Cli_Sock):
#this method is responsible for caching
Req_Type = splitMessage[0]
Req_path = splitMessage[1]
Req_path = Req_path[1:]
print "Request is ", Req_Type, " to URL : ", Req_path
#Searching available cache if file exists
url = urlparse(Req_path)
file_to_use = "/" + Req_path
print file_to_use
try:
file = open(file_to_use[5:], "r")
data = file.readlines()
print "File Present in Cache\n"
#Proxy Server Will Send A Response Message
#Cli_Sock.send("HTTP/1.0 200 OK\r\n")
#Cli_Sock.send("Content-Type:text/html")
#Cli_Sock.send("\r\n")
#Proxy Server Will Send Data
for i in range(0, len(data)):
print (data[i])
Cli_Sock.send(data[i])
print "Reading file from cache\n"
except IOError:
print "File Doesn't Exists In Cache\n fetching file from server \n
creating cache"
serv_proxy = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
host_name = Req_path
print "HOST NAME:", host_name
try:
serv_proxy.connect((url.host_name, 80))
print 'Socket connected to port 80 of the host'
fileobj = serv_proxy.makefile('r', 0)
fileobj.write("GET " + "http://" + Req_path + " HTTP/1.0\n\n")
# Read the response into buffer
buffer = fileobj.readlines()
# Create a new file in the cache for the requested file.
# Also send the response in the buffer to client socket
# and the corresponding file in the cache
tmpFile = open(file_to_use, "wb")
for data in buffer:
tmpFile.write(data)
tcpCliSock.send(data)
except:
print 'Illegal Request'
Cli_Sock.close()
while True:
# Start receiving data from the client
print 'Initiating server... \n Accepting connection\n'
Cli_Sock, addr = Serv_Sock.accept() # Accept a connection from client
#print addr
print ' connection received from: ', addr
message = Cli_Sock.recv(1024) #Recieves data from Socket
splitMessage = message.split()
if len(splitMessage) <= 1:
continue
caching_object(splitMessage, Cli_Sock)
Your errors are not related to URI scheme (http or https) but to files and socket use.
When you are trying to open a file with:
file = open(file_to_use[1:], "r")
you are passing an illegal file path (http://ebay.com/ in your example).
As you are working with URIs, you could use a parser like urlparse, so you can handle better the schema, hostname, etc...
For example:
url = urlparse(Req_path)
file_to_use = url.hostname
file = open(file_to_use, "r")
and use only the hostname as a file name.
Another problem is with the use of sockets. Function connect should receive hostname, not hostname with schema which is what you are doing. Again, with the help of the parser:
serv_proxy.connect((url.hostname, 80))
Besides that, you do not call listen on a client (see examples), so you can remove that line.
Finally, again to create the new file, use the hostname:
tmpFile = open(file_to_use, "wb")

Python Web Server socket

I have to create a web server in Python. Below is the code I am working on. When i execute it, I initially get no error and it prints "Ready to serve.." , but after opening a browser and running http://10.1.10.187:50997/HelloWorld.html (HelloWorld is an html file in the same folder as my python code, while 10.1.10.187 is my IP address and 50997) is the server port), I get a TypeError saying 'a bytes like object is required and not str". please help me in resolving this and kindly let me know if any other modifications are required.
#Import socket module
from socket import *
#Create a TCP server socket
#(AF_INET is used for IPv4 protocols)
#(SOCK_STREAM is used for TCP)
# Assign a port number
serverPort = 50997
serverSocket = socket(AF_INET, SOCK_STREAM)
#serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#print ("hostname is: "), gethostname()
#print ("hostname is: "), socket.gethostname()
# Bind the socket to server address and server port
serverSocket.bind(("", serverPort))
# Listen to at most 1 connection at a time
serverSocket.listen(1)
# Server should be up and running and listening to the incoming connections
while True:
print ("Ready to serve...")
# Set up a new connection from the client
connectionSocket, addr = serverSocket.accept()
try:
# Receives the request message from the client
message = connectionSocket.recv(1024)
print ("Message is: "), message
filename = message.split()[1]
print ("File name is: "), filename
f = open(filename[1:])
outputdata = f.read()
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.send("\r\n")
# Close the client connection socket
connectionSocket.close()
except IOError:
# Send HTTP response message for file not found
connectionSocket.send("HTTP/1.1 404 Not Found\r\n\r\n")
connectionSocket.send("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n")
# Close the client connection socket
connectionSocket.close()
serverSocket.close()
The error I am exacly getting-
Ready to serve...
Message is:
File name is:
Traceback (most recent call last):
File "intro.py", line 56, in <module>
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
TypeError: a bytes-like object is required, not 'str'
You need to convert the string you are sending into bytes, using a text format. A good text format to use is UTF-8. You can implement this conversion like so:
bytes(string_to_convert, 'UTF-8')
or, in the context of your code:
connectionSocket.send(bytes("HTTP/1.1 404 Not Found\r\n\r\n","UTF-8"))
connectionSocket.send(bytes("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n","UTF-8"))`

Categories

Resources