syntax error: unexpected newline, expecting comma or ) - go

I get error syntax error: unexpected newline, expecting comma or ). im new at golang. im try with new code but same error. can someone help me?.
my code
package main
import "fmt"
import "net/http"
import "html/template"
import "path"
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var filepath = path.Join("index.html")
var tmpl, err = template.ParseFiles(filepath)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.HandleFunc("/membuat-web-dengan-golang", func(w http.ResponseWriter, r *http.Request) {
var filepath = path.Join("membuat-web-dengan-golang.html")
var tmpl, err = template.ParseFiles(filepath)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("assets"))))
fmt.Println("server started at localhost:9000")
http.ListenAndServe(":9000", nil)
}

Hi your HandleFunc functions are missing the closing brackets. Check the fmt.Println(tmpl) line which I added to your code. The first closing curly bracket } is for the anonymous function and the second round bracket ) is for the HandleFunc.
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
var filepath = path.Join("index.html")
var tmpl, err = template.ParseFiles(filepath)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Println(tmpl)})
http.HandleFunc("/membuat-web-dengan-golang", func(w http.ResponseWriter, r *http.Request) {
var filepath = path.Join("membuat-web-dengan-golang.html")
var tmpl, err = template.ParseFiles(filepath)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
fmt.Println(tmpl)})
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("assets"))))
fmt.Println("server started at localhost:9000")
http.ListenAndServe(":9000", nil)
}

Related

Gorilla/sessions cookie not being set when SessionStore is from exported package

I'm having an issue with gorilla/sessions. My sessions aren't being saved when sessions.NewCookieStore([]byte("veryprivatekey")) is from a different package/exported variable.
Here is what works:
What works
exampleproj/main.go
package main
import (
"fmt"
"github.com/gorilla/mux"
"github.com/gorilla/sessions"
"net/http"
)
var store *sessions.CookieStore
var cookie_name = "sess"
func main() {
store = sessions.NewCookieStore([]byte("veryprivatekey"))
router := mux.NewRouter()
router.HandleFunc("/cookietest", cookietest)
router.HandleFunc("/cookietest2", cookietest2)
err := http.ListenAndServe(":8080", router)
if err != nil {
fmt.Print(err)
}
}
var cookietest = func(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, cookie_name)
if err != nil {
fmt.Println(err)
}
session.Values["Stack"] = "Overflow"
err = session.Save(r,w)
if err != nil {
fmt.Println(err)
}
}
var cookietest2 = func(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, cookie_name)
if err != nil {
fmt.Println(err)
}
fmt.Println("Stack: ", session.Values["Stack"])
}
(open localhost:8080/cookietest and check that a cookie was created)
The issue
Here is some code where sessions.CookieStore is from another package:
exampleproj/main.go
package main
import (
"expirements/example"
"fmt"
"github.com/gorilla/mux"
"net/http"
)
var cookie_name = "sess"
func main() {
router := mux.NewRouter()
router.HandleFunc("/cookietest", cookietest)
router.HandleFunc("/cookietest2", cookietest2)
err := http.ListenAndServe(":8080", router)
if err != nil {
fmt.Print(err)
}
}
var cookietest = func(w http.ResponseWriter, r *http.Request) {
session, err := example.Store.Get(r, cookie_name)
if err != nil {
fmt.Println(err)
}
session.Values["Stack"] = "Overflow"
err = session.Save(r,w)
if err != nil {
fmt.Println(err)
}
}
var cookietest2 = func(w http.ResponseWriter, r *http.Request) {
session, err := example.Store.Get(r, cookie_name)
if err != nil {
fmt.Println(err)
}
fmt.Println("Stack: ", session.Values["Stack"])
}
exampleproj/example/ex.go
package example
import (
"github.com/gorilla/sessions"
)
var Store *sessions.CookieStore
func init() {
Store = sessions.NewCookieStore([]byte("veryprivatekey"))
Store.Options = &sessions.Options{
//Domain: config.Host,
//Path: "/",
MaxAge: 259200,
Secure: true,
HttpOnly: true,
}
}
func GetStore() *sessions.CookieStore {
return Store
}
No cookies were set. I've also tried using GetStore() instead of example.Store, but that didn't work either. Am I supposed to declare a sessions.NewCookieStore for each package?
Solution is here - surprised I couldn't find more stackoverflow questions about this.

Serve html file with custom status code

I need to have a custom not found html page. Here is what I've tried:
package main
import (
"net/http"
"github.com/julienschmidt/httprouter"
)
func main() {
r := httprouter.New()
r.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(404)
http.ServeFile(w, r, "files/not-found.html")
})
http.ListenAndServe(":8000", r)
}
I have the line w.WriteHeader(404) to make sure the status code is 404, but the code above gives the error:
http: multiple response.WriteHeader calls
Without the line w.WriteHeader(404) there are no errors and the page is shown correctly, but the status code is 200. I want it to be 404.
You can simply just write the contents yourself.
Something like:
r.NotFound = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
contents, err := ioutil.ReadFile("files/not-found.html")
if err != nil {
panic(err) // or do something useful
}
w.WriteHeader(404)
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.Write(contents)
})
David's answer worked, and this is another way.
// other header stuff
w.WriteHeader(http.StatusNotFound)
file, err := os.Open("files/not-found.html")
if err != nil {
log.Println(err)
return
}
_, err = io.Copy(w, file)
if err != nil {
log.Println(err)
}
file.Close() // consider defer ^

Why am I getting a 404 on this golang route using gorilla mux?

I am getting a 404 when I go to:
http://127.0.0.1:12345/list-issues/sortbycategory
This is not the case when I got to /list-issues. Am I using gorilla mux correctly? From looking at the examples it seems to me that I am.
main.go:
package main
import (
"log"
"net/http"
"text/template"
"my_proj/uservoice_app/controllers"
"github.com/gorilla/mux"
)
func init() {
controllers.Tpl = template.Must(template.ParseGlob("templates/*.html"))
log.SetFlags(log.LstdFlags | log.Lshortfile)
}
func main() {
router := mux.NewRouter()
http.HandleFunc("/hello", controllers.Hello_cont)
http.HandleFunc("/write", controllers.Write_cont)
http.HandleFunc("/test", controllers.Test)
http.HandleFunc("/signup", controllers.Signup)
http.HandleFunc("/create-issue", controllers.CreateIssue)
http.HandleFunc("/list-issues", controllers.ListIssues)
//ROUTER:
router.HandleFunc("/list-issues/{sortby}", controllers.ListIssuesBy).Methods("GET")
fs := http.FileServer(http.Dir("static"))
http.Handle("/static/", http.StripPrefix("/static/", fs))
log.Fatal(http.ListenAndServe(":12345", nil))
}
list-issues.go
package controllers
import (
"net/http"
"database/sql"
"github.com/dustin/go-humanize"
"github.com/gorilla/mux"
"fmt"
)
func ListIssuesBy(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
sorter := vars["sortby"]
if sorter == "sortbycategory" {
fmt.Print("hello")
}
db, _ := sql.Open("mysql", "user:pass#tcp(127.0.0.1:3306)/mydb?parseTime=true")
rows, _ := db.Query("SELECT * from issues")
issuelist := []Issue{}
for rows.Next() {
var r Issue
err := rows.Scan(&r.ID, &r.Title, &r.Description, &r.Category, &r.Username, &r.Votes_up, &r.Votes_down, &r.StartDate, &r.Status, &r.CommentsThrd)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
HRDate2 := humanize.Time(r.StartDate.Local())
r.HRSinceDate = HRDate2
/*r.StartDate = HRDate*/
issuelist = append(issuelist, r)
}
renderlistissues(w, issuelist)
}
func ListIssues(w http.ResponseWriter, r *http.Request) {
db, _ := sql.Open("mysql", "user:pass#tcp(127.0.0.1:3306)/mydb?parseTime=true")
rows, _ := db.Query("SELECT * from issues")
issuelist := []Issue{}
for rows.Next() {
var r Issue
err := rows.Scan(&r.ID, &r.Title, &r.Description, &r.Category, &r.Username, &r.Votes_up, &r.Votes_down, &r.StartDate, &r.Status, &r.CommentsThrd)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
HRDate2 := humanize.Time(r.StartDate.Local())
r.HRSinceDate = HRDate2
/*r.StartDate = HRDate*/
issuelist = append(issuelist, r)
}
renderlistissues(w, issuelist)
}
func renderlistissues(w http.ResponseWriter, data []Issue) {
if err := Tpl.ExecuteTemplate(w, "list-issues", data); err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
}
}

get request url in martini.Context

I want to send email to myself with error occured on page http://localhost:3000/panic with containing error url - /panic in our case. But I can not figure out how to get url from c martini.Context inside RecoverWrap method.
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
m.Use(RecoverWrap)
m.Get("/panic", func() {
panic("some panic")
})
m.Get("/", func(req *http.Request, res http.ResponseWriter) {
res.Write([]byte("mainPage"))
})
m.Run()
}
func RecoverWrap(c martini.Context, w http.ResponseWriter) {
var err error
defer func(w http.ResponseWriter) {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
// how to get request url here
// I want to send email with error url
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}(w)
c.Next()
}
The answer is in adding req *http.Request parameter to func RecoverWrap(c martini.Context, req *http.Request, w http.ResponseWriter)
Full code:
package main
import (
"errors"
"fmt"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
m.Use(RecoverWrap)
m.Get("/panic", func() {
panic("some panic")
})
m.Get("/", func(req *http.Request, res http.ResponseWriter) {
res.Write([]byte("mainPage"))
})
m.Run()
}
func RecoverWrap(c martini.Context, req *http.Request, w http.ResponseWriter) {
var err error
defer func(w http.ResponseWriter) {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
fmt.Println("req.URL.Path")
fmt.Println(req.URL.Path)
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}(w)
c.Next()
}

martini recover for any panics

I want to wire RecoverWrap to all handlers of martini routes to make any panic be finished by code inside RecoverWrap.
I tried to do it like m.Use(RecoverWrap) but do not know how to do it exactly, it fails on compile.
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
//m.Use(RecoverWrap)
m.Get("/", func() {
panic("some panic")
})
m.Run()
}
func RecoverWrap(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
var err error
defer func() {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}()
h.ServeHTTP(w, req)
})
}
Middleware handlers in Martini do not get to "wrap" other handler calls, so http.Handler is not found by the injector.
What you can do is use context.Next():
package main
import (
"errors"
"github.com/go-martini/martini"
"net/http"
)
func main() {
m := martini.Classic()
m.Use(RecoverWrap)
m.Get("/", func() {
panic("some panic")
})
m.Run()
}
func RecoverWrap(c martini.Context, w http.ResponseWriter) {
var err error
defer func(w http.ResponseWriter) {
r := recover()
if r != nil {
switch t := r.(type) {
case string:
err = errors.New(t)
case error:
err = t
default:
err = errors.New("Unknown error")
}
http.Error(w, "Something goes wrong", http.StatusInternalServerError)
}
}(w)
c.Next()
}
You will have to make sure that your error handler is the first middleware registered, or those handlers running before will not be caught.
Actually, the same method is implemented in martini.Recovery:
https://github.com/go-martini/martini/blob/6241001738f6e1b1ea7c4a4089195e1b0681609a/recovery.go#L115

Resources