good morning!!!!
Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
C
chat
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Harbor Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
github
tinode
chat
Commits
eac88f67
Commit
eac88f67
authored
2 years ago
by
or-else
Browse files
Options
Downloads
Patches
Plain Diff
fix CORS handling, #840
parent
001a35d0
No related branches found
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
server/hdl_files.go
+53
-14
53 additions, 14 deletions
server/hdl_files.go
server/media/media.go
+20
-19
20 additions, 19 deletions
server/media/media.go
with
73 additions
and
33 deletions
server/hdl_files.go
+
53
−
14
View file @
eac88f67
...
...
@@ -39,6 +39,32 @@ func largeFileServe(wrt http.ResponseWriter, req *http.Request) {
}
}
// Preflight request: process before any security checks.
if
req
.
Method
==
http
.
MethodOptions
{
headers
,
statusCode
,
err
:=
mh
.
Headers
(
req
,
true
)
if
err
!=
nil
{
writeHttpResponse
(
decodeStoreError
(
err
,
""
,
now
,
nil
),
err
)
return
}
for
name
,
values
:=
range
headers
{
for
_
,
value
:=
range
values
{
wrt
.
Header
()
.
Add
(
name
,
value
)
}
}
if
statusCode
<=
0
{
statusCode
=
http
.
StatusNoContent
}
wrt
.
WriteHeader
(
statusCode
)
logs
.
Info
.
Println
(
"media serve: preflight completed"
)
return
}
// Check if this is a GET/HEAD request.
if
req
.
Method
!=
http
.
MethodGet
&&
req
.
Method
!=
http
.
MethodHead
{
writeHttpResponse
(
ErrOperationNotAllowed
(
""
,
""
,
now
),
errors
.
New
(
"method '"
+
req
.
Method
+
"' not allowed"
))
return
}
// Check for API key presence
if
isValid
,
_
:=
checkAPIKey
(
getAPIKey
(
req
));
!
isValid
{
writeHttpResponse
(
ErrAPIKeyRequired
(
now
),
errors
.
New
(
"invalid or missing API key"
))
...
...
@@ -63,12 +89,6 @@ func largeFileServe(wrt http.ResponseWriter, req *http.Request) {
return
}
// Check if this is a GET/OPTIONS/HEAD request.
if
req
.
Method
!=
http
.
MethodGet
&&
req
.
Method
!=
http
.
MethodHead
&&
req
.
Method
!=
http
.
MethodOptions
{
writeHttpResponse
(
ErrOperationNotAllowed
(
""
,
""
,
now
),
errors
.
New
(
"method '"
+
req
.
Method
+
"' not allowed"
))
return
}
// Check if media handler redirects or adds headers.
headers
,
statusCode
,
err
:=
mh
.
Headers
(
req
,
true
)
if
err
!=
nil
{
...
...
@@ -98,7 +118,7 @@ func largeFileServe(wrt http.ResponseWriter, req *http.Request) {
return
}
if
req
.
Method
==
http
.
MethodHead
||
req
.
Method
==
http
.
MethodOptions
{
if
req
.
Method
==
http
.
MethodHead
{
wrt
.
WriteHeader
(
http
.
StatusOK
)
logs
.
Info
.
Println
(
"media serve: completed"
,
req
.
Method
,
"uid="
,
uid
)
return
...
...
@@ -137,9 +157,28 @@ func largeFileReceive(wrt http.ResponseWriter, req *http.Request) {
}
}
// Check if this is a POST/PUT/OPTIONS/HEAD request.
if
req
.
Method
!=
http
.
MethodPost
&&
req
.
Method
!=
http
.
MethodPut
&&
req
.
Method
!=
http
.
MethodHead
&&
req
.
Method
!=
http
.
MethodOptions
{
// Preflight request: process before any security checks.
if
req
.
Method
==
http
.
MethodOptions
{
headers
,
statusCode
,
err
:=
mh
.
Headers
(
req
,
false
)
if
err
!=
nil
{
writeHttpResponse
(
decodeStoreError
(
err
,
""
,
now
,
nil
),
err
)
return
}
for
name
,
values
:=
range
headers
{
for
_
,
value
:=
range
values
{
wrt
.
Header
()
.
Add
(
name
,
value
)
}
}
if
statusCode
<=
0
{
statusCode
=
http
.
StatusNoContent
}
wrt
.
WriteHeader
(
statusCode
)
logs
.
Info
.
Println
(
"media upload: preflight completed"
)
return
}
// Check if this is a POST/PUT/HEAD request.
if
req
.
Method
!=
http
.
MethodPost
&&
req
.
Method
!=
http
.
MethodPut
&&
req
.
Method
!=
http
.
MethodHead
{
writeHttpResponse
(
ErrOperationNotAllowed
(
""
,
""
,
now
),
errors
.
New
(
"method '"
+
req
.
Method
+
"' not allowed"
))
return
}
...
...
@@ -175,7 +214,7 @@ func largeFileReceive(wrt http.ResponseWriter, req *http.Request) {
// Check if uploads are handled elsewhere.
headers
,
statusCode
,
err
:=
mh
.
Headers
(
req
,
false
)
if
err
!=
nil
{
logs
.
Info
.
Println
(
"
H
eaders check failed"
,
err
)
logs
.
Info
.
Println
(
"
media upload: h
eaders check failed"
,
err
)
writeHttpResponse
(
decodeStoreError
(
err
,
""
,
now
,
nil
),
err
)
return
}
...
...
@@ -210,7 +249,7 @@ func largeFileReceive(wrt http.ResponseWriter, req *http.Request) {
file
,
_
,
err
:=
req
.
FormFile
(
"file"
)
if
err
!=
nil
{
logs
.
Info
.
Println
(
"
I
nvalid multipart form"
,
err
)
logs
.
Info
.
Println
(
"
media upload: i
nvalid multipart form"
,
err
)
if
strings
.
Contains
(
err
.
Error
(),
"request body too large"
)
{
writeHttpResponse
(
ErrTooLarge
(
msgID
,
""
,
now
),
err
)
}
else
{
...
...
@@ -240,7 +279,7 @@ func largeFileReceive(wrt http.ResponseWriter, req *http.Request) {
url
,
size
,
err
:=
mh
.
Upload
(
fdef
,
file
)
if
err
!=
nil
{
logs
.
Info
.
Println
(
"
U
pload failed"
,
file
,
"key"
,
fdef
.
Location
,
err
)
logs
.
Info
.
Println
(
"
media u
pload
:
failed"
,
file
,
"key"
,
fdef
.
Location
,
err
)
store
.
Files
.
FinishUpload
(
fdef
,
false
,
0
)
writeHttpResponse
(
decodeStoreError
(
err
,
msgID
,
now
,
nil
),
err
)
return
...
...
@@ -248,7 +287,7 @@ func largeFileReceive(wrt http.ResponseWriter, req *http.Request) {
fdef
,
err
=
store
.
Files
.
FinishUpload
(
fdef
,
true
,
size
)
if
err
!=
nil
{
logs
.
Info
.
Println
(
"
F
ailed to finalize
upload
"
,
file
,
"key"
,
fdef
.
Location
,
err
)
logs
.
Info
.
Println
(
"
media upload: f
ailed to finalize"
,
file
,
"key"
,
fdef
.
Location
,
err
)
// Best effort cleanup.
mh
.
Delete
([]
string
{
fdef
.
Location
})
writeHttpResponse
(
decodeStoreError
(
err
,
msgID
,
now
,
nil
),
err
)
...
...
This diff is collapsed.
Click to expand it.
server/media/media.go
+
20
−
19
View file @
eac88f67
...
...
@@ -70,8 +70,9 @@ func matchCORSOrigin(allowed []string, origin string) string {
return
"*"
}
origin
=
strings
.
ToLower
(
origin
)
for
_
,
val
:=
range
allowed
{
if
val
==
origin
{
if
strings
.
ToLower
(
val
)
==
origin
{
return
origin
}
}
...
...
@@ -87,7 +88,7 @@ func matchCORSMethod(allowMethods []string, method string) bool {
method
=
strings
.
ToUpper
(
method
)
for
_
,
mm
:=
range
allowMethods
{
if
mm
==
method
{
if
strings
.
ToUpper
(
mm
)
==
method
{
return
true
}
}
...
...
@@ -102,17 +103,6 @@ func CORSHandler(req *http.Request, allowedOrigins []string, serve bool) (http.H
return
nil
,
0
}
headers
:=
map
[
string
][]
string
{
// Always add Vary because of possible intermediate caches.
"Vary"
:
{
"Origin"
,
"Access-Control-Request-Method"
},
}
allowedOrigin
:=
matchCORSOrigin
(
allowedOrigins
,
req
.
Header
.
Get
(
"Origin"
))
if
allowedOrigin
==
""
{
// CORS policy does not match the origin.
return
headers
,
http
.
StatusOK
}
var
allowMethods
[]
string
if
serve
{
allowMethods
=
[]
string
{
http
.
MethodGet
,
http
.
MethodHead
,
http
.
MethodOptions
}
...
...
@@ -120,16 +110,27 @@ func CORSHandler(req *http.Request, allowedOrigins []string, serve bool) (http.H
allowMethods
=
[]
string
{
http
.
MethodPost
,
http
.
MethodPut
,
http
.
MethodHead
,
http
.
MethodOptions
}
}
headers
:=
map
[
string
][]
string
{
// Always add Vary because of possible intermediate caches.
"Vary"
:
{
"Origin"
,
"Access-Control-Request-Method"
},
"Access-Control-Allow-Headers"
:
{
"*"
},
"Access-Control-Max-Age"
:
{
"86400"
},
"Access-Control-Allow-Credentials"
:
{
"true"
},
"Access-Control-Allow-Methods"
:
{
strings
.
Join
(
allowMethods
,
", "
)},
}
if
!
matchCORSMethod
(
allowMethods
,
req
.
Header
.
Get
(
"Access-Control-Request-Method"
))
{
// CORS policy does not allow this method.
return
headers
,
http
.
StatusOK
return
headers
,
http
.
StatusNoContent
}
allowedOrigin
:=
matchCORSOrigin
(
allowedOrigins
,
req
.
Header
.
Get
(
"Origin"
))
if
allowedOrigin
==
""
{
// CORS policy does not match the origin.
return
headers
,
http
.
StatusNoContent
}
headers
[
"Access-Control-Allow-Origin"
]
=
[]
string
{
allowedOrigin
}
headers
[
"Access-Control-Allow-Headers"
]
=
[]
string
{
"*"
}
headers
[
"Access-Control-Allow-Methods"
]
=
[]
string
{
strings
.
Join
(
allowMethods
,
","
)}
headers
[
"Access-Control-Max-Age"
]
=
[]
string
{
"86400"
}
headers
[
"Access-Control-Allow-Credentials"
]
=
[]
string
{
"true"
}
return
headers
,
http
.
Status
OK
return
headers
,
http
.
Status
NoContent
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment