dart/php handler — don't use redirect to set cookie

This commit is contained in:
Vladimir Krivosheev
2016-04-26 16:30:01 +02:00
parent 2d15b5d307
commit 21df259d75
3 changed files with 19 additions and 27 deletions
@@ -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 {
@@ -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)
@@ -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)
}
}
}
}
private class ClientInfo(val channel: Channel, val extraHeaders: HttpHeaders)