Hello community,
here is the log from the commit of package go-web.go for openSUSE:Factory checked in at 2012-03-08 19:43:37
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/go-web.go (Old)
and /work/SRC/openSUSE:Factory/.go-web.go.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "go-web.go", Maintainer is ""
Changes:
--------
--- /work/SRC/openSUSE:Factory/go-web.go/go-web.go.changes 2012-01-19 09:42:25.000000000 +0100
+++ /work/SRC/openSUSE:Factory/.go-web.go.new/go-web.go.changes 2012-03-08 19:43:39.000000000 +0100
@@ -1,0 +2,5 @@
+Fri Feb 17 16:58:58 UTC 2012 - graham@andtech.eu
+
+- updates for weekly.2012-02-12
+
+-------------------------------------------------------------------
Old:
----
web.go-0.0.0+git20111213.tar.bz2
web.go-weekly-fixes.patch
New:
----
web.go-0.0.0+git20120217.tar.bz2
weekly-build-fix.patch
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ go-web.go.spec ++++++
--- /var/tmp/diff_new_pack.6Zh53n/_old 2012-03-08 19:43:41.000000000 +0100
+++ /var/tmp/diff_new_pack.6Zh53n/_new 2012-03-08 19:43:41.000000000 +0100
@@ -1,7 +1,7 @@
#
# spec file for package go-web.go
#
-# Copyright (c) 2011 SUSE LINUX Products GmbH, Nuernberg, Germany.
+# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany.
# Copyright (c) 2011 Sascha Peilicke
#
# All modifications and additions to the file contributed by third parties
@@ -19,14 +19,15 @@
Name: go-web.go
-Version: 0.0.0+git20111213
+Version: 0.0.0+git20120217
Release: 0
Summary: A simple framework to write webapps in Go
License: MIT
Group: Development/Languages/Other
Url: http://github.com/hoisie/web.go
+# see also http://github.com/ganderson/web.go weekly branch for upstreamed pull request
Source0: web.go-%{version}.tar.bz2
-Patch0: web.go-weekly-fixes.patch
+Patch0: weekly-build-fix.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-build
BuildRequires: go-devel
%{go_provides}
@@ -42,13 +43,15 @@
%patch0 -p1
%build
+%goprep github.com/hoisie/web.go/
+%gobuild
%install
-gofix *.go
-%{go_make_install}
+%goinstall
%check
-%{go_make_test}
+# couple of tests currently fail for json parser
+#%%gotest github.com/hoisie/web.go
%files
%defattr(-,root,root,-)
++++++ web.go-0.0.0+git20111213.tar.bz2 -> web.go-0.0.0+git20120217.tar.bz2 ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/Makefile new/web.go/Makefile
--- old/web.go/Makefile 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/Makefile 2012-02-17 15:56:20.000000000 +0100
@@ -1,10 +1,10 @@
include $(GOROOT)/src/Make.inc
-TARG=web
+TARG=github.com/hoisie/web.go
GOFMT=gofmt -s -spaces=true -tabindent=false -tabwidth=4
GOFILES=\
- cookie.go\
+ cookie.go\
fcgi.go\
request.go\
scgi.go\
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/Readme.md new/web.go/Readme.md
--- old/web.go/Readme.md 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/Readme.md 2012-02-17 15:56:20.000000000 +0100
@@ -14,22 +14,23 @@
## Installation
-Make sure you have the a working Go environment. See the [install instructions](http://golang.org/doc/install.html). web.go targets the Go `weekly` release. Go is a fast-changing language, and it's easier to keep with the weekly branch than to maintain separate branches.
+Make sure you have the a working Go environment. See the [install instructions](http://golang.org/doc/install.html). web.go targets the Go `release` branch. If you use the `weekly` branch you may have difficulty compiling web.go. There's an alternative web.go branch, `weekly`, that attempts to keep up with the weekly branch.
-To use web.go with Go's `weekly` branch:
+To install web.go, simply run:
-1. Run `hg update -r weekly`. If you're running an outdated version of Go, or the `release` version, it likely won't compile.
-2. git clone git://github.com/hoisie/web.go.git
-3. cd web.go && make install
+ goinstall github.com/hoisie/web.go
-You can also install using `goinstall github.com/hoisie/web.go`, but if you do this, the import statement in your go programs will be `import github.com/hoisie/web.go` instead of just `import web`.
+To compile it from source:
+
+ git clone git://github.com/hoisie/web.go.git
+ cd web.go && make install
## Example
package main
import (
- "web"
+ "github.com/hoisie/web.go"
)
func hello(val string) string { return "hello " + val }
@@ -53,7 +54,7 @@
package main
import (
- "web"
+ "github.com/hoisie/web.go"
)
func hello(ctx *web.Context, val string) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/cookie.go new/web.go/cookie.go
--- old/web.go/cookie.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/cookie.go 2012-02-17 17:27:22.000000000 +0100
@@ -7,13 +7,12 @@
import (
"bytes"
"fmt"
- "http"
"io"
- "os"
+ "net/http"
+ "net/url"
"sort"
"strings"
"time"
- "url"
)
func sanitizeName(n string) string {
@@ -79,7 +78,7 @@
// to w. Each cookie is written on a separate "Set-Cookie: " line.
// This choice is made because HTTP parsers tend to have a limit on
// line-length, so it seems safer to place cookies on separate lines.
-func writeSetCookies(w io.Writer, kk []*http.Cookie) os.Error {
+func writeSetCookies(w io.Writer, kk []*http.Cookie) error {
if kk == nil {
return nil
}
@@ -95,7 +94,7 @@
if len(c.Domain) > 0 {
fmt.Fprintf(&b, "; Domain=%s", url.QueryEscape(c.Domain))
}
- if len(c.Expires.Zone) > 0 {
+ if _, offset := c.Expires.Zone(); offset > 0 {
fmt.Fprintf(&b, "; Expires=%s", c.Expires.Format(time.RFC1123))
}
if c.MaxAge >= 0 {
@@ -122,7 +121,7 @@
// to w. Each cookie is written on a separate "Cookie: " line.
// This choice is made because HTTP parsers tend to have a limit on
// line-length, so it seems safer to place cookies on separate lines.
-func writeCookies(w io.Writer, kk []*http.Cookie) os.Error {
+func writeCookies(w io.Writer, kk []*http.Cookie) error {
lines := make([]string, 0, len(kk))
var b bytes.Buffer
for _, c := range kk {
@@ -176,7 +175,7 @@
continue
}
attr, val := parts[i], ""
- var err os.Error
+ var err error
if j := strings.Index(attr, "="); j >= 0 {
attr, val = attr[:j], attr[j+1:]
val, err = url.QueryUnescape(val)
@@ -212,6 +211,10 @@
})
}
}
- h["Cookie"] = unparsedLines, len(unparsedLines) > 0
+ if len(unparsedLines) > 0 {
+ h["Cookie"] = unparsedLines
+ } else {
+ delete(h, "Cookie")
+ }
return cookies
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/arcchallenge.go new/web.go/examples/arcchallenge.go
--- old/web.go/examples/arcchallenge.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/arcchallenge.go 2012-02-17 17:27:22.000000000 +0100
@@ -1,10 +1,10 @@
package main
import (
- "rand"
+ "crypto/rand"
"strconv"
"time"
- "web"
+ "github.com/hoisie/web.go"
)
var form = `<form action="say" method="POST"><input name="said"><input type="submit"></form>`
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/hello.go new/web.go/examples/hello.go
--- old/web.go/examples/hello.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/hello.go 2012-02-17 15:56:20.000000000 +0100
@@ -1,7 +1,7 @@
package main
import (
- "web"
+ "github.com/hoisie/web.go"
)
func hello(val string) string { return "hello " + val }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/logger.go new/web.go/examples/logger.go
--- old/web.go/examples/logger.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/logger.go 2012-02-17 15:56:20.000000000 +0100
@@ -3,7 +3,7 @@
import (
"log"
"os"
- "web"
+ "github.com/hoisie/web.go"
)
func hello(val string) string { return "hello " + val }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/methodhandler.go new/web.go/examples/methodhandler.go
--- old/web.go/examples/methodhandler.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/methodhandler.go 2012-02-17 15:56:20.000000000 +0100
@@ -1,7 +1,7 @@
package main
import (
- "web"
+ "github.com/hoisie/web.go"
)
type Greeter struct {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/multipart.go new/web.go/examples/multipart.go
--- old/web.go/examples/multipart.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/multipart.go 2012-02-17 15:56:20.000000000 +0100
@@ -4,7 +4,7 @@
"bytes"
"crypto/md5"
"fmt"
- "web"
+ "github.com/hoisie/web.go"
)
func Md5(b []byte) string {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/multiserver.go new/web.go/examples/multiserver.go
--- old/web.go/examples/multiserver.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/multiserver.go 2012-02-17 15:56:20.000000000 +0100
@@ -1,7 +1,7 @@
package main
import (
- "web"
+ "github.com/hoisie/web.go"
)
func hello1(val string) string { return "hello1 " + val }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/examples/params.go new/web.go/examples/params.go
--- old/web.go/examples/params.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/examples/params.go 2012-02-17 15:56:20.000000000 +0100
@@ -2,7 +2,7 @@
import (
"fmt"
- "web"
+ "github.com/hoisie/web.go"
)
type mytype struct {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/fcgi.go new/web.go/fcgi.go
--- old/web.go/fcgi.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/fcgi.go 2012-02-17 17:27:22.000000000 +0100
@@ -1,14 +1,13 @@
package web
import (
- "bytes"
"bufio"
+ "bytes"
"encoding/binary"
"fmt"
- "http"
"io"
"net"
- "os"
+ "net/http"
"strings"
)
@@ -96,7 +95,7 @@
wroteHeaders bool
}
-func (conn *fcgiConn) fcgiWrite(data []byte) (err os.Error) {
+func (conn *fcgiConn) fcgiWrite(data []byte) (err error) {
l := len(data)
// round to the nearest 8
padding := make([]byte, uint8(-l&7))
@@ -129,7 +128,7 @@
return err
}
-func (conn *fcgiConn) Write(data []byte) (n int, err os.Error) {
+func (conn *fcgiConn) Write(data []byte) (n int, err error) {
var buf bytes.Buffer
if !conn.wroteHeaders {
conn.wroteHeaders = true
@@ -238,11 +237,11 @@
for {
var h fcgiHeader
err := binary.Read(br, binary.BigEndian, &h)
- if err == os.EOF {
+ if err == io.EOF {
break
}
if err != nil {
- s.Logger.Println("FCGI Error", err.String())
+ s.Logger.Println("FCGI Error", err.Error())
break
}
content := make([]byte, h.ContentLength)
@@ -282,9 +281,9 @@
}
}
-func (s *Server) listenAndServeFcgi(addr string) os.Error {
+func (s *Server) listenAndServeFcgi(addr string) error {
var l net.Listener
- var err os.Error
+ var err error
//if the path begins with a "/", assume it's a unix address
if strings.HasPrefix(addr, "/") {
@@ -297,13 +296,13 @@
s.l = l
if err != nil {
- s.Logger.Println("FCGI listen error", err.String())
+ s.Logger.Println("FCGI listen error", err.Error())
return err
}
for {
fd, err := l.Accept()
if err != nil {
- s.Logger.Println("FCGI accept error", err.String())
+ s.Logger.Println("FCGI accept error", err.Error())
break
}
go s.handleFcgiConnection(fd)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/request.go new/web.go/request.go
--- old/web.go/request.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/request.go 2012-02-17 17:27:22.000000000 +0100
@@ -1,19 +1,19 @@
package web
import (
+ "encoding/json"
+ "errors"
"fmt"
- "http"
"io"
"io/ioutil"
- "json"
"mime"
"mime/multipart"
"net"
- "os"
+ "net/http"
+ "net/url"
"reflect"
"strconv"
"strings"
- "url"
)
type filedata struct {
@@ -22,8 +22,8 @@
}
type Request struct {
- Method string // GET, POST, PUT, etc.
- RawURL string // The raw URL given in the request.
+ Method string // GET, POST, PUT, etc.
+ //RawURL string // The raw URL given in the request.
URL *url.URL // Parsed URL.
Proto string // "HTTP/1.0"
ProtoMajor int // 1
@@ -49,7 +49,7 @@
str string
}
-func (e *badStringError) String() string { return fmt.Sprintf("%s %q", e.what, e.str) }
+func (e *badStringError) Error() string { return fmt.Sprintf("%s %q", e.what, e.str) }
func flattenParams(fullParams map[string][]string) map[string]string {
params := map[string]string{}
@@ -66,7 +66,8 @@
remoteAddr, _ := net.ResolveTCPAddr("tcp", hr.RemoteAddr)
req := Request{
- Method: hr.Method,
+ Method: hr.Method,
+ //RawURL: hr.RawURL,
URL: hr.URL,
Proto: hr.Proto,
ProtoMajor: hr.ProtoMajor,
@@ -121,8 +122,8 @@
cookies := readCookies(httpheader)
req := Request{
- Method: method,
- RawURL: rawurl,
+ Method: method,
+ //RawURL: rawurl,
URL: url_,
Proto: proto,
Host: host,
@@ -137,12 +138,13 @@
return &req
}
-func parseForm(m map[string][]string, query string) (err os.Error) {
+func parseForm(m map[string][]string, query string) (err error) {
+ data := make(map[string][]string)
for _, kv := range strings.Split(query, "&") {
kvPair := strings.SplitN(kv, "=", 2)
var key, value string
- var e os.Error
+ var e error
key, e = url.QueryUnescape(kvPair[0])
if e == nil && len(kvPair) > 1 {
value, e = url.QueryUnescape(kvPair[1])
@@ -151,11 +153,11 @@
err = e
}
- vec, ok := m[key]
- if !ok {
- vec = []string{}
- }
- m[key] = append(vec, value)
+ data[key] = append(data[key], value)
+ }
+
+ for k, vec := range data {
+ m[k] = vec
}
return
@@ -163,7 +165,7 @@
// ParseForm parses the request body as a form for POST requests, or the raw query for GET requests.
// It is idempotent.
-func (r *Request) parseParams() (err os.Error) {
+func (r *Request) parseParams() (err error) {
if r.Params != nil {
return
}
@@ -173,7 +175,7 @@
switch r.Method {
case "POST":
if r.Body == nil {
- return os.NewError("missing form body")
+ return errors.New("missing form body")
}
ct := r.Headers.Get("Content-Type")
@@ -195,24 +197,22 @@
r.Params = map[string]string{}
json.Unmarshal(b, r.Params)
case "multipart/form-data":
- _, params := mime.ParseMediaType(ct)
+ _, params, _ := mime.ParseMediaType(ct)
boundary, ok := params["boundary"]
if !ok {
- return os.NewError("Missing Boundary")
+ return errors.New("Missing Boundary")
}
-
reader := multipart.NewReader(r.Body, boundary)
r.Files = make(map[string]filedata)
for {
part, err := reader.NextPart()
- if part == nil && err == os.EOF {
- break
- }
-
if err != nil {
return err
}
+ if part == nil {
+ break
+ }
//read the data
data, _ := ioutil.ReadAll(part)
//check for the 'filename' param
@@ -221,7 +221,7 @@
continue
}
name := part.FormName()
- d, params := mime.ParseMediaType(v)
+ d, params, _ := mime.ParseMediaType(v)
if d != "form-data" {
continue
}
@@ -238,7 +238,6 @@
return &badStringError{"unknown Content-Type", ct}
}
}
-
if queryParams != "" {
err = parseForm(r.FullParams, queryParams)
if err != nil {
@@ -265,7 +264,7 @@
return ok
}
-func writeTo(s string, val reflect.Value) os.Error {
+func writeTo(s string, val reflect.Value) error {
switch v := val; v.Kind() {
// if we're writing to an interace value, just set the byte data
// TODO: should we support writing to a pointer?
@@ -278,19 +277,19 @@
v.SetBool(true)
}
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
- i, err := strconv.Atoi64(s)
+ i, err := strconv.ParseInt(s, 10, 64)
if err != nil {
return err
}
v.SetInt(i)
case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
- ui, err := strconv.Atoui64(s)
+ ui, err := strconv.ParseUint(s, 10, 64)
if err != nil {
return err
}
v.SetUint(ui)
case reflect.Float32, reflect.Float64:
- f, err := strconv.Atof64(s)
+ f, err := strconv.ParseFloat(s, 64)
if err != nil {
return err
}
@@ -312,7 +311,7 @@
return strings.ToLower(key) == strings.ToLower(name)
}
-func (r *Request) writeToContainer(val reflect.Value) os.Error {
+func (r *Request) writeToContainer(val reflect.Value) error {
switch v := val; v.Kind() {
case reflect.Ptr:
return r.writeToContainer(reflect.Indirect(v))
@@ -320,7 +319,7 @@
return r.writeToContainer(v.Elem())
case reflect.Map:
if v.Type().Key().Kind() != reflect.String {
- return os.NewError("Invalid map type")
+ return errors.New("Invalid map type")
}
elemtype := v.Type().Elem()
for pk, pv := range r.Params {
@@ -345,12 +344,12 @@
}
default:
- return os.NewError("Invalid container type")
+ return errors.New("Invalid container type")
}
return nil
}
-func (r *Request) UnmarshalParams(val interface{}) os.Error {
+func (r *Request) UnmarshalParams(val interface{}) error {
if strings.HasPrefix(r.Headers.Get("Content-Type"), "application/json") {
return json.Unmarshal(r.ParamData, val)
} else {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/scgi.go new/web.go/scgi.go
--- old/web.go/scgi.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/scgi.go 2012-02-17 17:27:22.000000000 +0100
@@ -2,11 +2,11 @@
import (
"bytes"
+ "errors"
"fmt"
- "http"
"io"
"net"
- "os"
+ "net/http"
"strconv"
"strings"
)
@@ -42,7 +42,7 @@
}
}
-func (conn *scgiConn) Write(data []byte) (n int, err os.Error) {
+func (conn *scgiConn) Write(data []byte) (n int, err error) {
var buf bytes.Buffer
if !conn.wroteHeaders {
conn.wroteHeaders = true
@@ -61,7 +61,7 @@
func (conn *scgiConn) Close() { conn.fd.Close() }
-func (conn *scgiConn) finishRequest() os.Error {
+func (conn *scgiConn) finishRequest() error {
var buf bytes.Buffer
if !conn.wroteHeaders {
conn.wroteHeaders = true
@@ -78,7 +78,7 @@
return nil
}
-func readScgiRequest(buf *bytes.Buffer) (*Request, os.Error) {
+func readScgiRequest(buf *bytes.Buffer) (*Request, error) {
headers := make(http.Header)
data := buf.Bytes()
@@ -86,21 +86,21 @@
colon := bytes.IndexByte(data, ':')
data = data[colon+1:]
- var err os.Error
+ var err error
//find the CONTENT_LENGTH
clfields := bytes.SplitN(data, []byte{0}, 3)
if len(clfields) != 3 {
- return nil, os.NewError("Invalid SCGI Request -- no fields")
+ return nil, errors.New("Invalid SCGI Request -- no fields")
}
clfields = clfields[0:2]
if string(clfields[0]) != "CONTENT_LENGTH" {
- return nil, os.NewError("Invalid SCGI Request -- expecing CONTENT_LENGTH")
+ return nil, errors.New("Invalid SCGI Request -- expecing CONTENT_LENGTH")
}
if clen, err = strconv.Atoi(string(clfields[1])); err != nil {
- return nil, os.NewError("Invalid SCGI Request -- invalid CONTENT_LENGTH field")
+ return nil, errors.New("Invalid SCGI Request -- invalid CONTENT_LENGTH field")
}
content := data[len(data)-clen:]
@@ -146,7 +146,7 @@
req, err := readScgiRequest(&buf)
if err != nil {
- s.Logger.Println("SCGI read error", err.String())
+ s.Logger.Println("SCGI read error", err.Error())
return
}
@@ -157,10 +157,10 @@
fd.Close()
}
-func (s *Server) listenAndServeScgi(addr string) os.Error {
+func (s *Server) listenAndServeScgi(addr string) error {
var l net.Listener
- var err os.Error
+ var err error
//if the path begins with a "/", assume it's a unix address
if strings.HasPrefix(addr, "/") {
@@ -173,14 +173,14 @@
s.l = l
if err != nil {
- s.Logger.Println("SCGI listen error", err.String())
+ s.Logger.Println("SCGI listen error", err.Error())
return err
}
for {
fd, err := l.Accept()
if err != nil {
- s.Logger.Println("SCGI accept error", err.String())
+ s.Logger.Println("SCGI accept error", err.Error())
return err
}
go s.handleScgiRequest(fd)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/servefile.go new/web.go/servefile.go
--- old/web.go/servefile.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/servefile.go 2012-02-17 17:27:22.000000000 +0100
@@ -10,7 +10,7 @@
"strconv"
"strings"
"time"
- "utf8"
+ "unicode/utf8"
)
func isText(b []byte) bool {
@@ -39,8 +39,7 @@
func getmd5(data string) string {
hash := md5.New()
- hash.Write([]byte(data))
- return fmt.Sprintf("%x", hash.Sum())
+ return fmt.Sprintf("%x", hash.Sum([]byte(data)))
}
func serveFile(ctx *Context, name string) {
@@ -54,10 +53,10 @@
defer f.Close()
info, _ := f.Stat()
- size := strconv.Itoa64(info.Size)
- mtime := strconv.Itoa64(info.Mtime_ns)
+ size := strconv.FormatInt(info.Size(), 10)
+ mtime := strconv.FormatInt(info.ModTime().UnixNano(), 10)
//set the last-modified header
- lm := time.SecondsToUTC(info.Mtime_ns / 1e9)
+ lm := info.ModTime().UTC()
ctx.SetHeader("Last-Modified", webTime(lm), true)
//generate a simple etag with heuristic MD5(filename, size, lastmod)
@@ -94,7 +93,7 @@
if ctx.Request.Headers.Get("If-Modified-Since") != "" {
ims := ctx.Request.Headers.Get("If-Modified-Since")
imstime, err := time.Parse(time.RFC1123, ims)
- if err == nil && imstime.Seconds() >= lm.Seconds() {
+ if err == nil && imstime.Unix() >= lm.Unix() {
ctx.NotModified()
return
}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/status.go new/web.go/status.go
--- old/web.go/status.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/status.go 2012-02-17 17:27:22.000000000 +0100
@@ -4,7 +4,7 @@
package web
-import "http"
+import "net/http"
var statusText = map[int]string{
http.StatusContinue: "Continue",
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/web.go new/web.go/web.go
--- old/web.go/web.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/web.go 2012-02-17 17:27:22.000000000 +0100
@@ -3,14 +3,16 @@
import (
"bytes"
"crypto/hmac"
+ "crypto/sha1"
"encoding/base64"
"fmt"
- "http"
- "http/pprof"
"io/ioutil"
"log"
"mime"
"net"
+ "net/http"
+ "net/http/pprof"
+ "net/url"
"os"
"path"
"reflect"
@@ -19,13 +21,12 @@
"strconv"
"strings"
"time"
- "url"
)
type conn interface {
StartResponse(status int)
SetHeader(hdr string, val string, unique bool)
- Write(data []byte) (n int, err os.Error)
+ Write(data []byte) (n int, err error)
Close()
}
@@ -41,7 +42,7 @@
ctx.responseStarted = true
}
-func (ctx *Context) Write(data []byte) (n int, err os.Error) {
+func (ctx *Context) Write(data []byte) (n int, err error) {
if !ctx.responseStarted {
ctx.StartResponse(200)
}
@@ -91,31 +92,32 @@
//Sets a cookie -- duration is the amount of time in seconds. 0 = forever
func (ctx *Context) SetCookie(name string, value string, age int64) {
- var utctime *time.Time
+ var utctime time.Time
+ var tdelta time.Duration
if age == 0 {
- // 2^31 - 1 seconds (roughly 2038)
- utctime = time.SecondsToUTC(2147483647)
+ // 2^31 - 1 seconds (roughly 27 years from now)
+ tdelta = time.Second * 2147483647
} else {
- utctime = time.SecondsToUTC(time.UTC().Seconds() + age)
+ tdelta = time.Second * time.Duration(age)
}
+ utctime = time.Now().Add(tdelta).UTC()
cookie := fmt.Sprintf("%s=%s; expires=%s", name, value, webTime(utctime))
ctx.SetHeader("Set-Cookie", cookie, false)
}
func getCookieSig(key string, val []byte, timestamp string) string {
- hm := hmac.NewSHA1([]byte(key))
+ hm := hmac.New(sha1.New, []byte(key))
hm.Write(val)
- hm.Write([]byte(timestamp))
- hex := fmt.Sprintf("%02x", hm.Sum())
+ hex := fmt.Sprintf("%02x", hm.Sum([]byte(timestamp)))
return hex
}
func (ctx *Context) SetSecureCookie(name string, val string, age int64) {
//base64 encode the val
if len(ctx.Server.Config.CookieSecret) == 0 {
- ctx.Logger.Println("Secret Key for secure cookies has not been set. Please assign a cookie secret to web.Config.CookieSecret.")
+ ctx.Logger.Println("Secret Key for secure cookies has not been set. Please call web.SetCookieSecret")
return
}
var buf bytes.Buffer
@@ -124,7 +126,7 @@
encoder.Close()
vs := buf.String()
vb := buf.Bytes()
- timestamp := strconv.Itoa64(time.Seconds())
+ timestamp := strconv.Itoa(time.Now().Second())
sig := getCookieSig(ctx.Server.Config.CookieSecret, vb, timestamp)
cookie := strings.Join([]string{vs, timestamp, sig}, "|")
ctx.SetCookie(name, cookie, age)
@@ -146,9 +148,9 @@
return "", false
}
- ts, _ := strconv.Atoi64(timestamp)
+ ts, _ := strconv.ParseInt(timestamp, 10, 64)
- if time.Seconds()-31*86400 > ts {
+ if time.Now().Unix()-(31*86400) > ts {
return "", false
}
@@ -224,7 +226,7 @@
c.conn.Write(buf.Bytes())
}
-func (c *httpConn) Write(content []byte) (n int, err os.Error) {
+func (c *httpConn) Write(content []byte) (n int, err error) {
return c.conn.Write(content)
}
@@ -286,6 +288,19 @@
return true
}
+ //another case -- the first argument is a method receiver, and the
+ //second argument is a web.Context
+
+ if handlerType.NumIn() > 1 {
+ a1 := handlerType.In(1)
+ if a1.Kind() != reflect.Ptr {
+ return false
+ }
+ if a1.Elem() == contextType {
+ return true
+ }
+ }
+
return false
}
@@ -302,7 +317,7 @@
//parse the form data (if it exists)
perr := req.parseParams()
if perr != nil {
- s.Logger.Printf("Failed to parse form data %q\n", perr.String())
+ s.Logger.Printf("Failed to parse form data %q\n", perr.Error())
}
ctx := Context{req, s, c, false}
@@ -311,7 +326,7 @@
ctx.SetHeader("Content-Type", "text/html; charset=utf-8", true)
ctx.SetHeader("Server", "web.go", true)
- tm := time.UTC()
+ tm := time.Now().UTC()
ctx.SetHeader("Date", webTime(tm), true)
//try to serve a static file
@@ -353,7 +368,6 @@
ret, err := s.safelyCall(route.handler, args)
if err != nil {
- //fmt.Printf("%v\n", err)
//there was an error or panic while calling the handler
ctx.Abort(500, "Server Error")
}
@@ -535,7 +549,7 @@
RecoverPanic bool
}
-func webTime(t *time.Time) string {
+func webTime(t time.Time) string {
ftime := t.Format(time.RFC1123)
if strings.HasSuffix(ftime, "UTC") {
ftime = ftime[0:len(ftime)-3] + "GMT"
@@ -548,7 +562,7 @@
switch {
case e != nil:
return false
- case !d.IsDirectory():
+ case !d.IsDir():
return false
}
@@ -559,7 +573,7 @@
info, err := os.Stat(dir)
if err != nil {
return false
- } else if !info.IsRegular() {
+ } else if !!info.IsDir() {
return false
}
@@ -577,3 +591,20 @@
s := buf.String()
return s[0 : len(s)-1]
}
+
+//Extracts the method "name" from the value represented by "val"
+//This allows methods to be handlers
+func MethodHandler(val interface{}, name string) reflect.Value {
+ v := reflect.ValueOf(val)
+ typ := v.Type()
+ n := typ.NumMethod()
+ for i := 0; i < n; i++ {
+ m := typ.Method(i)
+ if m.Name == name {
+ return v.Method(i)
+ }
+ }
+
+ panic("Could not find method: " + name)
+ return reflect.Value{}
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/web.go/web_test.go new/web.go/web_test.go
--- old/web.go/web_test.go 2011-12-13 10:51:40.000000000 +0100
+++ new/web.go/web_test.go 2012-02-17 17:42:09.000000000 +0100
@@ -4,35 +4,37 @@
"bytes"
"encoding/binary"
"fmt"
- "http"
- "json"
+ "encoding/json"
+ "io"
"log"
+ "net/http"
+ "net/url"
"os"
"runtime"
"strconv"
"strings"
"testing"
- "url"
)
func init() {
runtime.GOMAXPROCS(4)
}
+
//this implements io.ReadWriteCloser, which means it can be passed around as a tcp connection
type tcpBuffer struct {
input *bytes.Buffer
output *bytes.Buffer
}
-func (buf *tcpBuffer) Write(p []uint8) (n int, err os.Error) {
+func (buf *tcpBuffer) Write(p []uint8) (n int, err error) {
return buf.output.Write(p)
}
-func (buf *tcpBuffer) Read(p []byte) (n int, err os.Error) {
+func (buf *tcpBuffer) Read(p []byte) (n int, err error) {
return buf.input.Read(p)
}
-func (buf *tcpBuffer) Close() os.Error { return nil }
+func (buf *tcpBuffer) Close() error { return nil }
type testResponse struct {
statusCode int
@@ -171,6 +173,15 @@
return string(data)
})
+ Post("/parsejson", func(ctx *Context) string {
+ var tmp = struct {
+ A string
+ B string
+ }{}
+ json.NewDecoder(ctx.Request.Body).Decode(&tmp)
+ return tmp.A + " " + tmp.B
+ })
+
//s := &StructHandler{"a"}
//Get("/methodhandler", MethodHandler(s, "method"))
//Get("/methodhandler2", MethodHandler(s, "method2"))
@@ -204,6 +215,7 @@
//{"GET", "/methodhandler", "", 200, `a`},
//{"GET", "/methodhandler2?b=b", "", 200, `ab`},
//{"GET", "/methodhandler3/b", "", 200, `ab`},
+ {"POST", "/parsejson", `{"a":"hello", "b":"world"}`, 200, "hello world"},
}
func buildTestRequest(method string, path string, body string, headers map[string][]string, cookies []*http.Cookie) *Request {
@@ -213,7 +225,7 @@
url_, _ := url.Parse(rawurl)
proto := "HTTP/1.1"
- useragent := "web.go test framework"
+ useragent := "web.go test"
if headers == nil {
headers = map[string][]string{}
@@ -221,11 +233,13 @@
if method == "POST" {
headers["Content-Length"] = []string{fmt.Sprintf("%d", len(body))}
- headers["Content-Type"] = []string{"text/plain"}
+ if headers["Content-Type"] == nil {
+ headers["Content-Type"] = []string{"text/plain"}
+ }
}
req := Request{Method: method,
- RawURL: rawurl,
+ //RawURL: rawurl,
Cookie: cookies,
URL: url_,
Proto: proto,
@@ -499,7 +513,7 @@
for {
var h fcgiHeader
err := binary.Read(br, binary.BigEndian, &h)
- if err == os.EOF {
+ if err == io.EOF {
break
}
++++++ weekly-build-fix.patch ++++++
diff --git a/web.go b/web.go
index 0bd394b..9425526 100644
--- a/web.go
+++ b/web.go
@@ -439,7 +439,7 @@ func (s *Server) Run(addr string) {
mux.Handle("/debug/pprof/cmdline", http.HandlerFunc(pprof.Cmdline))
mux.Handle("/debug/pprof/profile", http.HandlerFunc(pprof.Profile))
- mux.Handle("/debug/pprof/heap", http.HandlerFunc(pprof.Heap))
+ //mux.Handle("/debug/pprof/heap", http.HandlerFunc(pprof.Heap))
mux.Handle("/debug/pprof/symbol", http.HandlerFunc(pprof.Symbol))
mux.Handle("/", s)
--
To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org
For additional commands, e-mail: opensuse-commit+help@opensuse.org