golang 与 fastcgi 如何阅读 REMOTE_USER
golang with fastcgi how to read REMOTE_USER
简而言之:如何使用 fastcgi 在 golang 上读取 CGI var REMOTE_USER?
长:
我正在尝试编写一个程序,以便在套接字上使用 fcgi 在 httpd 后面工作。 httpd 执行 ssl 终止并提供基本身份验证。我需要阅读 $REMOTE_USER,但我不能在 golang 中阅读,而我可以在 perl 中阅读。
我的代码基于this fcgi example。我试试
func homeView(w http.ResponseWriter, r *http.Request) {
user, pass, authok := r.BasicAuth()
但是 authok 始终为 false,user 和 pass 仍然为空,尽管我确信授权(由 httpd 完成)是正确的。为了消除其他错误,我在perl中完成了:
my $socket = FCGI::OpenSocket("/run/fcgi-check.sock", 5);
my $q = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);
while ($q->Accept() >= 0) {
my $c = CGI::Simple->new;
my $user_id = $c->remote_user();
它在 perl 中运行良好。
为了调试,我打印了 r.Header 的输出,我得到:
map[Authorization:[]
go see 的 header 没有任何授权信息,我说得对吗?但它在 perl 中确实如此。
这是一个完整但最小的 golang 代码示例,它演示了这个问题(在 OpenBSD 5.8 上使用 go 版本 go1.4.2 openbsd/amd64 和在 httpd.conf 中使用 'authenticate "/" with restricted_users' 的 OpenBSDs httpd。
package main
import (
"github.com/gorilla/mux"
"io"
"log"
"fmt"
"net"
"net/http"
"net/http/fcgi"
)
func homeView(w http.ResponseWriter, r *http.Request) {
headers := w.Header()
headers.Add("Content-Type", "text/html")
headers.Add("Cache-Control", "no-cache, no-store, must-revalidate")
headers.Add("Pragma", "no-cache")
headers.Add("Expires", "0")
r.ParseForm()
user, pass, authok := r.BasicAuth()
if authok {
io.WriteString(w, fmt.Sprintln("Auth OK"))
io.WriteString(w, fmt.Sprintln("user is: "+user+", pass is: "+pass))
} else {
io.WriteString(w, fmt.Sprintln("Auth NOT OK"))
}
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/check/", homeView)
var err error
listener, err := net.Listen("unix", "/run/fcgi-check.sock")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
err = fcgi.Serve(listener, r)
if err != nil { log.Fatal(err)}
}
不胜感激!
提前致谢!
T.
虽然 @JimB
是正确的,您的方法是错误的,但我会按照说明回答问题。
net/http/fcgi
包使用 net/http/cgi
的机制来填充 http.Request
的实例——传递给你的处理程序——使用 "parameters" (key/value 对)由网络服务器在 FastCGI 会话(调用)期间提交。
这是完成 here.
现在,如果您要检查 the relevant bit of the net/http/cgi
code, you'll see that the variables which are not mapped to specific dedicated fields of http.Request
get converted to HTTP "headers"。
这意味着,您的代码应该能够使用类似
的方式访问您需要的变量
ruser := r.Header.Get("Remote-User")
2015-12-02 更新: @JimB
和 OP 进行的研究表明显然无法读取 REMOTE_USER
下的变量快速CGI。抱歉噪音。
简单的回答(从 go 版本 1.4.2 开始)是 go 目前不支持 CGI 变量的传输 REMOTE_USER。
fcgi 包的 core change 正在审核中,即将合并。如果它不再与您相关,希望它对其他人有用。
Go 1.9 将公开 cgi 环境变量。如这张已关闭的票证所示:
简而言之:如何使用 fastcgi 在 golang 上读取 CGI var REMOTE_USER?
长: 我正在尝试编写一个程序,以便在套接字上使用 fcgi 在 httpd 后面工作。 httpd 执行 ssl 终止并提供基本身份验证。我需要阅读 $REMOTE_USER,但我不能在 golang 中阅读,而我可以在 perl 中阅读。
我的代码基于this fcgi example。我试试
func homeView(w http.ResponseWriter, r *http.Request) {
user, pass, authok := r.BasicAuth()
但是 authok 始终为 false,user 和 pass 仍然为空,尽管我确信授权(由 httpd 完成)是正确的。为了消除其他错误,我在perl中完成了:
my $socket = FCGI::OpenSocket("/run/fcgi-check.sock", 5);
my $q = FCGI::Request(\*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);
while ($q->Accept() >= 0) {
my $c = CGI::Simple->new;
my $user_id = $c->remote_user();
它在 perl 中运行良好。
为了调试,我打印了 r.Header 的输出,我得到:
map[Authorization:[]
go see 的 header 没有任何授权信息,我说得对吗?但它在 perl 中确实如此。
这是一个完整但最小的 golang 代码示例,它演示了这个问题(在 OpenBSD 5.8 上使用 go 版本 go1.4.2 openbsd/amd64 和在 httpd.conf 中使用 'authenticate "/" with restricted_users' 的 OpenBSDs httpd。
package main
import (
"github.com/gorilla/mux"
"io"
"log"
"fmt"
"net"
"net/http"
"net/http/fcgi"
)
func homeView(w http.ResponseWriter, r *http.Request) {
headers := w.Header()
headers.Add("Content-Type", "text/html")
headers.Add("Cache-Control", "no-cache, no-store, must-revalidate")
headers.Add("Pragma", "no-cache")
headers.Add("Expires", "0")
r.ParseForm()
user, pass, authok := r.BasicAuth()
if authok {
io.WriteString(w, fmt.Sprintln("Auth OK"))
io.WriteString(w, fmt.Sprintln("user is: "+user+", pass is: "+pass))
} else {
io.WriteString(w, fmt.Sprintln("Auth NOT OK"))
}
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/check/", homeView)
var err error
listener, err := net.Listen("unix", "/run/fcgi-check.sock")
if err != nil {
log.Fatal(err)
}
defer listener.Close()
err = fcgi.Serve(listener, r)
if err != nil { log.Fatal(err)}
}
不胜感激!
提前致谢! T.
虽然 @JimB
是正确的,您的方法是错误的,但我会按照说明回答问题。
net/http/fcgi
包使用 net/http/cgi
的机制来填充 http.Request
的实例——传递给你的处理程序——使用 "parameters" (key/value 对)由网络服务器在 FastCGI 会话(调用)期间提交。
这是完成 here.
现在,如果您要检查 the relevant bit of the net/http/cgi
code, you'll see that the variables which are not mapped to specific dedicated fields of http.Request
get converted to HTTP "headers"。
这意味着,您的代码应该能够使用类似
ruser := r.Header.Get("Remote-User")
2015-12-02 更新: @JimB
和 OP 进行的研究表明显然无法读取 REMOTE_USER
下的变量快速CGI。抱歉噪音。
简单的回答(从 go 版本 1.4.2 开始)是 go 目前不支持 CGI 变量的传输 REMOTE_USER。
fcgi 包的 core change 正在审核中,即将合并。如果它不再与您相关,希望它对其他人有用。
Go 1.9 将公开 cgi 环境变量。如这张已关闭的票证所示: