0
votes

My server provides a wsgi.py script to embed a python application. I need to fill an application (environ, start_response) function to answer HTTP requests. I could manage GET and POST requests (as provided in the code below). But in the html code I return for a GET request, I have some <img src='images/mypicture.png' /> and the image is NOT displayed in the first round.

I was using Bottle for local dev and that was managed using a specific answer for images data queries. But on the external server (Apache, Python 3.7) I have no access to Bottle, and need to write simple wsgi code. How can I detect a request for an image, so that I can return the correct header and data? I can manage GET and POST requests, but don't detect when an image is required.

def my_get_post_form(environ):
    # Simple way to retrieve the POST form data (works fine on my server)
    input = environ['wsgi.input']
    nSize = int(environ['CONTENT_LENGTH'])
    sBuf = input.read(nSize)
    return(sBuf)

def application(environ, start_response):    

    sMethod = environ['REQUEST_METHOD']
    sParam = environ['QUERY_STRING'].split("&")
    sPath = environ['PATH_INFO']
    sFull = environ['SCRIPT_NAME']

    # It does NOT detect an image request...
    if '.png' in sFull:        
        data = open(sFull, 'rb').read()
        start_response('200 OK', [('Content-Type', 'image/png'),
                                  ('content-length', str(len(data)))])
        return(data)

    # This works : I return html code with <img /> tags inside
    # This html code includes a form
    if sMethod.upper() == "GET":
        start_response('200 OK',[('Content-Type','text/html; charset=utf-8')])
        return ['<!DOCTYPE html><html><meta charset="utf-8">',
                sHtmlD.encode('utf-8'),
                sFormExterne.encode('utf-8'),
                sHtmlF.encode('utf-8')]

    # This works too, to retrieve the form data, make some computations
    # and return the result in an html page
    if sMethod.upper() == "POST":
        sParam = str(my_get_post_form(environ)).split("&")
        ... some computations ...
        start_response('200 OK',[('Content-Type','text/html; charset=utf-8')])
        return ['<!DOCTYPE html><html><meta charset="utf-8">'.encode('utf-8'),
                sHtmlD.encode('utf-8'),
                sStats.encode('utf-8'),
                sHtmlF.encode('utf-8')]

What I expected was to retrieve the image name somewhere in the environment... So that I can return the appropriate answer (the image data, and correct headers). It looks like PATH_INFO and SCRIPT_NAME do not return the image filename Any idea to perform this?

2

2 Answers

0
votes

You can serve static images from the apache document root or use an "Alias".

https://httpd.apache.org/docs/2.4/urlmapping.html#documentroot

0
votes

I found it!
That was quite simple in fact...
(which doesn't mean easy to find :-)) So, here is the code, and I confirm that once you returned an html file to a GET query, and this html file contains img tags, you will receive as many requests as you have images to retrieve
Just need to identify that the query is expecting an image, here is how:

import wsgiref, wsgiref.util # Maybe just environment['PATH_INFO'] returns the same...
def application(environ, start_response):    
    sMethod = environ['REQUEST_METHOD']
    sParam = environ['QUERY_STRING'].split("&")
    sPath = environ['PATH_INFO']
    sFile = wsgiref.util.request_uri(environ, include_query=True)   
    # Asking for a complementary image mentioned in the html file returned in GET
    if '.png' in sFile:
        sImage = sFile[sFile.find("images/"):]  # If your images are in images folder      
        data = open(sImage, 'rb').read()
        start_response('200 OK', [('Content-Type', 'image/png'),
                                  ('content-length', str(len(data)))])
        return(data)

    if sMethod.upper() == "GET":
    ....