简体   繁体   English

如何将CGI转换为WSGI?

[英]How do I Convert CGI to WSGI?

I inherited a code base that uses CGI scripts. 我继承了使用CGI脚本的代码库。 From what I read they're inefficient because they fork a new process every time a request comes in. I'm currently attempting to convert them to WSGI but I'm confused on the following: 据我了解,它们效率低下,因为每次请求进入时它们都会派生一个新流程。我目前正在尝试将它们转换为WSGI,但是我对以下内容感到困惑:

  1. How are WSGI and CGI different code-wise? WSGI和CGI在代码方面有何不同? I know that the application must be callable but other than that, I'm not sure on what else I will have to do to change it. 我知道该应用程序必须是可调用的,但除此之外,我不确定要更改它还需要做什么。

  2. How do I benchmark the increase in efficiency that I read should be obvious with the change? 如何以我的基准衡量我所读到的效率变化与变化有关?

Other info that might be useful would be that I'm going to be using Apache and mod_wsgi. 其他可能有用的信息是我将使用Apache和mod_wsgi。

Let me know if there's any other info I can provide. 让我知道是否还有其他我可以提供的信息。

In some ways wsgi abstracts out some of the stuff cgi does into a pure python function call, with no side effects. wsgi在某些方面将cgi所做的某些事情抽象为纯python函数调用,而没有副作用。

The "inputs" to a cgi program are the process environment, in os.environ and sys.stdin . cgi程序的“输入”是进程环境,位于os.environsys.stdin The output to such a program is sys.stdout , with errors reaching the server log from sys.stderr . 此类程序的输出为sys.stdout ,错误从sys.stderr到达服务器日志。

A wsgi application is a python function taking two* arguments, usually called environ (which will be a dict ) and start_response (which will be another function). wsgi应用程序是一个带两个*参数的python函数,通常称为environ (将是dict )和start_response (将是另一个函数)。

The first argument is a dict , containing all of the things a cgi program would get in os.environ , but it also contains a couple of extra keys. 第一个参数是dict ,包含cgi程序将在os.environ获得的所有内容,但它还包含几个额外的键。 Notably, it contains "wsgi.input" , a file-like object which takes the place of sys.stdin for the purposes of request body. 值得注意的是,它包含"wsgi.input" ,这是一个类似文件的对象,出于请求正文的目的,它代替sys.stdin

A cgi program uses sys.stdout for both the HTTP response line, response headers, and response body. 一个cgi程序将sys.stdout用于HTTP响应行,响应标头和响应正文。 In a wsgi program, the first two are passed as arguments to the start_response argument. 在wsgi程序中,前两个作为参数传递给start_response参数。 A wsgi response body is not** written to a file; wsgi响应正文未**写入文件; instead, it's returned from the app function. 相反,它是从app函数返回的。

A typical CGI program might look like this: 一个典型的CGI程序可能如下所示:

import os, sys
request_size = int(os.environ.get("HTTP_CONTENT_LENGTH", "0"))
person = sys.stdin.read(request_size)

response = "Hello %s!\n" % person
print "Status: 200 OK"
print "Content-Type: text/plain"
print "Content-Length: %d" % len(response)
print
print response

The equivalent wsgi program would look like: 等效的wsgi程序如下所示:

def myApp(environ, start_response):
    request_size = int(environ.get("HTTP_CONTENT_LENGTH", "0"))
    wsgi_input = environ.get("wsgi.input")
    person = wsgi_input.read(request_size) if request_size and wsgi_input else ""
    response = "Hello %s!\n" % person

    start_response("200 OK",
        [("Content-Type", "text/plain"),
         ("Content-Length", str(len(response)))]

    return [response]

* for technical reasons, there's an optional, third argument, mostly for "middleware" *由于技术原因,有一个可选的第三个参数,主要用于“中间件”
** for compatability with old web frameworks, start_response() returns a file-like object that can be written to, but this is not recommended. **为了与旧的Web框架兼容,start_response()返回可以写入的类似文件的对象,但是不建议这样做。 In your case it might simplify the conversion, but since an invasive change is needed anyway, see if you can avoid it. 在您的情况下,这可能会简化转换,但是由于仍然需要进行侵入式更改,因此请查看是否可以避免。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM