php - G-WAN,CGI 脚本的输出 header

标签 php http cgi go g-wan

我正在尝试通过 CGI 脚本设置 HTTP header ,例如 Content-Type

PHP 中:

header('Content-Type: text/plain');
// or
echo 'Content-Type: text/plain', "\r\n\r\n"; // as first line

或在 Go 中:

fmt.Print("Content-Type: text/plain\r\n\r\n") // as first line

两者都对输出没有影响。

如何做到这一点?

编辑

我还在 Go 中使用 CGI 包尝试了以下操作:

package main

import "fmt"
import "os"
import "net/http/cgi"

func main() {
    r,e := cgi.Request()
    if e != nil {
        fmt.Println(e)
        os.Exit(200)
    }
    fmt.Printf("%#v", r)
    os.Exit(200)
}

但是我得到了错误:

cgi: failed to parse REQUEST_URI into a URL:

最佳答案

问题 1:

如果您的脚本返回有效的 HTTP 返回码(如 200),那么 G-WAN 会构建相应的 HTTP header ,除非它们已经存在(以 "HTTP/1.x 200 开头)好的” 这里)。

因此,使用脚本语言强制给定content-type(除了那些支持 G-WAN API 的语言,如 C、C++、D 和 Objective-C) 你必须返回 1 并定义你回复的所有 HTTP header 。

支持G-WAN API的编程语言可以使用get_env(argv, REPLY_MIME_TYPE);(如fractal.c等所示)让G- WAN 构建其余的 header 。

问题 2:

环境变量 REQUEST_URI(虽然有用)不是受支持的 CGI v1 specification (RFC-3875) 的一部分。我已请求在未来的版本中添加 REQUEST_URI

G-WAN 提供的脚本示例列出了 v3.12 支持的变量:

// ----------------------------------------------------------------------------
// CGI/1.1 environment variables:
// ----------------------------------------------------------------------------
// "AUTH_TYPE",          // "" | "Basic" | "Digest" | etc.
// "CONTENT_LENGTH",     // "" | entity_length
// "CONTENT_TYPE",       // "" | content_type
// "GATEWAY_INTERFACE",  // "CGI/1.1"
// "PATH_INFO",          // "" | ( "/" path )
// "PATH_TRANSLATED",    // disk filename for PATH_INFO
// "QUERY_STRING",       // "" | ?"hellox.c&name=toto"
// "REMOTE_ADDR",        // client IP address
// "REMOTE_HOST",        // client DNS name (or IP addr)
// "REMOTE_IDENT",       // client identity (RFC 1413), opt
// "REMOTE_USER",        // client identity (if auth)
// "REQUEST_METHOD",     // "GET" | "HEAD" | "PUT", etc.
// "SCRIPT_NAME",        // "" | ("/" path "hello.c")
// "SERVER_NAME",        // "gwan.com" | IP address
// "SERVER_PORT",        // "80"
// "SERVER_PROTOCOL",    // "HTTP/1.1" | "HTTP/1.0" | "HTTP/0.9"
// "SERVER_SOFTWARE",    // "G-WAN"
// ----------------------------------------------------------------------------

请注意,您可以使用以下(更快的)Go 代码访问请求和参数(如果有):

// args[1] /opt/gwan/10.10.20.80_80/#192.168.200.80/csp/hello.go
// args[2] arg1=123
// args[3] arg2=456

for i := 1; i < len(os.Args); i++ {
   fmt.Printf("args[%d] %s<br>", i, os.Args[i])
 }

更新

我们通过电子邮件收到此源代码:

package main

import "fmt"
import "os"

func main() 
{
   p := "<h1>Hello world!</h1><p>This is dog bla</p>"
   fmt.Printf("%s 200 OK\r\n", os.Getenv("SERVER_PROTOCOL"))
   fmt.Print("Content-Type: text/html; charset=UTF-8\r\n")
   fmt.Print("Connection: Keep-Alive\r\n")
   fmt.Printf("Content-Length: %d\r\n",len(p))
   fmt.Print("\r\n")
   fmt.Print(p)  
}

请注意此代码不正确:它甚至无法编译 - 并且 G-WAN 报告以下错误:

loading.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Error: hell.go
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# command-line-arguments
0.0.0.0_8080/#0.0.0.0/csp/hell.go:7: syntax error: unexpected semicolon or newline before {
0.0.0.0_8080/#0.0.0.0/csp/hell.go:9: non-declaration statement outside function body
0.0.0.0_8080/#0.0.0.0/csp/hell.go:10: non-declaration statement outside function body
0.0.0.0_8080/#0.0.0.0/csp/hell.go:11: non-declaration statement outside function body
0.0.0.0_8080/#0.0.0.0/csp/hell.go:12: non-declaration statement outside function body
0.0.0.0_8080/#0.0.0.0/csp/hell.go:13: non-declaration statement outside function body
0.0.0.0_8080/#0.0.0.0/csp/hell.go:14: non-declaration statement outside function body
0.0.0.0_8080/#0.0.0.0/csp/hell.go:16: syntax error: unexpected }

 4|import "os"
 5|
 6|func main() 
 7!{
 8|   p := "<h1>Hello world!</h1><p>This is dog bla</p>"
 9|   fmt.Printf("%s 200 OK\r\n", os.Getenv("SERVER_PROTOCOL"))
10|   fmt.Print("Content-Type: text/html; charset=UTF-8\r\n")
11|   fmt.Print("Connection: Keep-Alive\r\n")


To run G-WAN, you must fix the error(s) or remove this Servlet.

这很可能是您没有看到程序被“更新”的原因:旧版本(如果有)没有被 G-WAN 运行时更新的错误版本所取代。

当您开发(编辑脚本)时,您应该始终查看终端以检查您新编辑的代码是否编译。

我建议您查看(工作中的)hello.go 示例,了解main() 和(强制性)预期定义的要求是什么返回代码

当没有使用返回码时(如在您的代码中),G-WAN 将注入(inject)默认 HTTP header (在您的情况下为 HTTP/0.9 200 OK),这将绕过您的 HTTP header (如果有的话) ),因此 Internet 浏览器将等待直到超时,因为它不知道您回复的长度。

如示例和手册中所述,要告诉 G-WAN 不要创建 HTTP header ,您必须返回 1-99 范围内的值(0 表示关闭连接200-600 保留给 HTTP 返回代码,告诉 G-WAN 生成相应的 HTTP header )。

关于php - G-WAN,CGI 脚本的输出 header ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14357907/

相关文章:

ruby - 在脚本完成之前使用 Ruby CGI 返回响应?

php - 如何从PHP中的多维数组中获取最高值和最低值以及总和

php - 为什么我收到 max_user_connections SQL 错误?

php - OpenAPI PHP 客户端给出 Fatal Error with anyOf

php - 如何使用 php 或使用外部网站自动检测时区

http - IP地址定位检测技术

ajax - 如何保护ajax内容

javascript - AngularJS 服务函数不返回 promise

python - 如何从cgi脚本调用web浏览器?

perl - 如何确保用户不会意外读取我的 CGI 代码