IDEA-155360 Open In Browser : files from library jars cannot be opened
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Thu, 28 Apr 2016 16:09:07 +0000 (18:09 +0200)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Thu, 28 Apr 2016 16:09:07 +0000 (18:09 +0200)
platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerPathHandler.kt

index dae131732a646021e0e5ab4e6d28287e939820c5..513a36b4a38fb46498b53bda7a9bc02067ddcd24 100644 (file)
@@ -248,11 +248,25 @@ private fun doProcess(urlDecoder: QueryStringDecoder, request: FullHttpRequest,
   return false
 }
 
-internal fun validateToken(request: HttpRequest, channel: Channel): HttpHeaders? {
-  val cookieString = request.headers().get(HttpHeaderNames.COOKIE)
-  if (cookieString != null) {
-    val cookies = ServerCookieDecoder.STRICT.decode(cookieString)
-    for (cookie in cookies) {
+internal fun HttpRequest.isSignedRequest(): Boolean {
+  // we must check referrer - if html cached, browser will send request without query
+  val token = headers().get(TOKEN_HEADER_NAME)
+      ?: QueryStringDecoder(uri()).parameters().get(TOKEN_PARAM_NAME)?.firstOrNull()
+      ?: referrer?.let { QueryStringDecoder(it).parameters().get(TOKEN_PARAM_NAME)?.firstOrNull() }
+
+  if (token != null && tokens.getIfPresent(token) != null) {
+    tokens.invalidate(token)
+    return true
+  }
+  else {
+    return false
+  }
+}
+
+@JvmOverloads
+internal fun validateToken(request: HttpRequest, channel: Channel, isSignedRequest: Boolean = request.isSignedRequest()): HttpHeaders? {
+  request.headers().get(HttpHeaderNames.COOKIE)?.let {
+    for (cookie in ServerCookieDecoder.STRICT.decode(it)) {
       if (cookie.name() == STANDARD_COOKIE.name()) {
         if (cookie.value() == STANDARD_COOKIE.value()) {
           return EmptyHttpHeaders.INSTANCE
@@ -262,18 +276,13 @@ 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 = 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)
+  if (isSignedRequest) {
     return DefaultHttpHeaders().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(STANDARD_COOKIE) + "; SameSite=strict")
   }
 
+  val urlDecoder = QueryStringDecoder(request.uri())
   if (!urlDecoder.path().endsWith("/favicon.ico")) {
+    val url = "${channel.uriScheme}://${request.host!!}${urlDecoder.path()}"
     SwingUtilities.invokeAndWait {
       ProjectUtil.focusProjectWindow(null, true)
 
index e88bb2c9819340c329c44d654e8e0baef4839513..7f8c575a1a9bacdd02fc31b57ae58d12d01f38ba 100644 (file)
@@ -41,7 +41,8 @@ private class DefaultWebServerPathHandler : WebServerPathHandler() {
                        projectName: String,
                        decodedRawPath: String,
                        isCustomHost: Boolean): Boolean {
-    val extraHttpHeaders = validateToken(request, context.channel()) ?: return true
+    val isSignedRequest = request.isSignedRequest()
+    val extraHttpHeaders = validateToken(request, context.channel(), isSignedRequest) ?: return true
 
     val channel = context.channel()
     val pathToFileManager = WebServerPathToFileManager.getInstance(project)
@@ -89,7 +90,7 @@ private class DefaultWebServerPathHandler : WebServerPathHandler() {
     }
 
     // if extraHttpHeaders is not empty, it means that we get request wih token in the query
-    if (extraHttpHeaders.isEmpty && request.origin == null && request.referrer == null && request.isRegularBrowser() && !canBeAccessedDirectly(pathInfo.name)) {
+    if (!isSignedRequest && request.origin == null && request.referrer == null && request.isRegularBrowser() && !canBeAccessedDirectly(pathInfo.name)) {
       HttpResponseStatus.NOT_FOUND.send(context.channel(), request)
       return true
     }