Procházet zdrojové kódy

Refactor HTTP context handling

Frédéric Guillot před 7 roky
rodič
revize
eee1f31903
76 změnil soubory, kde provedl 434 přidání a 587 odebrání
  1. 4 9
      api/category.go
  2. 6 10
      api/entry.go
  3. 6 11
      api/feed.go
  4. 1 2
      api/icon.go
  5. 3 3
      api/opml.go
  6. 9 17
      api/user.go
  7. 9 19
      fever/fever.go
  8. 0 122
      http/context/context.go
  9. 128 0
      http/request/context.go
  10. 10 0
      http/request/doc.go
  11. 8 8
      middleware/app_session.go
  12. 4 4
      middleware/basic_auth.go
  13. 0 25
      middleware/context_keys.go
  14. 10 0
      middleware/doc.go
  15. 5 4
      middleware/fever.go
  16. 3 3
      middleware/user_session.go
  17. 4 6
      ui/about.go
  18. 3 6
      ui/bookmark_entries.go
  19. 5 7
      ui/category_create.go
  20. 4 6
      ui/category_edit.go
  21. 4 7
      ui/category_entries.go
  22. 4 6
      ui/category_list.go
  23. 3 6
      ui/category_remove.go
  24. 4 6
      ui/category_save.go
  25. 4 7
      ui/category_update.go
  26. 2 1
      ui/controller.go
  27. 3 6
      ui/entry_bookmark.go
  28. 3 6
      ui/entry_category.go
  29. 3 6
      ui/entry_feed.go
  30. 3 6
      ui/entry_read.go
  31. 3 6
      ui/entry_save.go
  32. 1 3
      ui/entry_scraper.go
  33. 3 6
      ui/entry_search.go
  34. 2 4
      ui/entry_toggle_bookmark.go
  35. 3 6
      ui/entry_unread.go
  36. 3 4
      ui/entry_update_status.go
  37. 3 6
      ui/feed_edit.go
  38. 3 6
      ui/feed_entries.go
  39. 5 7
      ui/feed_list.go
  40. 2 4
      ui/feed_refresh.go
  41. 1 3
      ui/feed_remove.go
  42. 3 6
      ui/feed_update.go
  43. 3 6
      ui/history_entries.go
  44. 3 3
      ui/history_flush.go
  45. 9 12
      ui/integration_pocket.go
  46. 4 6
      ui/integration_show.go
  47. 5 7
      ui/integration_update.go
  48. 2 6
      ui/login_check.go
  49. 4 5
      ui/login_show.go
  50. 4 6
      ui/logout.go
  51. 8 10
      ui/oauth2_callback.go
  52. 1 3
      ui/oauth2_redirect.go
  53. 5 7
      ui/oauth2_unlink.go
  54. 3 4
      ui/opml_export.go
  55. 4 6
      ui/opml_import.go
  56. 4 6
      ui/opml_upload.go
  57. 3 6
      ui/search_entries.go
  58. 14 17
      ui/session/session.go
  59. 5 7
      ui/session_list.go
  60. 1 4
      ui/session_remove.go
  61. 4 5
      ui/settings_show.go
  62. 5 6
      ui/settings_update.go
  63. 3 5
      ui/static_manifest.go
  64. 4 5
      ui/subscription_add.go
  65. 3 5
      ui/subscription_bookmarklet.go
  66. 4 5
      ui/subscription_choose.go
  67. 5 6
      ui/subscription_submit.go
  68. 3 5
      ui/unread_entries.go
  69. 3 3
      ui/unread_mark_all_read.go
  70. 5 6
      ui/user_create.go
  71. 3 5
      ui/user_edit.go
  72. 4 5
      ui/user_list.go
  73. 1 4
      ui/user_remove.go
  74. 4 6
      ui/user_save.go
  75. 3 6
      ui/user_update.go
  76. 11 9
      ui/view/view.go

+ 4 - 9
api/category.go

@@ -8,7 +8,6 @@ import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 )
 )
@@ -21,8 +20,7 @@ func (c *Controller) CreateCategory(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	category.UserID = userID
 	category.UserID = userID
 	if err := category.ValidateCategoryCreation(); err != nil {
 	if err := category.ValidateCategoryCreation(); err != nil {
 		json.BadRequest(w, err)
 		json.BadRequest(w, err)
@@ -57,8 +55,7 @@ func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	category.UserID = ctx.UserID()
+	category.UserID = request.UserID(r)
 	category.ID = categoryID
 	category.ID = categoryID
 	if err := category.ValidateCategoryModification(); err != nil {
 	if err := category.ValidateCategoryModification(); err != nil {
 		json.BadRequest(w, err)
 		json.BadRequest(w, err)
@@ -76,8 +73,7 @@ func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
 
 
 // GetCategories is the API handler to get a list of categories for a given user.
 // GetCategories is the API handler to get a list of categories for a given user.
 func (c *Controller) GetCategories(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) GetCategories(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	categories, err := c.store.Categories(ctx.UserID())
+	categories, err := c.store.Categories(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
@@ -88,8 +84,7 @@ func (c *Controller) GetCategories(w http.ResponseWriter, r *http.Request) {
 
 
 // RemoveCategory is the API handler to remove a category.
 // RemoveCategory is the API handler to remove a category.
 func (c *Controller) RemoveCategory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) RemoveCategory(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	categoryID, err := request.IntParam(r, "categoryID")
 	categoryID, err := request.IntParam(r, "categoryID")
 	if err != nil {
 	if err != nil {
 		json.BadRequest(w, err)
 		json.BadRequest(w, err)

+ 6 - 10
api/entry.go

@@ -9,7 +9,6 @@ import (
 	"net/http"
 	"net/http"
 	"time"
 	"time"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/model"
 	"miniflux.app/model"
@@ -30,10 +29,7 @@ func (c *Controller) GetFeedEntry(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
-
-	builder := c.store.NewEntryQueryBuilder(userID)
+	builder := c.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithFeedID(feedID)
 	builder.WithFeedID(feedID)
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
 
 
@@ -59,7 +55,7 @@ func (c *Controller) GetEntry(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	builder := c.store.NewEntryQueryBuilder(context.New(r).UserID())
+	builder := c.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
 
 
 	entry, err := builder.GetEntry()
 	entry, err := builder.GetEntry()
@@ -111,7 +107,7 @@ func (c *Controller) GetFeedEntries(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	builder := c.store.NewEntryQueryBuilder(context.New(r).UserID())
+	builder := c.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithFeedID(feedID)
 	builder.WithFeedID(feedID)
 	builder.WithStatus(status)
 	builder.WithStatus(status)
 	builder.WithOrder(order)
 	builder.WithOrder(order)
@@ -164,7 +160,7 @@ func (c *Controller) GetEntries(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	builder := c.store.NewEntryQueryBuilder(context.New(r).UserID())
+	builder := c.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithStatus(status)
 	builder.WithStatus(status)
 	builder.WithOrder(order)
 	builder.WithOrder(order)
 	builder.WithDirection(direction)
 	builder.WithDirection(direction)
@@ -200,7 +196,7 @@ func (c *Controller) SetEntryStatus(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	if err := c.store.SetEntriesStatus(context.New(r).UserID(), entryIDs, status); err != nil {
+	if err := c.store.SetEntriesStatus(request.UserID(r), entryIDs, status); err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
 	}
 	}
@@ -216,7 +212,7 @@ func (c *Controller) ToggleBookmark(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	if err := c.store.ToggleBookmark(context.New(r).UserID(), entryID); err != nil {
+	if err := c.store.ToggleBookmark(request.UserID(r), entryID); err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
 	}
 	}

+ 6 - 11
api/feed.go

@@ -8,7 +8,6 @@ import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 )
 )
@@ -31,8 +30,7 @@ func (c *Controller) CreateFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 
 
 	if c.store.FeedURLExists(userID, feedInfo.FeedURL) {
 	if c.store.FeedURLExists(userID, feedInfo.FeedURL) {
 		json.BadRequest(w, errors.New("This feed_url already exists"))
 		json.BadRequest(w, errors.New("This feed_url already exists"))
@@ -72,8 +70,7 @@ func (c *Controller) RefreshFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 
 
 	if !c.store.FeedExists(userID, feedID) {
 	if !c.store.FeedExists(userID, feedID) {
 		json.NotFound(w, errors.New("Unable to find this feed"))
 		json.NotFound(w, errors.New("Unable to find this feed"))
@@ -103,8 +100,7 @@ func (c *Controller) UpdateFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 
 
 	originalFeed, err := c.store.FeedByID(userID, feedID)
 	originalFeed, err := c.store.FeedByID(userID, feedID)
 	if err != nil {
 	if err != nil {
@@ -140,7 +136,7 @@ func (c *Controller) UpdateFeed(w http.ResponseWriter, r *http.Request) {
 
 
 // GetFeeds is the API handler that get all feeds that belongs to the given user.
 // GetFeeds is the API handler that get all feeds that belongs to the given user.
 func (c *Controller) GetFeeds(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) GetFeeds(w http.ResponseWriter, r *http.Request) {
-	feeds, err := c.store.Feeds(context.New(r).UserID())
+	feeds, err := c.store.Feeds(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
@@ -157,7 +153,7 @@ func (c *Controller) GetFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	feed, err := c.store.FeedByID(context.New(r).UserID(), feedID)
+	feed, err := c.store.FeedByID(request.UserID(r), feedID)
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
@@ -179,8 +175,7 @@ func (c *Controller) RemoveFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 
 
 	if !c.store.FeedExists(userID, feedID) {
 	if !c.store.FeedExists(userID, feedID) {
 		json.NotFound(w, errors.New("Feed not found"))
 		json.NotFound(w, errors.New("Feed not found"))

+ 1 - 2
api/icon.go

@@ -8,7 +8,6 @@ import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 )
 )
@@ -26,7 +25,7 @@ func (c *Controller) FeedIcon(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	icon, err := c.store.IconByFeedID(context.New(r).UserID(), feedID)
+	icon, err := c.store.IconByFeedID(request.UserID(r), feedID)
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return

+ 3 - 3
api/opml.go

@@ -7,7 +7,7 @@ package api // import "miniflux.app/api"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/xml"
 	"miniflux.app/http/response/xml"
 	"miniflux.app/reader/opml"
 	"miniflux.app/reader/opml"
@@ -16,7 +16,7 @@ import (
 // Export is the API handler that export feeds to OPML.
 // Export is the API handler that export feeds to OPML.
 func (c *Controller) Export(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Export(w http.ResponseWriter, r *http.Request) {
 	opmlHandler := opml.NewHandler(c.store)
 	opmlHandler := opml.NewHandler(c.store)
-	opml, err := opmlHandler.Export(context.New(r).UserID())
+	opml, err := opmlHandler.Export(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
@@ -28,7 +28,7 @@ func (c *Controller) Export(w http.ResponseWriter, r *http.Request) {
 // Import is the API handler that import an OPML file.
 // Import is the API handler that import an OPML file.
 func (c *Controller) Import(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Import(w http.ResponseWriter, r *http.Request) {
 	opmlHandler := opml.NewHandler(c.store)
 	opmlHandler := opml.NewHandler(c.store)
-	err := opmlHandler.Import(context.New(r).UserID(), r.Body)
+	err := opmlHandler.Import(request.UserID(r), r.Body)
 	defer r.Body.Close()
 	defer r.Body.Close()
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)

+ 9 - 17
api/user.go

@@ -8,15 +8,13 @@ import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 )
 )
 
 
 // CurrentUser is the API handler to retrieve the authenticated user.
 // CurrentUser is the API handler to retrieve the authenticated user.
 func (c *Controller) CurrentUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CurrentUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return
@@ -27,8 +25,7 @@ func (c *Controller) CurrentUser(w http.ResponseWriter, r *http.Request) {
 
 
 // CreateUser is the API handler to create a new user.
 // CreateUser is the API handler to create a new user.
 func (c *Controller) CreateUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CreateUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if !ctx.IsAdminUser() {
+	if !request.IsAdminUser(r) {
 		json.Forbidden(w)
 		json.Forbidden(w)
 		return
 		return
 	}
 	}
@@ -61,8 +58,7 @@ func (c *Controller) CreateUser(w http.ResponseWriter, r *http.Request) {
 
 
 // UpdateUser is the API handler to update the given user.
 // UpdateUser is the API handler to update the given user.
 func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if !ctx.IsAdminUser() {
+	if !request.IsAdminUser(r) {
 		json.Forbidden(w)
 		json.Forbidden(w)
 		return
 		return
 	}
 	}
@@ -106,8 +102,7 @@ func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
 
 
 // Users is the API handler to get the list of users.
 // Users is the API handler to get the list of users.
 func (c *Controller) Users(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Users(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if !ctx.IsAdminUser() {
+	if !request.IsAdminUser(r) {
 		json.Forbidden(w)
 		json.Forbidden(w)
 		return
 		return
 	}
 	}
@@ -118,14 +113,13 @@ func (c *Controller) Users(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	users.UseTimezone(ctx.UserTimezone())
+	users.UseTimezone(request.UserTimezone(r))
 	json.OK(w, r, users)
 	json.OK(w, r, users)
 }
 }
 
 
 // UserByID is the API handler to fetch the given user by the ID.
 // UserByID is the API handler to fetch the given user by the ID.
 func (c *Controller) UserByID(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UserByID(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if !ctx.IsAdminUser() {
+	if !request.IsAdminUser(r) {
 		json.Forbidden(w)
 		json.Forbidden(w)
 		return
 		return
 	}
 	}
@@ -147,14 +141,13 @@ func (c *Controller) UserByID(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	user.UseTimezone(ctx.UserTimezone())
+	user.UseTimezone(request.UserTimezone(r))
 	json.OK(w, r, user)
 	json.OK(w, r, user)
 }
 }
 
 
 // UserByUsername is the API handler to fetch the given user by the username.
 // UserByUsername is the API handler to fetch the given user by the username.
 func (c *Controller) UserByUsername(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UserByUsername(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if !ctx.IsAdminUser() {
+	if !request.IsAdminUser(r) {
 		json.Forbidden(w)
 		json.Forbidden(w)
 		return
 		return
 	}
 	}
@@ -176,8 +169,7 @@ func (c *Controller) UserByUsername(w http.ResponseWriter, r *http.Request) {
 
 
 // RemoveUser is the API handler to remove an existing user.
 // RemoveUser is the API handler to remove an existing user.
 func (c *Controller) RemoveUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) RemoveUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if !ctx.IsAdminUser() {
+	if !request.IsAdminUser(r) {
 		json.Forbidden(w)
 		json.Forbidden(w)
 		return
 		return
 	}
 	}

+ 9 - 19
fever/fever.go

@@ -11,7 +11,6 @@ import (
 	"time"
 	"time"
 
 
 	"miniflux.app/config"
 	"miniflux.app/config"
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/integration"
 	"miniflux.app/integration"
@@ -180,8 +179,7 @@ is_spark equal to 1.
 
 
 */
 */
 func (c *Controller) handleGroups(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleGroups(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Fetching groups for userID=%d", userID)
 	logger.Debug("[Fever] Fetching groups for userID=%d", userID)
 
 
 	categories, err := c.store.Categories(userID)
 	categories, err := c.store.Categories(userID)
@@ -231,8 +229,7 @@ should be limited to feeds with an is_spark equal to 0.
 For the “Sparks” super group the items should be limited to feeds with an is_spark equal to 1.
 For the “Sparks” super group the items should be limited to feeds with an is_spark equal to 1.
 */
 */
 func (c *Controller) handleFeeds(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleFeeds(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Fetching feeds for userID=%d", userID)
 	logger.Debug("[Fever] Fetching feeds for userID=%d", userID)
 
 
 	feeds, err := c.store.Feeds(userID)
 	feeds, err := c.store.Feeds(userID)
@@ -285,8 +282,7 @@ A PHP/HTML example:
 	echo '<img src="data:'.$favicon['data'].'">';
 	echo '<img src="data:'.$favicon['data'].'">';
 */
 */
 func (c *Controller) handleFavicons(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleFavicons(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Fetching favicons for userID=%d", userID)
 	logger.Debug("[Fever] Fetching favicons for userID=%d", userID)
 
 
 	icons, err := c.store.Icons(userID)
 	icons, err := c.store.Icons(userID)
@@ -341,8 +337,7 @@ Three optional arguments control determine the items included in the response.
 func (c *Controller) handleItems(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleItems(w http.ResponseWriter, r *http.Request) {
 	var result itemsResponse
 	var result itemsResponse
 
 
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Fetching items for userID=%d", userID)
 	logger.Debug("[Fever] Fetching items for userID=%d", userID)
 
 
 	builder := c.store.NewEntryQueryBuilder(userID)
 	builder := c.store.NewEntryQueryBuilder(userID)
@@ -425,8 +420,7 @@ A request with the unread_item_ids argument will return one additional member:
     unread_item_ids (string/comma-separated list of positive integers)
     unread_item_ids (string/comma-separated list of positive integers)
 */
 */
 func (c *Controller) handleUnreadItems(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleUnreadItems(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Fetching unread items for userID=%d", userID)
 	logger.Debug("[Fever] Fetching unread items for userID=%d", userID)
 
 
 	builder := c.store.NewEntryQueryBuilder(userID)
 	builder := c.store.NewEntryQueryBuilder(userID)
@@ -457,8 +451,7 @@ with the remote Fever installation.
 	saved_item_ids (string/comma-separated list of positive integers)
 	saved_item_ids (string/comma-separated list of positive integers)
 */
 */
 func (c *Controller) handleSavedItems(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleSavedItems(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Fetching saved items for userID=%d", userID)
 	logger.Debug("[Fever] Fetching saved items for userID=%d", userID)
 
 
 	builder := c.store.NewEntryQueryBuilder(userID)
 	builder := c.store.NewEntryQueryBuilder(userID)
@@ -486,8 +479,7 @@ func (c *Controller) handleSavedItems(w http.ResponseWriter, r *http.Request) {
 	id=? where ? is replaced with the id of the item to modify
 	id=? where ? is replaced with the id of the item to modify
 */
 */
 func (c *Controller) handleWriteItems(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleWriteItems(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Receiving mark=item call for userID=%d", userID)
 	logger.Debug("[Fever] Receiving mark=item call for userID=%d", userID)
 
 
 	entryID := request.FormInt64Value(r, "id")
 	entryID := request.FormInt64Value(r, "id")
@@ -544,8 +536,7 @@ func (c *Controller) handleWriteItems(w http.ResponseWriter, r *http.Request) {
 	before=? where ? is replaced with the Unix timestamp of the the local client’s most recent items API request
 	before=? where ? is replaced with the Unix timestamp of the the local client’s most recent items API request
 */
 */
 func (c *Controller) handleWriteFeeds(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleWriteFeeds(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Receiving mark=feed call for userID=%d", userID)
 	logger.Debug("[Fever] Receiving mark=feed call for userID=%d", userID)
 
 
 	feedID := request.FormInt64Value(r, "id")
 	feedID := request.FormInt64Value(r, "id")
@@ -585,8 +576,7 @@ func (c *Controller) handleWriteFeeds(w http.ResponseWriter, r *http.Request) {
 	before=? where ? is replaced with the Unix timestamp of the the local client’s most recent items API request
 	before=? where ? is replaced with the Unix timestamp of the the local client’s most recent items API request
 */
 */
 func (c *Controller) handleWriteGroups(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) handleWriteGroups(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	userID := ctx.UserID()
+	userID := request.UserID(r)
 	logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID)
 	logger.Debug("[Fever] Receiving mark=group call for userID=%d", userID)
 
 
 	groupID := request.FormInt64Value(r, "id")
 	groupID := request.FormInt64Value(r, "id")

+ 0 - 122
http/context/context.go

@@ -1,122 +0,0 @@
-// Copyright 2018 Frédéric Guillot. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-package context // import "miniflux.app/http/context"
-
-import (
-	"net/http"
-
-	"miniflux.app/middleware"
-)
-
-// Context contains helper functions related to the current request.
-type Context struct {
-	request *http.Request
-}
-
-// IsAdminUser checks if the logged user is administrator.
-func (c *Context) IsAdminUser() bool {
-	return c.getContextBoolValue(middleware.IsAdminUserContextKey)
-}
-
-// IsAuthenticated returns a boolean if the user is authenticated.
-func (c *Context) IsAuthenticated() bool {
-	return c.getContextBoolValue(middleware.IsAuthenticatedContextKey)
-}
-
-// UserID returns the UserID of the logged user.
-func (c *Context) UserID() int64 {
-	return c.getContextIntValue(middleware.UserIDContextKey)
-}
-
-// UserTimezone returns the timezone used by the logged user.
-func (c *Context) UserTimezone() string {
-	value := c.getContextStringValue(middleware.UserTimezoneContextKey)
-	if value == "" {
-		value = "UTC"
-	}
-	return value
-}
-
-// UserLanguage get the locale used by the current logged user.
-func (c *Context) UserLanguage() string {
-	language := c.getContextStringValue(middleware.UserLanguageContextKey)
-	if language == "" {
-		language = "en_US"
-	}
-	return language
-}
-
-// UserTheme get the theme used by the current logged user.
-func (c *Context) UserTheme() string {
-	theme := c.getContextStringValue(middleware.UserThemeContextKey)
-	if theme == "" {
-		theme = "default"
-	}
-	return theme
-}
-
-// CSRF returns the current CSRF token.
-func (c *Context) CSRF() string {
-	return c.getContextStringValue(middleware.CSRFContextKey)
-}
-
-// SessionID returns the current session ID.
-func (c *Context) SessionID() string {
-	return c.getContextStringValue(middleware.SessionIDContextKey)
-}
-
-// UserSessionToken returns the current user session token.
-func (c *Context) UserSessionToken() string {
-	return c.getContextStringValue(middleware.UserSessionTokenContextKey)
-}
-
-// OAuth2State returns the current OAuth2 state.
-func (c *Context) OAuth2State() string {
-	return c.getContextStringValue(middleware.OAuth2StateContextKey)
-}
-
-// FlashMessage returns the message message if any.
-func (c *Context) FlashMessage() string {
-	return c.getContextStringValue(middleware.FlashMessageContextKey)
-}
-
-// FlashErrorMessage returns the message error message if any.
-func (c *Context) FlashErrorMessage() string {
-	return c.getContextStringValue(middleware.FlashErrorMessageContextKey)
-}
-
-// PocketRequestToken returns the Pocket Request Token if any.
-func (c *Context) PocketRequestToken() string {
-	return c.getContextStringValue(middleware.PocketRequestTokenContextKey)
-}
-
-func (c *Context) getContextStringValue(key middleware.ContextKey) string {
-	if v := c.request.Context().Value(key); v != nil {
-		return v.(string)
-	}
-
-	return ""
-}
-
-func (c *Context) getContextBoolValue(key middleware.ContextKey) bool {
-	if v := c.request.Context().Value(key); v != nil {
-		return v.(bool)
-	}
-
-	return false
-}
-
-func (c *Context) getContextIntValue(key middleware.ContextKey) int64 {
-	if v := c.request.Context().Value(key); v != nil {
-		return v.(int64)
-	}
-
-	return 0
-}
-
-// New creates a new Context.
-func New(r *http.Request) *Context {
-	return &Context{r}
-}

+ 128 - 0
http/request/context.go

@@ -0,0 +1,128 @@
+// Copyright 2018 Frédéric Guillot. All rights reserved.
+// Use of this source code is governed by the Apache 2.0
+// license that can be found in the LICENSE file.
+
+package request // import "miniflux.app/http/request"
+
+import "net/http"
+
+// ContextKey represents a context key.
+type ContextKey int
+
+// List of context keys.
+const (
+	UserIDContextKey ContextKey = iota
+	UserTimezoneContextKey
+	IsAdminUserContextKey
+	IsAuthenticatedContextKey
+	UserSessionTokenContextKey
+	UserLanguageContextKey
+	UserThemeContextKey
+	SessionIDContextKey
+	CSRFContextKey
+	OAuth2StateContextKey
+	FlashMessageContextKey
+	FlashErrorMessageContextKey
+	PocketRequestTokenContextKey
+)
+
+// IsAdminUser checks if the logged user is administrator.
+func IsAdminUser(r *http.Request) bool {
+	return getContextBoolValue(r, IsAdminUserContextKey)
+}
+
+// IsAuthenticated returns a boolean if the user is authenticated.
+func IsAuthenticated(r *http.Request) bool {
+	return getContextBoolValue(r, IsAuthenticatedContextKey)
+}
+
+// UserID returns the UserID of the logged user.
+func UserID(r *http.Request) int64 {
+	return getContextInt64Value(r, UserIDContextKey)
+}
+
+// UserTimezone returns the timezone used by the logged user.
+func UserTimezone(r *http.Request) string {
+	value := getContextStringValue(r, UserTimezoneContextKey)
+	if value == "" {
+		value = "UTC"
+	}
+	return value
+}
+
+// UserLanguage get the locale used by the current logged user.
+func UserLanguage(r *http.Request) string {
+	language := getContextStringValue(r, UserLanguageContextKey)
+	if language == "" {
+		language = "en_US"
+	}
+	return language
+}
+
+// UserTheme get the theme used by the current logged user.
+func UserTheme(r *http.Request) string {
+	theme := getContextStringValue(r, UserThemeContextKey)
+	if theme == "" {
+		theme = "default"
+	}
+	return theme
+}
+
+// CSRF returns the current CSRF token.
+func CSRF(r *http.Request) string {
+	return getContextStringValue(r, CSRFContextKey)
+}
+
+// SessionID returns the current session ID.
+func SessionID(r *http.Request) string {
+	return getContextStringValue(r, SessionIDContextKey)
+}
+
+// UserSessionToken returns the current user session token.
+func UserSessionToken(r *http.Request) string {
+	return getContextStringValue(r, UserSessionTokenContextKey)
+}
+
+// OAuth2State returns the current OAuth2 state.
+func OAuth2State(r *http.Request) string {
+	return getContextStringValue(r, OAuth2StateContextKey)
+}
+
+// FlashMessage returns the message message if any.
+func FlashMessage(r *http.Request) string {
+	return getContextStringValue(r, FlashMessageContextKey)
+}
+
+// FlashErrorMessage returns the message error message if any.
+func FlashErrorMessage(r *http.Request) string {
+	return getContextStringValue(r, FlashErrorMessageContextKey)
+}
+
+// PocketRequestToken returns the Pocket Request Token if any.
+func PocketRequestToken(r *http.Request) string {
+	return getContextStringValue(r, PocketRequestTokenContextKey)
+}
+
+func getContextStringValue(r *http.Request, key ContextKey) string {
+	if v := r.Context().Value(key); v != nil {
+		return v.(string)
+	}
+
+	return ""
+}
+
+func getContextBoolValue(r *http.Request, key ContextKey) bool {
+	if v := r.Context().Value(key); v != nil {
+		return v.(bool)
+	}
+
+	return false
+}
+
+func getContextInt64Value(r *http.Request, key ContextKey) int64 {
+	if v := r.Context().Value(key); v != nil {
+		return v.(int64)
+	}
+
+	return 0
+}

+ 10 - 0
http/request/doc.go

@@ -0,0 +1,10 @@
+// Copyright 2018 Frédéric Guillot. All rights reserved.
+// Use of this source code is governed by the MIT license
+// that can be found in the LICENSE file.
+
+/*
+
+Package request holds helper functions regarding the HTTP request.
+
+*/
+package request // import "miniflux.app/http/request"

+ 8 - 8
middleware/app_session.go

@@ -49,14 +49,14 @@ func (m *Middleware) AppSession(next http.Handler) http.Handler {
 		}
 		}
 
 
 		ctx := r.Context()
 		ctx := r.Context()
-		ctx = context.WithValue(ctx, SessionIDContextKey, session.ID)
-		ctx = context.WithValue(ctx, CSRFContextKey, session.Data.CSRF)
-		ctx = context.WithValue(ctx, OAuth2StateContextKey, session.Data.OAuth2State)
-		ctx = context.WithValue(ctx, FlashMessageContextKey, session.Data.FlashMessage)
-		ctx = context.WithValue(ctx, FlashErrorMessageContextKey, session.Data.FlashErrorMessage)
-		ctx = context.WithValue(ctx, UserLanguageContextKey, session.Data.Language)
-		ctx = context.WithValue(ctx, UserThemeContextKey, session.Data.Theme)
-		ctx = context.WithValue(ctx, PocketRequestTokenContextKey, session.Data.PocketRequestToken)
+		ctx = context.WithValue(ctx, request.SessionIDContextKey, session.ID)
+		ctx = context.WithValue(ctx, request.CSRFContextKey, session.Data.CSRF)
+		ctx = context.WithValue(ctx, request.OAuth2StateContextKey, session.Data.OAuth2State)
+		ctx = context.WithValue(ctx, request.FlashMessageContextKey, session.Data.FlashMessage)
+		ctx = context.WithValue(ctx, request.FlashErrorMessageContextKey, session.Data.FlashErrorMessage)
+		ctx = context.WithValue(ctx, request.UserLanguageContextKey, session.Data.Language)
+		ctx = context.WithValue(ctx, request.UserThemeContextKey, session.Data.Theme)
+		ctx = context.WithValue(ctx, request.PocketRequestTokenContextKey, session.Data.PocketRequestToken)
 		next.ServeHTTP(w, r.WithContext(ctx))
 		next.ServeHTTP(w, r.WithContext(ctx))
 	})
 	})
 }
 }

+ 4 - 4
middleware/basic_auth.go

@@ -50,10 +50,10 @@ func (m *Middleware) BasicAuth(next http.Handler) http.Handler {
 		m.store.SetLastLogin(user.ID)
 		m.store.SetLastLogin(user.ID)
 
 
 		ctx := r.Context()
 		ctx := r.Context()
-		ctx = context.WithValue(ctx, UserIDContextKey, user.ID)
-		ctx = context.WithValue(ctx, UserTimezoneContextKey, user.Timezone)
-		ctx = context.WithValue(ctx, IsAdminUserContextKey, user.IsAdmin)
-		ctx = context.WithValue(ctx, IsAuthenticatedContextKey, true)
+		ctx = context.WithValue(ctx, request.UserIDContextKey, user.ID)
+		ctx = context.WithValue(ctx, request.UserTimezoneContextKey, user.Timezone)
+		ctx = context.WithValue(ctx, request.IsAdminUserContextKey, user.IsAdmin)
+		ctx = context.WithValue(ctx, request.IsAuthenticatedContextKey, true)
 
 
 		next.ServeHTTP(w, r.WithContext(ctx))
 		next.ServeHTTP(w, r.WithContext(ctx))
 	})
 	})

+ 0 - 25
middleware/context_keys.go

@@ -1,25 +0,0 @@
-// Copyright 2018 Frédéric Guillot. All rights reserved.
-// Use of this source code is governed by the Apache 2.0
-// license that can be found in the LICENSE file.
-
-package middleware // import "miniflux.app/middleware"
-
-// ContextKey represents a context key.
-type ContextKey int
-
-// List of context keys.
-const (
-	UserIDContextKey ContextKey = iota
-	UserTimezoneContextKey
-	IsAdminUserContextKey
-	IsAuthenticatedContextKey
-	UserSessionTokenContextKey
-	UserLanguageContextKey
-	UserThemeContextKey
-	SessionIDContextKey
-	CSRFContextKey
-	OAuth2StateContextKey
-	FlashMessageContextKey
-	FlashErrorMessageContextKey
-	PocketRequestTokenContextKey
-)

+ 10 - 0
middleware/doc.go

@@ -0,0 +1,10 @@
+// Copyright 2018 Frédéric Guillot. All rights reserved.
+// Use of this source code is governed by the MIT license
+// that can be found in the LICENSE file.
+
+/*
+
+Package middleware contains application HTTP middlewares.
+
+*/
+package middleware // import "miniflux.app/middleware"

+ 5 - 4
middleware/fever.go

@@ -8,6 +8,7 @@ import (
 	"context"
 	"context"
 	"net/http"
 	"net/http"
 
 
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
 )
 )
@@ -34,10 +35,10 @@ func (m *Middleware) FeverAuth(next http.Handler) http.Handler {
 		m.store.SetLastLogin(user.ID)
 		m.store.SetLastLogin(user.ID)
 
 
 		ctx := r.Context()
 		ctx := r.Context()
-		ctx = context.WithValue(ctx, UserIDContextKey, user.ID)
-		ctx = context.WithValue(ctx, UserTimezoneContextKey, user.Timezone)
-		ctx = context.WithValue(ctx, IsAdminUserContextKey, user.IsAdmin)
-		ctx = context.WithValue(ctx, IsAuthenticatedContextKey, true)
+		ctx = context.WithValue(ctx, request.UserIDContextKey, user.ID)
+		ctx = context.WithValue(ctx, request.UserTimezoneContextKey, user.Timezone)
+		ctx = context.WithValue(ctx, request.IsAdminUserContextKey, user.IsAdmin)
+		ctx = context.WithValue(ctx, request.IsAuthenticatedContextKey, true)
 
 
 		next.ServeHTTP(w, r.WithContext(ctx))
 		next.ServeHTTP(w, r.WithContext(ctx))
 	})
 	})

+ 3 - 3
middleware/user_session.go

@@ -34,9 +34,9 @@ func (m *Middleware) UserSession(next http.Handler) http.Handler {
 			logger.Debug("[Middleware:UserSession] %s", session)
 			logger.Debug("[Middleware:UserSession] %s", session)
 
 
 			ctx := r.Context()
 			ctx := r.Context()
-			ctx = context.WithValue(ctx, UserIDContextKey, session.UserID)
-			ctx = context.WithValue(ctx, IsAuthenticatedContextKey, true)
-			ctx = context.WithValue(ctx, UserSessionTokenContextKey, session.Token)
+			ctx = context.WithValue(ctx, request.UserIDContextKey, session.UserID)
+			ctx = context.WithValue(ctx, request.IsAuthenticatedContextKey, true)
+			ctx = context.WithValue(ctx, request.UserSessionTokenContextKey, session.Token)
 
 
 			next.ServeHTTP(w, r.WithContext(ctx))
 			next.ServeHTTP(w, r.WithContext(ctx))
 		}
 		}

+ 4 - 6
ui/about.go

@@ -7,8 +7,8 @@ package ui // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
 	"miniflux.app/version"
 	"miniflux.app/version"
@@ -16,16 +16,14 @@ import (
 
 
 // About shows the about page.
 // About shows the about page.
 func (c *Controller) About(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) About(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("version", version.Version)
 	view.Set("version", version.Version)
 	view.Set("build_date", version.BuildDate)
 	view.Set("build_date", version.BuildDate)
 	view.Set("menu", "settings")
 	view.Set("menu", "settings")

+ 3 - 6
ui/bookmark_entries.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,9 +17,7 @@ import (
 
 
 // ShowStarredPage renders the page with all starred entries.
 // ShowStarredPage renders the page with all starred entries.
 func (c *Controller) ShowStarredPage(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowStarredPage(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -47,8 +44,8 @@ func (c *Controller) ShowStarredPage(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
 	view.Set("total", count)
 	view.Set("total", count)
 	view.Set("entries", entries)
 	view.Set("entries", entries)

+ 5 - 7
ui/category_create.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
@@ -15,16 +15,14 @@ import (
 
 
 // CreateCategory shows the form to create a new category.
 // CreateCategory shows the form to create a new category.
 func (c *Controller) CreateCategory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CreateCategory(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("menu", "categories")
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))

+ 4 - 6
ui/category_edit.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -17,11 +16,10 @@ import (
 
 
 // EditCategory shows the form to modify a category.
 // EditCategory shows the form to modify a category.
 func (c *Controller) EditCategory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) EditCategory(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -33,7 +31,7 @@ func (c *Controller) EditCategory(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	category, err := c.store.Category(ctx.UserID(), categoryID)
+	category, err := c.store.Category(request.UserID(r), categoryID)
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 4 - 7
ui/category_entries.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,9 +17,7 @@ import (
 
 
 // CategoryEntries shows all entries for the given category.
 // CategoryEntries shows all entries for the given category.
 func (c *Controller) CategoryEntries(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CategoryEntries(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -32,7 +29,7 @@ func (c *Controller) CategoryEntries(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	category, err := c.store.Category(ctx.UserID(), categoryID)
+	category, err := c.store.Category(request.UserID(r), categoryID)
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -64,8 +61,8 @@ func (c *Controller) CategoryEntries(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("category", category)
 	view.Set("category", category)
 	view.Set("total", count)
 	view.Set("total", count)
 	view.Set("entries", entries)
 	view.Set("entries", entries)

+ 4 - 6
ui/category_list.go

@@ -7,17 +7,15 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
+	"miniflux.app/http/request"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
 )
 )
 
 
 // CategoryList shows the page with all categories.
 // CategoryList shows the page with all categories.
 func (c *Controller) CategoryList(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CategoryList(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -29,8 +27,8 @@ func (c *Controller) CategoryList(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("categories", categories)
 	view.Set("categories", categories)
 	view.Set("total", len(categories))
 	view.Set("total", len(categories))
 	view.Set("menu", "categories")
 	view.Set("menu", "categories")

+ 3 - 6
ui/category_remove.go

@@ -2,12 +2,11 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -16,9 +15,7 @@ import (
 
 
 // RemoveCategory deletes a category from the database.
 // RemoveCategory deletes a category from the database.
 func (c *Controller) RemoveCategory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) RemoveCategory(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -30,7 +27,7 @@ func (c *Controller) RemoveCategory(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	category, err := c.store.Category(ctx.UserID(), categoryID)
+	category, err := c.store.Category(request.UserID(r), categoryID)
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 4 - 6
ui/category_save.go

@@ -7,10 +7,10 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
+	"miniflux.app/http/request"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
 	"miniflux.app/model"
 	"miniflux.app/model"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -20,9 +20,7 @@ import (
 
 
 // SaveCategory validate and save the new category into the database.
 // SaveCategory validate and save the new category into the database.
 func (c *Controller) SaveCategory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) SaveCategory(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -30,8 +28,8 @@ func (c *Controller) SaveCategory(w http.ResponseWriter, r *http.Request) {
 
 
 	categoryForm := form.NewCategoryForm(r)
 	categoryForm := form.NewCategoryForm(r)
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("form", categoryForm)
 	view.Set("form", categoryForm)
 	view.Set("menu", "categories")
 	view.Set("menu", "categories")
 	view.Set("user", user)
 	view.Set("user", user)

+ 4 - 7
ui/category_update.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -20,9 +19,7 @@ import (
 
 
 // UpdateCategory validates and updates a category.
 // UpdateCategory validates and updates a category.
 func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -34,7 +31,7 @@ func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	category, err := c.store.Category(ctx.UserID(), categoryID)
+	category, err := c.store.Category(request.UserID(r), categoryID)
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -47,8 +44,8 @@ func (c *Controller) UpdateCategory(w http.ResponseWriter, r *http.Request) {
 
 
 	categoryForm := form.NewCategoryForm(r)
 	categoryForm := form.NewCategoryForm(r)
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("form", categoryForm)
 	view.Set("form", categoryForm)
 	view.Set("category", category)
 	view.Set("category", category)
 	view.Set("menu", "categories")
 	view.Set("menu", "categories")

+ 2 - 1
ui/controller.go

@@ -5,13 +5,14 @@
 package ui  // import "miniflux.app/ui"
 package ui  // import "miniflux.app/ui"
 
 
 import (
 import (
-	"github.com/gorilla/mux"
 	"miniflux.app/config"
 	"miniflux.app/config"
 	"miniflux.app/locale"
 	"miniflux.app/locale"
 	"miniflux.app/reader/feed"
 	"miniflux.app/reader/feed"
 	"miniflux.app/scheduler"
 	"miniflux.app/scheduler"
 	"miniflux.app/storage"
 	"miniflux.app/storage"
 	"miniflux.app/template"
 	"miniflux.app/template"
+
+	"github.com/gorilla/mux"
 )
 )
 
 
 // Controller contains all HTTP handlers for the user interface.
 // Controller contains all HTTP handlers for the user interface.

+ 3 - 6
ui/entry_bookmark.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -20,9 +19,7 @@ import (
 
 
 // ShowStarredEntry shows a single feed entry in "starred" mode.
 // ShowStarredEntry shows a single feed entry in "starred" mode.
 func (c *Controller) ShowStarredEntry(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowStarredEntry(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -78,8 +75,8 @@ func (c *Controller) ShowStarredEntry(w http.ResponseWriter, r *http.Request) {
 		prevEntryRoute = route.Path(c.router, "starredEntry", "entryID", prevEntry.ID)
 		prevEntryRoute = route.Path(c.router, "starredEntry", "entryID", prevEntry.ID)
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("entry", entry)
 	view.Set("entry", entry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("nextEntry", nextEntry)
 	view.Set("nextEntry", nextEntry)

+ 3 - 6
ui/entry_category.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -20,9 +19,7 @@ import (
 
 
 // ShowCategoryEntry shows a single feed entry in "category" mode.
 // ShowCategoryEntry shows a single feed entry in "category" mode.
 func (c *Controller) ShowCategoryEntry(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowCategoryEntry(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -85,8 +82,8 @@ func (c *Controller) ShowCategoryEntry(w http.ResponseWriter, r *http.Request) {
 		prevEntryRoute = route.Path(c.router, "categoryEntry", "categoryID", categoryID, "entryID", prevEntry.ID)
 		prevEntryRoute = route.Path(c.router, "categoryEntry", "categoryID", categoryID, "entryID", prevEntry.ID)
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("entry", entry)
 	view.Set("entry", entry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("nextEntry", nextEntry)
 	view.Set("nextEntry", nextEntry)

+ 3 - 6
ui/entry_feed.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -20,9 +19,7 @@ import (
 
 
 // ShowFeedEntry shows a single feed entry in "feed" mode.
 // ShowFeedEntry shows a single feed entry in "feed" mode.
 func (c *Controller) ShowFeedEntry(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowFeedEntry(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -85,8 +82,8 @@ func (c *Controller) ShowFeedEntry(w http.ResponseWriter, r *http.Request) {
 		prevEntryRoute = route.Path(c.router, "feedEntry", "feedID", feedID, "entryID", prevEntry.ID)
 		prevEntryRoute = route.Path(c.router, "feedEntry", "feedID", feedID, "entryID", prevEntry.ID)
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("entry", entry)
 	view.Set("entry", entry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("nextEntry", nextEntry)
 	view.Set("nextEntry", nextEntry)

+ 3 - 6
ui/entry_read.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -19,9 +18,7 @@ import (
 
 
 // ShowReadEntry shows a single feed entry in "history" mode.
 // ShowReadEntry shows a single feed entry in "history" mode.
 func (c *Controller) ShowReadEntry(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowReadEntry(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -66,8 +63,8 @@ func (c *Controller) ShowReadEntry(w http.ResponseWriter, r *http.Request) {
 		prevEntryRoute = route.Path(c.router, "readEntry", "entryID", prevEntry.ID)
 		prevEntryRoute = route.Path(c.router, "readEntry", "entryID", prevEntry.ID)
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("entry", entry)
 	view.Set("entry", entry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("nextEntry", nextEntry)
 	view.Set("nextEntry", nextEntry)

+ 3 - 6
ui/entry_save.go

@@ -2,13 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/integration"
 	"miniflux.app/integration"
@@ -23,9 +22,7 @@ func (c *Controller) SaveEntry(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-
-	builder := c.store.NewEntryQueryBuilder(ctx.UserID())
+	builder := c.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
 	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithoutStatus(model.EntryStatusRemoved)
 
 
@@ -40,7 +37,7 @@ func (c *Controller) SaveEntry(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	settings, err := c.store.Integration(ctx.UserID())
+	settings, err := c.store.Integration(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		json.ServerError(w, err)
 		json.ServerError(w, err)
 		return
 		return

+ 1 - 3
ui/entry_scraper.go

@@ -8,7 +8,6 @@ import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/model"
 	"miniflux.app/model"
@@ -24,8 +23,7 @@ func (c *Controller) FetchContent(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	builder := c.store.NewEntryQueryBuilder(ctx.UserID())
+	builder := c.store.NewEntryQueryBuilder(request.UserID(r))
 	builder.WithEntryID(entryID)
 	builder.WithEntryID(entryID)
 	builder.WithoutStatus(model.EntryStatusRemoved)
 	builder.WithoutStatus(model.EntryStatusRemoved)
 
 

+ 3 - 6
ui/entry_search.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -20,9 +19,7 @@ import (
 
 
 // ShowSearchEntry shows a single entry in "search" mode.
 // ShowSearchEntry shows a single entry in "search" mode.
 func (c *Controller) ShowSearchEntry(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowSearchEntry(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -80,8 +77,8 @@ func (c *Controller) ShowSearchEntry(w http.ResponseWriter, r *http.Request) {
 		prevEntryRoute = route.Path(c.router, "searchEntry", "entryID", prevEntry.ID)
 		prevEntryRoute = route.Path(c.router, "searchEntry", "entryID", prevEntry.ID)
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("searchQuery", searchQuery)
 	view.Set("searchQuery", searchQuery)
 	view.Set("entry", entry)
 	view.Set("entry", entry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("prevEntry", prevEntry)

+ 2 - 4
ui/entry_toggle_bookmark.go

@@ -2,12 +2,11 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
@@ -21,8 +20,7 @@ func (c *Controller) ToggleBookmark(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	if err := c.store.ToggleBookmark(ctx.UserID(), entryID); err != nil {
+	if err := c.store.ToggleBookmark(request.UserID(r), entryID); err != nil {
 		logger.Error("[Controller:ToggleBookmark] %v", err)
 		logger.Error("[Controller:ToggleBookmark] %v", err)
 		json.ServerError(w, nil)
 		json.ServerError(w, nil)
 		return
 		return

+ 3 - 6
ui/entry_unread.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -20,9 +19,7 @@ import (
 
 
 // ShowUnreadEntry shows a single feed entry in "unread" mode.
 // ShowUnreadEntry shows a single feed entry in "unread" mode.
 func (c *Controller) ShowUnreadEntry(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowUnreadEntry(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -86,8 +83,8 @@ func (c *Controller) ShowUnreadEntry(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 	entry.Status = model.EntryStatusRead
 	entry.Status = model.EntryStatusRead
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("entry", entry)
 	view.Set("entry", entry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("prevEntry", prevEntry)
 	view.Set("nextEntry", nextEntry)
 	view.Set("nextEntry", nextEntry)

+ 3 - 4
ui/entry_update_status.go

@@ -2,13 +2,13 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"errors"
 	"errors"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
 )
 )
@@ -27,8 +27,7 @@ func (c *Controller) UpdateEntriesStatus(w http.ResponseWriter, r *http.Request)
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	err = c.store.SetEntriesStatus(ctx.UserID(), entryIDs, status)
+	err = c.store.SetEntriesStatus(request.UserID(r), entryIDs, status)
 	if err != nil {
 	if err != nil {
 		logger.Error("[Controller:UpdateEntryStatus] %v", err)
 		logger.Error("[Controller:UpdateEntryStatus] %v", err)
 		json.ServerError(w, nil)
 		json.ServerError(w, nil)

+ 3 - 6
ui/feed_edit.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -17,9 +16,7 @@ import (
 
 
 // EditFeed shows the form to modify a subscription.
 // EditFeed shows the form to modify a subscription.
 func (c *Controller) EditFeed(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) EditFeed(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -60,8 +57,8 @@ func (c *Controller) EditFeed(w http.ResponseWriter, r *http.Request) {
 		Password:     feed.Password,
 		Password:     feed.Password,
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("form", feedForm)
 	view.Set("form", feedForm)
 	view.Set("categories", categories)
 	view.Set("categories", categories)
 	view.Set("feed", feed)
 	view.Set("feed", feed)

+ 3 - 6
ui/feed_entries.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,9 +17,7 @@ import (
 
 
 // ShowFeedEntries shows all entries for the given feed.
 // ShowFeedEntries shows all entries for the given feed.
 func (c *Controller) ShowFeedEntries(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowFeedEntries(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -64,8 +61,8 @@ func (c *Controller) ShowFeedEntries(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("feed", feed)
 	view.Set("feed", feed)
 	view.Set("entries", entries)
 	view.Set("entries", entries)
 	view.Set("total", count)
 	view.Set("total", count)

+ 5 - 7
ui/feed_list.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
@@ -15,9 +15,7 @@ import (
 
 
 // ShowFeedsPage shows the page with all subscriptions.
 // ShowFeedsPage shows the page with all subscriptions.
 func (c *Controller) ShowFeedsPage(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowFeedsPage(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -29,8 +27,8 @@ func (c *Controller) ShowFeedsPage(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("feeds", feeds)
 	view.Set("feeds", feeds)
 	view.Set("total", len(feeds))
 	view.Set("total", len(feeds))
 	view.Set("menu", "feeds")
 	view.Set("menu", "feeds")

+ 2 - 4
ui/feed_refresh.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -23,8 +22,7 @@ func (c *Controller) RefreshFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	if err := c.feedHandler.RefreshFeed(ctx.UserID(), feedID); err != nil {
+	if err := c.feedHandler.RefreshFeed(request.UserID(r), feedID); err != nil {
 		logger.Error("[Controller:RefreshFeed] %v", err)
 		logger.Error("[Controller:RefreshFeed] %v", err)
 	}
 	}
 
 
@@ -33,7 +31,7 @@ func (c *Controller) RefreshFeed(w http.ResponseWriter, r *http.Request) {
 
 
 // RefreshAllFeeds refresh all feeds in the background for the current user.
 // RefreshAllFeeds refresh all feeds in the background for the current user.
 func (c *Controller) RefreshAllFeeds(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) RefreshAllFeeds(w http.ResponseWriter, r *http.Request) {
-	userID := context.New(r).UserID()
+	userID := request.UserID(r)
 	jobs, err := c.store.NewUserBatch(userID, c.store.CountFeeds(userID))
 	jobs, err := c.store.NewUserBatch(userID, c.store.CountFeeds(userID))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)

+ 1 - 3
ui/feed_remove.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -22,8 +21,7 @@ func (c *Controller) RemoveFeed(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	if err := c.store.RemoveFeed(ctx.UserID(), feedID); err != nil {
+	if err := c.store.RemoveFeed(request.UserID(r), feedID); err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
 	}
 	}

+ 3 - 6
ui/feed_update.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -20,9 +19,7 @@ import (
 
 
 // UpdateFeed update a subscription and redirect to the feed entries page.
 // UpdateFeed update a subscription and redirect to the feed entries page.
 func (c *Controller) UpdateFeed(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UpdateFeed(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -53,8 +50,8 @@ func (c *Controller) UpdateFeed(w http.ResponseWriter, r *http.Request) {
 
 
 	feedForm := form.NewFeedForm(r)
 	feedForm := form.NewFeedForm(r)
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("form", feedForm)
 	view.Set("form", feedForm)
 	view.Set("categories", categories)
 	view.Set("categories", categories)
 	view.Set("feed", feed)
 	view.Set("feed", feed)

+ 3 - 6
ui/history_entries.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,9 +17,7 @@ import (
 
 
 // ShowHistoryPage renders the page with all read entries.
 // ShowHistoryPage renders the page with all read entries.
 func (c *Controller) ShowHistoryPage(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowHistoryPage(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -46,8 +43,8 @@ func (c *Controller) ShowHistoryPage(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("entries", entries)
 	view.Set("entries", entries)
 	view.Set("total", count)
 	view.Set("total", count)
 	view.Set("pagination", c.getPagination(route.Path(c.router, "history"), count, offset))
 	view.Set("pagination", c.getPagination(route.Path(c.router, "history"), count, offset))

+ 3 - 3
ui/history_flush.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -15,7 +15,7 @@ import (
 
 
 // FlushHistory changes all "read" items to "removed".
 // FlushHistory changes all "read" items to "removed".
 func (c *Controller) FlushHistory(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) FlushHistory(w http.ResponseWriter, r *http.Request) {
-	err := c.store.FlushHistory(context.New(r).UserID())
+	err := c.store.FlushHistory(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 9 - 12
ui/integration_pocket.go

@@ -7,8 +7,8 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/integration/pocket"
 	"miniflux.app/integration/pocket"
@@ -18,9 +18,7 @@ import (
 
 
 // PocketAuthorize redirects the end-user to Pocket website to authorize the application.
 // PocketAuthorize redirects the end-user to Pocket website to authorize the application.
 func (c *Controller) PocketAuthorize(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) PocketAuthorize(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -32,13 +30,13 @@ func (c *Controller) PocketAuthorize(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
+	sess := session.New(c.store, request.SessionID(r))
 	connector := pocket.NewConnector(c.cfg.PocketConsumerKey(integration.PocketConsumerKey))
 	connector := pocket.NewConnector(c.cfg.PocketConsumerKey(integration.PocketConsumerKey))
 	redirectURL := c.cfg.BaseURL() + route.Path(c.router, "pocketCallback")
 	redirectURL := c.cfg.BaseURL() + route.Path(c.router, "pocketCallback")
 	requestToken, err := connector.RequestToken(redirectURL)
 	requestToken, err := connector.RequestToken(redirectURL)
 	if err != nil {
 	if err != nil {
 		logger.Error("[Pocket:Authorize] %v", err)
 		logger.Error("[Pocket:Authorize] %v", err)
-		sess.NewFlashErrorMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Unable to fetch request token from Pocket!"))
+		sess.NewFlashErrorMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Unable to fetch request token from Pocket!"))
 		response.Redirect(w, r, route.Path(c.router, "integrations"))
 		response.Redirect(w, r, route.Path(c.router, "integrations"))
 		return
 		return
 	}
 	}
@@ -49,10 +47,9 @@ func (c *Controller) PocketAuthorize(w http.ResponseWriter, r *http.Request) {
 
 
 // PocketCallback saves the personal access token after the authorization step.
 // PocketCallback saves the personal access token after the authorization step.
 func (c *Controller) PocketCallback(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) PocketCallback(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
+	sess := session.New(c.store, request.SessionID(r))
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -65,10 +62,10 @@ func (c *Controller) PocketCallback(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 
 
 	connector := pocket.NewConnector(c.cfg.PocketConsumerKey(integration.PocketConsumerKey))
 	connector := pocket.NewConnector(c.cfg.PocketConsumerKey(integration.PocketConsumerKey))
-	accessToken, err := connector.AccessToken(ctx.PocketRequestToken())
+	accessToken, err := connector.AccessToken(request.PocketRequestToken(r))
 	if err != nil {
 	if err != nil {
 		logger.Error("[Pocket:Callback] %v", err)
 		logger.Error("[Pocket:Callback] %v", err)
-		sess.NewFlashErrorMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Unable to fetch access token from Pocket!"))
+		sess.NewFlashErrorMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Unable to fetch access token from Pocket!"))
 		response.Redirect(w, r, route.Path(c.router, "integrations"))
 		response.Redirect(w, r, route.Path(c.router, "integrations"))
 		return
 		return
 	}
 	}
@@ -82,6 +79,6 @@ func (c *Controller) PocketCallback(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess.NewFlashMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Your Pocket account is now linked!"))
+	sess.NewFlashMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Your Pocket account is now linked!"))
 	response.Redirect(w, r, route.Path(c.router, "integrations"))
 	response.Redirect(w, r, route.Path(c.router, "integrations"))
 }
 }

+ 4 - 6
ui/integration_show.go

@@ -7,7 +7,7 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
@@ -16,9 +16,7 @@ import (
 
 
 // ShowIntegrations renders the page with all external integrations.
 // ShowIntegrations renders the page with all external integrations.
 func (c *Controller) ShowIntegrations(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowIntegrations(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -55,8 +53,8 @@ func (c *Controller) ShowIntegrations(w http.ResponseWriter, r *http.Request) {
 		PocketConsumerKey:    integration.PocketConsumerKey,
 		PocketConsumerKey:    integration.PocketConsumerKey,
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("form", integrationForm)
 	view.Set("form", integrationForm)
 	view.Set("menu", "settings")
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("user", user)

+ 5 - 7
ui/integration_update.go

@@ -9,8 +9,8 @@ import (
 	"fmt"
 	"fmt"
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -19,10 +19,8 @@ import (
 
 
 // UpdateIntegration updates integration settings.
 // UpdateIntegration updates integration settings.
 func (c *Controller) UpdateIntegration(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UpdateIntegration(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	sess := session.New(c.store, request.SessionID(r))
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -38,7 +36,7 @@ func (c *Controller) UpdateIntegration(w http.ResponseWriter, r *http.Request) {
 	integrationForm.Merge(integration)
 	integrationForm.Merge(integration)
 
 
 	if integration.FeverUsername != "" && c.store.HasDuplicateFeverUsername(user.ID, integration.FeverUsername) {
 	if integration.FeverUsername != "" && c.store.HasDuplicateFeverUsername(user.ID, integration.FeverUsername) {
-		sess.NewFlashErrorMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("There is already someone else with the same Fever username!"))
+		sess.NewFlashErrorMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("There is already someone else with the same Fever username!"))
 		response.Redirect(w, r, route.Path(c.router, "integrations"))
 		response.Redirect(w, r, route.Path(c.router, "integrations"))
 		return
 		return
 	}
 	}
@@ -55,6 +53,6 @@ func (c *Controller) UpdateIntegration(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess.NewFlashMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Preferences saved!"))
+	sess.NewFlashMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Preferences saved!"))
 	response.Redirect(w, r, route.Path(c.router, "integrations"))
 	response.Redirect(w, r, route.Path(c.router, "integrations"))
 }
 }

+ 2 - 6
ui/login_check.go

@@ -3,7 +3,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/cookie"
 	"miniflux.app/http/cookie"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
@@ -18,13 +17,10 @@ import (
 // CheckLogin validates the username/password and redirects the user to the unread page.
 // CheckLogin validates the username/password and redirects the user to the unread page.
 func (c *Controller) CheckLogin(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CheckLogin(w http.ResponseWriter, r *http.Request) {
 	remoteAddr := request.RealIP(r)
 	remoteAddr := request.RealIP(r)
-
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-
+	sess := session.New(c.store, request.SessionID(r))
 	authForm := form.NewAuthForm(r)
 	authForm := form.NewAuthForm(r)
 
 
-	view := view.New(c.tpl, ctx, sess)
+	view := view.New(c.tpl, r, sess)
 	view.Set("errorMessage", "Invalid username or password.")
 	view.Set("errorMessage", "Invalid username or password.")
 	view.Set("form", authForm)
 	view.Set("form", authForm)
 
 

+ 4 - 5
ui/login_show.go

@@ -7,8 +7,8 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
@@ -17,13 +17,12 @@ import (
 
 
 // ShowLoginPage shows the login form.
 // ShowLoginPage shows the login form.
 func (c *Controller) ShowLoginPage(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowLoginPage(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	if ctx.IsAuthenticated() {
+	if request.IsAuthenticated(r) {
 		response.Redirect(w, r, route.Path(c.router, "unread"))
 		response.Redirect(w, r, route.Path(c.router, "unread"))
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	html.OK(w, r, view.Render("login"))
 	html.OK(w, r, view.Render("login"))
 }
 }

+ 4 - 6
ui/logout.go

@@ -7,8 +7,8 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/cookie"
 	"miniflux.app/http/cookie"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,10 +18,8 @@ import (
 
 
 // Logout destroy the session and redirects the user to the login page.
 // Logout destroy the session and redirects the user to the login page.
 func (c *Controller) Logout(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Logout(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	sess := session.New(c.store, request.SessionID(r))
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -30,7 +28,7 @@ func (c *Controller) Logout(w http.ResponseWriter, r *http.Request) {
 	sess.SetLanguage(user.Language)
 	sess.SetLanguage(user.Language)
 	sess.SetTheme(user.Theme)
 	sess.SetTheme(user.Theme)
 
 
-	if err := c.store.RemoveUserSessionByToken(user.ID, ctx.UserSessionToken()); err != nil {
+	if err := c.store.RemoveUserSessionByToken(user.ID, request.UserSessionToken(r)); err != nil {
 		logger.Error("[Controller:Logout] %v", err)
 		logger.Error("[Controller:Logout] %v", err)
 	}
 	}
 
 

+ 8 - 10
ui/oauth2_callback.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/cookie"
 	"miniflux.app/http/cookie"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
@@ -20,8 +19,7 @@ import (
 
 
 // OAuth2Callback receives the authorization code and create a new session.
 // OAuth2Callback receives the authorization code and create a new session.
 func (c *Controller) OAuth2Callback(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) OAuth2Callback(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
+	sess := session.New(c.store, request.SessionID(r))
 
 
 	provider := request.Param(r, "provider", "")
 	provider := request.Param(r, "provider", "")
 	if provider == "" {
 	if provider == "" {
@@ -38,8 +36,8 @@ func (c *Controller) OAuth2Callback(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 
 
 	state := request.QueryParam(r, "state", "")
 	state := request.QueryParam(r, "state", "")
-	if state == "" || state != ctx.OAuth2State() {
-		logger.Error(`[OAuth2] Invalid state value: got "%s" instead of "%s"`, state, ctx.OAuth2State())
+	if state == "" || state != request.OAuth2State(r) {
+		logger.Error(`[OAuth2] Invalid state value: got "%s" instead of "%s"`, state, request.OAuth2State(r))
 		response.Redirect(w, r, route.Path(c.router, "login"))
 		response.Redirect(w, r, route.Path(c.router, "login"))
 		return
 		return
 	}
 	}
@@ -58,7 +56,7 @@ func (c *Controller) OAuth2Callback(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	if ctx.IsAuthenticated() {
+	if request.IsAuthenticated(r) {
 		user, err := c.store.UserByExtraField(profile.Key, profile.ID)
 		user, err := c.store.UserByExtraField(profile.Key, profile.ID)
 		if err != nil {
 		if err != nil {
 			html.ServerError(w, err)
 			html.ServerError(w, err)
@@ -66,18 +64,18 @@ func (c *Controller) OAuth2Callback(w http.ResponseWriter, r *http.Request) {
 		}
 		}
 
 
 		if user != nil {
 		if user != nil {
-			logger.Error("[OAuth2] User #%d cannot be associated because %s is already associated", ctx.UserID(), user.Username)
-			sess.NewFlashErrorMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("There is already someone associated with this provider!"))
+			logger.Error("[OAuth2] User #%d cannot be associated because %s is already associated", request.UserID(r), user.Username)
+			sess.NewFlashErrorMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("There is already someone associated with this provider!"))
 			response.Redirect(w, r, route.Path(c.router, "settings"))
 			response.Redirect(w, r, route.Path(c.router, "settings"))
 			return
 			return
 		}
 		}
 
 
-		if err := c.store.UpdateExtraField(ctx.UserID(), profile.Key, profile.ID); err != nil {
+		if err := c.store.UpdateExtraField(request.UserID(r), profile.Key, profile.ID); err != nil {
 			html.ServerError(w, err)
 			html.ServerError(w, err)
 			return
 			return
 		}
 		}
 
 
-		sess.NewFlashMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Your external account is now linked!"))
+		sess.NewFlashMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Your external account is now linked!"))
 		response.Redirect(w, r, route.Path(c.router, "settings"))
 		response.Redirect(w, r, route.Path(c.router, "settings"))
 		return
 		return
 	}
 	}

+ 1 - 3
ui/oauth2_redirect.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -17,8 +16,7 @@ import (
 
 
 // OAuth2Redirect redirects the user to the consent page to ask for permission.
 // OAuth2Redirect redirects the user to the consent page to ask for permission.
 func (c *Controller) OAuth2Redirect(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) OAuth2Redirect(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
+	sess := session.New(c.store, request.SessionID(r))
 
 
 	provider := request.Param(r, "provider", "")
 	provider := request.Param(r, "provider", "")
 	if provider == "" {
 	if provider == "" {

+ 5 - 7
ui/oauth2_unlink.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -32,26 +31,25 @@ func (c *Controller) OAuth2Unlink(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
+	sess := session.New(c.store, request.SessionID(r))
 
 
-	hasPassword, err := c.store.HasPassword(ctx.UserID())
+	hasPassword, err := c.store.HasPassword(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
 	}
 	}
 
 
 	if !hasPassword {
 	if !hasPassword {
-		sess.NewFlashErrorMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("You must define a password otherwise you won't be able to login again."))
+		sess.NewFlashErrorMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("You must define a password otherwise you won't be able to login again."))
 		response.Redirect(w, r, route.Path(c.router, "settings"))
 		response.Redirect(w, r, route.Path(c.router, "settings"))
 		return
 		return
 	}
 	}
 
 
-	if err := c.store.RemoveExtraField(ctx.UserID(), authProvider.GetUserExtraKey()); err != nil {
+	if err := c.store.RemoveExtraField(request.UserID(r), authProvider.GetUserExtraKey()); err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
 	}
 	}
 
 
-	sess.NewFlashMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Your external account is now dissociated!"))
+	sess.NewFlashMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Your external account is now dissociated!"))
 	response.Redirect(w, r, route.Path(c.router, "settings"))
 	response.Redirect(w, r, route.Path(c.router, "settings"))
 }
 }

+ 3 - 4
ui/opml_export.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/xml"
 	"miniflux.app/http/response/xml"
 	"miniflux.app/reader/opml"
 	"miniflux.app/reader/opml"
@@ -15,8 +15,7 @@ import (
 
 
 // Export generates the OPML file.
 // Export generates the OPML file.
 func (c *Controller) Export(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Export(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	opml, err := opml.NewHandler(c.store).Export(ctx.UserID())
+	opml, err := opml.NewHandler(c.store).Export(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 4 - 6
ui/opml_import.go

@@ -7,7 +7,7 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
@@ -15,16 +15,14 @@ import (
 
 
 // Import shows the import form.
 // Import shows the import form.
 func (c *Controller) Import(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Import(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("menu", "feeds")
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))

+ 4 - 6
ui/opml_upload.go

@@ -7,7 +7,7 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -19,9 +19,7 @@ import (
 
 
 // UploadOPML handles OPML file importation.
 // UploadOPML handles OPML file importation.
 func (c *Controller) UploadOPML(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UploadOPML(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -42,8 +40,8 @@ func (c *Controller) UploadOPML(w http.ResponseWriter, r *http.Request) {
 		fileHeader.Size,
 		fileHeader.Size,
 	)
 	)
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("menu", "feeds")
 	view.Set("menu", "feeds")
 	view.Set("user", user)
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))

+ 3 - 6
ui/search_entries.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,9 +17,7 @@ import (
 
 
 // ShowSearchEntries shows all entries for the given feed.
 // ShowSearchEntries shows all entries for the given feed.
 func (c *Controller) ShowSearchEntries(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowSearchEntries(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -48,8 +45,8 @@ func (c *Controller) ShowSearchEntries(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	pagination := c.getPagination(route.Path(c.router, "searchEntries"), count, offset)
 	pagination := c.getPagination(route.Path(c.router, "searchEntries"), count, offset)
 	pagination.SearchQuery = searchQuery
 	pagination.SearchQuery = searchQuery
 
 

+ 14 - 17
ui/session/session.go

@@ -6,67 +6,64 @@ package session // import "miniflux.app/ui/session"
 
 
 import (
 import (
 	"miniflux.app/crypto"
 	"miniflux.app/crypto"
-	"miniflux.app/http/context"
 	"miniflux.app/storage"
 	"miniflux.app/storage"
 )
 )
 
 
 // Session handles session data.
 // Session handles session data.
 type Session struct {
 type Session struct {
-	store *storage.Storage
-	ctx   *context.Context
+	store     *storage.Storage
+	sessionID string
 }
 }
 
 
 // NewOAuth2State generates a new OAuth2 state and stores the value into the database.
 // NewOAuth2State generates a new OAuth2 state and stores the value into the database.
 func (s *Session) NewOAuth2State() string {
 func (s *Session) NewOAuth2State() string {
 	state := crypto.GenerateRandomString(32)
 	state := crypto.GenerateRandomString(32)
-	s.store.UpdateSessionField(s.ctx.SessionID(), "oauth2_state", state)
+	s.store.UpdateSessionField(s.sessionID, "oauth2_state", state)
 	return state
 	return state
 }
 }
 
 
 // NewFlashMessage creates a new flash message.
 // NewFlashMessage creates a new flash message.
 func (s *Session) NewFlashMessage(message string) {
 func (s *Session) NewFlashMessage(message string) {
-	s.store.UpdateSessionField(s.ctx.SessionID(), "flash_message", message)
+	s.store.UpdateSessionField(s.sessionID, "flash_message", message)
 }
 }
 
 
 // FlashMessage returns the current flash message if any.
 // FlashMessage returns the current flash message if any.
-func (s *Session) FlashMessage() string {
-	message := s.ctx.FlashMessage()
+func (s *Session) FlashMessage(message string) string {
 	if message != "" {
 	if message != "" {
-		s.store.UpdateSessionField(s.ctx.SessionID(), "flash_message", "")
+		s.store.UpdateSessionField(s.sessionID, "flash_message", "")
 	}
 	}
 	return message
 	return message
 }
 }
 
 
 // NewFlashErrorMessage creates a new flash error message.
 // NewFlashErrorMessage creates a new flash error message.
 func (s *Session) NewFlashErrorMessage(message string) {
 func (s *Session) NewFlashErrorMessage(message string) {
-	s.store.UpdateSessionField(s.ctx.SessionID(), "flash_error_message", message)
+	s.store.UpdateSessionField(s.sessionID, "flash_error_message", message)
 }
 }
 
 
 // FlashErrorMessage returns the last flash error message if any.
 // FlashErrorMessage returns the last flash error message if any.
-func (s *Session) FlashErrorMessage() string {
-	message := s.ctx.FlashErrorMessage()
+func (s *Session) FlashErrorMessage(message string) string {
 	if message != "" {
 	if message != "" {
-		s.store.UpdateSessionField(s.ctx.SessionID(), "flash_error_message", "")
+		s.store.UpdateSessionField(s.sessionID, "flash_error_message", "")
 	}
 	}
 	return message
 	return message
 }
 }
 
 
 // SetLanguage updates the language field in session.
 // SetLanguage updates the language field in session.
 func (s *Session) SetLanguage(language string) {
 func (s *Session) SetLanguage(language string) {
-	s.store.UpdateSessionField(s.ctx.SessionID(), "language", language)
+	s.store.UpdateSessionField(s.sessionID, "language", language)
 }
 }
 
 
 // SetTheme updates the theme field in session.
 // SetTheme updates the theme field in session.
 func (s *Session) SetTheme(theme string) {
 func (s *Session) SetTheme(theme string) {
-	s.store.UpdateSessionField(s.ctx.SessionID(), "theme", theme)
+	s.store.UpdateSessionField(s.sessionID, "theme", theme)
 }
 }
 
 
 // SetPocketRequestToken updates Pocket Request Token.
 // SetPocketRequestToken updates Pocket Request Token.
 func (s *Session) SetPocketRequestToken(requestToken string) {
 func (s *Session) SetPocketRequestToken(requestToken string) {
-	s.store.UpdateSessionField(s.ctx.SessionID(), "pocket_request_token", requestToken)
+	s.store.UpdateSessionField(s.sessionID, "pocket_request_token", requestToken)
 }
 }
 
 
 // New returns a new session handler.
 // New returns a new session handler.
-func New(store *storage.Storage, ctx *context.Context) *Session {
-	return &Session{store, ctx}
+func New(store *storage.Storage, sessionID string) *Session {
+	return &Session{store, sessionID}
 }
 }

+ 5 - 7
ui/session_list.go

@@ -7,20 +7,18 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
+	"miniflux.app/http/request"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
-
-	"miniflux.app/http/context"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 )
 )
 
 
 // ShowSessions shows the list of active user sessions.
 // ShowSessions shows the list of active user sessions.
 func (c *Controller) ShowSessions(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowSessions(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -34,7 +32,7 @@ func (c *Controller) ShowSessions(w http.ResponseWriter, r *http.Request) {
 
 
 	sessions.UseTimezone(user.Timezone)
 	sessions.UseTimezone(user.Timezone)
 
 
-	view.Set("currentSessionToken", ctx.UserSessionToken())
+	view.Set("currentSessionToken", request.UserSessionToken(r))
 	view.Set("sessions", sessions)
 	view.Set("sessions", sessions)
 	view.Set("menu", "settings")
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("user", user)

+ 1 - 4
ui/session_remove.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -17,15 +16,13 @@ import (
 
 
 // RemoveSession remove a user session.
 // RemoveSession remove a user session.
 func (c *Controller) RemoveSession(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) RemoveSession(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
 	sessionID, err := request.IntParam(r, "sessionID")
 	sessionID, err := request.IntParam(r, "sessionID")
 	if err != nil {
 	if err != nil {
 		html.BadRequest(w, err)
 		html.BadRequest(w, err)
 		return
 		return
 	}
 	}
 
 
-	err = c.store.RemoveUserSessionByID(ctx.UserID(), sessionID)
+	err = c.store.RemoveUserSessionByID(request.UserID(r), sessionID)
 	if err != nil {
 	if err != nil {
 		logger.Error("[Controller:RemoveSession] %v", err)
 		logger.Error("[Controller:RemoveSession] %v", err)
 	}
 	}

+ 4 - 5
ui/settings_show.go

@@ -7,7 +7,7 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/locale"
 	"miniflux.app/locale"
 	"miniflux.app/model"
 	"miniflux.app/model"
@@ -18,11 +18,10 @@ import (
 
 
 // ShowSettings shows the settings page.
 // ShowSettings shows the settings page.
 func (c *Controller) ShowSettings(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowSettings(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 5 - 6
ui/settings_update.go

@@ -7,9 +7,9 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/locale"
 	"miniflux.app/locale"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
@@ -21,11 +21,10 @@ import (
 
 
 // UpdateSettings update the settings.
 // UpdateSettings update the settings.
 func (c *Controller) UpdateSettings(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UpdateSettings(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -70,6 +69,6 @@ func (c *Controller) UpdateSettings(w http.ResponseWriter, r *http.Request) {
 
 
 	sess.SetLanguage(user.Language)
 	sess.SetLanguage(user.Language)
 	sess.SetTheme(user.Theme)
 	sess.SetTheme(user.Theme)
-	sess.NewFlashMessage(c.translator.GetLanguage(ctx.UserLanguage()).Get("Preferences saved!"))
+	sess.NewFlashMessage(c.translator.GetLanguage(request.UserLanguage(r)).Get("Preferences saved!"))
 	response.Redirect(w, r, route.Path(c.router, "settings"))
 	response.Redirect(w, r, route.Path(c.router, "settings"))
 }
 }

+ 3 - 5
ui/static_manifest.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/response/json"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/model"
 	"miniflux.app/model"
@@ -32,9 +32,7 @@ func (c *Controller) WebManifest(w http.ResponseWriter, r *http.Request) {
 		BackgroundColor string            `json:"background_color"`
 		BackgroundColor string            `json:"background_color"`
 	}
 	}
 
 
-	ctx := context.New(r)
-	themeColor := model.ThemeColor(ctx.UserTheme())
-
+	themeColor := model.ThemeColor(request.UserTheme(r))
 	manifest := &webManifest{
 	manifest := &webManifest{
 		Name:            "Miniflux",
 		Name:            "Miniflux",
 		ShortName:       "Miniflux",
 		ShortName:       "Miniflux",

+ 4 - 5
ui/subscription_add.go

@@ -7,19 +7,18 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
 )
 )
 
 
 // AddSubscription shows the form to add a new feed.
 // AddSubscription shows the form to add a new feed.
 func (c *Controller) AddSubscription(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) AddSubscription(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 3 - 5
ui/subscription_bookmarklet.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -17,11 +16,10 @@ import (
 
 
 // Bookmarklet prefill the form to add a subscription from the URL provided by the bookmarklet.
 // Bookmarklet prefill the form to add a subscription from the URL provided by the bookmarklet.
 func (c *Controller) Bookmarklet(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) Bookmarklet(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 4 - 5
ui/subscription_choose.go

@@ -7,9 +7,9 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
@@ -18,11 +18,10 @@ import (
 
 
 // ChooseSubscription shows a page to choose a subscription.
 // ChooseSubscription shows a page to choose a subscription.
 func (c *Controller) ChooseSubscription(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ChooseSubscription(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 5 - 6
ui/subscription_submit.go

@@ -7,9 +7,9 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
 	"miniflux.app/reader/subscription"
 	"miniflux.app/reader/subscription"
@@ -20,11 +20,10 @@ import (
 
 
 // SubmitSubscription try to find a feed from the URL provided by the user.
 // SubmitSubscription try to find a feed from the URL provided by the user.
 func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	v := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	v := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -89,7 +88,7 @@ func (c *Controller) SubmitSubscription(w http.ResponseWriter, r *http.Request)
 
 
 		response.Redirect(w, r, route.Path(c.router, "feedEntries", "feedID", feed.ID))
 		response.Redirect(w, r, route.Path(c.router, "feedEntries", "feedID", feed.ID))
 	case n > 1:
 	case n > 1:
-		v := view.New(c.tpl, ctx, sess)
+		v := view.New(c.tpl, r, sess)
 		v.Set("subscriptions", subscriptions)
 		v.Set("subscriptions", subscriptions)
 		v.Set("form", subscriptionForm)
 		v.Set("form", subscriptionForm)
 		v.Set("menu", "feeds")
 		v.Set("menu", "feeds")

+ 3 - 5
ui/unread_entries.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
@@ -18,11 +17,10 @@ import (
 
 
 // ShowUnreadPage render the page with all unread entries.
 // ShowUnreadPage render the page with all unread entries.
 func (c *Controller) ShowUnreadPage(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowUnreadPage(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 3 - 3
ui/unread_mark_all_read.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
@@ -15,7 +15,7 @@ import (
 
 
 // MarkAllAsRead marks all unread entries as read.
 // MarkAllAsRead marks all unread entries as read.
 func (c *Controller) MarkAllAsRead(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) MarkAllAsRead(w http.ResponseWriter, r *http.Request) {
-	if err := c.store.MarkAllAsRead(context.New(r).UserID()); err != nil {
+	if err := c.store.MarkAllAsRead(request.UserID(r)); err != nil {
 		logger.Error("[MarkAllAsRead] %v", err)
 		logger.Error("[MarkAllAsRead] %v", err)
 	}
 	}
 
 

+ 5 - 6
ui/user_create.go

@@ -2,12 +2,12 @@
 // Use of this source code is governed by the Apache 2.0
 // Use of this source code is governed by the Apache 2.0
 // license that can be found in the LICENSE file.
 // license that can be found in the LICENSE file.
 
 
-package ui  // import "miniflux.app/ui"
+package ui // import "miniflux.app/ui"
 
 
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
+	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
@@ -16,11 +16,10 @@ import (
 
 
 // CreateUser shows the user creation form.
 // CreateUser shows the user creation form.
 func (c *Controller) CreateUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) CreateUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 3 - 5
ui/user_edit.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -17,11 +16,10 @@ import (
 
 
 // EditUser shows the form to edit a user.
 // EditUser shows the form to edit a user.
 func (c *Controller) EditUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) EditUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 4 - 5
ui/user_list.go

@@ -7,19 +7,18 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/view"
 	"miniflux.app/ui/view"
 )
 )
 
 
 // ShowUsers renders the list of users.
 // ShowUsers renders the list of users.
 func (c *Controller) ShowUsers(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) ShowUsers(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 
 
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 1 - 4
ui/user_remove.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -16,9 +15,7 @@ import (
 
 
 // RemoveUser deletes a user from the database.
 // RemoveUser deletes a user from the database.
 func (c *Controller) RemoveUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) RemoveUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return

+ 4 - 6
ui/user_save.go

@@ -7,9 +7,9 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
+	"miniflux.app/http/request"
 	"miniflux.app/http/route"
 	"miniflux.app/http/route"
 	"miniflux.app/logger"
 	"miniflux.app/logger"
 	"miniflux.app/ui/form"
 	"miniflux.app/ui/form"
@@ -19,9 +19,7 @@ import (
 
 
 // SaveUser validate and save the new user into the database.
 // SaveUser validate and save the new user into the database.
 func (c *Controller) SaveUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) SaveUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -34,8 +32,8 @@ func (c *Controller) SaveUser(w http.ResponseWriter, r *http.Request) {
 
 
 	userForm := form.NewUserForm(r)
 	userForm := form.NewUserForm(r)
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("menu", "settings")
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))

+ 3 - 6
ui/user_update.go

@@ -7,7 +7,6 @@ package ui  // import "miniflux.app/ui"
 import (
 import (
 	"net/http"
 	"net/http"
 
 
-	"miniflux.app/http/context"
 	"miniflux.app/http/request"
 	"miniflux.app/http/request"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response"
 	"miniflux.app/http/response/html"
 	"miniflux.app/http/response/html"
@@ -20,9 +19,7 @@ import (
 
 
 // UpdateUser validate and update a user.
 // UpdateUser validate and update a user.
 func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
 func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
-	ctx := context.New(r)
-
-	user, err := c.store.UserByID(ctx.UserID())
+	user, err := c.store.UserByID(request.UserID(r))
 	if err != nil {
 	if err != nil {
 		html.ServerError(w, err)
 		html.ServerError(w, err)
 		return
 		return
@@ -52,8 +49,8 @@ func (c *Controller) UpdateUser(w http.ResponseWriter, r *http.Request) {
 
 
 	userForm := form.NewUserForm(r)
 	userForm := form.NewUserForm(r)
 
 
-	sess := session.New(c.store, ctx)
-	view := view.New(c.tpl, ctx, sess)
+	sess := session.New(c.store, request.SessionID(r))
+	view := view.New(c.tpl, r, sess)
 	view.Set("menu", "settings")
 	view.Set("menu", "settings")
 	view.Set("user", user)
 	view.Set("user", user)
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))
 	view.Set("countUnread", c.store.CountUnreadEntries(user.ID))

+ 11 - 9
ui/view/view.go

@@ -5,7 +5,9 @@
 package view // import "miniflux.app/ui/view"
 package view // import "miniflux.app/ui/view"
 
 
 import (
 import (
-	"miniflux.app/http/context"
+	"net/http"
+
+	"miniflux.app/http/request"
 	"miniflux.app/template"
 	"miniflux.app/template"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/session"
 	"miniflux.app/ui/static"
 	"miniflux.app/ui/static"
@@ -14,7 +16,7 @@ import (
 // View wraps template argument building.
 // View wraps template argument building.
 type View struct {
 type View struct {
 	tpl    *template.Engine
 	tpl    *template.Engine
-	ctx    *context.Context
+	r      *http.Request
 	params map[string]interface{}
 	params map[string]interface{}
 }
 }
 
 
@@ -26,17 +28,17 @@ func (v *View) Set(param string, value interface{}) *View {
 
 
 // Render executes the template with arguments.
 // Render executes the template with arguments.
 func (v *View) Render(template string) []byte {
 func (v *View) Render(template string) []byte {
-	return v.tpl.Render(template, v.ctx.UserLanguage(), v.params)
+	return v.tpl.Render(template, request.UserLanguage(v.r), v.params)
 }
 }
 
 
 // New returns a new view with default parameters.
 // New returns a new view with default parameters.
-func New(tpl *template.Engine, ctx *context.Context, sess *session.Session) *View {
-	b := &View{tpl, ctx, make(map[string]interface{})}
-	theme := ctx.UserTheme()
+func New(tpl *template.Engine, r *http.Request, sess *session.Session) *View {
+	b := &View{tpl, r, make(map[string]interface{})}
+	theme := request.UserTheme(r)
 	b.params["menu"] = ""
 	b.params["menu"] = ""
-	b.params["csrf"] = ctx.CSRF()
-	b.params["flashMessage"] = sess.FlashMessage()
-	b.params["flashErrorMessage"] = sess.FlashErrorMessage()
+	b.params["csrf"] = request.CSRF(r)
+	b.params["flashMessage"] = sess.FlashMessage(request.FlashMessage(r))
+	b.params["flashErrorMessage"] = sess.FlashErrorMessage(request.FlashErrorMessage(r))
 	b.params["theme"] = theme
 	b.params["theme"] = theme
 	b.params["theme_checksum"] = static.StylesheetsChecksums[theme]
 	b.params["theme_checksum"] = static.StylesheetsChecksums[theme]
 	b.params["app_js_checksum"] = static.JavascriptsChecksums["app"]
 	b.params["app_js_checksum"] = static.JavascriptsChecksums["app"]