-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat!: add ContentType, expanded Accept parsing #6
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,34 +1,106 @@ | ||
package trustlesshttp | ||
|
||
import "fmt" | ||
import ( | ||
"strconv" | ||
"strings" | ||
) | ||
|
||
type ContentTypeOrder string | ||
|
||
const ( | ||
MimeTypeCar = "application/vnd.ipld.car" // The only accepted MIME type | ||
MimeTypeCarVersion = "1" // We only accept version 1 of the MIME type | ||
FormatParameterCar = "car" // The only valid format parameter value | ||
FilenameExtCar = ".car" // The only valid filename extension | ||
DefaultIncludeDupes = true // The default value for an unspecified "dups" parameter. See https://github.com/ipfs/specs/pull/412. | ||
ResponseCacheControlHeader = "public, max-age=29030400, immutable" // Magic cache control values | ||
DefaultIncludeDupes = true // The default value for an unspecified "dups" parameter. | ||
DefaultOrder = ContentTypeOrderDfs // The default value for an unspecified "order" parameter. | ||
|
||
ContentTypeOrderDfs ContentTypeOrder = "dfs" | ||
ContentTypeOrderUnk ContentTypeOrder = "unk" | ||
) | ||
|
||
var ( | ||
ResponseChunkDelimeter = []byte("0\r\n") // An http/1.1 chunk delimeter, used for specifying an early end to the response | ||
baseContentType = fmt.Sprintf("%s; version=%s; order=dfs", MimeTypeCar, MimeTypeCarVersion) | ||
) | ||
|
||
// ContentType represents a Content-Type descriptor for use with the response | ||
// Content-Type header or the request Accept header specifically for | ||
// Trustless Gateway requests and responses. | ||
type ContentType struct { | ||
MimeType string | ||
Order ContentTypeOrder | ||
Duplicates bool | ||
Quality float32 | ||
} | ||
|
||
func (ct ContentType) String() string { | ||
sb := strings.Builder{} | ||
sb.WriteString(ct.MimeType) | ||
sb.WriteString(";version=") | ||
sb.WriteString(MimeTypeCarVersion) | ||
sb.WriteString(";order=") | ||
sb.WriteString(string(ct.Order)) | ||
if ct.Duplicates { | ||
sb.WriteString(";dups=y") | ||
} else { | ||
sb.WriteString(";dups=n") | ||
} | ||
if ct.Quality < 1 && ct.Quality >= 0.00 { | ||
sb.WriteString(";q=") | ||
// write quality with max 3 decimal places | ||
sb.WriteString(strconv.FormatFloat(float64(ct.Quality), 'g', 3, 32)) | ||
} | ||
return sb.String() | ||
} | ||
|
||
// WithOrder returns a new ContentType with the specified order. | ||
func (ct ContentType) WithOrder(order ContentTypeOrder) ContentType { | ||
ct.Order = order | ||
return ct | ||
} | ||
|
||
// WithDuplicates returns a new ContentType with the specified duplicates. | ||
func (ct ContentType) WithDuplicates(duplicates bool) ContentType { | ||
ct.Duplicates = duplicates | ||
return ct | ||
} | ||
|
||
// WithMime returns a new ContentType with the specified mime type. | ||
func (ct ContentType) WithMimeType(mime string) ContentType { | ||
ct.MimeType = mime | ||
return ct | ||
} | ||
|
||
// WithQuality returns a new ContentType with the specified quality. | ||
func (ct ContentType) WithQuality(quality float32) ContentType { | ||
ct.Quality = quality | ||
return ct | ||
} | ||
|
||
func DefaultContentType() ContentType { | ||
return ContentType{ | ||
MimeType: MimeTypeCar, | ||
Order: DefaultOrder, | ||
Duplicates: DefaultIncludeDupes, | ||
Quality: 1, | ||
} | ||
} | ||
|
||
// ResponseContentTypeHeader returns the value for the Content-Type header for a | ||
// Trustless Gateway response which will vary depending on whether duplicates | ||
// are included or not. Otherwise, the header is the same for all responses. | ||
// | ||
// Deprecated: Use DefaultContentType().WithDuplicates(duplicates).String() instead. | ||
func ResponseContentTypeHeader(duplicates bool) string { | ||
if duplicates { | ||
return baseContentType + "; dups=y" | ||
} | ||
return baseContentType + "; dups=n" | ||
return DefaultContentType().WithDuplicates(duplicates).String() | ||
} | ||
|
||
// RequestAcceptHeader returns the value for the Accept header for a Trustless | ||
// Gateway request which will vary depending on whether duplicates are included | ||
// or not. Otherwise, the header is the same for all requests. | ||
// | ||
// Deprecated: Use DefaultContentType().WithDuplicates(duplicates).String() instead. | ||
func RequestAcceptHeader(duplicates bool) string { | ||
return ResponseContentTypeHeader(duplicates) | ||
} |
This file contains 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
This file contains 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this a useful value? we don't seem to do anything with an unknown ordering, and if the ordering is anything other than an understood 'dfs' we presumably would want to stream it through unchanged rather than try to change it to "unk"? since we'd be comparing against known values, like 'dfs', what do we get by defining and parsing an 'unk' value here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's defined by the spec https://specs.ipfs.tech/http-gateways/trustless-gateway/#car-order-content-type-parameter
I'm not particularly a fan of this existing but but the idea of it being in here is that a consumer of this library can decide what to do with it. Currently Lassie will ignore it and assume
dfs
and error on you for feeding bad data. Frisbii will always give youdfs
regardless of what you ask for (on the assumption thatdfs
is a subset ofunk
so this is acceptable).This isn't new btw, it was in Lassie like this; no behaviour should be changing with this, it just gets surfaced as a parameter you can inspect now if you care.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it does seem like premature complexity / over engineering
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ipfs/specs#412
It was nearly
dfs
,rnd
,weak
!Our approach atm is to 🙈; although it's at least exposed here if you actually wanted to do something with it. I'm going to assume that nobody will that wants to interoperate with our current tools (Lassie primarily).