douwaif22244 2013-01-16 11:56
浏览 38
已采纳

G-WAN,CGI脚本的输出头

I'm trying to set an HTTP header like Content-Type over a CGI script.

In PHP:

header('Content-Type: text/plain');
// or
echo 'Content-Type: text/plain', "

"; // as first line

or in Go:

fmt.Print("Content-Type: text/plain

") // as first line

Both have no effect on the output.

How can this be done?

EDIT

I also tried the following in Go, using the CGI package:

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)
}

but I get the error:

cgi: failed to parse REQUEST_URI into a URL:
  • 写回答

1条回答 默认 最新

  • doubao6681 2013-01-16 16:11
    关注

    Question 1:

    If your script returns a valid HTTP return code (like 200) then G-WAN builds the corresponding HTTP Headers unless they are already there (starting with "HTTP/1.x 200 OK" here).

    So, to force a given content-type with scripted languages (other than those which support the G-WAN API like C, C++, D, and Objective-C) you would have to return 1 and define ALL the HTTP headers of your reply.

    The programming languages that support the G-WAN API can use get_env(argv, REPLY_MIME_TYPE); (as shown in fractal.c and others) and let G-WAN build the rest of the headers.

    Question 2:

    The environment variable REQUEST_URI (while useful) is not part of the supported CGI v1 specification (RFC-3875). I have requested that REQUEST_URI is added in a future release.

    The script examples provided with G-WAN list the supported variables by 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"
    // ----------------------------------------------------------------------------
    

    Note that you can however access both the request and the parameters (if any) by using the following (and faster) Go code:

    // 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])
     }
    

    UPDATE

    We received this source code by email:

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

    Please note that this code is incorrect: it does not even compile - and G-WAN reports the following errors:

    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
    ", os.Getenv("SERVER_PROTOCOL"))
    10|   fmt.Print("Content-Type: text/html; charset=UTF-8
    ")
    11|   fmt.Print("Connection: Keep-Alive
    ")
    
    
    To run G-WAN, you must fix the error(s) or remove this Servlet.
    

    This is most probably why you haven't seen the program being "updated": the old version, if any, was not replaced by the faulty version updated while G-WAN was running.

    When you develop (editing scripts) you should always have a look at the terminal to check if your newly edited code compiles.

    I recommend you to look at the (working) hello.go example to see what the requirements are for the expected definition of main() and the (madatory) return code.

    When no return code is used (like in your code), G-WAN will inject default HTTP headers (HTTP/0.9 200 OK in your case) which will bypass your HTTP headers (if any) and as a result the Internet Browser will wait until it times-out because it does not know the length of your reply.

    As documented in the examples and in the manual, to tell G-WAN not to create HTTP headers you have to return a value in the 1-99 range (0 means close connection and 200-600 is reserved for HTTP return codes that tell G-WAN to generate the correspondig HTTP headers).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题