2021-12-11 17:50:00 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GoToSocial 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 18:42:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								   Copyright  ( C )  2021 - 2022  GoToSocial  Authors  admin @ gotosocial . org 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-11 17:50:00 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   This  program  is  free  software :  you  can  redistribute  it  and / or  modify 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   it  under  the  terms  of  the  GNU  Affero  General  Public  License  as  published  by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   the  Free  Software  Foundation ,  either  version  3  of  the  License ,  or 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   ( at  your  option )  any  later  version . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   This  program  is  distributed  in  the  hope  that  it  will  be  useful , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   but  WITHOUT  ANY  WARRANTY ;  without  even  the  implied  warranty  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   MERCHANTABILITY  or  FITNESS  FOR  A  PARTICULAR  PURPOSE .   See  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   GNU  Affero  General  Public  License  for  more  details . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   You  should  have  received  a  copy  of  the  GNU  Affero  General  Public  License 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								   along  with  this  program .   If  not ,  see  < http : //www.gnu.org/licenses/>. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								* /  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  api  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"errors" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"github.com/gin-gonic/gin" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Offer represents an offered mime-type.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  Offer  string  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppJSON            Offer  =  ` application/json `                                                      // AppJSON is the mime type for 'application/json'. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppActivityJSON    Offer  =  ` application/activity+json `                                             // AppActivityJSON is the mime type for 'application/activity+json'. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppActivityLDJSON  Offer  =  ` application/ld+json; profile="https://www.w3.org/ns/activitystreams" `  // AppActivityLDJSON is the mime type for 'application/ld+json; profile="https://www.w3.org/ns/activitystreams"' 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TextHTML           Offer  =  ` text/html `                                                             // TextHTML is the mime type for 'text/html'. 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// ActivityPubAcceptHeaders represents the Accept headers mentioned here:  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// https://www.w3.org/TR/activitypub/#retrieving-objects  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  ActivityPubAcceptHeaders  =  [ ] Offer {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppActivityJSON , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppActivityLDJSON , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// JSONAcceptHeaders is a slice of offers that just contains application/json types.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  JSONAcceptHeaders  =  [ ] Offer {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									AppJSON , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// HTMLAcceptHeaders is a slice of offers that just contains text/html types.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								var  HTMLAcceptHeaders  =  [ ] Offer {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									TextHTML , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// NegotiateAccept takes the *gin.Context from an incoming request, and a  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// slice of Offers, and performs content negotiation for the given request  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// with the given content-type offers. It will return a string representation  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of the first suitable content-type, or an error if something goes wrong or  
						 
					
						
							
								
									
										
										
										
											2021-12-20 11:08:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// a suitable content-type cannot be matched.  
						 
					
						
							
								
									
										
										
										
											2021-12-11 17:50:00 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// For example, if the request in the *gin.Context has Accept headers of value  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// [application/json, text/html], and the provided offers are of value  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// [application/json, application/xml], then the returned string will be  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// 'application/json', which indicates the content-type that should be returned.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
									
										
										
										
											2021-12-20 11:08:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// If the length of offers is 0, then an error will be returned, so this function  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// should only be called in places where format negotiation is actually needed.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// If there are no Accept headers in the request, then the first offer will be returned,  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// under the assumption that it's better to serve *something* than error out completely.  
						 
					
						
							
								
									
										
										
										
											2021-12-11 17:50:00 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Callers can use the offer slices exported in this package as shortcuts for  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// often-used Accept types.  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								//  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// See https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation#server-driven_content_negotiation  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  NegotiateAccept ( c  * gin . Context ,  offers  ... Offer )  ( string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( offers )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  errors . New ( "no format offered" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									strings  :=  [ ] string { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  _ ,  o  :=  range  offers  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										strings  =  append ( strings ,  string ( o ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-20 11:08:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									accepts  :=  c . Request . Header . Values ( "Accept" ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  len ( accepts )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// there's no accept header set, just return the first offer 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  strings [ 0 ] ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-11 17:50:00 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									format  :=  c . NegotiateFormat ( strings ... ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  format  ==  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  fmt . Errorf ( "no format can be offered for requested Accept header(s) %s; this endpoint offers %s" ,  accepts ,  offers ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  format ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}