httpsession.c

Go to the documentation of this file.
00001 /***************************************************************************
00002  $RCSfile$
00003                              -------------------
00004     begin       : Fri Feb 15 2008
00005     copyright   : (C) 2008 by Martin Preuss
00006     email       : martin@libchipcard.de
00007 
00008  ***************************************************************************
00009  *          Please see toplevel file COPYING for license details           *
00010  ***************************************************************************/
00011 
00012 
00013 #ifdef HAVE_CONFIG_H
00014 # include <config.h>
00015 #endif
00016 
00017 
00018 #include "httpsession_p.h"
00019 #include "i18n_l.h"
00020 
00021 #include <gwenhywfar/io_socket.h>
00022 #include <gwenhywfar/io_tls.h>
00023 #include <gwenhywfar/io_http.h>
00024 #include <gwenhywfar/io_buffered.h>
00025 #include <gwenhywfar/iomanager.h>
00026 
00027 #include <gwenhywfar/misc.h>
00028 #include <gwenhywfar/debug.h>
00029 #include <gwenhywfar/gui.h>
00030 
00031 #include <assert.h>
00032 
00033 
00034 GWEN_INHERIT_FUNCTIONS(GWEN_HTTP_SESSION)
00035 
00036 
00037 
00038 GWEN_HTTP_SESSION *GWEN_HttpSession_new(const char *url,
00039                                         uint32_t guiid) {
00040   GWEN_HTTP_SESSION *sess;
00041 
00042   GWEN_NEW_OBJECT(GWEN_HTTP_SESSION, sess);
00043   assert(sess);
00044   sess->usage=1;
00045   GWEN_INHERIT_INIT(GWEN_HTTP_SESSION, sess);
00046   if (url)
00047     sess->url=GWEN_Url_fromString(url);
00048   sess->guiid=guiid;
00049 
00050   return sess;
00051 }
00052 
00053 
00054 
00055 void GWEN_HttpSession_Attach(GWEN_HTTP_SESSION *sess) {
00056   assert(sess);
00057   assert(sess->usage);
00058   sess->usage++;
00059 }
00060 
00061 
00062 
00063 void GWEN_HttpSession_free(GWEN_HTTP_SESSION *sess) {
00064   if (sess) {
00065     assert(sess->usage);
00066     if (sess->usage==1) {
00067       GWEN_INHERIT_FINI(GWEN_HTTP_SESSION, sess);
00068       GWEN_Io_Layer_free(sess->ioLayer);
00069       free(sess->httpUserAgent);
00070       free(sess->httpContentType);
00071       GWEN_FREE_OBJECT(sess);
00072     }
00073     else {
00074       sess->usage--;
00075     }
00076   }
00077 }
00078 
00079 
00080 
00081 GWEN_IO_LAYER *GWEN_HttpSession_GetIoLayer(const GWEN_HTTP_SESSION *sess) {
00082   assert(sess);
00083   assert(sess->usage);
00084 
00085   return sess->ioLayer;
00086 }
00087 
00088 
00089 
00090 uint32_t GWEN_HttpSession_GetGuiId(const GWEN_HTTP_SESSION *sess) {
00091   assert(sess);
00092   assert(sess->usage);
00093 
00094   return sess->guiid;
00095 }
00096 
00097 
00098 
00099 uint32_t GWEN_HttpSession_GetFlags(const GWEN_HTTP_SESSION *sess) {
00100   assert(sess);
00101   assert(sess->usage);
00102 
00103   return sess->flags;
00104 }
00105 
00106 
00107 
00108 void GWEN_HttpSession_SetFlags(GWEN_HTTP_SESSION *sess, uint32_t fl) {
00109   assert(sess);
00110   assert(sess->usage);
00111 
00112   sess->flags=fl;
00113 }
00114 
00115 
00116 
00117 void GWEN_HttpSession_AddFlags(GWEN_HTTP_SESSION *sess, uint32_t fl) {
00118   assert(sess);
00119   assert(sess->usage);
00120 
00121   sess->flags|=fl;
00122 }
00123 
00124 
00125 
00126 void GWEN_HttpSession_SubFlags(GWEN_HTTP_SESSION *sess, uint32_t fl) {
00127   assert(sess);
00128   assert(sess->usage);
00129 
00130   sess->flags&=~fl;
00131 }
00132 
00133 
00134 
00135 const char *GWEN_HttpSession_GetHttpUserAgent(const GWEN_HTTP_SESSION *sess) {
00136   assert(sess);
00137   assert(sess->usage);
00138 
00139   return sess->httpUserAgent;
00140 }
00141 
00142 
00143 
00144 void GWEN_HttpSession_SetHttpUserAgent(GWEN_HTTP_SESSION *sess, const char *s) {
00145   assert(sess);
00146   assert(sess->usage);
00147 
00148   free(sess->httpUserAgent);
00149   if (s)
00150     sess->httpUserAgent=strdup(s);
00151   else
00152     sess->httpUserAgent=NULL;
00153 }
00154 
00155 
00156 
00157 const char *GWEN_HttpSession_GetHttpContentType(const GWEN_HTTP_SESSION *sess) {
00158   assert(sess);
00159   assert(sess->usage);
00160 
00161   return sess->httpContentType;
00162 }
00163 
00164 
00165 
00166 void GWEN_HttpSession_SetHttpContentType(GWEN_HTTP_SESSION *sess, const char *s) {
00167   assert(sess);
00168   assert(sess->usage);
00169 
00170   free(sess->httpContentType);
00171   if (s)
00172     sess->httpContentType=strdup(s);
00173   else
00174     sess->httpContentType=NULL;
00175 }
00176 
00177 
00178 
00179 int GWEN_HttpSession_GetHttpVMajor(const GWEN_HTTP_SESSION *sess) {
00180   assert(sess);
00181   assert(sess->usage);
00182 
00183   return sess->httpVMajor;
00184 }
00185 
00186 
00187 
00188 void GWEN_HttpSession_SetHttpVMajor(GWEN_HTTP_SESSION *sess, int i) {
00189   assert(sess);
00190   assert(sess->usage);
00191 
00192   sess->httpVMajor=i;
00193 }
00194 
00195 
00196 
00197 int GWEN_HttpSession_GetHttpVMinor(const GWEN_HTTP_SESSION *sess) {
00198   assert(sess);
00199   assert(sess->usage);
00200 
00201   return sess->httpVMinor;
00202 }
00203 
00204 
00205 
00206 void GWEN_HttpSession_SetHttpVMinor(GWEN_HTTP_SESSION *sess, int i) {
00207   assert(sess);
00208   assert(sess->usage);
00209 
00210   sess->httpVMinor=i;
00211 }
00212 
00213 
00214 
00215 
00216 
00217 
00218 int GWEN_HttpSession__SetAddress(GWEN_HTTP_SESSION *sess,
00219                                  GWEN_INETADDRESS *addr,
00220                                  const char *peerAddr) {
00221   int err;
00222 
00223   err=GWEN_InetAddr_SetAddress(addr, peerAddr);
00224   if (err) {
00225     char dbgbuf[256];
00226 
00227     snprintf(dbgbuf, sizeof(dbgbuf)-1,
00228              I18N("Resolving hostname \"%s\" ..."),
00229              peerAddr);
00230     dbgbuf[sizeof(dbgbuf)-1]=0;
00231     GWEN_Gui_ProgressLog(sess->guiid,
00232                          GWEN_LoggerLevel_Notice,
00233                          dbgbuf);
00234     DBG_INFO(GWEN_LOGDOMAIN, "Resolving hostname \"%s\"",
00235              peerAddr);
00236     err=GWEN_InetAddr_SetName(addr, peerAddr);
00237     if (err) {
00238       snprintf(dbgbuf, sizeof(dbgbuf)-1,
00239                I18N("Unknown hostname \"%s\""),
00240                peerAddr);
00241       dbgbuf[sizeof(dbgbuf)-1]=0;
00242       GWEN_Gui_ProgressLog(sess->guiid,
00243                            GWEN_LoggerLevel_Error,
00244                            dbgbuf);
00245       DBG_ERROR(GWEN_LOGDOMAIN,
00246                 "Error resolving hostname \"%s\":",
00247                 peerAddr);
00248       DBG_ERROR_ERR(GWEN_LOGDOMAIN, err);
00249       return err;
00250     }
00251     else {
00252       char addrBuf[256];
00253 
00254       err=GWEN_InetAddr_GetAddress(addr, addrBuf, sizeof(addrBuf)-1);
00255       addrBuf[sizeof(addrBuf)-1]=0;
00256       if (err) {
00257         DBG_ERROR_ERR(GWEN_LOGDOMAIN, err);
00258       }
00259       else {
00260         snprintf(dbgbuf, sizeof(dbgbuf)-1,
00261                  I18N("IP address is %s"),
00262                  addrBuf);
00263         dbgbuf[sizeof(dbgbuf)-1]=0;
00264         GWEN_Gui_ProgressLog(sess->guiid,
00265                              GWEN_LoggerLevel_Notice,
00266                              dbgbuf);
00267       }
00268     }
00269   }
00270 
00271   return 0;
00272 }
00273 
00274 
00275 
00276 int GWEN_HttpSession_Init(GWEN_HTTP_SESSION *sess) {
00277   int port;
00278   GWEN_SOCKET *sk;
00279   GWEN_INETADDRESS *addr;
00280   GWEN_IO_LAYER *io;
00281   GWEN_IO_LAYER *ioBase;
00282   int rv;
00283   GWEN_DB_NODE *db;
00284   const char *s;
00285   int isHttps;
00286 
00287   /* prepare socket layer */
00288   sk=GWEN_Socket_new(GWEN_SocketTypeTCP);
00289   io=GWEN_Io_LayerSocket_new(sk);
00290 
00291   addr=GWEN_InetAddr_new(GWEN_AddressFamilyIP);
00292   rv=GWEN_HttpSession__SetAddress(sess, addr, GWEN_Url_GetServer(sess->url));
00293   if (rv<0) {
00294     DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00295     GWEN_InetAddr_free(addr);
00296     return rv;
00297   }
00298 
00299   /* determine protocol */
00300   s=GWEN_Url_GetProtocol(sess->url);
00301   if (s) {
00302     if (strcasecmp(s, "http")==0) {
00303       isHttps=0;
00304     }
00305     else if (strcasecmp(s, "https")==0) {
00306       isHttps=1;
00307     }
00308     else {
00309       char dbgbuf[256];
00310 
00311       DBG_ERROR(GWEN_LOGDOMAIN, "Unknown protocol \"%s\"", s);
00312       snprintf(dbgbuf, sizeof(dbgbuf)-1,
00313                I18N("Unknown protocol \"%s\""),
00314                s);
00315       dbgbuf[sizeof(dbgbuf)-1]=0;
00316 
00317       GWEN_Gui_ProgressLog(sess->guiid,
00318                            GWEN_LoggerLevel_Error,
00319                            dbgbuf);
00320       GWEN_InetAddr_free(addr);
00321       return GWEN_ERROR_INVALID;
00322     }
00323   }
00324   else {
00325     /* default */
00326     isHttps=1;
00327   }
00328 
00329   port=GWEN_Url_GetPort(sess->url);
00330   if (port==0) {
00331     if (isHttps)
00332       port=443;
00333     else
00334       port=80;
00335   }
00336   GWEN_InetAddr_SetPort(addr, port);
00337   GWEN_Io_LayerSocket_SetPeerAddr(io, addr);
00338 
00339   /* prepare TLS layer */
00340   if (isHttps) {
00341     ioBase=io;
00342     io=GWEN_Io_LayerTls_new(ioBase);
00343     if (io==NULL) {
00344       GWEN_InetAddr_free(addr);
00345       GWEN_Io_Layer_free(ioBase);
00346       return GWEN_ERROR_GENERIC;
00347     }
00348     GWEN_Io_Layer_AddFlags(io,
00349                            GWEN_IO_LAYER_TLS_FLAGS_ALLOW_V1_CA_CRT|
00350                            GWEN_IO_LAYER_TLS_FLAGS_ADD_TRUSTED_CAS);
00351 
00352     if (sess->flags & GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3)
00353       GWEN_Io_Layer_AddFlags(io, GWEN_IO_LAYER_TLS_FLAGS_FORCE_SSL_V3);
00354 
00355     GWEN_Io_LayerTls_SetRemoteHostName(io, GWEN_Url_GetServer(sess->url));
00356   }
00357 
00358   /* prepare buffered layer */
00359   ioBase=io;
00360   io=GWEN_Io_LayerBuffered_new(ioBase);
00361   if (io==NULL) {
00362     GWEN_InetAddr_free(addr);
00363     GWEN_Io_Layer_free(ioBase);
00364     return GWEN_ERROR_GENERIC;
00365   }
00366 
00367   /* prepare HTTP layer */
00368   ioBase=io;
00369   io=GWEN_Io_LayerHttp_new(ioBase);
00370   if (io==NULL) {
00371     GWEN_InetAddr_free(addr);
00372     GWEN_Io_Layer_free(ioBase);
00373     return GWEN_ERROR_GENERIC;
00374   }
00375 
00376   /* prepare HTTP command line */
00377   db=GWEN_Io_LayerHttp_GetDbCommandOut(io);
00378   if (sess->httpVMajor) {
00379     char numbuf[32];
00380 
00381     snprintf(numbuf, sizeof(numbuf)-1, "HTTP/%d.%d",
00382              sess->httpVMajor, sess->httpVMinor);
00383     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", numbuf);
00384   }
00385   else
00386     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "protocol", "HTTP/1.0");
00387 
00388   if (1) {
00389     GWEN_BUFFER *pbuf;
00390 
00391     pbuf=GWEN_Buffer_new(0, 256, 0, 1);
00392     rv=GWEN_Url_toCommandString(sess->url, pbuf);
00393     if (rv) {
00394       DBG_INFO(GWEN_LOGDOMAIN, "here (%d)", rv);
00395       GWEN_Buffer_free(pbuf);
00396       GWEN_InetAddr_free(addr);
00397       GWEN_Io_Layer_free(ioBase);
00398       return rv;
00399     }
00400     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "url",
00401                          GWEN_Buffer_GetStart(pbuf));
00402     GWEN_Buffer_free(pbuf);
00403   }
00404 
00405   /* prepare HTTP out header */
00406   db=GWEN_Io_LayerHttp_GetDbHeaderOut(io);
00407   GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00408                        "Host", GWEN_Url_GetServer(sess->url));
00409   GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00410                        "Pragma", "no-cache");
00411   GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00412                        "Cache-control", "no cache");
00413   if (sess->httpContentType)
00414     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00415                          "Content-type", sess->httpContentType);
00416 
00417   if (sess->httpUserAgent)
00418     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00419                          "User-Agent", sess->httpUserAgent);
00420   GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Connection", "close");
00421   GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS, "Content-length", 0);
00422 
00423   /* now register the layer */
00424   rv=GWEN_Io_Manager_RegisterLayer(io);
00425   if (rv<0) {
00426     DBG_INFO(GWEN_LOGDOMAIN, "Could not register io layer (%d)", rv);
00427     GWEN_InetAddr_free(addr);
00428     GWEN_Io_Layer_free(io);
00429     return 0;
00430   }
00431 
00432   sess->ioLayer=io;
00433   GWEN_InetAddr_free(addr);
00434   return 0;
00435 }
00436 
00437 
00438 
00439 int GWEN_HttpSession_Fini(GWEN_HTTP_SESSION *sess) {
00440   assert(sess);
00441   assert(sess->usage);
00442 
00443   GWEN_Io_Layer_free(sess->ioLayer);
00444   sess->ioLayer=0;
00445   return 0;
00446 }
00447 
00448 
00449 
00450 int GWEN_HttpSession_SendPacket(GWEN_HTTP_SESSION *sess,
00451                                 const char *httpCommand,
00452                                 const uint8_t *buf, uint32_t blen,
00453                                 int timeout) {
00454   int rv;
00455 
00456   assert(sess);
00457   assert(sess->usage);
00458 
00459   /* first connect to server */
00460   GWEN_Gui_ProgressLog(sess->guiid,
00461                        GWEN_LoggerLevel_Notice,
00462                        I18N("Connecting to server..."));
00463   rv=GWEN_Io_Layer_ConnectRecursively(sess->ioLayer, NULL, 0,
00464                                       sess->guiid, 30000);
00465   if (rv==GWEN_ERROR_SSL) {
00466     GWEN_IO_LAYER *ioTls;
00467 
00468     /* try again with alternated SSLv3 flag */
00469     DBG_NOTICE(GWEN_LOGDOMAIN,
00470                "SSL-Error connecting (%d), retrying", rv);
00471     GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00472                                         GWEN_IO_REQUEST_FLAGS_FORCE,
00473                                         sess->guiid, 2000);
00474     ioTls=GWEN_Io_Layer_FindBaseLayerByType(sess->ioLayer,
00475                                             GWEN_IO_LAYER_TLS_TYPE);
00476     assert(ioTls);
00477 
00478     if (sess->flags & GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3) {
00479       DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (non-SSLv3)");
00480       GWEN_Gui_ProgressLog(sess->guiid,
00481                            GWEN_LoggerLevel_Info,
00482                            I18N("Retrying to connect (non-SSLv3)"));
00483       GWEN_Io_Layer_SubFlags(ioTls, GWEN_IO_LAYER_TLS_FLAGS_FORCE_SSL_V3);
00484       rv=GWEN_Io_Layer_ConnectRecursively(sess->ioLayer, NULL, 0,
00485                                           sess->guiid, 30000);
00486       if (rv==0) {
00487         GWEN_HttpSession_SubFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00488       }
00489     }
00490     else {
00491       DBG_INFO(GWEN_LOGDOMAIN, "Retrying to connect (SSLv3)");
00492       GWEN_Gui_ProgressLog(sess->guiid,
00493                            GWEN_LoggerLevel_Info,
00494                            I18N("Retrying to connect (SSLv3)"));
00495       GWEN_Io_Layer_AddFlags(ioTls, GWEN_IO_LAYER_TLS_FLAGS_FORCE_SSL_V3);
00496       rv=GWEN_Io_Layer_ConnectRecursively(sess->ioLayer, NULL, 0,
00497                                           sess->guiid, 30000);
00498       if (rv==0) {
00499         GWEN_HttpSession_AddFlags(sess, GWEN_HTTP_SESSION_FLAGS_FORCE_SSL3);
00500       }
00501     }
00502   }
00503 
00504   if (rv<0) {
00505     DBG_INFO(GWEN_LOGDOMAIN, "Could not connect to server (%d)", rv);
00506     GWEN_Gui_ProgressLog(sess->guiid,
00507                          GWEN_LoggerLevel_Error,
00508                          I18N("Could not connect to server"));
00509     GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00510                                         GWEN_IO_REQUEST_FLAGS_FORCE,
00511                                         sess->guiid, 2000);
00512     return rv;
00513   }
00514   else {
00515     GWEN_DB_NODE *db;
00516 
00517     GWEN_Gui_ProgressLog(sess->guiid,
00518                          GWEN_LoggerLevel_Info,
00519                          I18N("Connected."));
00520 
00521     /* set command */
00522     db=GWEN_Io_LayerHttp_GetDbCommandOut(sess->ioLayer);
00523     GWEN_DB_SetCharValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00524                          "command",
00525                          httpCommand);
00526 
00527     /* set content length */
00528     db=GWEN_Io_LayerHttp_GetDbHeaderOut(sess->ioLayer);
00529     GWEN_DB_SetIntValue(db, GWEN_DB_FLAGS_OVERWRITE_VARS,
00530                         "Content-length", blen);
00531 
00532     GWEN_Gui_ProgressLog(sess->guiid,
00533                          GWEN_LoggerLevel_Info,
00534                          I18N("Sending message..."));
00535     rv=GWEN_Io_Layer_WriteBytes(sess->ioLayer,
00536                                 buf, blen,
00537                                 GWEN_IO_REQUEST_FLAGS_PACKETBEGIN |
00538                                 GWEN_IO_REQUEST_FLAGS_PACKETEND |
00539                                 GWEN_IO_REQUEST_FLAGS_FLUSH,
00540                                 sess->guiid, timeout);
00541     if (rv<0) {
00542       DBG_INFO(GWEN_LOGDOMAIN, "Could not send message (%d)", rv);
00543       GWEN_Gui_ProgressLog(sess->guiid,
00544                            GWEN_LoggerLevel_Error,
00545                            I18N("Could not send message"));
00546       GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00547                                           GWEN_IO_REQUEST_FLAGS_FORCE,
00548                                           sess->guiid, 2000);
00549       return rv;
00550     }
00551 
00552     DBG_INFO(GWEN_LOGDOMAIN, "Message sent.");
00553     GWEN_Gui_ProgressLog(sess->guiid,
00554                          GWEN_LoggerLevel_Info,
00555                          I18N("Message sent."));
00556     return 0;
00557   }
00558 }
00559 
00560 
00561 
00562 int GWEN_HttpSession__RecvPacket(GWEN_HTTP_SESSION *sess,
00563                                  GWEN_BUFFER *buf, int timeout) {
00564   int rv;
00565   GWEN_DB_NODE *db;
00566   int code;
00567 
00568   assert(sess);
00569   assert(sess->usage);
00570 
00571   /* recv packet (this reads the HTTP body) */
00572   rv=GWEN_Io_Layer_ReadPacketToBuffer(sess->ioLayer, buf, 0,
00573                                       sess->guiid, 30000);
00574   if (rv<0) {
00575     if (GWEN_Buffer_GetUsedBytes(buf)) {
00576       /* data received, check for common error codes */
00577       if (rv==GWEN_ERROR_EOF || (rv==GWEN_ERROR_IO)) {
00578         DBG_INFO(GWEN_LOGDOMAIN,
00579                  "We received an error, but we still got data, "
00580                  "so we ignore the error here");
00581       }
00582       else {
00583         DBG_INFO(GWEN_LOGDOMAIN, "No message received (%d)", rv);
00584         GWEN_Gui_ProgressLog(sess->guiid,
00585                              GWEN_LoggerLevel_Error,
00586                              I18N("No message received"));
00587         return rv;
00588       }
00589     }
00590     else {
00591       DBG_INFO(GWEN_LOGDOMAIN, "No message received (%d)", rv);
00592       GWEN_Gui_ProgressLog(sess->guiid,
00593                            GWEN_LoggerLevel_Error,
00594                            I18N("No message received"));
00595       return rv;
00596     }
00597   }
00598 
00599   /* check for status and log it */
00600   db=GWEN_Io_LayerHttp_GetDbStatusIn(sess->ioLayer);
00601   code=GWEN_DB_GetIntValue(db, "code", 0, 0);
00602   if (code) {
00603     GWEN_BUFFER *lbuf;
00604     char sbuf[32];
00605     const char *text;
00606 
00607     lbuf=GWEN_Buffer_new(0, 64, 0, 1);
00608     GWEN_Buffer_AppendString(lbuf, "HTTP-Status: ");
00609     snprintf(sbuf, sizeof(sbuf)-1, "%d", code);
00610     sbuf[sizeof(sbuf)-1]=0;
00611     GWEN_Buffer_AppendString(lbuf, sbuf);
00612     text=GWEN_DB_GetCharValue(db, "text", 0, NULL);
00613     if (text) {
00614       GWEN_Buffer_AppendString(lbuf, " (");
00615       GWEN_Buffer_AppendString(lbuf, text);
00616       GWEN_Buffer_AppendString(lbuf, ")");
00617     }
00618     DBG_DEBUG(GWEN_LOGDOMAIN, "Status: %d (%s)",
00619               code, text);
00620     if (code<200 || code>299) {
00621       /* response is only ok for continuation (100) code */
00622       if (code!=100) {
00623         GWEN_DB_NODE *dbHeaderIn;
00624 
00625         dbHeaderIn=GWEN_Io_LayerHttp_GetDbHeaderIn(sess->ioLayer);
00626         DBG_ERROR(GWEN_LOGDOMAIN,
00627                   "Got an error response (%d: %s)",
00628                   code, text);
00629         GWEN_Gui_ProgressLog(sess->guiid,
00630                              GWEN_LoggerLevel_Error,
00631                              GWEN_Buffer_GetStart(lbuf));
00632         GWEN_Buffer_Reset(lbuf);
00633 
00634         if (code==301 || code==303 || code==305 || code==307) {
00635           /* moved */
00636           if (dbHeaderIn) {
00637             const char *s;
00638 
00639             s=GWEN_DB_GetCharValue(dbHeaderIn, "Location", 0, 0);
00640             if (s) {
00641               switch(code) {
00642               case 301:
00643               case 303:
00644                 GWEN_Buffer_AppendString(lbuf,
00645                                          I18N("HTTP: Moved permanently"));
00646                 break;
00647               case 305:
00648                 GWEN_Buffer_AppendString(lbuf,
00649                                          I18N("HTTP: Use proxy"));
00650                 break;
00651               case 307:
00652                 GWEN_Buffer_AppendString(lbuf,
00653                                          I18N("HTTP: Moved temporarily"));
00654                 break;
00655               default:
00656                 GWEN_Buffer_AppendString(lbuf,
00657                                          I18N("HTTP: Moved"));
00658               } /* switch */
00659               GWEN_Buffer_AppendString(lbuf, " (");
00660               GWEN_Buffer_AppendString(lbuf, s);
00661               GWEN_Buffer_AppendString(lbuf, ")");
00662 
00663               GWEN_Gui_ProgressLog(sess->guiid,
00664                                    GWEN_LoggerLevel_Warning,
00665                                    GWEN_Buffer_GetStart(lbuf));
00666             }
00667           }
00668         }
00669       }
00670       else {
00671         GWEN_Gui_ProgressLog(sess->guiid,
00672                              GWEN_LoggerLevel_Notice,
00673                              GWEN_Buffer_GetStart(lbuf));
00674       }
00675     }
00676     else {
00677       GWEN_Gui_ProgressLog(sess->guiid,
00678                            GWEN_LoggerLevel_Info,
00679                            GWEN_Buffer_GetStart(lbuf));
00680     }
00681     GWEN_Buffer_free(lbuf);
00682   }
00683   else {
00684     DBG_ERROR(GWEN_LOGDOMAIN, "No HTTP status code received");
00685     GWEN_Gui_ProgressLog(sess->guiid,
00686                          GWEN_LoggerLevel_Error,
00687                          I18N("No HTTP status code received"));
00688     code=GWEN_ERROR_BAD_DATA;
00689   }
00690 
00691   return code;
00692 }
00693 
00694 
00695 
00696 int GWEN_HttpSession_RecvPacket(GWEN_HTTP_SESSION *sess,
00697                                 GWEN_BUFFER *buf, int timeout) {
00698   int rv;
00699   uint32_t pos;
00700 
00701   /* read response */
00702   pos=GWEN_Buffer_GetPos(buf);
00703   for (;;) {
00704     GWEN_Gui_ProgressLog(sess->guiid,
00705                          GWEN_LoggerLevel_Info,
00706                          I18N("Waiting for response..."));
00707     rv=GWEN_HttpSession__RecvPacket(sess, buf, timeout);
00708     if (rv<0 || rv<200 || rv>299) {
00709       DBG_INFO(GWEN_LOGDOMAIN,
00710                "Error receiving packet (%d)", rv);
00711       GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00712                                           GWEN_IO_REQUEST_FLAGS_FORCE,
00713                                           sess->guiid, 2000);
00714       return rv;
00715     }
00716     if (rv!=100)
00717       break;
00718     GWEN_Gui_ProgressLog(sess->guiid,
00719                          GWEN_LoggerLevel_Info,
00720                          I18N("Received continuation response."));
00721     GWEN_Buffer_Crop(buf, 0, pos);
00722   }
00723 
00724   GWEN_Gui_ProgressLog(sess->guiid,
00725                        GWEN_LoggerLevel_Info,
00726                        I18N("Response received."));
00727 
00728   /* disconnect */
00729   GWEN_Gui_ProgressLog(sess->guiid,
00730                        GWEN_LoggerLevel_Info,
00731                        I18N("Disconnecting from server..."));
00732   GWEN_Io_Layer_DisconnectRecursively(sess->ioLayer, NULL,
00733                                       GWEN_IO_REQUEST_FLAGS_FORCE,
00734                                       sess->guiid, 2000);
00735   GWEN_Gui_ProgressLog(sess->guiid,
00736                        GWEN_LoggerLevel_Info,
00737                        I18N("Disconnected."));
00738 
00739   return 0;
00740 }
00741 
00742 
00743 
00744 
00745 
00746 
00747 

Generated on Fri Apr 11 01:53:46 2008 for gwenhywfar by  doxygen 1.5.5