view src/luan/modules/http/Http.luan @ 1213:d5d5d29d7592

fix cookie bug
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 14 Mar 2018 18:50:18 -0600
parents f9136432847e
children b6aa2cd51b02
line wrap: on
line source

java()
local Luan = require "luan:Luan.luan"
local error = Luan.error
local ipairs = Luan.ipairs or error()
local pairs = Luan.pairs or error()
local type = Luan.type or error()
local Io = require "luan:Io.luan"
local Html = require "luan:Html.luan"
local url_encode = Html.url_encode or error()
local Table = require "luan:Table.luan"
local clear = Table.clear or error()
local Package = require "luan:Package.luan"
local String = require "luan:String.luan"
local lower = String.lower or error()
local matches = String.matches or error()
local HttpServicer = require "java:luan.modules.http.HttpServicer"
local IoLuan = require "java:luan.modules.IoLuan"
local JavaLuan = require "java:luan.Luan"
local Response = require "java:luan.webserver.Response"
local ResponseOutputStream = require "java:luan.webserver.ResponseOutputStream"
local Status = require "java:luan.webserver.Status"
local OutputStreamWriter = require "java:java.io.OutputStreamWriter"
local HashMap = require "java:java.util.HashMap"


local Http = {}

Http.version = "luan"

function Http.new_request(java)
	local this = {}
	Http.request = this
	if java == nil then
		this.method = "GET"
		this.headers = {}
		this.parameters = {}
		this.cookies = {}
	else
		this.java = java
		this.raw_head = java.rawHead or error()
		this.method = java.method or error()
		this.raw_path = java.rawPath or error()
		this.path = java.path or error()
		this.protocol = java.protocol or error()
		this.headers = JavaLuan.toLuan(java.headers)
		this.parameters = JavaLuan.toLuan(java.parameters)
		this.cookies = JavaLuan.toLuan(java.cookies)
	end
	this.scheme = "http"

	function this.full_path()  -- compatible with jetty
		return this.raw_path or this.path
	end

	function this.url()
		return this.scheme.."://"..this.headers["host"]..this.raw_path
	end

	return this
end

local STATUS = {
	OK = 200
	MOVED_PERMANENTLY = 301
	FOUND = 302
	-- add more as needed
}
Http.STATUS = STATUS

function Http.new_response()
	local this = {}
	Http.response = this

	function this.reset()
		this.java = Response.new()
		this.headers = {}
		this.status = STATUS.OK
		this.writer = nil
	end

	this.reset()

	function this.send_redirect(location)
		this.reset()
		this.status = STATUS.FOUND
		this.headers["location"] = location
	end

	function this.send_error(status,msg)
		this.reset()
		this.status = status
		if msg ~= nil then
			this.headers["content-type"] = "text/plain; charset=utf-8"
			local writer = this.text_writer()
			writer.write(msg)
		end
	end

	function this.set_cookie(name,value,attributes)
		attributes = attributes or {}
		attributes["Path"] = attributes["Path"] or "/"
		local attrMap = HashMap.new()
		for attr_name, attr_value in pairs(attributes) do
			type(attr_name)=="string" or "cookie attribute name must be string"
			type(attr_value)=="string" or "cookie attribute value must be string"
			attrMap.put(attr_name,attr_value)
		end
		this.java.setCookie(name,value,attrMap)
	end

	function this.set_persistent_cookie(name,value,attributes)
		attributes = attributes or {}
		attributes["Max-Age"] = "10000000"
		this.set_cookie(name,value,attributes)
	end

	function this.remove_cookie(name,attributes)
		attributes = attributes or {}
		attributes["Max-Age"] = "0"
		this.set_cookie(name,"delete",attributes)
	end

	function this.text_writer()
		this.writer and "writer already set"
		this.writer = ResponseOutputStream.new(this.java)
		this.writer = OutputStreamWriter.new(this.writer)
		return IoLuan.textWriter(this.writer)
	end

	function this.binary_writer()
		this.writer and "writer already set"
		this.writer = ResponseOutputStream.new(this.java)
		return IoLuan.binaryWriter(this.writer)
	end

	return this
end

function Http.finish()  -- called only from java
	local response = Http.response or error()
	local java = response.java or error()
	java.status = Status.getStatus(response.status)
	for name, value in pairs(response.headers) do
		type(name)=="string" or "header name must be string"
		name = lower(name)
		value = JavaLuan.toJava(value)
		java.headers.put(name,value)
	end
	response.writer and response.writer.close()
	return java
end


function Http.uncache_site()
	for k in pairs(Table.copy(Package.loaded)) do
		if matches(k,"^site:") then
			Package.loaded[k] = nil
		end
	end
end

return Http