pass token in the headers in debug mode

This commit is contained in:
Vladimir Krivosheev
2016-04-27 12:53:35 +02:00
parent 332cdcf97d
commit 275c227e83
5 changed files with 47 additions and 7 deletions
@@ -40,6 +40,11 @@ import java.util.List;
public class BuiltInWebBrowserUrlProvider extends WebBrowserUrlProvider implements DumbAware {
@NotNull
public static List<Url> getUrls(@NotNull VirtualFile file, @NotNull Project project, @Nullable String currentAuthority) {
return getUrls(file, project, currentAuthority, true);
}
@NotNull
public static List<Url> getUrls(@NotNull VirtualFile file, @NotNull Project project, @Nullable String currentAuthority, boolean appendAccessToken) {
if (currentAuthority != null && !compareAuthority(currentAuthority)) {
return Collections.emptyList();
}
@@ -53,7 +58,7 @@ public class BuiltInWebBrowserUrlProvider extends WebBrowserUrlProvider implemen
String path = info.getPath();
String authority = currentAuthority == null ? "localhost:" + effectiveBuiltInServerPort : currentAuthority;
String query = "?" + BuiltInWebServerKt.TOKEN_PARAM_NAME + "=" + BuiltInWebServerKt.acquireToken();
String query = appendAccessToken ? "?" + BuiltInWebServerKt.TOKEN_PARAM_NAME + "=" + BuiltInWebServerKt.acquireToken() : "";
List<Url> urls = new SmartList<>(Urls.newHttpUrl(authority, '/' + project.getName() + '/' + path, query));
String path2 = info.getRootLessPathIfPossible();
@@ -118,7 +123,7 @@ public class BuiltInWebBrowserUrlProvider extends WebBrowserUrlProvider implemen
return Urls.newFromVirtualFile(file);
}
else {
return ContainerUtil.getFirstItem(getUrls(file, request.getProject(), null));
return ContainerUtil.getFirstItem(getUrls(file, request.getProject(), null, request.isAppendAccessToken()));
}
}
}
@@ -108,6 +108,7 @@ class BuiltInWebServer : HttpRequestHandler() {
internal fun isActivatable() = Registry.`is`("ide.built.in.web.server.activatable", false)
internal const val TOKEN_PARAM_NAME = "_ijt"
const val TOKEN_HEADER_NAME = "x-ijt"
private val STANDARD_COOKIE by lazy {
val productName = ApplicationNamesInfo.getInstance().lowercaseProductName
@@ -139,7 +140,7 @@ private val STANDARD_COOKIE by lazy {
// expire after access because we reuse tokens
private val tokens = CacheBuilder.newBuilder().expireAfterAccess(1, TimeUnit.MINUTES).build<String, Boolean>()
internal fun acquireToken(): String {
fun acquireToken(): String {
var token = tokens.asMap().keys.firstOrNull()
if (token == null) {
token = TokenGenerator.generate()
@@ -252,7 +253,9 @@ internal fun validateToken(request: HttpRequest, channel: Channel): HttpHeaders?
val urlDecoder = QueryStringDecoder(request.uri())
// we must check referrer - if html cached, browser will send request without query
val token = urlDecoder.parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() ?: request.referrer?.let { QueryStringDecoder(it).parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() }
val token = request.headers().get(TOKEN_HEADER_NAME)
?: urlDecoder.parameters().get(TOKEN_PARAM_NAME)?.firstOrNull()
?: request.referrer?.let { QueryStringDecoder(it).parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() }
val url = "${channel.uriScheme}://${request.host!!}${urlDecoder.path()}"
if (token != null && tokens.getIfPresent(token) != null) {
tokens.invalidate(token)
@@ -24,7 +24,7 @@ import io.netty.handler.codec.http.QueryStringDecoder
internal abstract class DelegatingHttpRequestHandlerBase : SimpleChannelInboundHandlerAdapter<FullHttpRequest>() {
override fun messageReceived(context: ChannelHandlerContext, message: FullHttpRequest) {
Logger.getInstance(BuiltInServer::class.java).debug { "IN HTTP: $message" }
Logger.getInstance(BuiltInServer::class.java).debug { "\n\nIN HTTP: $message\n\n" }
if (!process(context, message, QueryStringDecoder(message.uri()))) {
HttpResponseStatus.NOT_FOUND.send(context.channel(), message)
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2015 JetBrains s.r.o.
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -94,7 +94,14 @@ public class WebBrowserServiceImpl extends WebBrowserService {
public static Collection<Url> getDebuggableUrls(@Nullable PsiElement context) {
try {
OpenInBrowserRequest request = context == null ? null : OpenInBrowserRequest.create(context);
return request == null || request.getFile().getViewProvider().getBaseLanguage() == XMLLanguage.INSTANCE ? Collections.<Url>emptyList() : getUrls(getProvider(request), request);
if (request == null || request.getFile().getViewProvider().getBaseLanguage() == XMLLanguage.INSTANCE) {
return Collections.<Url>emptyList();
}
else {
// it is client responsibility to set token
request.setAppendAccessToken(false);
return getUrls(getProvider(request), request);
}
}
catch (WebBrowserUrlProvider.BrowserException ignored) {
return Collections.emptyList();
@@ -1,3 +1,18 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.intellij.ide.browsers;
import com.intellij.openapi.application.AccessToken;
@@ -15,6 +30,8 @@ import java.util.Collection;
public abstract class OpenInBrowserRequest {
private Collection<Url> result;
protected PsiFile file;
private boolean appendAccessToken = true;
public OpenInBrowserRequest(@NotNull PsiFile file) {
this.file = file;
@@ -72,4 +89,12 @@ public abstract class OpenInBrowserRequest {
public Collection<Url> getResult() {
return result;
}
public boolean isAppendAccessToken() {
return appendAccessToken;
}
public void setAppendAccessToken(boolean value) {
this.appendAccessToken = value;
}
}