gwenhywfar  4.3.1
httpsession.c
Go to the documentation of this file.
00001 /***************************************************************************
00002     begin       : Fri Feb 15 2008
00003     copyright   : (C) 2008-2011 by Martin Preuss
00004     email       : martin@libchipcard.de
00005 
00006  ***************************************************************************
00007  *          Please see toplevel file COPYING for license details           *
00008  ***************************************************************************/
00009 
00010 
00011 #ifdef HAVE_CONFIG_H
00012 # include <config.h>
00013 #endif
00014 
00015 #define DISABLE_DEBUGLOG
00016 
00017 
00018 #include "httpsession_p.h"
00019 #include "i18n_l.h"
00020 
00021 #include <gwenhywfar/syncio.h>
00022 #include <gwenhywfar/syncio_tls.h>
00023 #include <gwenhywfar/syncio_http.h>
00024 #include <gwenhywfar/syncio_file.h>
00025 
00026 #include <gwenhywfar/misc.h>
00027 #include <gwenhywfar/debug.h>
00028 #include <gwenhywfar/gui.h>
00029 
00030 #include <assert.h>
00031 #include <unistd.h>
00032 
00033 
00034 GWEN_INHERIT_FUNCTIONS(GWEN_HTTP_SESSION)
00035 
00036 
00037 
00038 GWEN_HTTP_SESSION *GWEN_HttpSession_new(const char *url, const char *defaultProto, int defaultPort) {
00039   GWEN_HTTP_SESSION *sess;
00040 
00041   GWEN_NEW_OBJECT(GWEN_HTTP_SESSION, sess);
00042   assert(sess);
00043   sess->usage=1;
00044   GWEN_INHERIT_INIT(GWEN_HTTP_SESSION, sess);
00045   if (url)
00046     sess->url=strdup(url);
00047   if (defaultProto)
00048     sess->defaultProtocol=strdup(defaultProto);
00049   sess->defaultPort=defaultPort;
00050 
00051   return sess;
00052 }
00053 
00054 
00055 
00056 void GWEN_HttpSession_Attach(GWEN_HTTP_SESSION *sess) {
00057   assert(sess);
00058   assert(sess->usage);
00059   sess->usage++;
00060 }
00061 
00062 
00063 
00064 void GWEN_HttpSession_free(GWEN_HTTP_SESSION *sess) {
00065   if (sess) {
00066     assert(sess->usage);
00067     if (sess->usage==1) {
00068       GWEN_INHERIT_FINI(GWEN_HTTP_SESSION, sess);
00069       GWEN_SyncIo_free(sess->syncIo);
00070       free(sess->url);
00071       free(sess->defaultProtocol);
00072       free(sess->httpUserAgent);
00073       free(sess->httpContentType);
00074       GWEN_FREE_OBJECT(sess);
00075     }
00076     else {
00077       sess->usage--;
00078     }
00079   }
00080 }
00081 
00082 
00083 
00084 uint32_t GWEN_HttpSession_GetFlags(const GWEN_HTTP_SESSION *sess) {
00085   assert(sess);
00086   assert(sess->usage);
00087 
00088   return sess->flags;
00089 }
00090 
00091 
00092 
00093 void GWEN_HttpSession_SetFlags(GWEN_HTTP_SESSION *sess, uint32_t fl) {
00094   assert(sess);
00095   assert(sess->usage);
00096 
00097   sess->flags=fl;
00098 }
00099 
00100 
00101 
00102 void GWEN_HttpSession_AddFlags(GWEN_HTTP_SESSION *sess, uint32_t fl) {
00103   assert(sess);
00104   assert(sess->usage);
00105 
00106   sess->flags|=fl;
00107 }
00108 
00109 
00110 
00111 void GWEN_HttpSession_SubFlags(GWEN_HTTP_SESSION *sess, uint32_t fl) {
00112   assert(sess);
00113   assert(sess->usage);
00114 
00115   sess->flags&=~fl;
00116 }
00117 
00118 
00119 
00120 const char *GWEN_HttpSession_GetHttpUserAgent(const GWEN_HTTP_SESSION *sess) {
00121   assert(sess);
00122   assert(sess->usage);
00123 
00124   return sess->httpUserAgent;
00125 }
00126 
00127 
00128 
00129 void GWEN_HttpSession_SetHttpUserAgent(GWEN_HTTP_SESSION *sess, const char *s) {
00130   assert(sess);
00131   assert(sess->usage);
00132 
00133   free(sess->httpUserAgent);
00134   if (s)
00135     sess->httpUserAgent=strdup(s);
00136   else
00137     sess->httpUserAgent=NULL;
00138 }
00139 
00140 
00141 
00142 const char *GWEN_HttpSession_GetHttpContentType(const GWEN_HTTP_SESSION *sess) {
00143   assert(sess);
00144   assert(sess->usage);
00145 
00146   return sess->httpContentType;
00147 }
00148 
00149 
00150 
00151 void GWEN_HttpSession_SetHttpContentType(GWEN_HTTP_SESSION *sess, const char *s) {
00152   assert(sess);
00153   assert(sess->usage);
00154 
00155   free(sess->httpContentType);
00156   if (s)
00157     sess->httpContentType=strdup(s);
00158   else
00159     sess->httpContentType=NULL;
00160 }
00161 
00162 
00163 
00164 int GWEN_HttpSession_GetHttpVMajor(const GWEN_HTTP_SESSION *sess) {
00165   assert(sess);
00166   assert(sess->usage);
00167 
00168   return sess->httpVMajor;
00169 }
00170 
00171 
00172 
00173 void GWEN_HttpSession_SetHttpVMajor(GWEN_HTTP_SESSION *sess, int i) {
00174   assert(sess);
00175   assert(sess->usage);
00176 
00177   sess->httpVMajor=i;
00178 }
00179 
00180 
00181 
00182 int GWEN_HttpSession_GetHttpVMinor(const GWEN_HTTP_SESSION *sess) {
00183   assert(sess);
00184   assert(sess->usage);
00185 
00186   return sess->httpVMinor;
00187 }
00188 
00189 
00190 
00191 void GWEN_HttpSession_SetHttpVMinor(GWEN_HTTP_SESSION *sess, int i) {
00192   assert(sess);
00193   assert(sess->usage);
00194 
00195   sess->httpVMinor=i;
00196 }
00197 
00198 
00199 
00200 
00201 
00202 
00203 int GWEN_HttpSession_Init(GWEN_HTTP_SESSION *sess) {
00204   GWEN_SYNCIO *sio;
00205   GWEN_SYNCIO *sioTls;
00206   GWEN_DB_NODE *db;
00207   int rv;
00208 
00209   rv=GWEN_Gui_GetSyncIo(sess->url,
00210                         (sess->defaultProtocol)?(sess->defaultProtocol):"http",
00211                         sess->defaultPort,
00212                         &sio);
00213   if (rv<0) {
00214     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00215     return rv;
00216   }
00217 
00218   if (strcasecmp(GWEN_SyncIo_GetTypeName(sio), GWEN_SYNCIO_HTTP_TYPE)!=0) {
00219     DBG_ERROR(GWEN_LOGDOMAIN, "URL does not lead to a HTTP layer");
00220     GWEN_SyncIo_free(sio);
00221     return GWEN_ERROR_INVALID;
00222   }
00223 
00224   /* prepare TLS layer */
00225   sioTls=GWEN_SyncIo_GetBaseIoByTypeName(sio, GWEN_SYNCIO_TLS_TYPE);
00226   if (sioTls) {
00227     GWEN_SyncIo_AddFlags(sioTls,
00228                          GWEN_SYNCIO_TLS_FLAGS_ALLOW_V1_CA_CRT|
00229                          GWEN_SYNCIO_TLS_FLAGS_ADD_TRUSTED_CAS);
00230 
00231     if (sess->flags & GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3)
00232       GWEN_SyncIo_AddFlags(sioTls, GWEN_SYNCIO_TLS_FLAGS_FORCE_SSL_V3);
00233   }
00234 
00235 
00236   /* prepare HTTP out header */
00237   db=GWEN_SyncIo_Http_GetDbHeaderOut(sio);
00238   if (sess->flags & GWEN_HTTP_SESSION_FLAGS_NO_CACHE) {
00239     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00240                          "Pragma", "no-cache");
00241     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00242                          "Cache-control", "no cache");
00243   }
00244   if (sess->httpContentType)
00245     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00246                          "Content-type", sess->httpContentType);
00247 
00248   if (sess->httpUserAgent)
00249     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00250                          "User-Agent", sess->httpUserAgent);
00251   GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "close");
00252   GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-length", 0);
00253 
00254   sess->syncIo=sio;
00255 
00256   return 0;
00257 }
00258 
00259 
00260 
00261 int GWEN_HttpSession_Fini(GWEN_HTTP_SESSION *sess) {
00262   assert(sess);
00263   assert(sess->usage);
00264 
00265   if (sess->syncIo) {
00266     GWEN_SyncIo_Disconnect(sess->syncIo);
00267     GWEN_SyncIo_free(sess->syncIo);
00268     sess->syncIo=NULL;
00269   }
00270 
00271   return 0;
00272 }
00273 
00274 
00275 
00276 int GWEN_HttpSession_SendPacket(GWEN_HTTP_SESSION *sess,
00277                                 const char *httpCommand,
00278                                 const uint8_t *buf, uint32_t blen) {
00279   int rv;
00280 
00281   assert(sess);
00282   assert(sess->usage);
00283 
00284   /* first connect to server */
00285   GWEN_Gui_ProgressLog(0,
00286                        GWEN_LoggerLevel_Notice,
00287                        I18N("Connecting to server..."));
00288   rv=GWEN_SyncIo_Connect(sess->syncIo);
00289   if (rv==GWEN_ERROR_SSL) {
00290     GWEN_SYNCIO *sioTls;
00291 
00292     /* try again with alternated SSLv3 flag */
00293     DBG_NOTICE(GWEN_LOGDOMAIN,
00294                "SSL-Error connecting (%d), retrying", rv);
00295     GWEN_SyncIo_Disconnect(sess->syncIo);
00296 
00297     sioTls=GWEN_SyncIo_GetBaseIoByTypeName(sess->syncIo, GWEN_SYNCIO_TLS_TYPE);
00298     if (sioTls) {
00299       if (sess->flags & GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3) {
00300         DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (non-SSLv3)");
00301         GWEN_Gui_ProgressLog(0,
00302                              GWEN_LoggerLevel_Info,
00303                              I18N("Retrying to connect (non-SSLv3)"));
00304         GWEN_SyncIo_SubFlags(sioTls, GWEN_SYNCIO_TLS_FLAGS_FORCE_SSL_V3);
00305         rv=GWEN_SyncIo_Connect(sess->syncIo);
00306         if (rv==0) {
00307           GWEN_HttpSession_SubFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00308         }
00309       }
00310       else {
00311         DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (SSLv3)");
00312         GWEN_Gui_ProgressLog(0,
00313                              GWEN_LoggerLevel_Info,
00314                              I18N("Retrying to connect (SSLv3)"));
00315         GWEN_SyncIo_AddFlags(sioTls, GWEN_SYNCIO_TLS_FLAGS_FORCE_SSL_V3);
00316         rv=GWEN_SyncIo_Connect(sess->syncIo);
00317         if (rv==0) {
00318           GWEN_HttpSession_AddFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00319         }
00320       }
00321     }
00322   }
00323 
00324   if (rv<0) {
00325     DBG_INFO(GWEN_LOGDOMAIN, "Could not connect to server (%d)", rv);
00326     GWEN_Gui_ProgressLog(0,
00327                          GWEN_LoggerLevel_Error,
00328                          I18N("Could not connect to server"));
00329     GWEN_SyncIo_Disconnect(sess->syncIo);
00330     return rv;
00331   }
00332   else {
00333     GWEN_DB_NODE *db;
00334 
00335     GWEN_Gui_ProgressLog(0,
00336                          GWEN_LoggerLevel_Info,
00337                          I18N("Connected."));
00338 
00339     /* set command */
00340     db=GWEN_SyncIo_Http_GetDbCommandOut(sess->syncIo);
00341     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00342                          "command",
00343                          httpCommand);
00344     if (sess->httpVMajor) {
00345       char numbuf[32];
00346 
00347       snprintf(numbuf, sizeof(numbuf)-1, "HTTP/%d.%d",
00348                sess->httpVMajor, sess->httpVMinor);
00349       numbuf[sizeof(numbuf)-1]=0;
00350       GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00351                            "protocol",
00352                            numbuf);
00353     }
00354     else
00355       GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00356                            "protocol",
00357                            "HTTP/1.0");
00358 
00359     /* set content length */
00360     db=GWEN_SyncIo_Http_GetDbHeaderOut(sess->syncIo);
00361     GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00362                         "Content-length", blen);
00363 
00364     GWEN_Gui_ProgressLog(0,
00365                          GWEN_LoggerLevel_Info,
00366                          I18N("Sending message..."));
00367 
00368     /* send request */
00369     rv=GWEN_SyncIo_WriteForced(sess->syncIo, buf, blen);
00370     if (rv<0) {
00371       DBG_INFO(GWEN_LOGDOMAIN, "Could not send message (%d)", rv);
00372       GWEN_Gui_ProgressLog2(0,
00373                             GWEN_LoggerLevel_Error,
00374                             I18N("Could not send message (%d)"),
00375                             rv);
00376       GWEN_SyncIo_Disconnect(sess->syncIo);
00377       return rv;
00378     }
00379 
00380     DBG_INFO(GWEN_LOGDOMAIN, "Message sent.");
00381     GWEN_Gui_ProgressLog(0,
00382                          GWEN_LoggerLevel_Info,
00383                          I18N("Message sent."));
00384     return 0;
00385   }
00386 }
00387 
00388 
00389 
00390 int GWEN_HttpSession__RecvPacket(GWEN_HTTP_SESSION *sess, GWEN_BUFFER *buf) {
00391   int rv;
00392 
00393   assert(sess);
00394   assert(sess->usage);
00395 
00396   rv=GWEN_SyncIo_Http_RecvBody(sess->syncIo, buf);
00397   if (rv<0) {
00398     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00399     return rv;
00400   }
00401   else if (rv<200 || rv>299) {
00402     /* response is only ok for continuation (100) code */
00403     if (rv==100) {
00404       DBG_INFO(GWEN_LOGDOMAIN, "Continue...");
00405     }
00406     else {
00407       GWEN_DB_NODE *dbHeaderIn;
00408 
00409       dbHeaderIn=GWEN_SyncIo_Http_GetDbHeaderIn(sess->syncIo);
00410 
00411       if (rv==301 || rv==303 || rv==305 || rv==307) {
00412         /* moved */
00413         if (dbHeaderIn) {
00414           const char *s;
00415 
00416           s=GWEN_DB_GetCharValue(dbHeaderIn, "Location", 0, 0);
00417           if (s) {
00418             switch(rv) {
00419             case 301:
00420             case 303:
00421               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Moved permanently to %s"), s);
00422               break;
00423             case 305:
00424               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Use proxy at %s"), s);
00425               break;
00426             case 307:
00427               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Moved temporarily to %s"), s);
00428               break;
00429             default:
00430               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Moved to %s"), s);
00431             } /* switch */
00432           }
00433         }
00434       } /* if moved */
00435     }
00436   }
00437 
00438   return rv;
00439 }
00440 
00441 
00442 
00443 int GWEN_HttpSession_RecvPacket(GWEN_HTTP_SESSION *sess, GWEN_BUFFER *buf) {
00444   int rv;
00445   uint32_t pos;
00446 
00447   /* read response */
00448   pos=GWEN_Buffer_GetPos(buf);
00449   for (;;) {
00450     GWEN_Gui_ProgressLog(0,
00451                          GWEN_LoggerLevel_Info,
00452                          I18N("Receiving response..."));
00453     rv=GWEN_HttpSession__RecvPacket(sess, buf);
00454     if (rv<0 || rv<200 || rv>299) {
00455       DBG_INFO(GWEN_LOGDOMAIN,
00456                "Error receiving packet (%d)", rv);
00457       GWEN_SyncIo_Disconnect(sess->syncIo);
00458       return rv;
00459     }
00460     if (rv!=100)
00461       break;
00462     GWEN_Gui_ProgressLog(0,
00463                          GWEN_LoggerLevel_Info,
00464                          I18N("Received continuation response."));
00465     GWEN_Buffer_Crop(buf, 0, pos);
00466   }
00467 
00468   GWEN_Gui_ProgressLog(0,
00469                        GWEN_LoggerLevel_Info,
00470                        I18N("Response received."));
00471 
00472   /* disconnect */
00473   GWEN_Gui_ProgressLog(0,
00474                        GWEN_LoggerLevel_Info,
00475                        I18N("Disconnecting from server..."));
00476   GWEN_SyncIo_Disconnect(sess->syncIo);
00477   GWEN_Gui_ProgressLog(0,
00478                        GWEN_LoggerLevel_Info,
00479                        I18N("Disconnected."));
00480   return rv;
00481 }
00482 
00483 
00484 
00485 int GWEN_HttpSession__RecvPacketToSio(GWEN_HTTP_SESSION *sess, GWEN_SYNCIO *sio) {
00486   int rv;
00487 
00488   assert(sess);
00489   assert(sess->usage);
00490 
00491   rv=GWEN_SyncIo_Http_RecvBodyToSio(sess->syncIo, sio);
00492   if (rv<0) {
00493     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00494     return rv;
00495   }
00496   else if (rv<200 || rv>299) {
00497     /* response is only ok for continuation (100) code */
00498     if (rv==100) {
00499       DBG_INFO(GWEN_LOGDOMAIN, "Continue...");
00500     }
00501     else {
00502       GWEN_DB_NODE *dbHeaderIn;
00503 
00504       dbHeaderIn=GWEN_SyncIo_Http_GetDbHeaderIn(sess->syncIo);
00505 
00506       if (rv==301 || rv==303 || rv==305 || rv==307) {
00507         /* moved */
00508         if (dbHeaderIn) {
00509           const char *s;
00510 
00511           s=GWEN_DB_GetCharValue(dbHeaderIn, "Location", 0, 0);
00512           if (s) {
00513             switch(rv) {
00514             case 301:
00515             case 303:
00516               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Moved permanently to %s"), s);
00517               break;
00518             case 305:
00519               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Use proxy at %s"), s);
00520               break;
00521             case 307:
00522               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Moved temporarily to %s"), s);
00523               break;
00524             default:
00525               GWEN_Gui_ProgressLog2(0, GWEN_LoggerLevel_Warning, I18N("HTTP: Moved to %s"), s);
00526             } /* switch */
00527           }
00528         }
00529       } /* if moved */
00530     }
00531   }
00532 
00533   return rv;
00534 }
00535 
00536 
00537 
00538 int GWEN_HttpSession_RecvPacketToFile(GWEN_HTTP_SESSION *sess, const char *fname) {
00539   int rv;
00540 
00541   /* read response */
00542   for (;;) {
00543     GWEN_SYNCIO *sio;
00544 
00545     sio=GWEN_SyncIo_File_new(fname, GWEN_SyncIo_File_CreationMode_CreateAlways);
00546     GWEN_SyncIo_AddFlags(sio,
00547                          GWEN_SYNCIO_FILE_FLAGS_READ |
00548                          GWEN_SYNCIO_FILE_FLAGS_WRITE |
00549                          GWEN_SYNCIO_FILE_FLAGS_UREAD |
00550                          GWEN_SYNCIO_FILE_FLAGS_UWRITE |
00551                          GWEN_SYNCIO_FILE_FLAGS_GREAD |
00552                          GWEN_SYNCIO_FILE_FLAGS_GWRITE);
00553     rv=GWEN_SyncIo_Connect(sio);
00554     if (rv<0) {
00555       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00556       GWEN_SyncIo_free(sio);
00557       return rv;
00558     }
00559 
00560     GWEN_Gui_ProgressLog(0,
00561                          GWEN_LoggerLevel_Info,
00562                          I18N("Receiving response..."));
00563     rv=GWEN_HttpSession__RecvPacketToSio(sess, sio);
00564     if (rv<0 || rv<200 || rv>299) {
00565       DBG_INFO(GWEN_LOGDOMAIN,
00566                "Error receiving packet (%d)", rv);
00567       GWEN_SyncIo_Disconnect(sio);
00568       GWEN_SyncIo_free(sio);
00569       unlink(fname);
00570       GWEN_SyncIo_Disconnect(sess->syncIo);
00571       return rv;
00572     }
00573     if (rv!=100) {
00574       int rv2;
00575 
00576       /* flush file and close it */
00577       rv2=GWEN_SyncIo_Flush(sio);
00578       if (rv2<0) {
00579         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv2);
00580         GWEN_SyncIo_free(sio);
00581         return rv2;
00582       }
00583       rv2=GWEN_SyncIo_Disconnect(sio);
00584       if (rv2<0) {
00585         DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv2);
00586         GWEN_SyncIo_free(sio);
00587         return rv2;
00588       }
00589       GWEN_SyncIo_free(sio);
00590       break;
00591     }
00592     GWEN_Gui_ProgressLog(0,
00593                          GWEN_LoggerLevel_Info,
00594                          I18N("Received continuation response."));
00595     GWEN_SyncIo_Disconnect(sio);
00596     GWEN_SyncIo_free(sio);
00597     unlink(fname);
00598   }
00599 
00600   GWEN_Gui_ProgressLog(0,
00601                        GWEN_LoggerLevel_Info,
00602                        I18N("Response received."));
00603 
00604   /* disconnect */
00605   GWEN_Gui_ProgressLog(0,
00606                        GWEN_LoggerLevel_Info,
00607                        I18N("Disconnecting from server..."));
00608   GWEN_SyncIo_Disconnect(sess->syncIo);
00609   GWEN_Gui_ProgressLog(0,
00610                        GWEN_LoggerLevel_Info,
00611                        I18N("Disconnected."));
00612   return rv;
00613 }
00614 
00615 
00616 
00617 int GWEN_HttpSession_ConnectionTest(GWEN_HTTP_SESSION *sess) {
00618   int rv;
00619 
00620   assert(sess);
00621   assert(sess->usage);
00622 
00623   /* first connect to server */
00624   GWEN_Gui_ProgressLog(0,
00625                        GWEN_LoggerLevel_Notice,
00626                        I18N("Connecting to server..."));
00627   rv=GWEN_SyncIo_Connect(sess->syncIo);
00628   if (rv==GWEN_ERROR_SSL) {
00629     GWEN_SYNCIO *sioTls;
00630 
00631     /* try again with alternated SSLv3 flag */
00632     DBG_NOTICE(GWEN_LOGDOMAIN,
00633                "SSL-Error connecting (%d), retrying", rv);
00634     GWEN_SyncIo_Disconnect(sess->syncIo);
00635 
00636     sioTls=GWEN_SyncIo_GetBaseIoByTypeName(sess->syncIo, GWEN_SYNCIO_TLS_TYPE);
00637     if (sioTls) {
00638       if (sess->flags & GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3) {
00639         DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (non-SSLv3)");
00640         GWEN_Gui_ProgressLog(0,
00641                              GWEN_LoggerLevel_Info,
00642                              I18N("Retrying to connect (non-SSLv3)"));
00643         GWEN_SyncIo_SubFlags(sioTls, GWEN_SYNCIO_TLS_FLAGS_FORCE_SSL_V3);
00644         rv=GWEN_SyncIo_Connect(sess->syncIo);
00645         if (rv==0) {
00646           GWEN_HttpSession_SubFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00647         }
00648       }
00649       else {
00650         DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (SSLv3)");
00651         GWEN_Gui_ProgressLog(0,
00652                              GWEN_LoggerLevel_Info,
00653                              I18N("Retrying to connect (SSLv3)"));
00654         GWEN_SyncIo_AddFlags(sioTls, GWEN_SYNCIO_TLS_FLAGS_FORCE_SSL_V3);
00655         rv=GWEN_SyncIo_Connect(sess->syncIo);
00656         if (rv==0) {
00657           GWEN_HttpSession_AddFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00658         }
00659       }
00660     }
00661   }
00662 
00663   if (rv<0) {
00664     DBG_INFO(GWEN_LOGDOMAIN, "Could not connect to server (%d)", rv);
00665     GWEN_Gui_ProgressLog(0,
00666                          GWEN_LoggerLevel_Error,
00667                          I18N("Could not connect to server"));
00668     GWEN_SyncIo_Disconnect(sess->syncIo);
00669     return rv;
00670   }
00671   else {
00672     GWEN_Gui_ProgressLog(0,
00673                          GWEN_LoggerLevel_Info,
00674                          I18N("Connected."));
00675 
00676     GWEN_SyncIo_Disconnect(sess->syncIo);
00677     GWEN_Gui_ProgressLog(0,
00678                          GWEN_LoggerLevel_Info,
00679                          I18N("Disconnected."));
00680     return 0;
00681   }
00682 }
00683 
00684 
00685 
00686