Пример #1
0
// WithValidateBaseURL is a middleware which checks if the request base URL
// is equal to the one store in the configuration, if not
// i.e. redirect from http://example.com/store/ to http://www.example.com/store/
// @see app/code/Magento/Store/App/FrontController/Plugin/RequestPreprocessor.php
func WithValidateBaseURL(cr config.ReaderPubSuber) ctxhttp.Middleware {

	// Having the GetBool command here, means you must restart the app to take
	// changes in effect. @todo refactor and use pub/sub to automatically change
	// the isRedirectToBase value.
	checkBaseURL, err := cr.GetBool(config.Path(PathRedirectToBase)) // scope default
	if config.NotKeyNotFoundError(err) && PkgLog.IsDebug() {
		PkgLog.Debug("ctxhttp.WithValidateBaseUrl.GetBool", "err", err, "path", PathRedirectToBase)
	}

	redirectCode := http.StatusMovedPermanently
	if rc, err := cr.GetInt(config.Path(PathRedirectToBase)); rc != redirectCode && false == config.NotKeyNotFoundError(err) {
		redirectCode = http.StatusFound
	}

	return func(h ctxhttp.Handler) ctxhttp.Handler {
		return ctxhttp.HandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {

			if checkBaseURL && r.Method != "POST" {

				_, requestedStore, err := FromContextReader(ctx)
				if err != nil {
					if PkgLog.IsDebug() {
						PkgLog.Debug("ctxhttp.WithValidateBaseUrl.FromContextServiceReader", "err", err, "ctx", ctx)
					}
					return errgo.Mask(err)
				}

				baseURL, err := requestedStore.BaseURL(config.URLTypeWeb, requestedStore.IsCurrentlySecure(r))
				if err != nil {
					if PkgLog.IsDebug() {
						PkgLog.Debug("ctxhttp.WithValidateBaseUrl.requestedStore.BaseURL", "err", err, "ctx", ctx)
					}
					return errgo.Mask(err)
				}

				if err := httputils.IsBaseURLCorrect(r, &baseURL); err != nil {
					if PkgLog.IsDebug() {
						PkgLog.Debug("store.WithValidateBaseUrl.IsBaseUrlCorrect.error", "err", err, "baseURL", baseURL, "request", r)
					}

					baseURL.Path = r.URL.Path
					baseURL.RawPath = r.URL.RawPath
					baseURL.RawQuery = r.URL.RawQuery
					baseURL.Fragment = r.URL.Fragment
					http.Redirect(w, r, (&baseURL).String(), redirectCode)
					return nil
				}
			}
			return h.ServeHTTPContext(ctx, w, r)
		})
	}
}
Пример #2
0
func TestIsBaseUrlCorrect(t *testing.T) {

	var nr = func(urlStr string) *http.Request {
		r, err := http.NewRequest("GET", urlStr, nil)
		if err != nil {
			t.Fatal(err)
		}
		return r
	}

	var pu = func(rawURL string) *url.URL {
		u, err := url.Parse(rawURL)
		if err != nil {
			t.Fatal(err)
		}
		return u
	}

	tests := []struct {
		req         *http.Request
		haveBaseURL *url.URL
		wantErr     error
	}{
		{nr("http://corestore.io/"), pu("http://corestore.io/"), nil},
		{nr("http://www.corestore.io/"), pu("http://corestore.io/"), httputils.ErrBaseURLDoNotMatch},
		{nr("http://corestore.io/"), pu("https://corestore.io/"), httputils.ErrBaseURLDoNotMatch},
		{nr("http://corestore.io/"), pu("http://corestore.io/subpath"), httputils.ErrBaseURLDoNotMatch},
		{nr("http://corestore.io/subpath"), pu("http://corestore.io/subpath"), nil},
		{nr("http://corestore.io/"), pu("http://corestore.io/"), nil},
		{nr("http://corestore.io/subpath/catalog/product/list"), pu("http://corestore.io/subpath"), nil},
	}
	for i, test := range tests {
		haveErr := httputils.IsBaseURLCorrect(test.req, test.haveBaseURL)
		if test.wantErr != nil {
			assert.EqualError(t, haveErr, test.wantErr.Error(), "Index %d", i)
		} else {
			assert.NoError(t, haveErr, "Index %d", i)
		}
	}
}