dart/php handler — don't use redirect to set cookie
authorVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Tue, 26 Apr 2016 14:30:01 +0000 (16:30 +0200)
committerVladimir Krivosheev <vladimir.krivosheev@jetbrains.com>
Tue, 26 Apr 2016 14:30:01 +0000 (16:30 +0200)
platform/built-in-server/src/org/jetbrains/builtInWebServer/BuiltInWebServer.kt
platform/built-in-server/src/org/jetbrains/builtInWebServer/DefaultWebServerPathHandler.kt
platform/built-in-server/src/org/jetbrains/io/fastCgi/FastCgiService.kt

index c5ea9abecb67024d235bb459ad979a24aa0dff42..0f3d9b2a31a3684e1389792c4a71753e67cb59c3 100644 (file)
@@ -236,7 +236,7 @@ private fun doProcess(urlDecoder: QueryStringDecoder, request: FullHttpRequest,
   return false
 }
 
-internal fun validateToken(request: HttpRequest, channel: Channel, redirectToSetCookie: Boolean): HttpHeaders? {
+internal fun validateToken(request: HttpRequest, channel: Channel): HttpHeaders? {
   val cookieString = request.headers().get(HttpHeaderNames.COOKIE)
   if (cookieString != null) {
     val cookies = ServerCookieDecoder.STRICT.decode(cookieString)
@@ -256,17 +256,7 @@ internal fun validateToken(request: HttpRequest, channel: Channel, redirectToSet
   val url = "${channel.uriScheme}://${request.host!!}${urlDecoder.path()}"
   if (token != null && tokens.getIfPresent(token) != null) {
     tokens.invalidate(token)
-    if (redirectToSetCookie) {
-      // we redirect because it is not easy to change and maintain all places where we send response
-      val response = HttpResponseStatus.MOVED_PERMANENTLY.response(request)
-      response.headers().add(HttpHeaderNames.LOCATION, url)
-      response.headers().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(STANDARD_COOKIE) + "; SameSite=strict")
-      response.send(channel, request)
-      return response.headers()
-    }
-    else {
-      return DefaultHttpHeaders().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(STANDARD_COOKIE) + "; SameSite=strict")
-    }
+    return DefaultHttpHeaders().set(HttpHeaderNames.SET_COOKIE, ServerCookieEncoder.STRICT.encode(STANDARD_COOKIE) + "; SameSite=strict")
   }
 
   SwingUtilities.invokeAndWait {
index 66a4fe4b3cbc8ee995b763df3526debdb7c7f09e..e88bb2c9819340c329c44d654e8e0baef4839513 100644 (file)
@@ -41,7 +41,7 @@ private class DefaultWebServerPathHandler : WebServerPathHandler() {
                        projectName: String,
                        decodedRawPath: String,
                        isCustomHost: Boolean): Boolean {
-    val extraHttpHeaders = validateToken(request, context.channel(), false) ?: return true
+    val extraHttpHeaders = validateToken(request, context.channel()) ?: return true
 
     val channel = context.channel()
     val pathToFileManager = WebServerPathToFileManager.getInstance(project)
index 437c0ea48c8f3842ea4fd1131a4ac14eb67b353a..a295c1ca12fa4ee51d49fb37027223d25a4b3ab8 100644 (file)
@@ -18,7 +18,6 @@ package org.jetbrains.io.fastCgi
 import com.intellij.openapi.diagnostic.Logger
 import com.intellij.openapi.project.Project
 import com.intellij.util.Consumer
-import com.intellij.util.containers.ConcurrentIntObjectMap
 import com.intellij.util.containers.ContainerUtil
 import io.netty.bootstrap.Bootstrap
 import io.netty.buffer.ByteBuf
@@ -35,7 +34,7 @@ val LOG = Logger.getInstance(FastCgiService::class.java)
 // todo send FCGI_ABORT_REQUEST if client channel disconnected
 abstract class FastCgiService(project: Project) : SingleConnectionNetService(project) {
   private val requestIdCounter = AtomicInteger()
-  protected val requests: ConcurrentIntObjectMap<Channel> = ContainerUtil.createConcurrentIntObjectMap<Channel>()
+  private val requests = ContainerUtil.createConcurrentIntObjectMap<ClientInfo>()
 
   override fun configureBootstrap(bootstrap: Bootstrap, errorOutputConsumer: Consumer<String>) {
     bootstrap.handler {
@@ -47,8 +46,8 @@ abstract class FastCgiService(project: Project) : SingleConnectionNetService(pro
         if (!requests.isEmpty) {
           val waitingClients = requests.elements().toList()
           requests.clear()
-          for (channel in waitingClients) {
-            sendBadGateway(channel)
+          for (client in waitingClients) {
+            sendBadGateway(client.channel, client.extraHeaders)
           }
         }
       }
@@ -103,30 +102,30 @@ abstract class FastCgiService(project: Project) : SingleConnectionNetService(pro
       }
     }
     finally {
-      val channel = requests.remove(fastCgiRequest.requestId)
-      if (channel != null) {
-        sendBadGateway(channel)
+      requests.remove(fastCgiRequest.requestId)?.let {
+        sendBadGateway(it.channel, it.extraHeaders)
       }
     }
   }
 
-  fun allocateRequestId(channel: Channel): Int {
+  fun allocateRequestId(channel: Channel, extraHeaders: HttpHeaders): Int {
     var requestId = requestIdCounter.getAndIncrement()
     if (requestId >= java.lang.Short.MAX_VALUE) {
       requestIdCounter.set(0)
       requestId = requestIdCounter.getAndDecrement()
     }
-    requests.put(requestId, channel)
+    requests.put(requestId, ClientInfo(channel, extraHeaders))
     return requestId
   }
 
   fun responseReceived(id: Int, buffer: ByteBuf?) {
-    val channel = requests.remove(id)
-    if (channel == null || !channel.isActive) {
+    val client = requests.remove(id)
+    if (client == null || !client.channel.isActive) {
       buffer?.release()
       return
     }
 
+    val channel = client.channel
     if (buffer == null) {
       HttpResponseStatus.BAD_GATEWAY.send(channel)
       return
@@ -139,6 +138,7 @@ abstract class FastCgiService(project: Project) : SingleConnectionNetService(pro
       if (!HttpUtil.isContentLengthSet(httpResponse)) {
         HttpUtil.setContentLength(httpResponse, buffer.readableBytes().toLong())
       }
+      httpResponse.headers().add(client.extraHeaders)
     }
     catch (e: Throwable) {
       buffer.release()
@@ -155,10 +155,10 @@ abstract class FastCgiService(project: Project) : SingleConnectionNetService(pro
   }
 }
 
-private fun sendBadGateway(channel: Channel) {
+private fun sendBadGateway(channel: Channel, extraHeaders: HttpHeaders) {
   try {
     if (channel.isActive) {
-      HttpResponseStatus.BAD_GATEWAY.send(channel)
+      HttpResponseStatus.BAD_GATEWAY.send(channel, extraHeaders = extraHeaders)
     }
   }
   catch (e: Throwable) {
@@ -218,4 +218,6 @@ private fun parseHeaders(response: HttpResponse, buffer: ByteBuf) {
       response.headers().add(key, value)
     }
   }
-}
\ No newline at end of file
+}
+
+private class ClientInfo(val channel: Channel, val extraHeaders: HttpHeaders)
\ No newline at end of file