Mini Web server: how to receive a GET from the outside?


#1

I’m trying to understand how can I receive some variables or some json I think the base for this should be the Mini Web Server Example and this should be the part that needs some changes

 # Type in your browser the board ip!
        print(“Waiting for connection…”)
        # here we wait for a connection
        clientsock,addr = sock.accept()
        print(“Incoming connection from”,addr)
        
        # yes! a connection is ready to use
        # first let’s create a SocketStream
        # it’s like a serial stream, but with a socket underneath.
        # This way we can read and print to the socket
        client = streams.SocketStream(clientsock)
        
        # let’s read all the HTTP headers from the browser
        # stop when a blank line is received
        line = client.readline()
        while line!="
" and line!="\r
“:

            line = client.readline()
        print(“HTTP request received!”)
        
        # let’s now send our headers (very minimal)
        # hint:
is added by print
        print(“HTTP/1.1 200 OK\r”,stream=client)
        print(“Content-Type: text/html\r”,stream=client)
        print(“Connection: close\r
\r”,stream=client)
        # see? as easy as print!
        print(“Hello ZERYNTH!”,random(0,100),”",stream=client)
        # close connection and go waiting for another one
        client.close()
client.readline() reads everything except the GET request. If i do a client.read(100) I am able to read the GET request. Is there a way I can easily parse this request or I have to do some manual string manipulation?<br><br><br>

#2

Hello matrix866, the GET request should be correctly read by the first readline(), I tried it and everything seems ok :slight_smile:
Try this:

 line = client.readline()
print(“GET is here: “,line)
 while line!=”
" and line!=”\r
":

  line = client.readline()
<p>For what concerns parsing a GET, you should take a look at urlparse.parse_qs http://doc.zerynth.com/core.zerynth.stdlib/r1.0.3/urlparse.html which takes a query string ( GET /path?query HTTP/1.1 ) and returns a dictionary of keys and values ;)<br></p><br><br>

#3

Thank you lorenzo! But I’m blocked again. I found an example in Zerynth system file “urlparse.py” that was very useful. This same code applied to my string “id=photon1&buzzer=on&led_ring=yellow HTTP/1.1” works perfectly…

#######################################

TEST

urls =[

http://www.google.com”,

http://foo:bar@w1.superman.com/very/long/path.html?p1=v1&p2=v2+%#more-details”,

https://secured.com:443”,

ftp://ftp.bogus.com/~some/path/to/a/file.txt”]

for url in urls:

tt = parse(url)

print(url)

print("===>",tt)

print("===>",parse_netloc(tt[1]))

print("===>",parse_qs(tt[-2]))

print()

...but in the real world I get en error doing the parse_qs. I tried printing a "A" first and before the line gotten with the readline function and I can see that the "A" in the end start a new paragraph so the parse_qs errror maybe related to that?<br><img alt="" src="https://community.viperize.it/uploads/editor/rs/sp16k1lts0hz.png" title="Image: https://community.viperize.it/uploads/editor/rs/sp16k1lts0hz.png"><br>

#4

OK I found a fix. The tt[3] needs to be casted to a string with str(t[3]) before being able to parse it. And before could be useful to:

aa = tt[3]
print(“3===>”,urlparse.parse_qs(str(aa[0:-11])))
[0:-11] to remove the " HTTP/1.1/n" from the string.<br><br>I tried many different kind of string.strip("something"), something = "\
" || "/n" but only the negative index worked to remove the new line from tt[3]

#5

Hi matrix866, the main problem here is that urlparse is expecting an url in the form:

scheme://netloc/path?query#fragment
<p>so it does not correctly parse your string which is in the form:</p><pre class=" CodeBlock">GET /path?query HTTP/1.1<br>

I suggest you to isolate your query for example like this:

qs = my_string.split(’?’)[1].split(’ ')[0]
<p>which should solve even your second issue and then pass it to urlparse.parse_qs ;)<br></p>

#6

Maybe I did something wrong but that code wasn’t working for me.

This one is doing the job. The aim is to filter the received request and create the list from the data in the GET request. Maybe could be useful for someone else.

client = streams.SocketStream(clientsock)
line = client.readline()
raw_request = line
while line!="
" and line!="\r
":
line = client.readline()
#Confirm message for the server script in JSON format
data = {}
data[‘message’] = ‘OK’
data_json = json.dumps(data)
print(“HTTP/1.1 200 OK\r”,stream=client)
print(“Content-Type: application/json\r”,stream=client)
print(“Connection: close\r
\r”,stream=client)
print(data_json,stream=client)
client.close()

if “=” in raw_request:
RAWGETrequest = urlparse.parse(raw_request)
GET_request = RAWGETrequest[3]
final_data_list = urlparse.parse_qs(str(GET_request[0:-11]))

<br>