Skip to content

Commit

Permalink
Added very early (incomplete) implementation of fcgi
Browse files Browse the repository at this point in the history
  • Loading branch information
Michael Hoisie committed Dec 28, 2009
1 parent d2f92bd commit 9468865
Show file tree
Hide file tree
Showing 3 changed files with 130 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile
Expand Up @@ -7,10 +7,12 @@ include $(GOROOT)/src/Make.$(GOARCH)
TARG=web TARG=web
GOFILES=\ GOFILES=\
web.go\ web.go\
fcgi.go\
scgi.go\ scgi.go\


include $(GOROOT)/src/Make.pkg include $(GOROOT)/src/Make.pkg


format: format:
gofmt -spaces=true -tabindent=false -tabwidth=4 -w web.go gofmt -spaces=true -tabindent=false -tabwidth=4 -w web.go
gofmt -spaces=true -tabindent=false -tabwidth=4 -w fcgi.go
gofmt -spaces=true -tabindent=false -tabwidth=4 -w scgi.go gofmt -spaces=true -tabindent=false -tabwidth=4 -w scgi.go
116 changes: 116 additions & 0 deletions fcgi.go
@@ -0,0 +1,116 @@
package web

import (
"bytes"
"bufio"
"encoding/binary"
"log"
"net"
)

const (
FcgiRequestComplete = 0
FcgiBeginRequest = 1
FcgiAbortRequest = 2
FcgiEndRequest = 3
FcgiParams = 4
FcgiStdin = 5
FcgiStdout = 6
FcgiStderr = 7
FcgiData = 8
FcgiGetValues = 9
FcgiGetValuesResult = 10
FcgiUnknownType = 11
FcgiMaxType = FcgiUnknownType
)

type FcgiHeader struct {
Version uint8
Type uint8
RequestId uint16
ContentLength uint16
PaddingLength uint8
Reserved uint8
}

func readFcgiParams(data []byte) {
var params = make(map[string]string)

for idx := 0; len(data) > idx; {
var keySize int = int(data[idx])
if keySize>>7 == 0 {
idx += 1
} else {
binary.Read(bytes.NewBuffer(data[idx:idx+4]), binary.BigEndian, &keySize)
idx += 4
}

var valSize int = int(data[idx])
if valSize>>7 == 0 {
idx += 1
} else {
binary.Read(bytes.NewBuffer(data[idx:idx+4]), binary.BigEndian, &valSize)
idx += 4
}

key := data[idx : idx+keySize]
idx += keySize
val := data[idx : idx+valSize]
idx += valSize

println(string(key), ":", string(val))
params[string(key)] = string(val)
}
}

func handleFcgiRequest(fd net.Conn) {

br := bufio.NewReader(fd)
for {
var h FcgiHeader
err := binary.Read(br, binary.BigEndian, &h)
if err != nil {
log.Stderrf(err.String())
}
content := make([]byte, h.ContentLength)
n, err := br.Read(content)
//read padding
if h.PaddingLength > 0 {
padding := make([]byte, h.PaddingLength)
n, err = br.Read(padding)
println("read padding", n)
}

switch h.Type {
//case FcgiBeginRequest:
// println("begin request!");
case FcgiParams:
readFcgiParams(content)
case FcgiStdin:
println("stdin")
case FcgiData:
println("data!")
case FcgiAbortRequest:
println("abort!")
}
}
}

func listenAndServeFcgi(addr string) {
println("listening and serving scgi!")
l, err := net.Listen("tcp", addr)
if err != nil {
log.Stderrf(err.String())
return
}

for {
fd, err := l.Accept()
if err != nil {
log.Stderrf(err.String())
break
}
go handleFcgiRequest(fd)

}
}
12 changes: 12 additions & 0 deletions web.go
Expand Up @@ -47,6 +47,13 @@ type Context struct {
*Response *Response
} }


type Conn interface {
StartResponse(status int) os.Error
SetHeader(hdr string, val string) os.Error
Write(data string) os.Error
Close() os.Error
}

func (ctx *Context) Abort(code int, message string) { func (ctx *Context) Abort(code int, message string) {
ctx.Response = newResponse(code, message) ctx.Response = newResponse(code, message)
} }
Expand Down Expand Up @@ -209,6 +216,11 @@ func RunScgi(addr string) {
listenAndServeScgi(addr) listenAndServeScgi(addr)
} }


func RunFcgi(addr string) {
log.Stdoutf("web.go serving fcgi %s", addr)
listenAndServeFcgi(addr)
}

func Get(route string, handler interface{}) { addRoute(route, "GET", handler) } func Get(route string, handler interface{}) { addRoute(route, "GET", handler) }


func Post(route string, handler interface{}) { addRoute(route, "POST", handler) } func Post(route string, handler interface{}) { addRoute(route, "POST", handler) }
Expand Down

0 comments on commit 9468865

Please sign in to comment.