@@ -135,7 +135,6 @@ func (s *svc) setHandler() {
135
135
r = r .WithContext (ctx )
136
136
switch r .Method {
137
137
case "HEAD" :
138
- addCorsHeader (w )
139
138
s .doHead (w , r )
140
139
return
141
140
case "GET" :
@@ -147,20 +146,16 @@ func (s *svc) setHandler() {
147
146
case "PATCH" :
148
147
s .doPatch (w , r )
149
148
return
149
+ case "OPTIONS" :
150
+ s .doOptions (w , r )
151
+ return
150
152
default :
151
153
w .WriteHeader (http .StatusNotImplemented )
152
154
return
153
155
}
154
156
})
155
157
}
156
158
157
- func addCorsHeader (res http.ResponseWriter ) {
158
- headers := res .Header ()
159
- headers .Set ("Access-Control-Allow-Origin" , "*" )
160
- headers .Set ("Access-Control-Allow-Headers" , "Content-Type, Origin, Authorization" )
161
- headers .Set ("Access-Control-Allow-Methods" , "GET, POST, OPTIONS, HEAD" )
162
- }
163
-
164
159
func (s * svc ) verify (ctx context.Context , r * http.Request ) (* transferClaims , error ) {
165
160
// Extract transfer token from request header. If not existing, assume that it's the last path segment instead.
166
161
token := r .Header .Get (TokenTransportHeader )
@@ -408,6 +403,52 @@ func (s *svc) doPatch(w http.ResponseWriter, r *http.Request) {
408
403
}
409
404
}
410
405
406
+ func (s * svc ) doOptions (w http.ResponseWriter , r * http.Request ) {
407
+ ctx := r .Context ()
408
+ log := appctx .GetLogger (ctx )
409
+
410
+ claims , err := s .verify (ctx , r )
411
+ if err != nil {
412
+ err = errors .Wrap (err , "datagateway: error validating transfer token" )
413
+ log .Error ().Err (err ).Str ("token" , r .Header .Get (TokenTransportHeader )).Msg ("invalid transfer token" )
414
+ w .WriteHeader (http .StatusForbidden )
415
+ return
416
+ }
417
+
418
+ log .Debug ().Str ("target" , claims .Target ).Msg ("sending request to internal data server" )
419
+
420
+ httpClient := s .client
421
+ httpReq , err := rhttp .NewRequest (ctx , "OPTIONS" , claims .Target , nil )
422
+ if err != nil {
423
+ log .Error ().Err (err ).Msg ("wrong request" )
424
+ w .WriteHeader (http .StatusInternalServerError )
425
+ return
426
+ }
427
+ httpReq .Header = r .Header
428
+
429
+ httpRes , err := httpClient .Do (httpReq )
430
+ if err != nil {
431
+ log .Error ().Err (err ).Msg ("error doing OPTIONS request to data service" )
432
+ w .WriteHeader (http .StatusInternalServerError )
433
+ return
434
+ }
435
+ defer httpRes .Body .Close ()
436
+
437
+ copyHeader (w .Header (), httpRes .Header )
438
+
439
+ // add upload expiry / transfer token expiry header for tus https://tus.io/protocols/resumable-upload.html#expiration
440
+ w .Header ().Set (UploadExpiresHeader , time .Unix (claims .ExpiresAt , 0 ).Format (time .RFC1123 ))
441
+
442
+ if httpRes .StatusCode != http .StatusOK {
443
+ // swallow the body and set content-length to 0 to prevent reverse proxies from trying to read from it
444
+ w .Header ().Set ("Content-Length" , "0" )
445
+ w .WriteHeader (httpRes .StatusCode )
446
+ return
447
+ }
448
+
449
+ w .WriteHeader (http .StatusOK )
450
+ }
451
+
411
452
func copyHeader (dst , src http.Header ) {
412
453
for key , values := range src {
413
454
for i := range values {
0 commit comments