@@ -24,6 +24,7 @@ import (
2424 "fmt"
2525 "log"
2626 "net/http"
27+ "net/url"
2728 "strings"
2829 "time"
2930
@@ -424,18 +425,13 @@ func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
424425
425426func (h * Handler ) handleGet (ctx context.Context , w http.ResponseWriter , r * http.Request ) {
426427 logger := logging .FromContext (ctx )
427- parts := strings . Split ( strings . TrimSuffix ( r .RequestURI , "/" ), "/" )
428- if len ( parts ) != 9 {
428+ ref , eventSource , eventID , err := parseLocation ( r .RequestURI )
429+ if err != nil {
429430 logger .Info ("Malformed uri" , zap .String ("URI" , r .RequestURI ))
430431 w .WriteHeader (http .StatusBadRequest )
431432 return
432433 }
433434
434- ref := types.NamespacedName {
435- Namespace : parts [2 ],
436- Name : parts [4 ],
437- }
438-
439435 js , err := h .lister .JobSinks (ref .Namespace ).Get (ref .Name )
440436 if err != nil {
441437 logger .Warn ("Failed to retrieve jobsink" , zap .String ("ref" , ref .String ()), zap .Error (err ))
@@ -450,10 +446,6 @@ func (h *Handler) handleGet(ctx context.Context, w http.ResponseWriter, r *http.
450446 logger .Warn ("Failed to verify AuthN and AuthZ." , zap .Error (err ))
451447 return
452448 }
453-
454- eventSource := parts [6 ]
455- eventID := parts [8 ]
456-
457449 jobName := toJobName (ref .Name , eventSource , eventID )
458450
459451 job , err := h .k8s .BatchV1 ().Jobs (ref .Namespace ).Get (r .Context (), jobName , metav1.GetOptions {})
@@ -499,13 +491,45 @@ func getServerTLSConfig(ctx context.Context) (*tls.Config, error) {
499491}
500492
501493func locationHeader (ref types.NamespacedName , source , id string ) string {
502- return fmt .Sprintf ("/namespaces/%s/name/%s/sources/%s/ids/%s" , ref .Namespace , ref .Name , source , id )
494+ return fmt .Sprintf (
495+ "/namespaces/%s/name/%s/sources/%s/ids/%s" ,
496+ url .PathEscape (ref .Namespace ),
497+ url .PathEscape (ref .Name ),
498+ url .PathEscape (source ),
499+ url .PathEscape (id ),
500+ )
503501}
504502
505503func jobLabelSelector (ref types.NamespacedName , id string ) string {
506504 return fmt .Sprintf ("%s=%s,%s=%s" , sinks .JobSinkIDLabel , id , sinks .JobSinkNameLabel , ref .Name )
507505}
508506
507+ func parseLocation (requestURI string ) (types.NamespacedName , string , string , error ) {
508+ parts := strings .Split (strings .TrimSuffix (requestURI , "/" ), "/" )
509+ if len (parts ) != 9 {
510+ return types.NamespacedName {}, "" , "" , fmt .Errorf ("unexpected path format" )
511+ }
512+
513+ namespace , err := url .PathUnescape (parts [2 ])
514+ if err != nil {
515+ return types.NamespacedName {}, "" , "" , fmt .Errorf ("invalid namespace path segment: %w" , err )
516+ }
517+ name , err := url .PathUnescape (parts [4 ])
518+ if err != nil {
519+ return types.NamespacedName {}, "" , "" , fmt .Errorf ("invalid name path segment: %w" , err )
520+ }
521+ source , err := url .PathUnescape (parts [6 ])
522+ if err != nil {
523+ return types.NamespacedName {}, "" , "" , fmt .Errorf ("invalid source path segment: %w" , err )
524+ }
525+ id , err := url .PathUnescape (parts [8 ])
526+ if err != nil {
527+ return types.NamespacedName {}, "" , "" , fmt .Errorf ("invalid id path segment: %w" , err )
528+ }
529+
530+ return types.NamespacedName {Namespace : namespace , Name : name }, source , id , nil
531+ }
532+
509533func toJobName (js string , source , id string ) string {
510534 h := md5 .Sum ([]byte (source + id )) //nolint:gosec
511535 return kmeta .ChildName (js + "-" , utils .ToDNS1123Subdomain (hex .EncodeToString (h [:])))
0 commit comments