@@ -74,12 +74,10 @@ func (s *Server) serveDetails(w http.ResponseWriter, r *http.Request) (err error
74
74
if err := validatePathAndVersion (ctx , s .ds , urlInfo .fullPath , urlInfo .requestedVersion ); err != nil {
75
75
return err
76
76
}
77
- var (
78
- resolvedModulePath = urlInfo .modulePath
79
- resolvedVersion = urlInfo .requestedVersion
80
- )
77
+
78
+ urlInfo .resolvedVersion = urlInfo .requestedVersion
81
79
if experiment .IsActive (ctx , internal .ExperimentUsePathInfo ) {
82
- resolvedModulePath , resolvedVersion , _ , err = s .ds .GetPathInfo (ctx , urlInfo .fullPath , urlInfo .modulePath , urlInfo .requestedVersion )
80
+ resolvedModulePath , resolvedVersion , _ , err : = s .ds .GetPathInfo (ctx , urlInfo .fullPath , urlInfo .modulePath , urlInfo .requestedVersion )
83
81
if err != nil {
84
82
if ! errors .Is (err , derrors .NotFound ) {
85
83
return err
@@ -90,50 +88,102 @@ func (s *Server) serveDetails(w http.ResponseWriter, r *http.Request) (err error
90
88
}
91
89
return s .servePathNotFoundPage (w , r , urlInfo .fullPath , urlInfo .modulePath , urlInfo .requestedVersion , pathType )
92
90
}
91
+ urlInfo .modulePath = resolvedModulePath
92
+ urlInfo .resolvedVersion = resolvedVersion
93
+
94
+ if isActivePathAtMaster (ctx ) && urlInfo .requestedVersion == internal .MasterVersion {
95
+ // Since path@master is a moving target, we don't want it to be stale.
96
+ // As a result, we enqueue every request of path@master to the frontend
97
+ // task queue, which will initiate a fetch request depending on the
98
+ // last time we tried to fetch this module version.
99
+ go func () {
100
+ if err := s .queue .ScheduleFetch (ctx , urlInfo .modulePath , internal .MasterVersion , "" , s .taskIDChangeInterval ); err != nil {
101
+ log .Errorf (ctx , "serveDetails(%q): %v" , r .URL .Path , err )
102
+ }
103
+ }()
104
+ }
93
105
}
94
- if isActivePathAtMaster (ctx ) && urlInfo .requestedVersion == internal .MasterVersion {
95
- // Since path@master is a moving target, we don't want it to be stale.
96
- // As a result, we enqueue every request of path@master to the frontend
97
- // task queue, which will initiate a fetch request depending on the
98
- // last time we tried to fetch this module version.
99
- go func () {
100
- if err := s .queue .ScheduleFetch (ctx , resolvedModulePath , internal .MasterVersion , "" , s .taskIDChangeInterval ); err != nil {
101
- log .Errorf (ctx , "serveDetails(%q): %v" , r .URL .Path , err )
102
- }
103
- }()
106
+ if isActiveUseDirectories (ctx ) {
107
+ return s .serveDetailsPage (w , r , urlInfo )
104
108
}
105
- // Depending on what the request was for, return the module or package page.
106
- if urlInfo .isModule || urlInfo .fullPath == stdlib .ModulePath {
107
- return s .legacyServeModulePage (w , r , urlInfo .fullPath , urlInfo .requestedVersion , resolvedVersion )
109
+ return s .legacyServeDetailsPage (w , r , urlInfo )
110
+ }
111
+
112
+ // serveDetailsPage serves a details page for a path using the paths,
113
+ // modules, documentation, readmes, licenses, and package_imports tables.
114
+ func (s * Server ) serveDetailsPage (w http.ResponseWriter , r * http.Request , info * urlPathInfo ) (err error ) {
115
+ defer derrors .Wrap (& err , "serveDetailsPage(w, r, %v)" , info )
116
+ ctx := r .Context ()
117
+ vdir , err := s .ds .GetDirectoryNew (ctx , info .fullPath , info .modulePath , info .resolvedVersion )
118
+ if err != nil {
119
+ return err
108
120
}
109
- if isActiveUseDirectories (ctx ) {
110
- return s .servePackagePageNew (w , r , urlInfo .fullPath , resolvedModulePath , urlInfo .requestedVersion , resolvedVersion )
121
+ switch {
122
+ case info .isModule :
123
+ var readme * internal.Readme
124
+ if vdir .Readme != nil {
125
+ readme = & internal.Readme {Filepath : vdir .Readme .Filepath , Contents : vdir .Readme .Contents }
126
+ }
127
+ return s .serveModulePageWithModule (ctx , w , r , & vdir .ModuleInfo , readme , info .requestedVersion )
128
+ case vdir .Package != nil :
129
+ return s .servePackagePageWithVersionedDirectory (ctx , w , r , vdir , info .requestedVersion )
130
+ default :
131
+ // TODO(https://golang.org/issue/39629): add function to get
132
+ // subdirectories from the paths table, and deprecate LegacyGetDirectory.
133
+ dir , err := s .ds .LegacyGetDirectory (ctx , info .fullPath , info .modulePath , info .resolvedVersion , internal .AllFields )
134
+ if err != nil {
135
+ return err
136
+ }
137
+ return s .legacyServeDirectoryPage (ctx , w , r , dir , info .requestedVersion )
111
138
}
112
- return s .legacyServePackagePage (w , r , urlInfo .fullPath , resolvedModulePath , urlInfo .requestedVersion , resolvedVersion )
139
+ }
140
+
141
+ // legacyServeDetailsPage serves a details page for a path using the packages,
142
+ // modules, licenses and imports tables.
143
+ func (s * Server ) legacyServeDetailsPage (w http.ResponseWriter , r * http.Request , info * urlPathInfo ) (err error ) {
144
+ defer derrors .Wrap (& err , "legacyServeDetailsPage(w, r, %v)" , info )
145
+ if info .isModule {
146
+ return s .legacyServeModulePage (w , r , info .fullPath , info .requestedVersion , info .resolvedVersion )
147
+ }
148
+ return s .legacyServePackagePage (w , r , info .fullPath , info .modulePath , info .requestedVersion , info .resolvedVersion )
113
149
}
114
150
115
151
type urlPathInfo struct {
116
- fullPath , modulePath , requestedVersion string
117
- isModule bool
118
- urlPath string
152
+ // fullPath is the full import path corresponding to the requested
153
+ // package/module/directory page.
154
+ fullPath string
155
+ // isModule indicates whether the /mod page should be shown.
156
+ isModule bool
157
+ // modulePath is the path of the module corresponding to the fullPath and
158
+ // resolvedVersion. If unknown, it is set to internal.UnknownModulePath.
159
+ modulePath string
160
+ // requestedVersion is the version requested by the user, which will be one
161
+ // of the following: "latest", "master", a Go version tag, or a semantic
162
+ // version.
163
+ requestedVersion string
164
+ // resolvedVersion is the semantic version stored in the database.
165
+ resolvedVersion string
119
166
}
120
167
121
168
func extractURLPathInfo (urlPath string ) (_ * urlPathInfo , err error ) {
122
169
defer derrors .Wrap (& err , "extractURLPathInfo(%q)" , urlPath )
123
170
124
- info := & urlPathInfo {urlPath : urlPath }
171
+ info := & urlPathInfo {}
125
172
if strings .HasPrefix (urlPath , "/mod/" ) {
126
- info . urlPath = strings .TrimPrefix (urlPath , "/mod" )
173
+ urlPath = strings .TrimPrefix (urlPath , "/mod" )
127
174
info .isModule = true
128
175
}
129
176
// Parse the fullPath, modulePath and requestedVersion, based on whether
130
177
// the path is in the stdlib. If unable to parse these elements, return
131
178
// http.StatusBadRequest.
132
- if parts := strings .SplitN (strings .TrimPrefix (info . urlPath , "/" ), "@" , 2 ); stdlib .Contains (parts [0 ]) {
133
- info .fullPath , info .requestedVersion , err = parseStdLibURLPath (info . urlPath )
179
+ if parts := strings .SplitN (strings .TrimPrefix (urlPath , "/" ), "@" , 2 ); stdlib .Contains (parts [0 ]) {
180
+ info .fullPath , info .requestedVersion , err = parseStdLibURLPath (urlPath )
134
181
info .modulePath = stdlib .ModulePath
182
+ if info .fullPath == stdlib .ModulePath {
183
+ info .isModule = true
184
+ }
135
185
} else {
136
- info .fullPath , info .modulePath , info .requestedVersion , err = parseDetailsURLPath (info . urlPath )
186
+ info .fullPath , info .modulePath , info .requestedVersion , err = parseDetailsURLPath (urlPath )
137
187
}
138
188
if err != nil {
139
189
return nil , err
0 commit comments