Skip to content

Instantly share code, notes, and snippets.

@korylprince
Created December 5, 2015 23:02
Show Gist options
  • Save korylprince/66040d1ffc635e633ec0 to your computer and use it in GitHub Desktop.
Save korylprince/66040d1ffc635e633ec0 to your computer and use it in GitHub Desktop.
uwsgi protocol library test
package main
//run uwsgi command below where test references test.py given below
//uwsgi --plugin python --uwsgi-socket :9090 --wsgi test
import (
"bytes"
"io"
"log"
"net"
"net/http"
"github.com/korylprince/uwsgi-go" //eventual package path
)
func handler(w http.ResponseWriter, r *http.Request) {
p := uwsgi.RequestPacket{Variables: uwsgi.Variables{"test": []byte("testing")}, Body: r.Body}
conn, err := net.Dial("tcp4", "localhost:9090")
if err != nil {
log.Println("uWSGI Dial Error:", err)
w.Write([]byte("uWSGI Dial Error"))
return
}
n, err := p.WriteTo(conn)
log.Println("Written:", n, "Error:", err)
buf := new(bytes.Buffer)
io.Copy(buf, conn)
log.Println(buf.Bytes())
log.Println(buf.String())
io.Copy(w, buf)
}
func main() {
http.HandleFunc("/", handler)
log.Println(http.ListenAndServe(":8080", nil))
}
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/plain')])
print(env)
return [bytes(str(env), 'utf-8')]
//Package uwsgi is a partial implementation of the uwsgi protocol:
//http://uwsgi-docs.readthedocs.org/en/latest/Protocol.html
package uwsgi
import (
"bytes"
"encoding/binary"
"io"
)
//RequestType is the modifier1 header number specifiying the type of request
type RequestType uint8
//Standard Request Types
const (
WSGIRequest uint8 = 0
PSGIRequest = 5
WSAPIRequest = 6
RACKRequest = 7
JWSGIRequest = 8
CGIRequest = 9
PHPRequest = 11
MonoASPNETRequest = 12
)
//Variables represents an array of uwsgi vars
type Variables map[string][]byte
//Bytes returns the []byte representation and size of a Variables
func (vars Variables) Bytes() (size uint16, data []byte) {
buf := new(bytes.Buffer)
for k, v := range vars {
binary.Write(buf, binary.LittleEndian, uint16(len(k)))
buf.WriteString(k)
binary.Write(buf, binary.LittleEndian, uint16(len(v)))
buf.Write(v)
}
return uint16(buf.Len()), buf.Bytes()
}
//RequestPacket represents a uwsgi request packet
type RequestPacket struct {
RequestType RequestType // uwsgi packet header modifier1; Defaults to WSGI
Variables //uwsgi Variables
Body io.Reader //HTTP Request Body
}
//WriteTo writes the whole packet to w until the Body drained or an error occurs.
//The return value n is the number of bytes written
//Any error encountered during the write is also returned.
func (p *RequestPacket) WriteTo(w io.Writer) (n int64, err error) {
dataSize, v := p.Variables.Bytes()
//header
err = binary.Write(w, binary.LittleEndian, struct {
Modifier1 RequestType
DataSize uint16
Modifier2 uint8
}{
p.RequestType,
dataSize,
0, //all supported requests types have modifier2 set to 0
})
if err != nil {
return 0, err
}
n = 4 //header size
//uwsgi vars
nTemp, err := w.Write(v)
n += int64(nTemp)
if err != nil {
return n, err
}
//body
nTemp64, err := io.Copy(w, p.Body)
n += nTemp64
return n, err
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment