@@ -110,14 +110,9 @@ func (s *Server) handleSearch(w http.ResponseWriter, r *http.Request) {
110
110
return
111
111
}
112
112
113
- if strings .Contains (query , "/" ) {
114
- pkg , err := s .ds .GetPackage (ctx , path .Clean (query ), internal .UnknownModulePath , internal .LatestVersion )
115
- if err == nil {
116
- http .Redirect (w , r , fmt .Sprintf ("/%s" , pkg .Path ), http .StatusFound )
117
- return
118
- } else if ! errors .Is (err , derrors .NotFound ) {
119
- log .Errorf (ctx , "error getting package for %s: %v" , path .Clean (query ), err )
120
- }
113
+ if path := searchRequestRedirectPath (ctx , s .ds , query ); path != "" {
114
+ http .Redirect (w , r , path , http .StatusFound )
115
+ return
121
116
}
122
117
123
118
page , err := fetchSearchPage (ctx , s .ds , query , newPaginationParams (r , defaultSearchLimit ))
@@ -130,6 +125,41 @@ func (s *Server) handleSearch(w http.ResponseWriter, r *http.Request) {
130
125
s .servePage (ctx , w , "search.tmpl" , page )
131
126
}
132
127
128
+ // searchRequestRedirectPath returns the path that a search request should be
129
+ // redirected to, or the empty string if there is no such path. Standard
130
+ // library packages that only contain one element (such as fmt, errors, etc.)
131
+ // will not redirect to allow users to search by those terms.
132
+ func searchRequestRedirectPath (ctx context.Context , ds internal.DataSource , query string ) string {
133
+ requestedPath := path .Clean (query )
134
+ if ! strings .Contains (requestedPath , "/" ) {
135
+ return ""
136
+ }
137
+ pkg , err := ds .GetPackage (ctx , requestedPath , internal .UnknownModulePath , internal .LatestVersion )
138
+ if err == nil {
139
+ return fmt .Sprintf ("/%s" , pkg .Path )
140
+ } else if ! errors .Is (err , derrors .NotFound ) {
141
+ log .Errorf (ctx , "error getting package for %s: %v" , requestedPath , err )
142
+ return ""
143
+ }
144
+
145
+ vi , err := ds .GetVersionInfo (ctx , requestedPath , internal .LatestVersion )
146
+ if err == nil {
147
+ return fmt .Sprintf ("/mod/%s" , vi .ModulePath )
148
+ } else if ! errors .Is (err , derrors .NotFound ) {
149
+ log .Errorf (ctx , "error getting module for %s: %v" , requestedPath , err )
150
+ return ""
151
+ }
152
+
153
+ dir , err := ds .GetDirectory (ctx , requestedPath , internal .UnknownModulePath , internal .LatestVersion , internal .AllFields )
154
+ if err == nil {
155
+ return fmt .Sprintf ("/%s" , dir .Path )
156
+ } else if ! errors .Is (err , derrors .NotFound ) {
157
+ log .Errorf (ctx , "error getting directory for %s: %v" , requestedPath , err )
158
+ return ""
159
+ }
160
+ return ""
161
+ }
162
+
133
163
// searchQuery extracts a search query from the request.
134
164
func searchQuery (r * http.Request ) string {
135
165
return strings .TrimSpace (r .FormValue ("q" ))
0 commit comments