1
1
package main
2
2
3
3
import (
4
+ "bytes"
4
5
"encoding/json"
5
6
"fmt"
6
7
"io"
8
+ "io/ioutil"
7
9
"log"
8
10
"net/http"
9
11
"os"
@@ -29,48 +31,46 @@ func handleComments(w http.ResponseWriter, r *http.Request) {
29
31
// Stat the file, so we can find it's current permissions
30
32
fi , err := os .Stat (dataFile )
31
33
if err != nil {
32
- http .Error (w , fmt .Sprintf ("Unable to stat data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
34
+ http .Error (w , fmt .Sprintf ("Unable to stat the data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
33
35
return
34
36
}
35
37
36
- // Open the file Read/Write
37
- cFile , err := os . OpenFile (dataFile , os . O_RDWR , fi . Mode () )
38
+ // Read the comments from the file.
39
+ commentData , err := ioutil . ReadFile (dataFile )
38
40
if err != nil {
39
- http .Error (w , fmt .Sprintf ("Unable to open data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
41
+ http .Error (w , fmt .Sprintf ("Unable to read the data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
40
42
return
41
43
}
42
- defer cFile .Close () //Ensure the file is closed when we are done.
43
44
44
45
switch r .Method {
45
46
case "POST" :
46
47
// Decode the JSON data
47
48
comments := make ([]comment , 0 )
48
- commentsDecoder := json .NewDecoder (cFile )
49
- if err := commentsDecoder .Decode (& comments ); err != nil {
50
- http .Error (w , fmt .Sprintf ("Unable to read comments from data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
49
+ if err := json .Unmarshal (commentData , & comments ); err != nil {
50
+ http .Error (w , fmt .Sprintf ("Unable to Unmarshal comments from data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
51
51
return
52
52
}
53
53
54
54
// Add a new comment to the in memory slice of comments
55
55
comments = append (comments , comment {Author : r .FormValue ("author" ), Text : r .FormValue ("text" )})
56
56
57
- // Truncate the file and Seek to the beginning of it
58
- if err := cFile .Truncate (0 ); err != nil {
59
- http .Error (w , fmt .Sprintf ("Unable to truncate data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
57
+ // Marshal the comments to indented json.
58
+ commentData , err = json .MarshalIndent (comments , "" , " " )
59
+ if err != nil {
60
+ http .Error (w , fmt .Sprintf ("Unable to marshal comments to json: %s" , err ), http .StatusInternalServerError )
60
61
return
61
62
}
62
- if r , err := cFile .Seek (0 , 0 ); r != 0 && err != nil {
63
- http .Error (w , fmt .Sprintf ("Unable to seek to beginning of data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
63
+
64
+ // Write out the comments to the file, preserving permissions
65
+ err := ioutil .WriteFile (dataFile , commentData , fi .Mode ())
66
+ if err != nil {
67
+ http .Error (w , fmt .Sprintf ("Unable to write comments to data file (%s): %s" , dataFile , err ), http .StatusInternalServerError )
64
68
return
65
69
}
66
70
67
- // Write out the json response
68
- commentsEncoder := json .NewEncoder (cFile )
69
- commentsEncoder .Encode (comments )
70
-
71
71
case "GET" :
72
72
// stream the contents of the file to the response
73
- io .Copy (w , cFile )
73
+ io .Copy (w , bytes . NewReader ( commentData ) )
74
74
75
75
default :
76
76
// Don't know the method, so error
0 commit comments