java.lang.Object
javax.servlet.GenericServlet
javax.servlet.http.HttpServlet
i2p.susi.webmail.WebMail
- All Implemented Interfaces:
Serializable, Servlet, ServletConfig
Main webmail application class providing email functionality for I2P.
- See Also:
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate static classCallback fromPOP3MailBox.connectToServer(NewMailListener).private static classThreaded sending.private static enumHow HTML parts are displayed.private static classCallback fromMailCache.loadFromDisk(NewMailListener).private static classData structure to hold any persistent data (to store them in session dictionary).private static enumThe page the servlet shows next.Field Summary
Modifier and TypeFieldDescriptionprivate final LogRouter log for this servlet.private static final StringParameter naming the message to show, by base64 UIDL.private static final StringButton discarding the composed message.private static final StringParameter naming an inline part by content id.private static final StringButton clearing the message selection.static final StringProperty key enabling the background POP3 check for new mail.static final StringProperty key setting the interval between background POP3 checks, in minutes.private static final StringConfig key for the composer width in columns.private static final StringConfig key for the composer height in rows.private static final StringConfig key copying sent mail to the sent folder.private static final StringConfig key enabling one-line message previews.private static final StringConfig key for the mail server host.private static final StringConfig key allowing HTML mail at all.private static final StringConfig key inverting HTML mail for dark themes.private static final StringConfig key preferring the HTML view.private static final StringConfig key marking blocked images in HTML mail.private static final StringConfig key showing a warning before HTML mail.static final StringProperty key setting the POP3 idle timeout, in seconds.(package private) static final StringConfig key: leave mail on the server.private static final StringConfig key pinning the POP3 and SMTP ports.private static final StringConfig key for the POP3 port.private static final StringConfig key for the SMTP port.private static final StringConfig key for the sender domain.private static final StringConfig key pinning the sender address.private static final StringConfig key for the display name sent with mail.private static final StringCompose-style field carrying the raw config text.private static final StringConfig key for the susimail theme.private static final StringButton opening the settings page.private static final StringBundle holding the console's translated strings.private static final StringPer-server Content-Security-Policy nonce.private static final StringParameter carrying the page number.private static final StringParameter naming the folder being shown.private static final StringParameter naming the sort in effect.private static final StringParameter reporting the current state, for debugging.private static final StringMail server host used when none is configured.private static final intPOP3 port used when none is configured.private static final intSMTP port used when none is configured.private static final StringTheme used when none is configured.private static final StringButton moving the message to the trash.private static final StringButton dropping an attachment from the draft.static final StringTranslated "Drafts" folder name.(package private) static final StringMaildir subfolder for current mail.static final StringTranslated "Sent" folder name.private static final StringDisplay name of the spam folder.private static final StringDisplay name of the trash folder.private static final String[]The folder names, in internal order.private static final String[]The folder names as shown, translated on use.private static final StringButton downloading an attachment.private static final StringParameter naming a draft's attachment.private static final StringParameter set when a draft is already stored.private static final StringButton showing the first page.private static final StringButton forwarding the message.private static final StringParameter carrying the mail server host.private static final StringParameter requesting the HTML view.private static final StringButton inverting the message selection.private static final StringButton showing the last page.private static final StringButton returning to the message list.private static final StringParameter for the login action.private static final StringButton ending the session.private static final StringButton marking every message read.private static final StringButton moving the message to another folder.private static final StringPath prefix used to build the page's own links.private static final StringButton starting a new message.private static final StringCompose field for the bcc list.private static final StringCompose field for the cc list.private static final StringCompose field naming an attachment to upload.private static final StringParameter naming a folder to create.private static final StringCompose field for the sender address.private static final StringCompose field for the subject.private static final StringCompose field for the message body.private static final StringCompose field for the recipients.private static final StringParameter naming a newly arrived message.private static final StringCompose field carrying the uploaded attachment.private static final StringButton showing the next message.private static final StringParameter naming the next message.private static final StringParameter carrying the next page number.private static final StringButton showing the next page.private static final StringParameter set while the mail server is unreachable.private static final StringParameter carrying the current page size.private static final StringParameter carrying the login password.private static final StringParameter carrying the POP3 port.private static final StringButton showing the previous message.private static final StringParameter naming the previous message.private static final StringParameter carrying the previous page number.private static final StringButton showing the previous page.private static final StringParameter naming an attachment to download.private static final StringConsole property selecting the Sora font.private static final StringConsole property forcing the mobile layout.private static final StringConsole property naming the theme.private static final StringConsole property applying one theme to all apps.private static final StringButton deleting the message for good.private static final StringButton re-fetching the mailbox.private static final StringButton replying to the message.private static final StringButton replying to all recipients.private static final StringButton saving the settings.private static final StringButton saving the settings under a new name.private static final StringButton saving the composed message as a draft.private static final StringButton sending the composed message.private static final longFixed id, the servlet is never serialized across versions.private static final StringButton changing the page size.private static final StringButton showing one message.private static final booleanSwitch enabling the HTML view of a message.private static final StringParameter carrying the SMTP port.private static final StringParameter naming the sort to apply.(package private) static final StringSort value for the date.(package private) static final StringDefault sort column.(package private) static final StringSort value for the message id.(package private) static final Folder.SortOrderDefault sort order.(package private) static final StringSort value for the sender.(package private) static final StringSort value for the size.(package private) static final StringSort value for the subject.private static final StringSpacer cell text, spacing is better done with CSS.private static final StringParameter carrying the form nonce.private static final StringButton switching to another folder.private static final booleanSwitch forcing the text-only view of every message.private static final StringParameter carrying the login user.The sort values accepted from a request, anything else is rejected.Constructor Summary
ConstructorsConstructorDescriptionWebMail()A fresh servlet: the logger is built by the field initialiser and every other setting is static, soGenericServlet.init()and the requests do the rest.Method Summary
Modifier and TypeMethodDescriptionprivate static StringLooks up a localized string in the message bundle.private static StringLooks up a localized string in the message bundle.private static StringLooks up a localized string in the message bundle.private static StringTag for translation.private booleanallowOrigin(HttpServletRequest request) Validate Origin header for POST requests.private static StringarrayToCSV(String[] arr) Join the array elements into a comma-separated string.private static StringbuildRecipientLine(String[] to) Build a comma-separated recipient line from the addresses.private static StringReturns html string of a form button with name and label.private static StringReturns html string of a disabled form button with name and label.private static booleanbuttonPressed(RequestWrapper request, String key) Check whether the named submit button "was pressed" in the request.private static StringBuildercomposeDraft(WebMail.SessionObject sessionObject, String from, String to, String cc, String bcc, String subject, String text, List<Attachment> attachments) Take the data from the parameters, and put it in a StringBuilder suitable for writing out as a Draft.private static StringBuildercomposeDraft(WebMail.SessionObject sessionObject, RequestWrapper request) Take the data from the request, and put it in a StringBuilder suitable for writing out as a Draft.private static StringconsoleGetString(String s, I2PAppContext ctx) Translate with the console bundle.voiddoGet(HttpServletRequest request, HttpServletResponse response) voiddoPost(HttpServletRequest request, HttpServletResponse response) private static StringescapeHtml(String s) HTML escaping helper.getCheckedItems(RequestWrapper request) Returns e.g.getCurrentFolder(WebMail.SessionObject session, RequestWrapper request) The folder selected in the request.private static MailCachegetCurrentMailCache(WebMail.SessionObject session, RequestWrapper request) The mail cache for the requested folder.private static StringgetDefaultSender(WebMail.SessionObject sessionObject) The sender string.private static MailPartgetMailPartFromID(MailPart part, int id) Find the part with the given id, recursively.private static MailPartgetMailPartFromID(MailPart part, String id) Find the part with the given content-id, recursively.private WebMail.SessionObjectgetSessionObject(HttpSession httpSession) The session's state, creating it if needed.private static String[]getThemes(I2PAppContext ctx) Find all themes installed under docs/themes/susimail.private static booleanEither mobile or text browser Copied from net.i2p.router.web.CSSHelper.booleanDetermine if a user-provided override.css file is active.private static StringLooks up the localized plural form for n items.private static StringpageName(WebMail.State state) Null-tolerant wrapper for the log call sites.(package private) static StringPlain-language name of the page a state value leads to, for the request log.private static WebMail.StateprocessComposeButtons(WebMail.SessionObject sessionObject, RequestWrapper request) Process buttons of compose message dialog This must be called BEFORE processStateChangeButtons so we can add the attachment before SEND.private static WebMail.StateprocessConfigButtons(WebMail.SessionObject sessionObject, RequestWrapper request, boolean isPOST, WebMail.State state) Processes the config buttons, both entering and exiting the page.private static booleanprocessDownloadLink(WebMail.SessionObject sessionObject, String showUIDL, RequestWrapper request, HttpServletResponse response) Process download link in message view.private static voidprocessDraftAttachmentLink(WebMail.SessionObject sessionObject, RequestWrapper request, HttpServletResponse response) Process thumbnail link in compose view Draft attachments are stored in the SessionObject and identified by hashcode only.private static intprocessFolderButtons(WebMail.SessionObject sessionObject, int page, RequestWrapper request) Process buttons of folder view.private static WebMail.StateprocessGenericButtons(WebMail.SessionObject sessionObject, RequestWrapper request, WebMail.State state) Handle the common folder and message buttons.private static WebMail.StateprocessLogin(WebMail.SessionObject sessionObject, RequestWrapper request, WebMail.State state) Start of state change and button processing: handle the login form, connecting to the mailbox.private static WebMail.StateprocessLogout(WebMail.SessionObject sessionObject, RequestWrapper request, boolean isPOST, WebMail.State state) End the session and show the login page.private static StringprocessMessageButtons(WebMail.SessionObject sessionObject, String showUIDL, RequestWrapper request) Process buttons of message view.private voidprocessRequest(HttpServletRequest httpRequest, HttpServletResponse response, boolean isPOST) The entry point for all web page loads.private static booleanprocessSaveAsLink(WebMail.SessionObject sessionObject, String showUIDL, RequestWrapper request, HttpServletResponse response) Process save-as link in message view.private static voidprocessSortingButtons(WebMail.SessionObject sessionObject, RequestWrapper request) Applies the sort buttons found in the request.private static WebMail.StateprocessStateChangeButtons(WebMail.SessionObject sessionObject, RequestWrapper request, boolean isPOST, WebMail.State state) Process all buttons, which possibly change internal state.(package private) static StringPrepare line for presentation between html tags.private static StringrenderDateCell(Mail mail, String jslink) Builds the HTML for the date cell of a mail row.private static StringrenderMailRow(Mail mail, String b64UIDL, String loc, String jslink, boolean isSpamFolder, boolean showToColumn) Renders a single mail row for the mailbox list.private static voidrenderNotifications(StringBuilder buf, boolean showRefresh, WebMail.SessionObject sessionObject) Renders the notification banners if needed.private static voidrenderPageNav(PrintWriter out, String folderName, int page, int pages, boolean outputHidden) Render pagination controls for a given page.static booleansafeEquals(String a, String b) Compares two strings, counting null as equal only to null.private static booleansaveDraft(WebMail.SessionObject sessionObject, String uidl, StringBuilder draft) Write out the draft.private static booleansaveDraftLocked(Log log, WebMail.SessionObject sessionObject, MailCache toMC, String uidl, StringBuilder draft) Caller must hold the MailCache write lock.private static booleansendAttachment(WebMail.SessionObject sessionObject, MailPart part, HttpServletResponse response, boolean isRaw) Stream one attachment part to the browser.private static booleansendMail(WebMail.SessionObject sessionObject, Draft draft) Take the data from the request, and put it in a StringBuilder suitable for writing out as a Draft.private static booleansendMailSaveAs(WebMail.SessionObject sessionObject, Mail mail, HttpServletResponse response) Send the mail to be saved by the browser.private voidsendRedirect(HttpServletRequest req, HttpServletResponse resp, String q) Redirect a POST to a GET (P-R-G), replacing the query string.(package private) static StringshortSessionId(String id) A Jetty session id is a long hex blob that nothing in the log viewer links, and it repeats on every request, so only its head is kept and bracketed.private static voidshowCompose(PrintWriter out, WebMail.SessionObject sessionObject, RequestWrapper request) Show the compose form.private static voidshowConfig(PrintWriter out, Folder<String> folder) Simple configure page.private static voidshowFolder(PrintWriter out, WebMail.SessionObject sessionObject, MailCache mc, RequestWrapper request) Show the message list for a folder.private static StringshowFolderSelect(String currentName, boolean disableCurrent) HTML select control listing the folders.private static voidshowLoading(PrintWriter out, WebMail.SessionObject sessionObject, RequestWrapper request) Show the loading page, refreshed by meta tag.private static voidshowLogin(PrintWriter out) Show the login form.private static voidshowMessage(PrintWriter out, WebMail.SessionObject sessionObject, MailCache mc, String showUIDL, boolean reallyDelete, WebMail.HtmlMode allowHTML) Show one message with its parts.private static voidshowPart(PrintWriter out, MailPart mailPart, int level, boolean html, WebMail.HtmlMode allowHtml) Recursively render all mail body parts.private static StringsortHeader(String name, String label, String imgPath, String currentName, Folder.SortOrder currentOrder, int page, String folder) Returns a html string of the label and two imaged links using the parameter name (used for sorting buttons in folder view).private static WebMail.StatethreadedStartup(WebMail.SessionObject sessionObject, boolean offline, WebMail.State state, String host, int pop3PortNo, String user, String pass) Starts one thread to load the emails from disk, and in parallel starts a second thread to connect to the POP3 server (unless user clicked the 'read mail offline' at login).private static StringtoTitleCase(String input) Capitalizes the first letter of each word.private static voidwaitForLoad(WebMail.SessionObject sessionObject, MailCache mc) Blocking wait, bounded to 5 seconds so a stuck loader cannot hang the servlet thread indefinitely.Methods inherited from class HttpServlet
doDelete, doHead, doOptions, doPut, doTrace, getLastModified, service, serviceMethods inherited from class GenericServlet
destroy, getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletInfo, getServletName, init, init, log, log
Field Details
_log
Router log for this servlet.serialVersionUID
private static final long serialVersionUIDFixed id, the servlet is never serialized across versions.- See Also:
DEFAULT_HOST
Mail server host used when none is configured.- See Also:
DEFAULT_POP3PORT
private static final int DEFAULT_POP3PORTPOP3 port used when none is configured.- See Also:
DEFAULT_SMTPPORT
private static final int DEFAULT_SMTPPORTSMTP port used when none is configured.- See Also:
myself
Path prefix used to build the page's own links.- See Also:
cspNonce
Per-server Content-Security-Policy nonce.LOGIN
OFFLINE
Parameter set while the mail server is unreachable.- See Also:
USER
PASS
Parameter carrying the login password.- See Also:
HOST
Parameter carrying the mail server host.- See Also:
POP3
SMTP
CUR_PAGE
Parameter carrying the page number.- See Also:
SUSI_NONCE
Parameter carrying the form nonce.- See Also:
B64UIDL
Parameter naming the message to show, by base64 UIDL.- See Also:
NEW_UIDL
Parameter naming a newly arrived message.- See Also:
PREV_B64UIDL
Parameter naming the previous message.- See Also:
NEXT_B64UIDL
Parameter naming the next message.- See Also:
PREV_PAGE_NUM
Parameter carrying the previous page number.- See Also:
NEXT_PAGE_NUM
Parameter carrying the next page number.- See Also:
CURRENT_SORT
Parameter naming the sort in effect.- See Also:
CURRENT_FOLDER
Parameter naming the folder being shown.- See Also:
NEW_FOLDER
Parameter naming a folder to create.- See Also:
DRAFT_EXISTS
Parameter set when a draft is already stored.- See Also:
DEBUG_STATE
Parameter reporting the current state, for debugging.- See Also:
LOGOUT
SAVE
SAVE_AS
Button saving the settings under a new name.- See Also:
REFRESH
CONFIGURE
Button opening the settings page.- See Also:
NEW
REPLY
REPLYALL
Button replying to all recipients.- See Also:
FORWARD
DELETE
Button moving the message to the trash.- See Also:
REALLYDELETE
Button deleting the message for good.- See Also:
MOVE_TO
Button moving the message to another folder.- See Also:
SWITCH_TO
Button switching to another folder.- See Also:
SHOW
DOWNLOAD
RAW_ATTACHMENT
Parameter naming an attachment to download.- See Also:
CID_ATTACHMENT
Parameter naming an inline part by content id.- See Also:
DRAFT_ATTACHMENT
Parameter naming a draft's attachment.- See Also:
HTML
MARKALL
CLEAR
Button clearing the message selection.- See Also:
INVERT
Button inverting the message selection.- See Also:
PREVPAGE
NEXTPAGE
FIRSTPAGE
LASTPAGE
PAGESIZE
Parameter carrying the current page size.- See Also:
SETPAGESIZE
SEND
SAVE_AS_DRAFT
Button saving the composed message as a draft.- See Also:
CANCEL
Button discarding the composed message.- See Also:
DELETE_ATTACHMENT
Button dropping an attachment from the draft.- See Also:
NEW_FROM
Compose field for the sender address.- See Also:
NEW_SUBJECT
NEW_TO
NEW_CC
NEW_BCC
NEW_TEXT
Compose field for the message body.- See Also:
NEW_FILENAME
Compose field naming an attachment to upload.- See Also:
NEW_UPLOAD
Compose field carrying the uploaded attachment.- See Also:
LIST
PREV
NEXT
SORT
SORT_ID
SORT_SENDER
SORT_SUBJECT
SORT_DATE
SORT_SIZE
SORT_DEFAULT
SORT_ORDER_DEFAULT
Default sort order.VALID_SORTS
DIR_FOLDER
DIR_DRAFTS
Translated "Drafts" folder name.DIR_SENT
Translated "Sent" folder name.DIR_TRASH
Display name of the trash folder.DIR_SPAM
Display name of the spam folder.DIRS
The folder names, in internal order.DISPLAY_DIRS
The folder names as shown, translated on use.CONFIG_TEXT
Compose-style field carrying the raw config text.- See Also:
SHOW_HTML
private static final boolean SHOW_HTMLSwitch enabling the HTML view of a message.- See Also:
TEXT_ONLY
private static final boolean TEXT_ONLYSwitch forcing the text-only view of every message.- See Also:
CONFIG_HOST
Config key for the mail server host.- See Also:
CONFIG_PORTS_FIXED
Config key pinning the POP3 and SMTP ports.- See Also:
CONFIG_PORTS_POP3
Config key for the POP3 port.- See Also:
CONFIG_PORTS_SMTP
Config key for the SMTP port.- See Also:
CONFIG_SENDER_FIXED
Config key pinning the sender address.- See Also:
CONFIG_SENDER_DOMAIN
Config key for the sender domain.- See Also:
CONFIG_SENDER_NAME
Config key for the display name sent with mail.- See Also:
CONFIG_COMPOSER_COLS
Config key for the composer width in columns.- See Also:
CONFIG_COMPOSER_ROWS
Config key for the composer height in rows.- See Also:
CONFIG_HTML_ALLOWED
Config key allowing HTML mail at all.- See Also:
CONFIG_HTML_PREFERRED
Config key preferring the HTML view.- See Also:
CONFIG_HTML_SHOW_WARNING
Config key showing a warning before HTML mail.- See Also:
CONFIG_HTML_ENABLE_DARKMODE
Config key inverting HTML mail for dark themes.- See Also:
CONFIG_HTML_SHOW_BLOCKED_IMAGES
Config key marking blocked images in HTML mail.- See Also:
CONFIG_ENABLE_MAIL_PREVIEWS
Config key enabling one-line message previews.- See Also:
CONFIG_COPY_TO_SENT
Config key copying sent mail to the sent folder.- See Also:
CONFIG_LEAVE_ON_SERVER
Config key: leave mail on the server.- See Also:
CONFIG_BACKGROUND_CHECK
Property key enabling the background POP3 check for new mail.- See Also:
CONFIG_CHECK_MINUTES
Property key setting the interval between background POP3 checks, in minutes.- See Also:
CONFIG_IDLE_SECONDS
Property key setting the POP3 idle timeout, in seconds.- See Also:
RC_PROP_THEME
Console property naming the theme.- See Also:
RC_PROP_UNIVERSAL_THEMING
Console property applying one theme to all apps.- See Also:
RC_PROP_FORCE_MOBILE_CONSOLE
Console property forcing the mobile layout.- See Also:
RC_PROP_ENABLE_SORA_FONT
Console property selecting the Sora font.- See Also:
CONFIG_THEME
Config key for the susimail theme.- See Also:
DEFAULT_THEME
Theme used when none is configured.- See Also:
spacer
Spacer cell text, spacing is better done with CSS.- See Also:
CONSOLE_BUNDLE_NAME
Bundle holding the console's translated strings.- See Also:
Constructor Details
WebMail
public WebMail()A fresh servlet: the logger is built by the field initialiser and every other setting is static, soGenericServlet.init()and the requests do the rest.
Method Details
safeEquals
Compares two strings, counting null as equal only to null.- Parameters:
a- one of the two strings to compare, may be nullb- the string compared against a, may be null- Returns:
- true if both are null or both non-null and equal, so a null operand never throws
button
Returns html string of a form button with name and label.- Parameters:
name- the button name, also used as its CSS class; some known names get extra classes or a title attributelabel- the text displayed on the button- Returns:
- the HTML for an input type=submit element, non-null
button2
sortHeader
private static String sortHeader(String name, String label, String imgPath, String currentName, Folder.SortOrder currentOrder, int page, String folder) Returns a html string of the label and two imaged links using the parameter name (used for sorting buttons in folder view).- Parameters:
name- the column name this header sorts by, also the sort link's parameter valuelabel- the text displayed in the header cellimgPath- URL prefix for the up and down arrow imagescurrentName- the column currently sorted by; when it equals name the active arrow is drawn as a plain imagecurrentOrder- the current sort direction, UP (descending) or DOWN (ascending)page- current page number, kept in the sort linksfolder- current folder name, kept in the sort links- Returns:
- the HTML markup for the header cell: the label followed by the up and down image links
buttonPressed
Check whether the named submit button "was pressed" in the request.- Parameters:
request- the current HTTP requestkey- the button name to look up as a request parameter- Returns:
- true if the parameter is present; CONFIGURE and NEW_UIDL also count when sent with an empty value
showPart
private static void showPart(PrintWriter out, MailPart mailPart, int level, boolean html, WebMail.HtmlMode allowHtml) Recursively render all mail body parts. 1. if type is multipart/alternative, look for preferred section and ignore others 2. if type is multipart/*, recursively call all these parts 3. if type is text/plain (or mail is not mime), print out 4. in all other cases print out message, that part is not displayed- Parameters:
out- where the rendered part is writtenmailPart- the MIME part to render, recursed into for multipart typeslevel- is increased by recursively calling sub partshtml- use html stylingallowHtml- allow display of text/html parts
toTitleCase
quoteHTML
processLogin
private static WebMail.State processLogin(WebMail.SessionObject sessionObject, RequestWrapper request, WebMail.State state) Start of state change and button processing: handle the login form, connecting to the mailbox.- Parameters:
sessionObject- the session to authenticate and store the mailbox inrequest- the current HTTP request carrying the login form fieldsstate- the current state; acted on only when it is AUTH- Returns:
- the next state: LOADING or LIST after a successful login, otherwise the incoming state unchanged
threadedStartup
private static WebMail.State threadedStartup(WebMail.SessionObject sessionObject, boolean offline, WebMail.State state, String host, int pop3PortNo, String user, String pass) Starts one thread to load the emails from disk, and in parallel starts a second thread to connect to the POP3 server (unless user clicked the 'read mail offline' at login). Either could finish first, but unless the local disk cache is really big, the loading will probably finish first. Once the POP3 connects, it waits for the disk loader to finish, and then does the fetching of new emails. The user may view the local folder once the first (loader) thread is done.- Parameters:
sessionObject- the session to initialize: caches, mailbox, and credentials are stored hereoffline- true to skip the POP3 connection and read only the disk cachestate- the current state; ignored, always replacedhost- the mail server host name to connect topop3PortNo- the POP3 port number, 0-65535user- the mailbox user namepass- the mailbox password- Returns:
- LOADING if the disk load is still running, LIST if it finished, AUTH if creating the disk cache failed
processLogout
private static WebMail.State processLogout(WebMail.SessionObject sessionObject, RequestWrapper request, boolean isPOST, WebMail.State state) End the session and show the login page.- Parameters:
sessionObject- the session to invalidate and disconnect on logoutrequest- the current HTTP requestisPOST- true for a POST request; logout is only honored thenstate- the current state; replaced by AUTH on logout- Returns:
- the next state: AUTH after a logout, otherwise the incoming state unchanged
processStateChangeButtons
private static WebMail.State processStateChangeButtons(WebMail.SessionObject sessionObject, RequestWrapper request, boolean isPOST, WebMail.State state) Process all buttons, which possibly change internal state. Also processes ?show=x for a GET.- Parameters:
sessionObject- the current session with the mailbox and cachesrequest- the current HTTP requestisPOST- disallow button pushes if falsestate- the current state, replaced when a button changes it- Returns:
- the next state to render, never null
getCheckedItems
Returns e.g. 3,5 for ?check3=1&check5=1 (or POST equivalent).- Parameters:
request- the current HTTP request, scanned for checkN parameters set to 1- Returns:
- non-null List of Base64 UIDLs, or attachment numbers as Strings
processGenericButtons
private static WebMail.State processGenericButtons(WebMail.SessionObject sessionObject, RequestWrapper request, WebMail.State state) Handle the common folder and message buttons.- Parameters:
sessionObject- the current session, whose mailbox is reconnected on refreshrequest- the current HTTP requeststate- the current state, returned unless the connection is lost- Returns:
- the state to render next:
WebMail.State.AUTHif the connection was lost, otherwise the incoming state unchanged
processComposeButtons
private static WebMail.State processComposeButtons(WebMail.SessionObject sessionObject, RequestWrapper request) Process buttons of compose message dialog This must be called BEFORE processStateChangeButtons so we can add the attachment before SEND.- Parameters:
sessionObject- the current session; uploaded attachments are stored in its attachments listrequest- the current HTTP request, read for the uploaded file and the draft UIDL- Returns:
- NEW if an attachment was uploaded or deleted, null otherwise
processMessageButtons
private static String processMessageButtons(WebMail.SessionObject sessionObject, String showUIDL, RequestWrapper request) Process buttons of message view.- Parameters:
sessionObject- the current session, used to locate the mail cache for delete and moveshowUIDL- the UIDL of the message being shown, returned unchanged when no button takes effectrequest- the current HTTP request- Returns:
- the next UIDL to see if PREV or NEXT was pushed, or null if REALLYDELETE was pushed, or showUIDL, or "delete" if DELETE was pushed. If null, next state should be LIST.
processDownloadLink
private static boolean processDownloadLink(WebMail.SessionObject sessionObject, String showUIDL, RequestWrapper request, HttpServletResponse response) Process download link in message view.- Parameters:
sessionObject- the current session, used to locate the mail cacheshowUIDL- the UIDL of the message whose attachment is requestedrequest- the current HTTP request, read for the download or attachment parameterresponse- the response the attachment or the 404 error is written to- Returns:
- If true, we sent an attachment or 404, do not send any other response
processDraftAttachmentLink
private static void processDraftAttachmentLink(WebMail.SessionObject sessionObject, RequestWrapper request, HttpServletResponse response) Process thumbnail link in compose view Draft attachments are stored in the SessionObject and identified by hashcode only.- Parameters:
sessionObject- the current session, whose attachment list is searched for the idrequest- the current HTTP request, read for the draft attachment idresponse- the response the attachment bytes or the 404 error are written to
processSaveAsLink
private static boolean processSaveAsLink(WebMail.SessionObject sessionObject, String showUIDL, RequestWrapper request, HttpServletResponse response) Process save-as link in message view.- Parameters:
sessionObject- the current session, used to locate the mail cacheshowUIDL- the UIDL of the message to saverequest- the current HTTP request, read for the save-as parameterresponse- the response the file or the 404 error is written to- Returns:
- If true, we sent the file or 404, do not send any other response
getMailPartFromID
getMailPartFromID
Find the part with the given content-id, recursively.- Parameters:
part- the root part to search, may be nullid- a content-id, without the surrounding <> or trailing @ part- Returns:
- the part with that content-id, or null if part is null or no sub-part matches
processFolderButtons
private static int processFolderButtons(WebMail.SessionObject sessionObject, int page, RequestWrapper request) Process buttons of folder view.- Parameters:
sessionObject- the current session; error and info messages and the reallyDelete flag are updated herepage- the current page number, 1-basedrequest- the current HTTP request- Returns:
- the page to display next, unchanged unless a paging button was pressed
processSortingButtons
private static void processSortingButtons(WebMail.SessionObject sessionObject, RequestWrapper request) Applies the sort buttons found in the request.- Parameters:
sessionObject- the session to updaterequest- the request to read
processConfigButtons
private static WebMail.State processConfigButtons(WebMail.SessionObject sessionObject, RequestWrapper request, boolean isPOST, WebMail.State state) Processes the config buttons, both entering and exiting the page.- Parameters:
sessionObject- the session to updaterequest- the request to readisPOST- disallow button pushes if falsestate- the state assumed so far- Returns:
- the new state, or null if unknown
getSessionObject
The session's state, creating it if needed.- Parameters:
httpSession- the servlet session the state is stored in under the "sessionObject" attribute- Returns:
- the session state, created and attached if absent, never null
isMobile
Either mobile or text browser Copied from net.i2p.router.web.CSSHelper.- Parameters:
ua- null ok- Returns:
- true if the user agent is a small-screen or text browser, false for a null agent or a full browser
getCurrentMailCache
The mail cache for the requested folder.- Parameters:
session- the current session, holding the caches by folder namerequest- the current HTTP request, read for the folder name- Returns:
- the cache for the requested folder, falling back to the inbox, or null if none is available
getCurrentFolder
private static Folder<String> getCurrentFolder(WebMail.SessionObject session, RequestWrapper request) The folder selected in the request.- Parameters:
session- the current session, holding the caches by folder namerequest- the current HTTP request, read for the folder name- Returns:
- the folder of the current mail cache, or null if there is no cache
waitForLoad
Blocking wait, bounded to 5 seconds so a stuck loader cannot hang the servlet thread indefinitely.- Parameters:
sessionObject- the session whose monitor is held while waiting for the load notificationmc- the cache to load; returns once it is loaded or the wait times out
pageName
Plain-language name of the page a state value leads to, for the request log.The state names are internal (
LIST,SHOW,NEW), and a log line that prints one says nothing to a reader trying to work out why a page came up empty. This maps each to what the browser is about to show. An unknown value falls back to the name itself so the log stays greppable against the code.- Parameters:
stateName- theStatename, as given bystate.name()- Returns:
- the page description, never null
pageName
Null-tolerant wrapper for the log call sites.statestarts null and stays that way on a GET for a mailbox that needs no login step, so the call sites cannot assume a value.- Parameters:
state- the state to describe, or null before any page is chosen- Returns:
- the page description, never null
shortSessionId
processRequest
private void processRequest(HttpServletRequest httpRequest, HttpServletResponse response, boolean isPOST) throws IOException, ServletException The entry point for all web page loads.- Parameters:
httpRequest- the incoming request, read for parameters, headers, and sessionresponse- the response the page, redirect, or attachment is written toisPOST- disallow button pushes if false- Throws:
IOException- if a redirect or attachment response cannot be writtenServletException- declared for the servlet API contract, not actually thrown by this method
renderNotifications
private static void renderNotifications(StringBuilder buf, boolean showRefresh, WebMail.SessionObject sessionObject) Renders the notification banners if needed. This separates errors and info/notes so that each type is handled independently, and at most one of each is shown.- Parameters:
buf- The StringBuilder to append markup to.showRefresh- Whether a refresh indicator should be shown.sessionObject- The current session context.
isOverrideCssActive
public boolean isOverrideCssActive()Determine if a user-provided override.css file is active.- Returns:
- true if an override.css exists in the current theme's susimail directory
sendRedirect
private void sendRedirect(HttpServletRequest req, HttpServletResponse resp, String q) throws IOException Redirect a POST to a GET (P-R-G), replacing the query string.- Parameters:
req- the current request, source of the redirect URLresp- the response the 303 status and Location header are set onq- starting with '?' or null- Throws:
IOException- if the response output stream cannot be opened
consoleGetString
Translate with the console bundle.- Parameters:
s- the English string to look upctx- the app context supplying the translation- Returns:
- the translated string, or the original if untranslated
sendAttachment
private static boolean sendAttachment(WebMail.SessionObject sessionObject, MailPart part, HttpServletResponse response, boolean isRaw) Stream one attachment part to the browser.- Parameters:
sessionObject- the current session, used for loggingpart- the MIME part to stream, or null for nothing to sendresponse- the response the attachment is written to, zipped unless isRawisRaw- if true, don't zip it- Returns:
- true if the part was written to the response, false if the part was null or the write threw an IOException
sendMailSaveAs
private static boolean sendMailSaveAs(WebMail.SessionObject sessionObject, Mail mail, HttpServletResponse response) Send the mail to be saved by the browser.- Parameters:
sessionObject- the current session, used for logging a failed copymail- the message whose raw body is copied outresponse- the response the .eml file is written to- Returns:
- true if the message was copied to the response, false if it has no body or the copy threw an IOException
composeDraft
private static StringBuilder composeDraft(WebMail.SessionObject sessionObject, RequestWrapper request) Take the data from the request, and put it in a StringBuilder suitable for writing out as a Draft. We do no validation of recipients, total length, sender, etc. here.- Parameters:
sessionObject- only for error messages and attachments. All other data is in the request.request- the current HTTP request, read for the compose form fields- Returns:
- null on error
composeDraft
private static StringBuilder composeDraft(WebMail.SessionObject sessionObject, String from, String to, String cc, String bcc, String subject, String text, List<Attachment> attachments) Take the data from the parameters, and put it in a StringBuilder suitable for writing out as a Draft. We do no validation of recipients, total length, sender, etc. here. All params except session may be null.- Parameters:
sessionObject- only for error messages. All data is in the parameters.from- the From header value, replaced by the default sender when the sender is fixed in the configto- the To recipients, a comma-separated listcc- the Cc recipients, a comma-separated listbcc- the Bcc recipients, kept only in the draftsubject- the subject line, "no subject" when blanktext- the message body, quoted-printable encodedattachments- the files to attach, null for none- Returns:
- null on error, with the reason appended to the session's error field
saveDraft
private static boolean saveDraft(WebMail.SessionObject sessionObject, String uidl, StringBuilder draft) Write out the draft.- Parameters:
sessionObject- only for error messages.uidl- the UIDL identifying the draft in the Drafts folderdraft- the composed draft text to write out- Returns:
- true if the draft was written to the Drafts folder, false if there is no Drafts folder or the write failed
saveDraftLocked
private static boolean saveDraftLocked(Log log, WebMail.SessionObject sessionObject, MailCache toMC, String uidl, StringBuilder draft) Caller must hold the MailCache write lock.- Parameters:
log- the session log, used for debug messagessessionObject- the current session; the failure reason is appended to its error fieldtoMC- the Drafts cache to write intouidl- the UIDL identifying the draft in that cachedraft- the composed draft text, null if composing failed- Returns:
- true if the draft was written, false on any error
sendMail
Take the data from the request, and put it in a StringBuilder suitable for writing out as a Draft.- Parameters:
sessionObject- only for error messages. All data is in the draft.draft- the saved draft message to send, read for sender, recipients, subject, and attachments- Returns:
- true if the message passed validation and was handed to the SMTP client, false if any check failed and no send was attempted
doGet
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - Overrides:
doGetin classHttpServlet- Throws:
IOExceptionServletException
doPost
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException - Overrides:
doPostin classHttpServlet- Throws:
IOExceptionServletException
allowOrigin
Validate Origin header for POST requests. Allows requests with matching Origin (same-origin), or no Origin header. Rejects cross-origin POST requests to prevent CSRF attacks.- Parameters:
request- the POST request, read for the Origin and Host headers- Returns:
- false only for a parseable cross-origin mismatch, true for a same-origin, missing, or unparseable Origin
arrayToCSV
showCompose
private static void showCompose(PrintWriter out, WebMail.SessionObject sessionObject, RequestWrapper request) Show the compose form.- Parameters:
out- where the form is writtensessionObject- the current session; supplies the Drafts cache and pending attachments, errors are appended to itrequest- the current HTTP request, read for the draft UIDL and form values
getDefaultSender
The sender string.- Parameters:
sessionObject- the current session, supplying the logged-in user- Returns:
- the sender as an RFC 822 personal name plus angle-addr, e.g. Name <user@mail.i2p>, never null
showLogin
Show the login form.- Parameters:
out- where the form is written
showLoading
private static void showLoading(PrintWriter out, WebMail.SessionObject sessionObject, RequestWrapper request) Show the loading page, refreshed by meta tag.- Parameters:
out- where the page is writtensessionObject- the current session, unused by the current pagerequest- the current HTTP request, unused by the current page
showFolder
private static void showFolder(PrintWriter out, WebMail.SessionObject sessionObject, MailCache mc, RequestWrapper request) Show the message list for a folder.- Parameters:
out- where the list is writtensessionObject- the current session, supplying the fetch state and error outputmc- the cache of the folder to display, supplying the folder and its pagesrequest- the current HTTP request, read for paging and sorting
renderMailRow
private static String renderMailRow(Mail mail, String b64UIDL, String loc, String jslink, boolean isSpamFolder, boolean showToColumn) Renders a single mail row for the mailbox list. This method encapsulates all per-row HTML construction for a given mail item. It returns the row markup as a String so the caller can append it to the overall page builder. The caller is responsible for providing the correct state (spam status, whether to show "To" vs "From", sorting context, etc.).- Parameters:
mail- the message to render, read for its flags, date, subject, sender, and recipientsb64UIDL- the Base64-encoded UIDL of the mail used for identifiersloc- the URL that the row should link to when openedjslink- the CSS class string that enables JavaScript-driven row interactionsisSpamFolder- true if the current folder is the spam folder, rendering its rows in spam styleshowToColumn- true to show the "To" column, false to show "From"- Returns:
- the HTML markup for a single <tr> representing the mail row, never null
renderDateCell
Builds the HTML for the date cell of a mail row.- Parameters:
mail- The Mail object for which the date cell is being renderedjslink- The string used to enable JavaScript-driven row interactions- Returns:
- the date cell markup, empty if mail is null
escapeHtml
showFolderSelect
HTML select control listing the folders.- Parameters:
currentName- the folder being viewed, left out of the list since one cannot move or switch to the current folderdisableCurrent- true for move to folder, false for select folder- Returns:
- the HTML for the select element, non-null
showMessage
private static void showMessage(PrintWriter out, WebMail.SessionObject sessionObject, MailCache mc, String showUIDL, boolean reallyDelete, WebMail.HtmlMode allowHTML) Show one message with its parts.- Parameters:
out- where the rendered message is writtensessionObject- the session holding the mailbox and the view settingsmc- the cache the message is fetched fromshowUIDL- the UIDL of the message to showreallyDelete- was the delete button pushed, if so, show the really delete? messageallowHTML- allow display of text/html parts
buildRecipientLine
showConfig
Simple configure page.- Parameters:
out- where the page is writtenfolder- the folder whose page size is shown, null before login
_x
_t
_t
_t
ngettext
getThemes
Find all themes installed under docs/themes/susimail.- Parameters:
ctx- the app context supplying the base directory- Returns:
- array of all the theme directory names found, empty if the theme directory is missing