PurePOP3 library : POP3 functions

All PureFORM, JaPBe, Libs and useful code maintained by gnozal

Moderator: gnozal

gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

PB wrote:> it would be helpful if you could send me the traces
Done; see your PM. :)
Ok.
It's a multipart/alternative format.
There is no 'Content-Transfer-Encoding:' after the boundary, only a 'Content-Type:'.
All 'multipart/alternative' messages I have tested had both 'Content-Transfer-Encoding:' and 'Content-Type:' after the boundary.
It works if I add a 'Content-Transfer-Encoding:' after the 'Content-Type:'.

I have updated the library. It should fix the problem.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Yep, works now. Thanks! :)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Just a quick question on POP3 access in general: my app is parsing the mail
and then actioning those mails BEFORE closing the POP server. Do you think
perhaps the time taken to do the actions is causing the timeouts? Maybe they
are conflicting with the network ops of your lib, as the actions I'm performing
are also network ones. Before I re-write my code, do you think there'd be any
benefit to parsing the mail, closing the POP server, and THEN doing the other
network actions; effectively having only one network op happening at a time,
rather than two simultaneously? Worth a shot? Or shouldn't it really matter?
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

PB wrote:Do you think perhaps the time taken to do the actions is causing the timeouts?
I don't think so.
The timeout is reset whenever a message is sent to the server.
PB wrote:Maybe they are conflicting with the network ops of your lib, as the actions I'm performing are also network ones.
If they aren't performed at the same time (thread), I don't see why.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

Hi gnozal,

My app checks my POP server every 30 seconds, but sometimes the following
problem occurs (not all the time). What do you think could be causing this?
I'm thinking maybe my POP server thinks I'm a bot trying to connect too
often? It still happens even if my interval is 60 seconds or more. :(

Also: there's no such word as "authentification", it should be "authentication".

Code: Select all

20/02/09 11:54:19  -----------------------------
20/02/09 11:54:19  Try to connect to POP server.
20/02/09 11:54:19  Success! E-mails waiting: 0
20/02/09 11:54:19  POP connection closed.
20/02/09 11:54:19  Done.
20/02/09 11:54:49  -----------------------------
20/02/09 11:54:49  Try to connect to POP server.
20/02/09 11:55:05  Failed (error -5: AuthentificationFailed).
20/02/09 11:55:05  Done.
20/02/09 11:55:35  -----------------------------
20/02/09 11:55:35  Try to connect to POP server.
20/02/09 11:55:35  Failed (error -2: NoConnection).
20/02/09 11:55:35  Done.
20/02/09 11:56:05  -----------------------------
20/02/09 11:56:05  Try to connect to POP server.
20/02/09 11:56:05  Failed (error -2: NoConnection).
20/02/09 11:56:05  Done.
20/02/09 11:56:35  -----------------------------
20/02/09 11:56:35  Try to connect to POP server.
20/02/09 11:56:35  Failed (error -2: NoConnection).
20/02/09 11:56:35  Done.
20/02/09 11:57:05  -----------------------------
(and so on for the next six hours)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
gnozal
PureBasic Expert
PureBasic Expert
Posts: 4229
Joined: Sat Apr 26, 2003 8:27 am
Location: Strasbourg / France
Contact:

Post by gnozal »

PB wrote:My app checks my POP server every 30 seconds, but sometimes the following problem occurs (not all the time). What do you think could be causing this?
I don't know, sorry.
PB wrote:I'm thinking maybe my POP server thinks I'm a bot trying to connect too often? It still happens even if my interval is 60 seconds or more. :(
Could be. Maybe it's not only the delay, but the same IP trying again and again ?
PB wrote:Also: there's no such word as "authentification", it should be "authentication".
There is ... in french.
I will upload a fixed help file / resident.
For free libraries and tools, visit my web site (also home of jaPBe V3 and PureFORM).
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

No worries, thanks for replying anyway. I'll have to re-think my approach.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
fizban
User
User
Posts: 31
Joined: Thu Sep 20, 2007 7:36 am
Location: Spain

multiline headers

Post by fizban »

This is a great library!

I just found a little thing: it seems that PurePOP3_HeaderFindNext() removes any preceding blank spaces. I am not sure it is a desired behaviour, since sometimes the header is folded in more than one line and, in order to indicate that, the first char of the line is either a tab or a space. When it is a tab, the function works as expected, but when there is a space it just disappears...
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

@gnozal: Regarding my problem of my app returning an error code of
"error -2: NoConnection" over and over (see my post above), I found
out that if my quit and re-launch my app, it can connect again. So it's
not an IP address problem. I've coded my app with a routine that if it
fails to connect 3 times, it re-launches and the problem's gone. Weird.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
rdority
User
User
Posts: 34
Joined: Mon Mar 30, 2009 10:46 pm
Location: Vancouver, BC

Pop3 locks up, if Internet is blocked after connecting!?

Post by rdority »

Hello all,

Does anyone have a suggestion for best way for PurePOP3 to recover from an interrupted Internet connection?

I have a small program (pasted at end of this post) with a button that calls a function, CheckMail() which then calls PurePOP3_OpenPop3Connection().

Things work very well so long as my Internet connection is not interrupted, in fact this problem only seems to arise

if the Internet is blocked After a successful connection (Scenario 1, described below). The issue seems to

occur after successfully connecting (Scenario 2).

Scenario #1, successful recovery from bad Internet connection Before connecting:

When the Internet is blocked and I click Check Mail, PurePOP3_OpenPop3Connection() naturally fails to

connect, returning the appropriate error codes, -2 for "no connection" in this case.

Once the Internet connection is established, the app recovers recover nicely and I can then click the Check Email

button and then requesters come up, telling me about the email that is waiting for me on the server. Success! :-)

- - -

Scenario #2, Unsuccessful Recovery from Disrupted Internet connection After initially connecting successfully:

Synopsis: With a good Internet connection, run the app and click Check Email. Then, after a requester / notifier comes up, block the Internet connection. Now the app doesn't seem to recover.

If the Internet connection is interrupted After PurePOP3_OpenPop3Connection() has successfully established a

connection, this little app never recovers once I restore the Internet connection.

With a good Internet connection, I click the Check Email and start to get requesters telling me about each email

on the server.

(So far so good, but here's where things get a little more interesting.)

If the Internet is then disconnected After clicking Check Email (successfully connecting and with one of the

message requesters still up), that is when the app gets into some kind of mode that so far I haven't figured out

how to recover from, (except by closing the app and re-running it).

This happens regardless of how the Internet is blocked (either through software like ZoneAlarm or by physically

unplugging the RJ45 cable)!

I've added a couple of "rcovery buttons", one which calls PurePOP3_ClosePOP3Connection() and another

which calls PurePOP3_Noop() however so far neither of these has helped.

When I shut the app down, and restart it, I click Check Email and PurePOP3_OpenPOP3Connection(...)

connects just fine and is able to connect once again to the server, so I have little reason to suspect the server is

causing this problem.

It seems something in my app or the PurePOP3 library needs to be reset somehow.

Is there a certain sequence of calls I should be making to restore PurePOP3_OpenPOP3Connection() 's ability

to connect?

Thank you very much,
Roark

Code: Select all


; PureBasic Visual Designer v3.95 build 1485 (PB4Code)

;- Window Constants

Enumeration
  #Window1
EndEnumeration

;- Gadget Constants
;
Enumeration
  #FrameEmailAccounts
  #LabelAddInPOP
  #InPOP
  #LabelAddUsername
  #Username
  #LabelAddEmailAddress
  #LabelAddDisplayName
  #EmailAddress
  #DisplayName
  #LabelAddPassword
  #Password
  #CheckEmail
  #Disconnect
  #ServerReset
EndEnumeration

Procedure Open_Window1()
  If OpenWindow(#Window1, 170, 89, 806, 554, "Spf -- Spam Protection Factor",  #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_TitleBar | #PB_Window_ScreenCentered )
    Frame3DGadget(#FrameEmailAccounts, 8, 8, 760, 500, "")
    TextGadget(#LabelAddInPOP, 28, 138, 110, 16, "In (POP)", #PB_Text_Center)
    StringGadget(#InPOP, 28, 158, 110, 20, "")
    TextGadget(#LabelAddUsername, 168, 138, 90, 16, "Username", #PB_Text_Center)
    StringGadget(#Username, 153, 158, 125, 20, "")
;    TextGadget(#LabelAddEmailAddress, 318, 138, 90, 16, "Email Address", #PB_Text_Center)
;    StringGadget(#EmailAddress, 283, 158, 160, 20, "")
    TextGadget(#LabelAddPassword, 618, 138, 90, 20, "Password", #PB_Text_Right)
    StringGadget(#Password, 598, 158, 140, 20, "", #PB_String_Password)
    ButtonGadget(#CheckEmail,638,208,100,40,"Check Email")
    ButtonGadget(#Disconnect, 638, 278, 100, 40, "Disconnect")
    ButtonGadget(#ServerReset, 638, 328, 100, 40, "Reset Server")
  EndIf
EndProcedure

Global w1

Procedure message(title.s,message.s)
  ProcedureReturn MessageRequester(title,message,#PB_MessageRequester_Ok)
EndProcedure

Procedure ask(title.s,message.s,flags)
  ProcedureReturn MessageRequester(title,message,flags)
EndProcedure

Procedure warn(msg.s)
  ProcedureReturn message(AppName$ + " :: Warning",msg)
EndProcedure

;-

Procedure LoadConfiguration()
  tempDir$ = GetTemporaryDirectory()
  
  f = ReadFile(#PB_Any,tempdir$+"config_delete")

  If f
    SetGadgetText(#InPOP,ReadString(f))
    SetGadgetText(#Username,ReadString(f))
;    SetGadgetText(#EmailAddress,ReadString(f))
    SetGadgetText(#Password,ReadString(f))
    CloseFile(f)
  EndIf
EndProcedure

Procedure SaveConfiguration()
  tempDir$ = GetTemporaryDirectory()

  f = CreateFile(#PB_Any,tempDir$+"config_delete")

  If f
    WriteStringN(f,GetGadgetText(#InPOP))
    WriteStringN(f,GetGadgetText(#Username))
;    WriteStringN(f,GetGadgetText(#EmailAddress))
    WriteStringN(f,GetGadgetText(#Password)) 
    CloseFile(f)
  EndIf
EndProcedure

;-

Procedure CheckEmail()

  failedToConnect = #False

  If checkingEmail
    warn("already checking email...")
    ProcedureReturn
  EndIf

  checkingEmail = #True ;now busy!
  
  port = 110
  server$ = GetGadgetText(#InPOP)
  username$ = GetGadgetText(#Username)
  password$ = GetGadgetText(#Password)
   
  If PurePOP3_OpenPOP3Connection(server$, port, username$, password$) <> #PurePOP3_Ok

    ;Connection Error, Seems to recover just fine when the connection fails here, but see 6 lines down...

    failedToConnect = #True
  
  Else
  
    mCount = PurePOP3_CountMessages()

    If mCount
    
      For i = 1 To mCount
      
        mNumber = i 
        
        If PurePOP3_RetrieveMessage(i) < 0

          ;Connection (disruption) Error, Never seems to recover when the connection fails here...
          
          Break ;out of For loop...
                  
        Else
          ;no error, show message info to user...

          info$ = PurePOP3_GetMessageInfo()

          date$ = StringField(info$,1,Chr(9))
          date$ = Right(date$,Len(date$)-Len("Delivery-date:"))

          subject$ = StringField(info$,2,Chr(9))
          subject$ = Right(subject$,Len(subject$)-Len("Subject:"))
            
          from$ = StringField(info$,3,Chr(9))
          from$ = Right(from$,Len(from$)-Len("From:"))

          message("Email","from="+from$+", subject="+subject$)
          
        EndIf ;PurePOP3_RetrieveMessage(i) 
      
      Next ;i = 1 to mCount...
    
    EndIf; mCount
    
    If failedToConnect = #False
      ;no errors
      PurePOP3_ClosePOP3Connection()
    EndIf
  
  EndIf ;PurePOP3_OpenPOP3Connection(Server, Port, User, Pwd) = #PurePOP3_Ok  

  checkingEmail = #False ;finished!
  
EndProcedure

;-
;- FUN STARTS HERE !!!

checkingEmail = #False

AppName$ = "Test POP3"

w1 = Open_Window1()

LoadConfiguration()

;- EVENT LOOP

Repeat 
  
  Event = WaitWindowEvent() 
  WindowID = EventWindow() 
  GadgetID = EventGadget() 
  EventType = EventType() 
  
;-LEFT MOUSE CLICK !!
  
  If Event = #PB_Event_Gadget And (EventType = PB_EventType_LeftClick) ;left click...
    
    Select GadgetID
  
      Case #CheckEmail:
        If checkingEmail = #False 
          CheckEmail()
        EndIf

      Case #Disconnect:        
        PurePOP3_ClosePOP3Connection() ;hoping this might help restore things...
        
      Case #ServerReset:
        PurePOP3_Reset() ;PurePOP3_Noop() ;hoping either of these might help restore things...
  
    EndSelect ;GadgetID
    
  EndIf ;left click...
  
Until (Event = #PB_Event_CloseWindow) ;End of the event loop

SaveConfiguration()

End
rdority
User
User
Posts: 34
Joined: Mon Mar 30, 2009 10:46 pm
Location: Vancouver, BC

Addendum

Post by rdority »

Basically, Scenario #1 is an example of when the Pop3 library recovers. This is when the Internet connection was down at the time PurePOP3_OpenPop3Connection() is called. If this happens and the Internet connection is later restored, PurePOP3_OpenPop3Connection() is able to connect just fine.

In Scenario #2 (in my post above), I should mention that the Internet connection is restored and yet PurePOP3_OpenPop3Connection() is never able to successfully connect again. I have to close the app, reopen it and then PurePOP3_OpenPop3Connection() is able to connect just fine.

The sequence of events:

With a valid Internet connection, click Check Mail which calls PurePOP3_OpenPop3Connection() and successfully connects. You then see a requester describing the 1st email on the server.

Now, disconnect the Internet.

Click OK on the requester, which would normally result in another requester box with info pertaining to the next email on the server and so on.

In this case, because the Internet connection has been disconnected, the app gets into a weird mode.

Wait 15 seconds and it appears the app may have recovered.

Now re-establish the Internet connection.

Note the clicking Check Mail, which calls PurePOP3_OpenPop3Connection() will no longer work, no matter what.

Close the app and then rerun it. Click Check Mail now and voila! Everything is working again!!

Help!!!!! :)

Thanks,
Roark
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Addendum

Post by PB »

> Close the app and then rerun it. Click Check Mail now and voila!
> Everything is working again!!

Yep, that's the exact same problem as mine. Have to relaunch to fix.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
rdority
User
User
Posts: 34
Joined: Mon Mar 30, 2009 10:46 pm
Location: Vancouver, BC

Re-start the PurePOP3 library?

Post by rdority »

It's odd that restarting the app would be the only way to accomplish this, ie resetting the PurePOP3 library so that it can connect to the server once again.

Maybe it's possible to re-initialize the PurePOP3 library, via a secret function call such as PurePOP3_Initialize_() that isn't documented.

Or a way to request for a PureBasic app to re-load a library of one's choice...

Or a way to fake any PureBasic app into thinking that it was just ran...

Naturally, any of these would likely be preferable to restarting one's app or instigating another instance of it via a thread, etc.

gnoval to the rescue? :)
rdority
User
User
Posts: 34
Joined: Mon Mar 30, 2009 10:46 pm
Location: Vancouver, BC

Since PurePop3 is unable to recover from this error...

Post by rdority »

Hey PB,

I know it's not the most ideal thing, but since re-opening the app does seem to be a reliable workaround, would you be so kind as to tell me how you arranged to have your app restart itself?

Here's a function I'm calling when there is a Pop3 error after successfully connecting (if Pop3 fails to connect it seems to recover okay on its own).

So far, it's not working.. :oops:

Code: Select all

Procedure RestartApp()

  If closingDown = #False 

    closingDown = #True ;global variable to make sure we don't call this more than once.
  
    SaveConfiguration()
  
    CloseHandle_(MutexID) ;let mutex go so we can start another instance of the program.
  
    CloseWindow(w1) ;w1 is global handle to main window.

    RunProgram(ProgramFilename()) ;start new instance of this program.
  
    End ;stop this instance of the program.
  
  EndIf ;closingDown = #False

EndProcedure
Sounds like yours is working. Any suggestions?

Thanks,
Roark
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Re: Since PurePop3 is unable to recover from this error...

Post by PB »

> would you be so kind as to tell me how you arranged to have your app restart itself?

It's nothing difficult, but I'm not using a mutex or window:

Code: Select all

a=PurePOP3_OpenPOP3Connection(pop3server$,Val(pop3port$),pop3login$,pop3pass$)

If a<>#PurePOP3_Ok

  failed+1

  If failed=3
    RunProgram(appname$) ; Name of my executable.
    End
  EndIf

Else

  ; Rest of app.

EndIf
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Post Reply