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 - [email protected]
+
+- 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 <[email protected]>
 #
 # 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: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to