-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
227 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
package main | ||
import ( | ||
"encoding/json" | ||
"log" | ||
"net/http" | ||
"io/ioutil" | ||
"strconv" | ||
"fmt" | ||
|
||
|
||
"github.com/gorilla/mux" | ||
) | ||
|
||
|
||
//struct used to send the id of the message in json format | ||
type messageID struct { | ||
Id int `json:"id"` | ||
} | ||
|
||
|
||
//Store for the Messages | ||
var msgStore = make(map[string]string) | ||
|
||
//int used as key into message store | ||
var idSeq int = 0 | ||
|
||
//============================================================================== | ||
// Struct Error handling | ||
type ErrorMessage struct { | ||
Status string `json:"status"` | ||
Message string `json:"error_message"` | ||
} | ||
|
||
func genericErrorHandler(w http.ResponseWriter, r *http.Request) { | ||
if p := recover(); p != nil { | ||
s := fmt.Sprintf("internal error>> %s", p) | ||
e := &ErrorMessage{Status:"error occured",Message: s} | ||
writeErrorResponse(w, e,http.StatusInternalServerError) | ||
} | ||
|
||
} | ||
func writeErrorResponse(w http.ResponseWriter,e *ErrorMessage, status int) { | ||
j, err := json.Marshal(e) | ||
if err != nil { | ||
panic(err) | ||
} | ||
fmt.Printf(e.Status,e.Message) | ||
w.Header().Set("Content-Type", "application/json") | ||
w.WriteHeader(status) | ||
w.Write(j) | ||
} | ||
//============================================================================== | ||
|
||
|
||
//POST method handler | ||
func PostMsgHandler(w http.ResponseWriter, r *http.Request) { | ||
defer genericErrorHandler(w,r) | ||
|
||
msgReader := http.MaxBytesReader(w,r.Body,4096) //Limit the max number of chars in message | ||
reqDump, err := ioutil.ReadAll(msgReader) | ||
|
||
if err != nil { | ||
panic (fmt.Sprintf("PostMsgHandler:[Max content length 4096] err[%s]", err)) | ||
} | ||
|
||
msgContent := string(reqDump[:]) | ||
idSeq++ | ||
k := strconv.Itoa(idSeq) | ||
msgStore[k] =msgContent | ||
|
||
log.Printf("Received message %d => %s", idSeq, msgContent) | ||
resp := &messageID{idSeq} | ||
j, err := json.Marshal(resp) | ||
if err != nil { | ||
panic(err) | ||
} | ||
w.Header().Set("Content-Type", "application/json") | ||
w.WriteHeader(http.StatusCreated) | ||
w.Write(j) | ||
} | ||
|
||
|
||
//HTTP GET - /messages/{id} | ||
func GetMsgHandler(w http.ResponseWriter, r *http.Request) { | ||
defer genericErrorHandler(w,r) | ||
vars := mux.Vars(r) | ||
k := vars["id"] | ||
log.Printf("key %s",k) | ||
if msgContent, ok := msgStore[k]; ok { | ||
log.Printf("Key found [%s]=>[%s]",k,msgContent) | ||
w.WriteHeader(http.StatusOK) | ||
fmt.Fprintf(w, msgContent) // Escape HTML special chars | ||
} else { | ||
log.Printf("Key Not found %s",k) | ||
w.WriteHeader(http.StatusNotFound) | ||
} | ||
|
||
} | ||
|
||
//Entry point of the program | ||
func main() { | ||
|
||
r := mux.NewRouter().StrictSlash(false) | ||
r.HandleFunc("/messages/{id}", GetMsgHandler).Methods("GET") | ||
r.HandleFunc("/messages", PostMsgHandler).Methods("POST") | ||
|
||
server := &http.Server{ | ||
Addr: ":8080", | ||
Handler: r, | ||
} | ||
log.Println("Listening...") | ||
server.ListenAndServe() | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
package main | ||
import ( | ||
"net/http" | ||
"net/http/httptest" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/gorilla/mux" | ||
) | ||
|
||
|
||
func TestStoreMsg(t *testing.T) { | ||
r := mux.NewRouter() | ||
r.HandleFunc("/messages", PostMsgHandler).Methods("POST") | ||
req, err := http.NewRequest( | ||
"POST", | ||
"/messages", | ||
strings.NewReader(`Hello World`), | ||
) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
w := httptest.NewRecorder() | ||
r.ServeHTTP(w, req) | ||
if w.Code != 201 { | ||
t.Errorf("HTTP Status expected: 201, got: %d", w.Code) | ||
} | ||
} | ||
|
||
func TestStoreTooLongMsg(t *testing.T) { | ||
r := mux.NewRouter() | ||
r.HandleFunc("/messages", PostMsgHandler).Methods("POST") | ||
byteSlice := []byte{0:'a',5000:'b'} | ||
tooLongString:= string(byteSlice[:]) | ||
|
||
req, err := http.NewRequest( | ||
"POST", | ||
"/messages", | ||
strings.NewReader(tooLongString), | ||
) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
|
||
w := httptest.NewRecorder() | ||
r.ServeHTTP(w, req) | ||
if w.Code != 500 { | ||
t.Errorf("HTTP Status expected: 500, got: %d", w.Code) | ||
} | ||
} | ||
|
||
|
||
func TestGetMsgHandler(t *testing.T) { | ||
r := mux.NewRouter() | ||
r.HandleFunc("/messages/{id}", GetMsgHandler).Methods("GET") | ||
req, err := http.NewRequest("GET", "/messages/1", nil) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
w := httptest.NewRecorder() | ||
|
||
r.ServeHTTP(w, req) | ||
if w.Code != 200 { | ||
t.Errorf("HTTP Status expected: 200, got: %d", w.Code) | ||
} | ||
} | ||
|
||
func TestGetNonExistentMsgHandler(t *testing.T) { | ||
r := mux.NewRouter() | ||
r.HandleFunc("/messages/{id}", GetMsgHandler).Methods("GET") | ||
req, err := http.NewRequest("GET", "/messages/31", nil) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
w := httptest.NewRecorder() | ||
|
||
r.ServeHTTP(w, req) | ||
if w.Code != 404 { | ||
t.Errorf("HTTP Status expected: 404, got: %d", w.Code) | ||
} | ||
} | ||
|
||
|
||
/* | ||
func TestGetMsgHandlerWithServer(t *testing.T) { | ||
log.SetPrefix("TestGetMsgHandlerWithServer:") | ||
log.Println ("Testing message retrieval") | ||
r := mux.NewRouter() | ||
r.HandleFunc("/messages/{id}", GetMsgHandler).Methods("GET") | ||
server := httptest.NewServer(r) | ||
defer server.Close() | ||
msgUrl := fmt.Sprintf("%s/messages/1", server.URL) | ||
log.Printf ("msgUrl %s", msgUrl) | ||
request, err := http.NewRequest("GET", msgUrl, nil) | ||
res, err := http.DefaultClient.Do(request) | ||
if err != nil { | ||
t.Error(err) | ||
} | ||
resDump, err2 := ioutil.ReadAll(res.Body) | ||
if err2 != nil { | ||
t.Error(err2) | ||
} | ||
log.Printf("Response is [%s]",string(resDump[:])) | ||
if res.StatusCode != 200 { | ||
t.Errorf("HTTP Status expected: 200, got: %d", res.StatusCode) | ||
} | ||
}*/ |