Up

 

  

 
How to program?
This page shows how to program the Scorpion WebServer.

GET requests

If you do not write an event handler for WebServer GET requests, the default behaviour is to return the contents of a file named in the URL field (unless, of course, you disable GET requests under the WebServer tab ).

The autogenerated skeleton event handler looks like this:

def Handle_WebServer_GET(Requester,URL,Header,Body):
#
# Requester = VT_BSTR
# URL = VT_BSTR
# Header = VT_BSTR
# Body = VT_BSTR
#
# Return 0 to deny, 1 to accept,
# or return tuple (Code,ContentType,ExHeaderLines,Response,Type).
# Type is 1 if Response is filename, 2 if Response is body.

# return 1
# return (200,"text/plain","","Python says hello",2)
#
return 1

The parameters to the function are extracted from the incoming HTTP message, and gives information about the request. The further processing depends on your return value(s).

Returning an integer:

By returning 1 (as above) you tell the WebServer to accept the request for default handling; by returning 0 it will deny it (which means the requester will be given a return code of 403, “Forbidden”).

Returning a tuple:

The five items in the tuple are –

  • Code: integer. The most common values are 200 (OK), 400 (Bad Request), 401 (Unauthorized), 403 (Forbidden), 404 (Not Found). Refer to RFC2068 for more codes.
  • ContentType: string. Common values are “text/plain”, “text/html”, “image/gif”, “image/jpeg”, but several more common codes exist.
  • ExHeaderLines: string. With this optional field you can add lines to the HTTP header. Each line must be of the format “<item>: <data>”, for example “Date: 2002-08-23”. If more than one line is specified, they must be separated by a CR/LF pair. You can code this using “\r” and “\n”, as in “Date: 2002-08-23\r\nTime: 08:00:00”. You do not need to put in the CR/LF pair at the end, that is done automatically if not present.
  • Response: string. In a HTTP reply this is really a series of 8-bit bytes. In Scorpion you specify a text string. If Type (the last tuple item) is returned as 1, this string is used as a file name, and the contents of that file are sent as the response body. (This is an absolute filename, and is not related to the WebServer Root directory!). If Type is set to 2, the raw contents of the string (8 bits per character) are sent as the body.
  • Type: 1 or 2, see above.

Example – returning a file:

def Handle_WebServer_GET(Requester,URL,Header,Body):

# (...)

return (200, "text/html", "", "C:/web/information.htm", 1)

Example – returning text:

def Handle_WebServer_GET(Requester,URL,Header,Body):

# (...)

response = "For information refer to RFC2068."

return (200, "text/plain", "", response, 2)

Example – using the requester’s IP address to decide:

def Handle_WebServer_GET(Requester,URL,Header,Body):

# (...)

if Requester.startswith("127.0.0.1"):
  print 'local access allowed from',Requester,':',URL
  return 1

if URL.lower().endswith('.gif')):
  print 'gif access allowed from',Requester,':',URL
  return 1

print 'remote access politely denied to', Requester

header = '<html><title>Sorry</title><body>'
body = '<H1>Access not granted</H1>'
footer = '</body></html>'

return (200,"text/html","",heaader+returnbody+footer,2)

PUT, DELETE and HEAD requests

For all of these requests, you simply return 0 to deny or 1 to accept. Not defining a handler results in the default action (accept) being taken.

POST requests

If the POST event handler is not implemented, POST requests are denied by the WebServer, returning the code 501 “Not Implemented”.

The autogenerated skeleton event handler looks like this:

def Handle_WebServer_POST(ID,Requester,URL,Header,Body):
#
# ID = VT_I4
# Requester = VT_BSTR
# URL = VT_BSTR
# Header = VT_BSTR
# Body = VT_BSTR
#
# Return 0 to deny, 1 for Async response, or return tuple (Code,ContentType,ExHeaderLines,Response).
# If you return nonzero for Async, you should call WebServer.AsyncPostResponse later.

# return 1
# return (200,"text/plain","","Postresponse")
#
return (200,"text/plain","","Postresponse")

The parameters are the same as for GET, except that a unique sequence ID (integer) is also given. This ID is important only for asynchroneous replies (below).

Again, you can return an integer or a tuple.

Returning an integer:

Simply return 1 to accept the request for asynchroneous handling (see below), or return 0 to deny it (which means 501 “Not Implemented” to the client).

Returning a tuple:

The five items in the tuple are (see also the description for GET above) –

  • Code: integer.
  • ContentType: string.
  • ExHeaderLines: string.
  • Response: string. For POST requests, the contents of this string (8 bits per character) are always sent as the body.

Example – returning a string:

def Handle_WebServer_POST(ID,Requester,URL,Header,Body):

# ...

return (200,"text/plain","","Postresponse")

Example – deferring the reply (asynchroneous handling):

def Handle_WebServer_POST(ID,Requester,URL,Header,Body):

# (...)

start_something(ID,Requester,URL,Header,Body)

return 1

The function start_something is not defined here, but it must somehow manage to at a later stage (after the POST handler has returned, mind you!) result in a call to the Async handler in the WebServer, as shown below.

Asynchroneous POST response

When the POST response has been determined, the HTTP request can be satisfied by the following call in a Python script of your choice:

WebServer.AsyncPostResponse(ID,Code,ContentType,ExHeaderLines,Body)

The ID must correspond to one received in a call to Handle_WebServer_POST earlier. What happens here is that the WebServer will map the ID to a request that was earlier given an asynchroneous handling, and send the values back to the requester. The parameters to the function are (with the exception of the ID) exactly the same as the items that would be returned as a tuple in a synchroneous response.

Of course, this call can also be made using TDVCmdProtocol. For example, an external program can make this call to satisfy the request:

WebServer.AsyncPostResponse;ID=<ID>;Code=<code>;ContentType=<contenttype>;ExHeaderLines=<exheaderlines>;Body=<body>

 
 

Scorpion Vision Version XV  : Build 764 - Date: 20200529
Scorpion Vision Software® is a registered trademark of Tordivel AS.
Copyright © 2000 - 2020 Tordivel AS.