forked from openrs2/openrs2
This commit adds support for: * Version negotiation. * HEAD requests. * Friendly error messages. * More robust reference counting. Signed-off-by: Graham <gpe@openrs2.org>bzip2
parent
92a01b6262
commit
620808cb97
@ -1,20 +1,91 @@ |
||||
package org.openrs2.game.net.http |
||||
|
||||
import io.netty.buffer.ByteBuf |
||||
import io.netty.channel.ChannelFutureListener |
||||
import io.netty.channel.ChannelHandlerContext |
||||
import io.netty.channel.FileRegion |
||||
import io.netty.handler.codec.http.DefaultHttpResponse |
||||
import io.netty.handler.codec.http.HttpHeaderNames |
||||
import io.netty.handler.codec.http.HttpHeaderValues |
||||
import io.netty.handler.codec.http.HttpResponse |
||||
import io.netty.handler.codec.http.HttpMethod |
||||
import io.netty.handler.codec.http.HttpRequest |
||||
import io.netty.handler.codec.http.HttpResponseStatus |
||||
import io.netty.handler.codec.http.HttpVersion |
||||
import io.netty.util.ReferenceCounted |
||||
import org.openrs2.buffer.copiedBuffer |
||||
import org.openrs2.buffer.use |
||||
|
||||
public object Http { |
||||
public const val MAX_CONTENT_LENGTH: Int = 65536 |
||||
public const val TEXT_X_CROSS_DOMAIN_POLICY: String = "text/x-cross-domain-policy" |
||||
private const val BANNER = "OpenRS2" |
||||
|
||||
public fun createResponse(status: HttpResponseStatus): HttpResponse { |
||||
val response = DefaultHttpResponse(HttpVersion.HTTP_1_1, status) |
||||
private fun writeResponse( |
||||
ctx: ChannelHandlerContext, |
||||
request: HttpRequest, |
||||
status: HttpResponseStatus, |
||||
content: ReferenceCounted, |
||||
contentType: CharSequence, |
||||
contentLength: Long |
||||
) { |
||||
val version = if (request.protocolVersion() == HttpVersion.HTTP_1_0) { |
||||
HttpVersion.HTTP_1_0 |
||||
} else { |
||||
HttpVersion.HTTP_1_1 |
||||
} |
||||
|
||||
val response = DefaultHttpResponse(version, status) |
||||
response.headers().add(HttpHeaderNames.CONNECTION, HttpHeaderValues.CLOSE) |
||||
response.headers().add(HttpHeaderNames.SERVER, "OpenRS2") |
||||
return response |
||||
response.headers().add(HttpHeaderNames.SERVER, BANNER) |
||||
response.headers().add(HttpHeaderNames.CONTENT_TYPE, contentType) |
||||
response.headers().add(HttpHeaderNames.CONTENT_LENGTH, contentLength) |
||||
|
||||
if (request.method() == HttpMethod.HEAD) { |
||||
ctx.write(response).addListener(ChannelFutureListener.CLOSE) |
||||
} else { |
||||
ctx.write(response, ctx.voidPromise()) |
||||
ctx.write(content.retain()).addListener(ChannelFutureListener.CLOSE) |
||||
} |
||||
} |
||||
|
||||
public fun writeResponse( |
||||
ctx: ChannelHandlerContext, |
||||
request: HttpRequest, |
||||
content: ByteBuf, |
||||
contentType: CharSequence |
||||
) { |
||||
writeResponse(ctx, request, HttpResponseStatus.OK, content, contentType, content.readableBytes().toLong()) |
||||
} |
||||
|
||||
public fun writeResponse( |
||||
ctx: ChannelHandlerContext, |
||||
request: HttpRequest, |
||||
content: FileRegion, |
||||
contentType: CharSequence |
||||
) { |
||||
writeResponse(ctx, request, HttpResponseStatus.OK, content, contentType, content.count()) |
||||
} |
||||
|
||||
public fun writeResponse(ctx: ChannelHandlerContext, request: HttpRequest, status: HttpResponseStatus) { |
||||
copiedBuffer( |
||||
""" |
||||
<!DOCTYPE html> |
||||
<html lang="en"> |
||||
<head> |
||||
<meta charset="UTF-8" /> |
||||
<title>$status</title> |
||||
</head> |
||||
<body> |
||||
<center> |
||||
<h1>$status</h1> |
||||
</center> |
||||
<hr /> |
||||
<center>$BANNER</center> |
||||
</body> |
||||
</html> |
||||
""".trimIndent().plus("\n"), Charsets.UTF_8 |
||||
).use { buf -> |
||||
writeResponse(ctx, request, status, buf, HttpHeaderValues.TEXT_HTML, buf.readableBytes().toLong()) |
||||
} |
||||
} |
||||
} |
||||
|
Loading…
Reference in new issue