1- // A microservice that accepts HTTP requests, creates a Task from given
2- // parameters, and adds the Task to a Push TaskQueue.
1+ // Package pushqueue provides a microservice that accepts HTTP requests, creates
2+ // a Task from given parameters, and adds the Task to a TaskQueue.
33package pushqueue
44
55import (
@@ -17,14 +17,24 @@ import (
1717
1818const defaultMessage = "<html><body>This is not the app you're looking for.</body></html>"
1919
20- // Requests can only add tasks to one of these whitelisted queue names .
20+ // The following queues should not be directly addressed .
2121var queueForType = map [etl.DataType ]string {
2222 etl .NDT : "etl-ndt-queue" ,
2323 etl .SS : "etl-sidestream-queue" ,
2424 etl .PT : "etl-traceroute-queue" ,
2525 etl .SW : "etl-disco-queue" ,
2626}
2727
28+ // Disallow any queue name that is an automatic queue target.
29+ func isDirectQueueNameOK (name string ) bool {
30+ for _ , value := range queueForType {
31+ if value == name {
32+ return false
33+ }
34+ }
35+ return true
36+ }
37+
2838func init () {
2939 http .HandleFunc ("/" , defaultHandler )
3040 http .HandleFunc ("/receiver" , receiver )
@@ -34,7 +44,8 @@ func init() {
3444// A default handler for root path.
3545func defaultHandler (w http.ResponseWriter , r * http.Request ) {
3646 if r .Method != http .MethodGet {
37- http .Error (w , "Method not allowed" , http .StatusMethodNotAllowed )
47+ // TODO - this is actually returning StatusOK. Weird!
48+ http .Error (w , `{"message": "Method not allowed"}` , http .StatusMethodNotAllowed )
3849 return
3950 }
4051 fmt .Fprintf (w , defaultMessage )
@@ -43,20 +54,16 @@ func defaultHandler(w http.ResponseWriter, r *http.Request) {
4354// queueStats provides statistics for a given queue.
4455func queueStats (w http.ResponseWriter , r * http.Request ) {
4556 queuename := r .FormValue ("queuename" )
57+ test := r .FormValue ("test-bypass" )
4658
4759 if queuename == "" {
4860 http .Error (w , `{"message": "Bad request parameters"}` , http .StatusBadRequest )
61+ log .Printf ("%+v\n " , w )
4962 return
5063 }
5164
52- // TODO(dev): maybe this should be made more efficient?
53- validQueue := false
54- for _ , queue := range queueForType {
55- validQueue = validQueue || (queuename == queue )
56- }
57- if ! validQueue {
58- // TODO(dev): return a list of valid queues
59- http .Error (w , `{"message": "Given queue name is not acceptable"}` , http .StatusNotAcceptable )
65+ // Bypass action if test mode.
66+ if test != "" {
6067 return
6168 }
6269
@@ -88,33 +95,51 @@ func receiver(w http.ResponseWriter, r *http.Request) {
8895 return
8996 }
9097
91- decoded_filename , err := storage .GetFilename (filename )
98+ decodedFilename , err := storage .GetFilename (filename )
9299 if err != nil {
93100 http .Error (w , `{"message": "Could not base64decode filename"}` , http .StatusBadRequest )
94101 return
95102 }
96103
97104 // Validate filename.
98- fn_data , err := etl .ValidateTestPath (decoded_filename )
105+ fnData , err := etl .ValidateTestPath (decodedFilename )
99106 if err != nil {
100107 log .Println (err )
101108 w .WriteHeader (http .StatusBadRequest )
102109 fmt .Fprintf (w , `{"message": "Invalid filename."}` )
103110 return
104111 }
105- // determine correct queue based on file name.
106- queuename , ok := queueForType [fn_data .GetDataType ()]
112+
113+ // determine correct queue based on parameter or file name.
114+ var ok bool
115+ queuename := r .FormValue ("queue" )
116+ if queuename != "" {
117+ ok = isDirectQueueNameOK (queuename )
118+ } else {
119+ queuename , ok = queueForType [fnData .GetDataType ()]
120+ }
121+
122+ if ! ok {
123+ w .WriteHeader (http .StatusBadRequest )
124+ fmt .Fprintf (w , `{"message": "Invalid queuename."}` )
125+ return
126+ }
107127
108128 // Lots of files will be archived that should not be enqueued. Pass
109129 // over those files without comment.
110130 // TODO(dev) count how many names we skip over using prometheus
111131 if ok {
112- ctx := appengine .NewContext (r )
113132 params := url.Values {"filename" : []string {filename }}
114133 t := taskqueue .NewPOSTTask ("/worker" , params )
115- if _ , err := taskqueue .Add (ctx , t , queuename ); err != nil {
116- http .Error (w , err .Error (), http .StatusInternalServerError )
117- return
134+ test := r .FormValue ("test-bypass" )
135+ if test == "" {
136+ // Skip queuing if bypass for test.
137+ ctx := appengine .NewContext (r )
138+ if _ , err := taskqueue .Add (ctx , t , queuename ); err != nil {
139+ http .Error (w , err .Error (), http .StatusInternalServerError )
140+ return
141+ }
142+
118143 }
119144 }
120145}
0 commit comments