-
Notifications
You must be signed in to change notification settings - Fork 387
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #73 from ponzu-cms/ponzu-dev
[core] Adding support to omit fields from json response, minor code reorganization
- Loading branch information
Showing
9 changed files
with
300 additions
and
197 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,74 @@ | ||
package api | ||
|
||
import ( | ||
"log" | ||
"net/http" | ||
"net/url" | ||
|
||
"github.com/ponzu-cms/ponzu/system/db" | ||
) | ||
|
||
// sendPreflight is used to respond to a cross-origin "OPTIONS" request | ||
func sendPreflight(res http.ResponseWriter) { | ||
res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") | ||
res.Header().Set("Access-Control-Allow-Origin", "*") | ||
res.WriteHeader(200) | ||
return | ||
} | ||
|
||
func responseWithCORS(res http.ResponseWriter, req *http.Request) (http.ResponseWriter, bool) { | ||
if db.ConfigCache("cors_disabled").(bool) == true { | ||
// check origin matches config domain | ||
domain := db.ConfigCache("domain").(string) | ||
origin := req.Header.Get("Origin") | ||
u, err := url.Parse(origin) | ||
if err != nil { | ||
log.Println("Error parsing URL from request Origin header:", origin) | ||
return res, false | ||
} | ||
|
||
// hack to get dev environments to bypass cors since u.Host (below) will | ||
// be empty, based on Go's url.Parse function | ||
if domain == "localhost" { | ||
domain = "" | ||
} | ||
origin = u.Host | ||
|
||
// currently, this will check for exact match. will need feedback to | ||
// determine if subdomains should be allowed or allow multiple domains | ||
// in config | ||
if origin == domain { | ||
// apply limited CORS headers and return | ||
res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") | ||
res.Header().Set("Access-Control-Allow-Origin", domain) | ||
return res, true | ||
} | ||
|
||
// disallow request | ||
res.WriteHeader(http.StatusForbidden) | ||
return res, false | ||
} | ||
|
||
// apply full CORS headers and return | ||
res.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type") | ||
res.Header().Set("Access-Control-Allow-Origin", "*") | ||
|
||
return res, true | ||
} | ||
|
||
// CORS wraps a HandlerFunc to respond to OPTIONS requests properly | ||
func CORS(next http.HandlerFunc) http.HandlerFunc { | ||
return db.CacheControl(http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { | ||
res, cors := responseWithCORS(res, req) | ||
if !cors { | ||
return | ||
} | ||
|
||
if req.Method == http.MethodOptions { | ||
sendPreflight(res) | ||
return | ||
} | ||
|
||
next.ServeHTTP(res, req) | ||
})) | ||
} |
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,64 @@ | ||
package api | ||
|
||
import ( | ||
"compress/gzip" | ||
"net/http" | ||
"strings" | ||
|
||
"github.com/ponzu-cms/ponzu/system/db" | ||
) | ||
|
||
// Gzip wraps a HandlerFunc to compress responses when possible | ||
func Gzip(next http.HandlerFunc) http.HandlerFunc { | ||
return http.HandlerFunc(func(res http.ResponseWriter, req *http.Request) { | ||
if db.ConfigCache("gzip_disabled").(bool) == true { | ||
next.ServeHTTP(res, req) | ||
return | ||
} | ||
|
||
// check if req header content-encoding supports gzip | ||
if strings.Contains(req.Header.Get("Accept-Encoding"), "gzip") { | ||
// gzip response data | ||
res.Header().Set("Content-Encoding", "gzip") | ||
var gzres gzipResponseWriter | ||
if pusher, ok := res.(http.Pusher); ok { | ||
gzres = gzipResponseWriter{res, pusher, gzip.NewWriter(res)} | ||
} else { | ||
gzres = gzipResponseWriter{res, nil, gzip.NewWriter(res)} | ||
} | ||
|
||
next.ServeHTTP(gzres, req) | ||
return | ||
} | ||
|
||
next.ServeHTTP(res, req) | ||
}) | ||
} | ||
|
||
type gzipResponseWriter struct { | ||
http.ResponseWriter | ||
pusher http.Pusher | ||
|
||
gw *gzip.Writer | ||
} | ||
|
||
func (gzw gzipResponseWriter) Write(p []byte) (int, error) { | ||
defer gzw.gw.Close() | ||
return gzw.gw.Write(p) | ||
} | ||
|
||
func (gzw gzipResponseWriter) Push(target string, opts *http.PushOptions) error { | ||
if gzw.pusher == nil { | ||
return nil | ||
} | ||
|
||
if opts == nil { | ||
opts = &http.PushOptions{ | ||
Header: make(http.Header), | ||
} | ||
} | ||
|
||
opts.Header.Set("Accept-Encoding", "gzip") | ||
|
||
return gzw.pusher.Push(target, opts) | ||
} |
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
Oops, something went wrong.