better request copy code

With state's lock as a pointer, we can use the `*r = *r2` statement for
copying which is much more concise and future proof.
diff --git a/request-server.go b/request-server.go
index 8c4229e..0a969e3 100644
--- a/request-server.go
+++ b/request-server.go
@@ -83,7 +83,8 @@
 	if !ok || r.Method == method { // re-check needed b/c lock race
 		return r, ok
 	}
-	r = &Request{Method: method, Filepath: r.Filepath, state: r.state}
+	r = r.copy()
+	r.Method = method
 	rs.openRequests[handle] = r
 	return r, ok
 }
diff --git a/request.go b/request.go
index 387639d..d74d6fa 100644
--- a/request.go
+++ b/request.go
@@ -65,6 +65,15 @@
 		state: state{RWMutex: new(sync.RWMutex)}}
 }
 
+// shallow copy of existing request
+func (r *Request) copy() *Request {
+	r.state.Lock()
+	defer r.state.Unlock()
+	r2 := new(Request)
+	*r2 = *r
+	return r2
+}
+
 // Context returns the request's context. To change the context,
 // use WithContext.
 //
@@ -86,17 +95,9 @@
 	if ctx == nil {
 		panic("nil context")
 	}
-	r.state.Lock()
-	defer r.state.Unlock()
-	r2 := &Request{
-		Method:   r.Method,
-		Filepath: r.Filepath,
-		Target:   r.Target,
-		Flags:    r.Flags,
-		Attrs:    r.Attrs,
-		state:    r.state,
-		ctx:      ctx,
-	}
+	r2 := r.copy()
+	r2.ctx = ctx
+	r2.cancelCtx = nil
 	return r2
 }