Last active
June 9, 2019 05:58
-
-
Save scascketta/cd3ded829de4a67b5a66 to your computer and use it in GitHub Desktop.
A Golang server to proxy XML requests, parse them to JSON, and add CORS headers.
This file contains hidden or 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
application: scenic-cedar-88515 | |
version: 1 | |
runtime: go | |
api_version: go1 | |
handlers: | |
- url: /.* | |
script: _go_app |
This file contains hidden or 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
package instaql | |
import ( | |
"appengine" | |
"appengine/urlfetch" | |
"fmt" | |
"io/ioutil" | |
"log" | |
"net/http" | |
"strconv" | |
) | |
func init() { | |
log.SetFlags(log.LstdFlags | log.Lshortfile) | |
http.HandleFunc("/", CorsMiddleware(proxy)) | |
} | |
func proxy(w http.ResponseWriter, r *http.Request) { | |
vals := r.URL.Query() | |
url := vals.Get("url") | |
if url == "" { | |
w.Write([]byte("No url provided")) | |
return | |
} | |
log.Println(url) | |
c := appengine.NewContext(r) | |
client := urlfetch.Client(c) | |
res, err := client.Get(url) | |
if err != nil { | |
http.Error(w, fmt.Sprintf("Error making request to %s: %s", url, err.Error()), http.StatusInternalServerError) | |
return | |
} | |
body, err := ioutil.ReadAll(res.Body) | |
if err != nil { | |
http.Error(w, "Error reading body from requested URL", http.StatusInternalServerError) | |
return | |
} | |
json, err := NextbusToJSON(body) | |
if err != nil { | |
http.Error(w, fmt.Sprintf("Error marshaling XML to JSON: %s", err.Error()), http.StatusInternalServerError) | |
return | |
} | |
w.Header().Set("Content-Type", "application/json") | |
w.Write(json) | |
return | |
} | |
func CorsMiddleware(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc { | |
return func(w http.ResponseWriter, r *http.Request) { | |
if r.Method == "OPTIONS" { | |
w.Header().Set("Access-Control-Allow-Methods", "GET, POST") | |
w.Header().Set("Access-Control-Max-Age", strconv.Itoa(60*60*6)) | |
w.Header().Set("Access-Control-Allow-Headers", "CONTENT-TYPE, ACCEPT") | |
return | |
} | |
w.Header().Set("Access-Control-Allow-Origin", "*") | |
fn(w, r) | |
} | |
} |
This file contains hidden or 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
package instaql | |
import ( | |
"encoding/json" | |
"encoding/xml" | |
"log" | |
) | |
type RunsData struct { | |
Runs []Run `xml:"Body>Nextbus2Response>Runs>Run" json:"runs"` | |
} | |
type Run struct { | |
Route string `json:"route"` | |
Sign string `json:"sign"` | |
Direction string `json:"direction"` | |
TripTime string `xml:"Triptime" json:"trip_time"` | |
TripID string `xml:"Tripid" json:"trip_id"` | |
Adherence string `json:"adherence"` | |
RealtimeValid string `xml:"Realtime>Valid" json:"valid"` | |
EstimatedTime string `xml:"Realtime>Estimatedtime" json:"estimated_time"` | |
PollTime string `xml:"Realtime>Polltime" json:"poll_time"` | |
VehicleID string `xml:"Realtime>Vehicleid" json:"vehicle_id"` | |
VehicleLon string `xml:"Realtime>Long" json:"vehicle_lon"` | |
VehicleLat string `xml:"Realtime>Lat" json:"vehicle_lat"` | |
Block string `json:"block"` | |
StopID string `xml:"Stopid" json:"stop_id"` | |
} | |
func NextbusToJSON(data []byte) ([]byte, error) { | |
xmlData := new(RunsData) | |
err := xml.Unmarshal(data, xmlData) | |
if err != nil { | |
log.Println(err) | |
return nil, err | |
} | |
res, err := json.Marshal(xmlData) | |
return res, err | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment