Browse Source

Properly close connection

Thomas Dy 2 years ago
parent
commit
c54efb5ef8
1 changed files with 25 additions and 22 deletions
  1. 25 22
      smtp.ts

+ 25 - 22
smtp.ts

@@ -53,10 +53,14 @@ export class Session {
   }
 
   async start() {
-    this.output("220 smtp2rss");
+    await this.output("220 smtp2rss");
     for await (const chunk of newlineIterator(iterateReader(this.conn))) {
-      this.input(chunk);
+      if (await this.input(chunk)) {
+        break;
+      }
     }
+    await this.output("221 smtp2rss closing");
+    this.conn.close();
   }
 
   input(data: string) {
@@ -74,65 +78,64 @@ export class Session {
     }
   }
 
-  waitingHello(data: string) {
+  async waitingHello(data: string) {
     const command = data.substring(0, 4);
     if (command === "HELO" || command === "EHLO") {
       this.state = State.WaitingMail;
-      this.output("250 OK");
+      await this.output("250 OK");
     } else {
-      this.output("500 Invalid state");
+      await this.output("500 Invalid state");
     }
   }
 
-  waitingMail(data: string) {
+  async waitingMail(data: string) {
     const command = data.substring(0, 4);
     if (command === "MAIL") {
       const match = data.match(/^MAIL FROM:<([^>]*)>.*$/);
       if (match !== null) {
         this.sender = match[1];
         this.state = State.WaitingRecipient;
-        this.output("250 OK");
+        await this.output("250 OK");
       } else {
-        this.output("500 Invalid sender");
+        await this.output("500 Invalid sender");
       }
     } else if (command === "QUIT") {
-      this.output("221 smtp2rss closing");
-      this.conn.close();
+      return true;
     } else {
-      this.output("500 Invalid state");
+      await this.output("500 Invalid state");
     }
   }
 
-  waitingRecipient(data: string) {
+  async waitingRecipient(data: string) {
     const command = data.substring(0, 4);
     if (command === "RCPT") {
       const match = data.match(/^RCPT TO:<([^>]*)>.*$/);
       if (match !== null) {
         this.recipient = match[1];
         this.state = State.WaitingData;
-        this.output("250 OK");
+        await this.output("250 OK");
       } else {
-        this.output("500 Invalid sender");
+        await this.output("500 Invalid sender");
       }
     } else {
-      this.output("500 Invalid state");
+      await this.output("500 Invalid state");
     }
   }
 
-  waitingData(data: string) {
+  async waitingData(data: string) {
     const command = data.substring(0, 4);
     if (command === "DATA") {
       this.state = State.ReceivingData;
-      this.output("354 Waiting for data");
+      await this.output("354 Waiting for data");
     } else {
-      this.output("500 Invalid state");
+      await this.output("500 Invalid state");
     }
   }
 
-  receivingData(data: string) {
+  async receivingData(data: string) {
     if (data === ".") {
       this.state = State.WaitingMail;
-      this.output("250 OK");
+      await this.output("250 OK");
 
       this.onReceive(this.recipient, this.sender, this.data);
       this.recipient = "";
@@ -143,8 +146,8 @@ export class Session {
     }
   }
 
-  output(response: string) {
-    this.conn.write(this.encoder.encode(`${response}\r\n`));
+  output(response: string): Promise<number> {
+    return this.conn.write(this.encoder.encode(`${response}\r\n`));
   }
 }