jbe/bsw@0: function encode.mime.unstructured_header_line(key, value) jbe/bsw@0: if not value then jbe/bsw@0: return "" jbe/bsw@0: end jbe/bsw@0: local charset = "UTF-8" -- TODO: support other charsets jbe/bsw@0: local key_length = #key + #(": ") jbe/bsw@0: if string.find(value, "^[\t -~]*$") then jbe/bsw@0: local need_encoding = false jbe/bsw@0: local parts = { key, ": " } jbe/bsw@0: local line_length = key_length jbe/bsw@0: local first_line = true jbe/bsw@0: for spaced_word in string.gmatch(value, "[\t ]*[^\t ]*") do jbe/bsw@0: if #spaced_word + line_length > 76 then jbe/bsw@0: if first_line or #spaced_word > 76 then jbe/bsw@0: need_encoding = true jbe/bsw@0: break jbe/bsw@0: end jbe/bsw@0: parts[#parts+1] = "\r\n" jbe/bsw@0: line_length = 0 jbe/bsw@0: end jbe/bsw@0: parts[#parts+1] = spaced_word jbe/bsw@0: line_length = line_length + #spaced_word jbe/bsw@0: first_line = false jbe/bsw@0: end jbe/bsw@0: if not need_encoding then jbe/bsw@0: parts[#parts+1] = "\r\n" jbe/bsw@0: return table.concat(parts) jbe/bsw@0: end jbe/bsw@0: charset = "US-ASCII" jbe/bsw@0: end jbe/bsw@0: local parts = { key, ": " } jbe/bsw@0: local line_length jbe/bsw@0: local opening = "=?" .. charset .. "?Q?" jbe/bsw@0: local closing = "?=" jbe/bsw@0: local indentation = "" jbe/bsw@0: for i = 1, key_length do jbe/bsw@0: indentation = indentation .. " " jbe/bsw@0: end jbe/bsw@0: local open = false jbe/bsw@0: for char in string.gmatch(value, ".") do jbe/bsw@0: local encoded_char jbe/bsw@0: if string.find(char, "^[0-9A-Za-z%.%-]$") then jbe/bsw@0: encoded_char = char jbe/bsw@0: else jbe/bsw@0: local byte = string.byte(char) jbe/bsw@0: if byte == 32 then jbe/bsw@0: encoded_char = "_" jbe/bsw@0: else jbe/bsw@0: encoded_char = string.format("=%02X", byte) jbe/bsw@0: end jbe/bsw@0: end jbe/bsw@0: if open and line_length + #encoded_char > 76 then jbe/bsw@0: parts[#parts+1] = closing jbe/bsw@0: parts[#parts+1] = "\r\n" jbe/bsw@0: parts[#parts+1] = indentation jbe/bsw@0: open = false jbe/bsw@0: end jbe/bsw@0: if not open then jbe/bsw@0: parts[#parts+1] = opening jbe/bsw@0: line_length = key_length + #opening + #closing jbe/bsw@0: open = true jbe/bsw@0: end jbe/bsw@0: parts[#parts+1] = encoded_char jbe/bsw@0: line_length = line_length + #encoded_char jbe/bsw@0: end jbe/bsw@0: if open then jbe/bsw@0: parts[#parts+1] = "?=" jbe/bsw@0: end jbe/bsw@0: parts[#parts+1] = "\r\n" jbe/bsw@0: return table.concat(parts) jbe/bsw@0: end