mirror of
				https://github.com/go-gitea/gitea.git
				synced 2025-10-31 21:28:11 +09:00 
			
		
		
		
	fix API link header (#7298)
This commit is contained in:
		| @@ -7,6 +7,7 @@ package context | ||||
|  | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"net/url" | ||||
| 	"strings" | ||||
|  | ||||
| 	"github.com/go-macaron/csrf" | ||||
| @@ -77,23 +78,49 @@ func (ctx *APIContext) Error(status int, title string, obj interface{}) { | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| // SetLinkHeader sets pagination link header by given total number and page size. | ||||
| func (ctx *APIContext) SetLinkHeader(total, pageSize int) { | ||||
| 	page := NewPagination(total, pageSize, ctx.QueryInt("page"), 0) | ||||
| func genAPILinks(curURL *url.URL, total, pageSize, curPage int) []string { | ||||
| 	page := NewPagination(total, pageSize, curPage, 0) | ||||
| 	paginater := page.Paginater | ||||
| 	links := make([]string, 0, 4) | ||||
|  | ||||
| 	if paginater.HasNext() { | ||||
| 		links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"next\"", setting.AppURL, ctx.Req.URL.Path[1:], paginater.Next())) | ||||
| 		u := *curURL | ||||
| 		queries := u.Query() | ||||
| 		queries.Set("page", fmt.Sprintf("%d", paginater.Next())) | ||||
| 		u.RawQuery = queries.Encode() | ||||
|  | ||||
| 		links = append(links, fmt.Sprintf("<%s%s>; rel=\"next\"", setting.AppURL, u.RequestURI()[1:])) | ||||
| 	} | ||||
| 	if !paginater.IsLast() { | ||||
| 		links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"last\"", setting.AppURL, ctx.Req.URL.Path[1:], paginater.TotalPages())) | ||||
| 		u := *curURL | ||||
| 		queries := u.Query() | ||||
| 		queries.Set("page", fmt.Sprintf("%d", paginater.TotalPages())) | ||||
| 		u.RawQuery = queries.Encode() | ||||
|  | ||||
| 		links = append(links, fmt.Sprintf("<%s%s>; rel=\"last\"", setting.AppURL, u.RequestURI()[1:])) | ||||
| 	} | ||||
| 	if !paginater.IsFirst() { | ||||
| 		links = append(links, fmt.Sprintf("<%s%s?page=1>; rel=\"first\"", setting.AppURL, ctx.Req.URL.Path[1:])) | ||||
| 		u := *curURL | ||||
| 		queries := u.Query() | ||||
| 		queries.Set("page", "1") | ||||
| 		u.RawQuery = queries.Encode() | ||||
|  | ||||
| 		links = append(links, fmt.Sprintf("<%s%s>; rel=\"first\"", setting.AppURL, u.RequestURI()[1:])) | ||||
| 	} | ||||
| 	if paginater.HasPrevious() { | ||||
| 		links = append(links, fmt.Sprintf("<%s%s?page=%d>; rel=\"prev\"", setting.AppURL, ctx.Req.URL.Path[1:], paginater.Previous())) | ||||
| 		u := *curURL | ||||
| 		queries := u.Query() | ||||
| 		queries.Set("page", fmt.Sprintf("%d", paginater.Previous())) | ||||
| 		u.RawQuery = queries.Encode() | ||||
|  | ||||
| 		links = append(links, fmt.Sprintf("<%s%s>; rel=\"prev\"", setting.AppURL, u.RequestURI()[1:])) | ||||
| 	} | ||||
| 	return links | ||||
| } | ||||
|  | ||||
| // SetLinkHeader sets pagination link header by given total number and page size. | ||||
| func (ctx *APIContext) SetLinkHeader(total, pageSize int) { | ||||
| 	links := genAPILinks(ctx.Req.URL, total, pageSize, ctx.QueryInt("page")) | ||||
|  | ||||
| 	if len(links) > 0 { | ||||
| 		ctx.Header().Set("Link", strings.Join(links, ",")) | ||||
|   | ||||
							
								
								
									
										51
									
								
								modules/context/api_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								modules/context/api_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,51 @@ | ||||
| // Copyright 2019 The Gitea Authors. All rights reserved. | ||||
| // Use of this source code is governed by a MIT-style | ||||
| // license that can be found in the LICENSE file. | ||||
|  | ||||
| package context | ||||
|  | ||||
| import ( | ||||
| 	"net/url" | ||||
| 	"strconv" | ||||
| 	"testing" | ||||
|  | ||||
| 	"code.gitea.io/gitea/modules/setting" | ||||
|  | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestGenAPILinks(t *testing.T) { | ||||
| 	setting.AppURL = "http://localhost:3000/" | ||||
| 	var kases = map[string][]string{ | ||||
| 		"api/v1/repos/jerrykan/example-repo/issues?state=all": { | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=2&state=all>; rel="next"`, | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=5&state=all>; rel="last"`, | ||||
| 		}, | ||||
| 		"api/v1/repos/jerrykan/example-repo/issues?state=all&page=1": { | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=2&state=all>; rel="next"`, | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=5&state=all>; rel="last"`, | ||||
| 		}, | ||||
| 		"api/v1/repos/jerrykan/example-repo/issues?state=all&page=2": { | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=3&state=all>; rel="next"`, | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=5&state=all>; rel="last"`, | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=1&state=all>; rel="first"`, | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=1&state=all>; rel="prev"`, | ||||
| 		}, | ||||
| 		"api/v1/repos/jerrykan/example-repo/issues?state=all&page=5": { | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=1&state=all>; rel="first"`, | ||||
| 			`<http://localhost:3000/api/v1/repos/jerrykan/example-repo/issues?page=4&state=all>; rel="prev"`, | ||||
| 		}, | ||||
| 	} | ||||
|  | ||||
| 	for req, response := range kases { | ||||
| 		u, err := url.Parse(setting.AppURL + req) | ||||
| 		assert.NoError(t, err) | ||||
|  | ||||
| 		p := u.Query().Get("page") | ||||
| 		curPage, _ := strconv.Atoi(p) | ||||
|  | ||||
| 		links := genAPILinks(u, 100, 20, curPage) | ||||
|  | ||||
| 		assert.EqualValues(t, links, response) | ||||
| 	} | ||||
| } | ||||
		Reference in New Issue
	
	Block a user